Skip to content

Commit

Permalink
Rebuild shim files based on upstream sources.
Browse files Browse the repository at this point in the history
This patch uses a new approach where shim files are copied from the
original and replace a list of key functions. This makes it easier to
build the shims across different upstream versions.

One tests is disabled:
- program linking is changed in the latest WebGL spec. this test can be
  turned on with a newer WebGL test suite.

This contribution is funded by https://higharc.com/
  • Loading branch information
null77 committed Jan 13, 2025
1 parent 7d66f8c commit 9188750
Show file tree
Hide file tree
Showing 23 changed files with 2,548 additions and 1,017 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
# Date keyword expansion
specs/latest/**/index.html filter=dater
*.js text eol=lf
41 changes: 38 additions & 3 deletions README.khronos.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
The Official Khronos WebGL Repository
# The Official Khronos WebGL Repository

This is the official home of the Khronos
WebGL repository for the WebGL specifications
Expand All @@ -8,7 +8,7 @@ Before adding a new test or editing an existing test
[please read these guidelines](sdk/tests/test-guidelines.md).

You can find live versions of the specifications at
http://www.khronos.org/webgl/
https://www.khronos.org/webgl/

The newest work in progress WebGL conformance test suite
for the next version of the spec can be accessed at.
Expand All @@ -18,6 +18,41 @@ Official live versions of the conformance test suite can be found at
https://www.khronos.org/registry/webgl/conformance-suites/

The WebGL Wiki can be found here
http://www.khronos.org/webgl/wiki/
https://www.khronos.org/webgl/wiki/

This repository is licensed under the MIT license and all
contributions are covered under the [MIT
CLA](https://gist.github.com/KhronosWebservices/8f6da941cd2bb316e1f32e40a7f94429).

## Cloning this repository

When cloning this repository please pass the --recursive flag to git:

git clone --recursive [URL]

This will properly install the [WebGLDeveloperTools](https://github.com/KhronosGroup/WebGLDeveloperTools)
repository as a git submodule under sdk/devtools/.

The last edited date in several specifications is automatically updated
via a smudge filter. To benefit from this you must issue the following
commands in the root of your clone.

On Unix (Linux, Mac OS X, etc.) platforms and Windows using Git for Windows'
Git Bash or Cygwin's bash terminal:

```bash
./install-gitconfig.sh
rm specs/latest/*/index.html
git checkout !$
```

On Windows with the Command Prompt (requires `git.exe` in a directory
on your %PATH%):

```cmd
install-gitconfig.bat
del specs/latest/1.0/index.html specs/latest/2.0/index.html
git checkout specs/latest/1.0/index.html specs/latest/2.0/index.html
```

The first command adds an [include] of the repo's `.gitconfig` to the local git config file`.git/config` in your clone of the repo. `.gitconfig` contains the config of the "dater" filter. The remaining commands force a new checkout of the index.html files to smudge them with the date. These two are unnecessary if you plan to edit these files. All are unecessary if you do not care about having the dates shown.
92 changes: 53 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,58 +1,72 @@
# The Official Khronos WebGL Repository
gl-conformance
==============
A port of the Khronos ARB WebGL conformance test suite to CommonJS and tape, so that it can be run without a browser or from within browserify easily.

# Example usage

To use the test suite, you pass it a reference to tape and whatever function you are going to use to create WebGL contexts:

```javascript
require('gl-conformance')({
tape: require('tape'),
createContext: function(width, height, options) {
//Replace this with a function that constructs your WebGL context
var canvas = document.createElement('canvas')
canvas.width = width
canvas.height = height
var context = canvas.getContext('webgl', options)
return context
}
})
```

This is the official home of the Khronos
WebGL repository for the WebGL specifications
and the WebGL conformance test suite.
Then it will churn away at all the Khronos/ARB test cases and report the output to stdout as one would expect tap/tape to do.

Before adding a new test or editing an existing test
[please read these guidelines](sdk/tests/test-guidelines.md).
# Installation

You can find live versions of the specifications at
https://www.khronos.org/webgl/
```
npm install gl-conformance
```

The newest work in progress WebGL conformance test suite
for the next version of the spec can be accessed at.
https://www.khronos.org/registry/webgl/sdk/tests/webgl-conformance-tests.html
# API

Official live versions of the conformance test suite can be found at
https://www.khronos.org/registry/webgl/conformance-suites/
### `require('gl-conformance')(environment)`
Runs the WebGL conformance suite within the given environment. `environment` is an object with the following properties:

The WebGL Wiki can be found here
https://www.khronos.org/webgl/wiki/
* `tape` a refernce to a [`tape` object](https://www.npmjs.org/package/tape)
* `createContext(width,height,opts)` a function which creates a WebGL context from the given parameters
* `filter(caseName)` an optional filter which returns `true` if the case `caseName` should be run

This repository is licensed under the MIT license and all
contributions are covered under the [MIT
CLA](https://gist.github.com/KhronosWebservices/8f6da941cd2bb316e1f32e40a7f94429).
# Building the test suite

## Cloning this repository
If you are installing from npm, you can ignore this section. Otherwise, for users who are building the project from github, you need to do the following:

When cloning this repository please pass the --recursive flag to git:

git clone --recursive [URL]
### 1. Install dependencies

This will properly install the [WebGLDeveloperTools](https://github.com/KhronosGroup/WebGLDeveloperTools)
repository as a git submodule under sdk/devtools/.
```
npm install
```

The last edited date in several specifications is automatically updated
via a smudge filter. To benefit from this you must issue the following
commands in the root of your clone.
### 2. Run the build script

On Unix (Linux, Mac OS X, etc.) platforms and Windows using Git for Windows'
Git Bash or Cygwin's bash terminal:
```
npm run-script build
```

### 3. Run the test (uses browser WebGL context)

```bash
./install-gitconfig.sh
rm specs/latest/*/index.html
git checkout !$
```
npm test
```

On Windows with the Command Prompt (requires `git.exe` in a directory
on your %PATH%):
### 4. Publish

```cmd
install-gitconfig.bat
del specs/latest/1.0/index.html specs/latest/2.0/index.html
git checkout specs/latest/1.0/index.html specs/latest/2.0/index.html
```
npm publish
```

# License
Conformance tests are (c) Khronos ARB

The first command adds an [include] of the repo's `.gitconfig` to the local git config file`.git/config` in your clone of the repo. `.gitconfig` contains the config of the "dater" filter. The remaining commands force a new checkout of the index.html files to smudge them with the date. These two are unnecessary if you plan to edit these files. All are unecessary if you do not care about having the dates shown.
CommonJS port by Mikola Lysenko
16 changes: 10 additions & 6 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,22 @@ var BLACKLIST = require('./lib/blacklist.json')
var VERSION = '1.0.3'
var TEST_DIR = path.join(__dirname, 'node-test')

// Build conformance test suite
var scanFiles = require('./lib/scan-files')
var parseCase = require('./lib/parse-case')
var genCase = require('./lib/compile-case')
var getResources = require('./lib/load-resources')

var SUITE_DIR = path.join(
__dirname,
'conformance-suites',
VERSION,
'conformance')

// We build shims ASAP because some scripts scan in shims immediately.
var buildShims = require('./lib/build-shims')
buildShims(SUITE_DIR)

// Build conformance test suite
var scanFiles = require('./lib/scan-files')
var parseCase = require('./lib/parse-case')
var genCase = require('./lib/compile-case')
var getResources = require('./lib/load-resources')

function fail (err) {
console.error('crashing', err)
process.exit(-1)
Expand Down
1 change: 1 addition & 0 deletions lib/blacklist.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"extensions/webgl-depth-texture.html",
"glsl/misc/re-compile-re-link.html",
"glsl/samplers/glsl-function-texture2dproj.html",
"programs/program-test.html",
"textures/texture-npot-video.html",
"textures/gl-pixelstorei.html",
"textures/gl-teximage.html",
Expand Down
110 changes: 110 additions & 0 deletions lib/build-shims.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
'use strict'

module.exports = buildShims

const fs = require('fs');
const path = require('path');

/**
* Reads the replacement functions from a file.
* @param {string} replacementsCode - replacement functions.
* @returns {object} - An object where keys are function names and values are their new implementations.
*/
function loadReplacements(replacementsCode) {
const replacements = {};

// Extract functions defined as "var name = function".
replacementsCode.replace(/var\s+(\w+)\s*=\s*function\s*\([^)]*\)\s*[\s\S]*?(?=\n\};?)\n\};?[^\n]*\n/g, (match, functionName) => {
replacements[functionName] = match;
});

// Extract functions defined as "function name"
replacementsCode.replace(/function\s+(\w+)\s*\([^)]*\)\s*[\s\S]*?(?=\n\};?)\n\};?[^\n]*\n/g, (match, functionName) => {
replacements[functionName] = match;
});

return replacements;
}

/**
* Replaces functions in the source code with the provided replacements.
* @param {string} sourceCode - The original source code.
* @param {object} replacements - An object containing function name to implementation mappings.
* @returns {string} - The modified source code.
*/
function replaceFunctionsInSource(sourceCode, replacements) {
return sourceCode.replace(
/var\s+(\w+)\s*=\s*\(?function\([^\)]*\)\s+[\s\S]*?(?=\n\};?)\n\};?[^\n]*\n/g,
(match, functionName) => {
if (replacements[functionName]) {
console.log(`Replacing function: ${functionName}`);
return replacements[functionName];
}
return match; // Keep the original function if no replacement is found.
}
).replace(
/function\s+(\w+)\([^\)]*\)\s+[\s\S]*?(?=\n\};?)\n\};?[^\n]*\n/g,
(match, functionName) => {
if (replacements[functionName]) {
console.log(`Replacing function: ${functionName}`);
return replacements[functionName];
}
return match; // Keep the original function if no replacement is found.
}
).replace(/\n\(function\s*\(\)[\s\S]*?(?=\n\})\n\}[^\n]*\n/, "");
}

function extractContentBeforeFirstFunction(replacementsCode) {
const regex = /^[\s\S]*?^.*\s(?=[^\r\n]*function)/m;
const match = replacementsCode.match(regex);

if (match) {
const contentBeforeFunction = match[0];
return contentBeforeFunction;
}

// If no "function" line is found, return the entire content
return replacementsCode;
}

/**
* Main function to process the JavaScript file.
* @param {string} inputFilePath - Path to the input JavaScript file.
* @param {string} replacementsFilePath - Path to the file containing replacement functions.
* @param {string} outputFilePath - Path to save the modified JavaScript file.
*/
function processFile(inputFilePath, replacementsFilePath, outputFilePath) {
try {
let sourceCode = fs.readFileSync(inputFilePath, 'utf-8');

if (fs.existsSync(replacementsFilePath)) {
const replacementsCode = fs.readFileSync(replacementsFilePath, 'utf-8');
const replacements = loadReplacements(replacementsCode);

const beforeFirstFunction = extractContentBeforeFirstFunction(replacementsCode);

sourceCode = replaceFunctionsInSource(sourceCode, replacements);

const TOP_MARKER = `*/`

sourceCode = sourceCode.replace(TOP_MARKER, `${TOP_MARKER}\n${beforeFirstFunction}`);
}

fs.writeFileSync(outputFilePath, sourceCode, 'utf-8');
console.log(`File processed and saved to ${outputFilePath}`);
} catch (error) {
console.error('Error processing file:', error);
}
}

function buildShims(suiteDir) {
var RESOURCES = require('./shims.json')
Object.keys(RESOURCES).forEach(function (resName) {
var resource = RESOURCES[resName]
var inputFilePath = path.join(suiteDir, resName)
var outputFilePath = path.join(__dirname, resource.path)
var replacementsFilePath = path.join(__dirname, 'shims', `${path.basename(resource.path, '.js')}-funcs.js`)
processFile(inputFilePath, replacementsFilePath, outputFilePath)
})

}
Loading

0 comments on commit 9188750

Please sign in to comment.