├── src ├── version.ts ├── binding.d.ts ├── tests │ ├── unsigned_byte_texture_upload_test.ts │ ├── half_float_texture_upload_test.ts │ ├── float_texture_upload_test.ts │ ├── test_utils.ts │ └── old_texture_test.ts └── index.ts ├── .gitignore ├── .npmignore ├── tsconfig.json ├── .vscode ├── c_cpp_properties.json └── settings.json ├── scripts ├── build-npm.sh ├── bundle.js ├── make-version ├── tag-version ├── publish-npm.sh └── install.js ├── package.json ├── CONTRIBUTING.md ├── binding ├── webgl_sync.h ├── webgl_sync.cc ├── binding.cc ├── webgl_extensions.h ├── egl_context_wrapper.h ├── utils.h ├── webgl_rendering_context.h ├── egl_context_wrapper.cc └── webgl_extensions.cc ├── tslint.json ├── binding.gyp ├── README.md ├── LICENSE └── yarn.lock /src/version.ts: -------------------------------------------------------------------------------- 1 | /** @license See the LICENSE file. */ 2 | 3 | // This code is auto-generated, do not modify this file! 4 | const version = '0.0.16'; 5 | export {version}; 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build/ 2 | dist/ 3 | deps/ 4 | node_modules/ 5 | yarn-error.log 6 | yalc.lock 7 | .yalc/ 8 | demo/train-* 9 | *.log 10 | .nyc_output/ 11 | coverage/ 12 | .DS_Store 13 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | demo/ 3 | deps/angle/* 4 | scripts/build-npm.sh 5 | scripts/make-version 6 | scripts/tag-version 7 | scripts/publish-npm.sh 8 | build/ 9 | src/ 10 | node_modules/ 11 | *.tgz 12 | .travis.yml 13 | .npmignore 14 | CONTRIBUTING.md 15 | tslint.json 16 | yarn.lock 17 | yalc.lock 18 | yarn-error.log 19 | .yalc/ 20 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "noImplicitAny": true, 5 | "sourceMap": true, 6 | "removeComments": true, 7 | "preserveConstEnums": true, 8 | "declaration": true, 9 | "target": "es5", 10 | "lib": ["es2015", "dom"], 11 | "outDir": "./dist", 12 | "noUnusedLocals": true, 13 | "noImplicitReturns": true, 14 | "noImplicitThis": true, 15 | "alwaysStrict": true, 16 | "noUnusedParameters": false, 17 | "pretty": true, 18 | "noFallthroughCasesInSwitch": true, 19 | "allowUnreachableCode": false, 20 | "experimentalDecorators": true 21 | }, 22 | "include": [ 23 | "src/" 24 | ] 25 | } 26 | -------------------------------------------------------------------------------- /.vscode/c_cpp_properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations": [ 3 | { 4 | "name": "Mac", 5 | "includePath": [ 6 | "${workspaceFolder}/**", 7 | "${workspaceFolder}/deps/angle/include", 8 | "${env.HOME}/.node-gyp/10.15.3/include/node", 9 | "/usr/include/c++/7", 10 | "/usr/local/google/home/kreeger/.node-gyp/10.14.2/include/node", 11 | "/usr/include/x86_64-linux-gnu/c++/7" 12 | ], 13 | "defines": [], 14 | "macFrameworkPath": [], 15 | "compilerPath": "/usr/bin/clang", 16 | "cStandard": "c11", 17 | "cppStandard": "c++17", 18 | "intelliSenseMode": "clang-x64" 19 | } 20 | ], 21 | "version": 4 22 | } -------------------------------------------------------------------------------- /scripts/build-npm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2019 Google Inc. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ============================================================================= 16 | 17 | set -e 18 | 19 | rimraf dist/ 20 | yarn 21 | tsc --sourceMap false 22 | npm pack 23 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "node-gles", 3 | "version": "0.0.17", 4 | "main": "dist/index.js", 5 | "types": "dist/index.d.ts", 6 | "gypfile": true, 7 | "repository": { 8 | "type": "git", 9 | "url": "https://github.com/google/node-gles.git" 10 | }, 11 | "engines": { 12 | "node": ">=8.11.0" 13 | }, 14 | "license": "Apache-2.0", 15 | "scripts": { 16 | "build-npm": "./scripts/build-npm.sh", 17 | "format": "clang-format -i -style=Google binding/*.cc binding/*.h", 18 | "install": "node scripts/install.js" 19 | }, 20 | "devDependencies": { 21 | "@types/bindings": "^1.3.0", 22 | "@types/node": "^10.9.4", 23 | "@types/progress": "^2.0.3", 24 | "@types/webgl2": "^0.0.4", 25 | "clang-format": "^1.2.4", 26 | "ts-node": "^7.0.1", 27 | "typescript": "^3.0.3", 28 | "yalc": "^1.0.0-pre.27" 29 | }, 30 | "dependencies": { 31 | "adm-zip": "^0.4.13", 32 | "bindings": "^1.3.0", 33 | "https-proxy-agent": "^2.2.3", 34 | "progress": "^2.0.3", 35 | "rimraf": "^2.6.2", 36 | "tar": "^6.0.1" 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/binding.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | export interface NodeJsGlBinding { 19 | createWebGLRenderingContext( 20 | width: number, 21 | height: number, 22 | client_major_es_version: number, 23 | client_minor_es_version: number, 24 | webgl_compatbility: boolean 25 | ): WebGLRenderingContext | WebGL2RenderingContext; 26 | } 27 | -------------------------------------------------------------------------------- /src/tests/unsigned_byte_texture_upload_test.ts: -------------------------------------------------------------------------------- 1 | import * as gles from '../.'; 2 | 3 | import {createTexture2D, ensureFramebufferAttachment, initEnvGL} from './test_utils'; 4 | 5 | const gl = gles.createWebGLRenderingContext(); 6 | 7 | console.log('VERSION: ' + gl.getParameter(gl.VERSION)); 8 | console.log('RENDERER: ' + gl.getParameter(gl.RENDERER)); 9 | 10 | initEnvGL(gl); // Don't worry about buffers in this demo 11 | 12 | const texture = createTexture2D(gl, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE); 13 | gl.bindTexture(gl.TEXTURE_2D, texture); 14 | 15 | const values = new Uint8Array([1, 2, 3, 4]); 16 | gl.texSubImage2D( 17 | gl.TEXTURE_2D, 0, 0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, values); 18 | 19 | const framebuffer = gl.createFramebuffer(); 20 | gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); 21 | gl.framebufferTexture2D( 22 | gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); 23 | ensureFramebufferAttachment(gl); 24 | 25 | const buffer = new Uint8Array(4); 26 | gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, buffer); 27 | console.log('buffer: ', buffer); 28 | -------------------------------------------------------------------------------- /scripts/bundle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | const os = require('os'); 19 | 20 | console.log('-----------'); 21 | const arch = `${os.platform()}-${os.arch().toLowerCase()}`; 22 | console.log('platform: ' + arch); 23 | console.log('-----------'); 24 | 25 | // > ninja -C out/Release libGLESv2 libEGL 26 | // > tar -czvf angle-darwin-x64.tar.gz angle/out/Release/*.dylib angle/include/ 27 | -------------------------------------------------------------------------------- /src/tests/half_float_texture_upload_test.ts: -------------------------------------------------------------------------------- 1 | import * as gles from '../.'; 2 | 3 | import {createTexture2D, ensureFramebufferAttachment, initEnvGL} from './test_utils'; 4 | 5 | const gl = gles.createWebGLRenderingContext(); 6 | 7 | console.log('VERSION: ' + gl.getParameter(gl.VERSION)); 8 | console.log('RENDERER: ' + gl.getParameter(gl.RENDERER)); 9 | 10 | const ext = gl.getExtension('OES_texture_half_float'); 11 | gl.getExtension('EXT_color_buffer_half_float'); 12 | 13 | initEnvGL(gl); // Don't worry about buffers in this demo 14 | 15 | const texture = createTexture2D(gl, gl.RGBA, gl.RGBA, ext.HALF_FLOAT_OES); 16 | gl.bindTexture(gl.TEXTURE_2D, texture); 17 | 18 | const values = new Float32Array([0.5, 1.5, 2.5, 3.5]); 19 | gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, gl.RGBA, gl.FLOAT, values); 20 | 21 | const framebuffer = gl.createFramebuffer(); 22 | gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); 23 | gl.framebufferTexture2D( 24 | gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); 25 | ensureFramebufferAttachment(gl); 26 | 27 | const buffer = new Float32Array(4); 28 | gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, buffer); 29 | console.log('buffer: ', buffer); 30 | -------------------------------------------------------------------------------- /src/tests/float_texture_upload_test.ts: -------------------------------------------------------------------------------- 1 | import * as gles from '../.'; 2 | 3 | import {createTexture2D, ensureFramebufferAttachment, initEnvGL} from './test_utils'; 4 | 5 | const gl = gles.createWebGLRenderingContext({}); 6 | const gl2 = gl as WebGL2RenderingContext; 7 | 8 | gl.getExtension('OES_texture_float'); 9 | gl.getExtension('EXT_color_buffer_float'); 10 | 11 | console.log('VERSION: ' + gl.getParameter(gl.VERSION)); 12 | console.log('RENDERER: ' + gl.getParameter(gl.RENDERER)); 13 | 14 | initEnvGL(gl); // Don't worry about buffers in this demo 15 | 16 | const texture = createTexture2D(gl, gl2.RGBA32F, gl.RGBA, gl.FLOAT); 17 | gl.bindTexture(gl.TEXTURE_2D, texture); 18 | 19 | const values = new Float32Array([0.5, 1.5, 2.5, 3.5]); 20 | gl.texSubImage2D(gl.TEXTURE_2D, 0, 0, 0, 1, 1, gl.RGBA, gl.FLOAT, values); 21 | 22 | const framebuffer = gl.createFramebuffer(); 23 | 24 | gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); 25 | gl.framebufferTexture2D( 26 | gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0); 27 | ensureFramebufferAttachment(gl); 28 | 29 | const buffer = new Float32Array(4); 30 | gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, buffer); 31 | console.log('buffer: ', buffer); 32 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Community Guidelines 26 | 27 | This project follows 28 | [Google's Open Source Community Guidelines](https://opensource.google.com/conduct/). -------------------------------------------------------------------------------- /binding/webgl_sync.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | #ifndef NODEJS_GL_WEBGL_SYNC_H_ 19 | #define NODEJS_GL_WEBGL_SYNC_H_ 20 | 21 | #include 22 | 23 | #include "angle/include/GLES2/gl2.h" 24 | 25 | #include "egl_context_wrapper.h" 26 | 27 | namespace nodejsgl { 28 | 29 | // Creates and wraps a JS object with a GLsync instance. 30 | napi_status WrapGLsync(napi_env env, GLsync &sync, 31 | EGLContextWrapper *egl_context_wrapper, 32 | napi_value *wrapped_value); 33 | 34 | } // namespace nodejsgl 35 | 36 | #endif // NODEJS_GL_WEBGL_SYNC_H_ 37 | -------------------------------------------------------------------------------- /scripts/make-version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // Copyright 2018 Google LLC. All Rights Reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ============================================================================= 16 | 17 | 18 | // Run this script from the base directory (not the script directory): 19 | // ./scripts/make-version 20 | 21 | const fs = require('fs'); 22 | const version = JSON.parse(fs.readFileSync('package.json', 'utf8')).version; 23 | 24 | const versionCode = 25 | `/** @license See the LICENSE file. */ 26 | 27 | // This code is auto-generated, do not modify this file! 28 | const version = '${version}'; 29 | export {version}; 30 | ` 31 | 32 | fs.writeFile('src/version.ts', versionCode, err => { 33 | if (err) { 34 | throw new Error(`Could not save version file ${version}: ${err}`); 35 | } 36 | console.log(`Version file for version ${version} saved sucessfully.`); 37 | }); 38 | -------------------------------------------------------------------------------- /scripts/tag-version: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | // Copyright 2019 Google LLC. All Rights Reserved. 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | // ============================================================================= 16 | 17 | 18 | // Run this script from the base directory (not the script directory): 19 | // ./scripts/tag-version 20 | 21 | var fs = require('fs'); 22 | var exec = require('child_process').exec; 23 | 24 | var version = JSON.parse(fs.readFileSync('package.json', 'utf8')).version; 25 | var tag = `v${version}`; 26 | 27 | exec(`git tag ${tag}`, err => { 28 | if (err) { 29 | throw new Error(`Could not git tag with ${tag}: ${err.message}.`); 30 | } 31 | console.log(`Successfully tagged with ${tag}.`); 32 | }); 33 | 34 | exec(`git push --tags`, err => { 35 | if (err) { 36 | throw new Error(`Could not push git tags: ${err.message}.`); 37 | } 38 | console.log(`Successfully pushed tags.`); 39 | }); 40 | -------------------------------------------------------------------------------- /scripts/publish-npm.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2019 Google Inc. All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ============================================================================= 16 | 17 | # Before you run this script, do this: 18 | # 1) Update the version in package.json 19 | # 2) Run ./scripts/make-version from the base dir of the project. 20 | # 3) Run `yarn` to update `yarn.lock`, in case you updated dependencies 21 | # 4) Commit to the master branch. 22 | 23 | # Then: 24 | # 5) Checkout the master branch of this repo. 25 | # 6) Run this script as `./scripts/publish-npm.sh` from the project base dir. 26 | 27 | set -e 28 | 29 | BRANCH=`git rev-parse --abbrev-ref HEAD` 30 | ORIGIN=`git config --get remote.origin.url` 31 | 32 | if [ "$BRANCH" != "master" ]; then 33 | echo "Error: Switch to the master branch before publishing." 34 | exit 35 | fi 36 | 37 | if ! [[ "$ORIGIN" =~ google/node-gles ]]; then 38 | echo "Error: Switch to the main repo (google/node-gles) before publishing." 39 | exit 40 | fi 41 | 42 | yarn build-npm 43 | ./scripts/make-version # This is for safety in case you forgot to do 2). 44 | npm publish 45 | ./scripts/tag-version 46 | echo 'Yay! Published a new package to npm.' 47 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | // tslint:disable-next-line:no-require-imports 19 | import bindings = require('bindings'); 20 | import {NodeJsGlBinding} from './binding'; 21 | 22 | const binding = bindings('nodejs_gl_binding') as NodeJsGlBinding; 23 | 24 | 25 | interface ContextArguments { 26 | width?: number, 27 | height?: number, 28 | webGLCompability?: boolean, 29 | majorVersion?: number, 30 | minorVersion?: number, 31 | }; 32 | 33 | const createWebGLRenderingContext = function(args: ContextArguments = {}) { 34 | const width = args.width || 1; 35 | const height = args.height || 1; 36 | const webGLCompability = args.webGLCompability || false; 37 | const majorVersion = args.majorVersion || 3; 38 | const minorVersion = args.minorVersion || 0; 39 | return binding.createWebGLRenderingContext( 40 | width, 41 | height, 42 | majorVersion, 43 | minorVersion, 44 | webGLCompability, 45 | ); 46 | 47 | 48 | } 49 | 50 | 51 | export { createWebGLRenderingContext }; 52 | -------------------------------------------------------------------------------- /binding/webgl_sync.cc: -------------------------------------------------------------------------------- 1 | /** * @license 2 | * Copyright 2019 Google Inc. All Rights Reserved. 3 | * Licensed under the Apache License, Version 2.0 (the "License"); 4 | * you may not use this file except in compliance with the License. 5 | * You may obtain a copy of the License at 6 | * 7 | * http://www.apache.org/licenses/LICENSE-2.0 8 | * 9 | * Unless required by applicable law or agreed to in writing, software 10 | * distributed under the License is distributed on an "AS IS" BASIS, 11 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | * See the License for the specific language governing permissions and 13 | * limitations under the License. 14 | * ============================================================================= 15 | */ 16 | 17 | #include "webgl_sync.h" 18 | 19 | #include "utils.h" 20 | 21 | namespace nodejsgl { 22 | 23 | void Cleanup(napi_env env, void* native, void* hint) { 24 | GLsync sync = static_cast(native); 25 | EGLContextWrapper* egl_context_wrapper = 26 | static_cast(hint); 27 | 28 | egl_context_wrapper->glDeleteSync(sync); 29 | #if DEBUG 30 | // TODO(kreeger): Fix this. 31 | /* context->CheckForErrors(); */ 32 | #endif 33 | } 34 | 35 | napi_status WrapGLsync(napi_env env, GLsync& sync, 36 | EGLContextWrapper* egl_context_wrapper, 37 | napi_value* wrapped_value) { 38 | napi_status nstatus; 39 | 40 | nstatus = napi_create_object(env, wrapped_value); 41 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 42 | 43 | nstatus = napi_wrap(env, *wrapped_value, sync, Cleanup, egl_context_wrapper, 44 | nullptr); 45 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 46 | 47 | return napi_ok; 48 | } 49 | 50 | } // namespace nodejsgl 51 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | // Place your settings in this file to overwrite default and user settings. 2 | { 3 | "files.associations": { 4 | "*.tcc": "cpp", 5 | "system_error": "cpp", 6 | "type_traits": "cpp", 7 | "__bit_reference": "cpp", 8 | "__functional_base": "cpp", 9 | "algorithm": "cpp", 10 | "atomic": "cpp", 11 | "bitset": "cpp", 12 | "chrono": "cpp", 13 | "functional": "cpp", 14 | "iterator": "cpp", 15 | "limits": "cpp", 16 | "locale": "cpp", 17 | "memory": "cpp", 18 | "ratio": "cpp", 19 | "tuple": "cpp", 20 | "vector": "cpp", 21 | "__locale": "cpp", 22 | "*.ipp": "cpp", 23 | "array": "cpp", 24 | "initializer_list": "cpp", 25 | "string_view": "cpp", 26 | "utility": "cpp", 27 | "xstring": "cpp", 28 | "string": "cpp", 29 | "istream": "cpp", 30 | "optional": "cpp", 31 | "ostream": "cpp", 32 | "*.inc": "cpp" 33 | }, 34 | "search.exclude": { 35 | "**/node_modules": true, 36 | "**/bower_components": true, 37 | "coverage/": true, 38 | "dist/": true, 39 | "**/bundle.js": true, 40 | "**/yarn.lock": true 41 | }, 42 | "tslint.enable": true, 43 | "tslint.run": "onType", 44 | "tslint.configFile": "tslint.json", 45 | "files.trimTrailingWhitespace": true, 46 | "editor.tabSize": 2, 47 | "editor.insertSpaces": true, 48 | "[typescript]": { 49 | "editor.formatOnSave": true 50 | }, 51 | "clang-format.style": "Google", 52 | "C_Cpp.clang_format_fallbackStyle": "Google", 53 | "files.insertFinalNewline": true, 54 | "editor.detectIndentation": false, 55 | "editor.wrappingIndent": "none", 56 | "typescript.tsdk": "node_modules/typescript/lib", 57 | "clang-format.executable": "${workspaceRoot}/node_modules/.bin/clang-format", 58 | "C_Cpp.intelliSenseEngineFallback": "Enabled", 59 | "editor.formatOnSave": true 60 | } 61 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rules": { 3 | "array-type": [true, "array-simple"], 4 | "arrow-return-shorthand": true, 5 | "ban": [true, 6 | ["fit"], 7 | ["fdescribe"], 8 | ["xit"], 9 | ["xdescribe"], 10 | ["fitAsync"], 11 | ["xitAsync"], 12 | ["fitFakeAsync"], 13 | ["xitFakeAsync"] 14 | ], 15 | "ban-types": [true, 16 | ["Object", "Use {} instead."], 17 | ["String", "Use 'string' instead."], 18 | ["Number", "Use 'number' instead."], 19 | ["Boolean", "Use 'boolean' instead."] 20 | ], 21 | "class-name": true, 22 | "interface-name": [true, "never-prefix"], 23 | "jsdoc-format": true, 24 | "forin": false, 25 | "label-position": true, 26 | "max-line-length": [true, 80], 27 | "new-parens": true, 28 | "no-angle-bracket-type-assertion": true, 29 | "no-any": true, 30 | "no-construct": true, 31 | "no-consecutive-blank-lines": true, 32 | "no-debugger": true, 33 | "no-default-export": true, 34 | "no-inferrable-types": true, 35 | "no-namespace": [true, "allow-declarations"], 36 | "no-reference": true, 37 | "no-require-imports": true, 38 | "no-string-throw": true, 39 | "no-unused-expression": true, 40 | "no-unused-variable": true, 41 | "no-var-keyword": true, 42 | "object-literal-shorthand": true, 43 | "only-arrow-functions": [true, "allow-declarations", "allow-named-functions"], 44 | "prefer-const": true, 45 | "radix": true, 46 | "restrict-plus-operands": true, 47 | "semicolon": [true, "always", "ignore-bound-class-methods"], 48 | "switch-default": true, 49 | "triple-equals": [true, "allow-null-check"], 50 | "use-isnan": true, 51 | "variable-name": [ 52 | true, 53 | "check-format", 54 | "ban-keywords", 55 | "allow-leading-underscore", 56 | "allow-trailing-underscore" 57 | ] 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /binding.gyp: -------------------------------------------------------------------------------- 1 | ## 2 | # @license 3 | # Copyright 2018 Google Inc. All Rights Reserved. 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # ============================================================================= 16 | 17 | # Node.js TensorFlow Binding config: 18 | { 19 | 'variables' : { 20 | 'angle_lib_dir': '<(module_root_dir)/deps/angle/out/Release' 21 | }, 22 | 'targets' : [{ 23 | 'target_name' : 'nodejs_gl_binding', 24 | 'sources' : [ 25 | 'binding/binding.cc', 26 | 'binding/egl_context_wrapper.cc', 27 | 'binding/webgl_extensions.cc', 28 | 'binding/webgl_rendering_context.cc', 29 | 'binding/webgl_sync.cc' 30 | ], 31 | 'include_dirs' : [ 32 | '..', 33 | '<(module_root_dir)/deps', 34 | '<(module_root_dir)/deps/angle/include' 35 | ], 36 | 'conditions' : [ 37 | [ 38 | 'OS=="linux"', { 39 | 'libraries' : [ 40 | '-Wl,-rpath,<@(angle_lib_dir)', 41 | '-lGLESv2', 42 | '-lEGL', 43 | ], 44 | 'library_dirs' : ['<(angle_lib_dir)'], 45 | } 46 | ], 47 | [ 48 | 'OS=="mac"', { 49 | 'libraries' : [ 50 | '-Wl,-rpath,<@(angle_lib_dir)', 51 | '-lGLESv2', 52 | '-lEGL', 53 | ], 54 | 'library_dirs' : ['<(angle_lib_dir)'], 55 | } 56 | ], 57 | [ 58 | 'OS=="win"', { 59 | 'defines': ['COMPILER_MSVC'], 60 | 'libraries': ['libGLESv2', 'libEGL'], 61 | 'library_dirs' : ['<(angle_lib_dir)'], 62 | }, 63 | ] 64 | ] 65 | }] 66 | } 67 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Headless WebGL / OpenGL ES runtime for Node.js 2 | 3 | **This repo is under active development and is not production-ready. We are 4 | actively developing as an open source project.** 5 | 6 | ## Details 7 | 8 | This project aims to provide a headless runtime for WebGL and OpenGL ES shaders under Node.js. This package will use the [ANGLE](https://github.com/google/angle) engine to translate WebGL and OpenGL ES shaders to the target runtime. Please see the [ANGLE project](https://github.com/google/angle) for more details on support. 9 | 10 | Future plans include surfacing an API for running [Compute Shaders](https://www.khronos.org/opengl/wiki/Compute_Shader) and a OpenGL ES API. Patches are welcome! 11 | 12 | ## Supported platforms 13 | 14 | * Mac OS 15 | * Windows 16 | * Linux 17 | 18 | ## Creating a WebGL context 19 | 20 | To create a new `WebGLRenderingContext` or `WebGL2RenderingContext` - simply include the package and call `createWebGLRenderingContext()`: 21 | 22 | ```js 23 | const nodeGles = require('node-gles'); 24 | 25 | const gl = nodeGles.binding.createWebGLRenderingContext(); 26 | 27 | // Now, use `gl` for regular WebGL calls: 28 | const tex = gl.createTexture(); 29 | gl.bindTexture(gl.TEXTURE_2D, texture); 30 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 31 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 32 | ... 33 | ``` 34 | 35 | ## Run demo 36 | *Clone this repo for current demos - examples coming soon* 37 | 38 | * Float32 texture upload and download: 39 | ```sh 40 | $ yarn ts-node src/tests/float_texture_upload_test.ts 41 | ... 42 | 43 | buffer: Float32Array [ 0.5, 1.5, 2.5, 3.5 ] 44 | ``` 45 | 46 | * Float16 texture upload and download: 47 | ```sh 48 | $ yarn ts-node src/tests/half_float_texture_upload_test.ts 49 | ... 50 | 51 | buffer: Float32Array [ 0.5, 1.5, 2.5, 3.5 ] 52 | ``` 53 | * Unsigned byte texture upload and download: 54 | ```sh 55 | $ yarn ts-node src/tests/unsigned_byte_texture_upload_test.ts 56 | ... 57 | 58 | buffer: Uint8Array [ 1, 2, 3, 4 ] 59 | ``` 60 | 61 | ## Development 62 | *Build instructions are under heavy development and will include an Angle binary* 63 | 64 | This project currently requires ANGLE to be checked out and built in the same parent folder as this repo. [Checkout and build ANGLE](https://github.com/google/angle/blob/master/doc/DevSetup.md) with the `Debug` setup. After ANGLE is built, run `yarn` for this project. 65 | -------------------------------------------------------------------------------- /binding/binding.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | #include 19 | 20 | #include "utils.h" 21 | #include "webgl_extensions.h" 22 | #include "webgl_rendering_context.h" 23 | 24 | namespace nodejsgl { 25 | 26 | static napi_value CreateWebGLRenderingContext(napi_env env, 27 | napi_callback_info info) { 28 | napi_value instance; 29 | napi_status nstatus = 30 | WebGLRenderingContext::NewInstance(env, &instance, info); 31 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nullptr); 32 | 33 | return instance; 34 | } 35 | 36 | static napi_value InitBinding(napi_env env, napi_value exports) { 37 | ANGLEInstancedArraysExtension::Register(env, exports); 38 | EXTBlendMinmaxExtension::Register(env, exports); 39 | EXTColorBufferFloatExtension::Register(env, exports); 40 | EXTColorBufferHalfFloatExtension::Register(env, exports); 41 | EXTFragDepthExtension::Register(env, exports); 42 | EXTShaderTextureLodExtension::Register(env, exports); 43 | EXTSRGBExtension::Register(env, exports); 44 | EXTTextureFilterAnisotropicExtension::Register(env, exports); 45 | OESElementIndexUintExtension::Register(env, exports); 46 | OESStandardDerivativesExtension::Register(env, exports); 47 | OESTextureFloatExtension::Register(env, exports); 48 | OESTextureFloatLinearExtension::Register(env, exports); 49 | OESTextureHalfFloatExtension::Register(env, exports); 50 | OESTextureHalfFloatLinearExtension::Register(env, exports); 51 | WebGLDebugRendererInfoExtension::Register(env, exports); 52 | WebGLDepthTextureExtension::Register(env, exports); 53 | WebGLLoseContextExtension::Register(env, exports); 54 | WebGLRenderingContext::Register(env, exports); 55 | 56 | napi_property_descriptor properties[] = { 57 | NAPI_DEFINE_METHOD("createWebGLRenderingContext", 58 | CreateWebGLRenderingContext), 59 | }; 60 | 61 | napi_status nstatus = 62 | napi_define_properties(env, exports, ARRAY_SIZE(properties), properties); 63 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nullptr); 64 | 65 | return exports; 66 | } 67 | 68 | NAPI_MODULE(nodejs_gl_binding, InitBinding) 69 | 70 | } // namespace nodejsgl 71 | -------------------------------------------------------------------------------- /src/tests/test_utils.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | // Contains utilities for running simple GPGPU tests. 19 | 20 | // 21 | // Inits GL environment for off-screen renderning and returns a vertex and index 22 | // buffer. 23 | // 24 | export function initEnvGL(gl: WebGLRenderingContext): 25 | [WebGLBuffer, WebGLBuffer] { 26 | gl.disable(gl.DEPTH_TEST); 27 | gl.disable(gl.STENCIL_TEST); 28 | gl.disable(gl.BLEND); 29 | gl.disable(gl.DITHER); 30 | gl.disable(gl.POLYGON_OFFSET_FILL); 31 | gl.disable(gl.SAMPLE_COVERAGE); 32 | gl.enable(gl.SCISSOR_TEST); 33 | gl.enable(gl.CULL_FACE); 34 | gl.cullFace(gl.BACK); 35 | 36 | const vertexBuffer = gl.createBuffer(); 37 | gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer); 38 | const coords = new Float32Array([ 39 | -1.0, 1.0, 0.0, 0.0, 1.0, -1.0, -1.0, 0.0, 0.0, 0.0, 40 | 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, -1.0, 0.0, 1.0, 0.0 41 | ]); 42 | gl.bufferData(gl.ARRAY_BUFFER, coords, gl.STATIC_DRAW); 43 | 44 | const indexBuffer = gl.createBuffer(); 45 | gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer); 46 | const indices = new Uint16Array([0, 1, 2, 2, 1, 3]); 47 | gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, indices, gl.STATIC_DRAW); 48 | 49 | return [vertexBuffer, indexBuffer]; 50 | } 51 | 52 | // 53 | // Creates and initializes a 2D texture. 54 | // 55 | export function createTexture2D( 56 | gl: WebGLRenderingContext, internalFormat: GLenum, format: GLenum, 57 | type: GLenum): WebGLTexture { 58 | const texture = gl.createTexture(); 59 | gl.bindTexture(gl.TEXTURE_2D, texture); 60 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); 61 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); 62 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 63 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 64 | gl.texImage2D(gl.TEXTURE_2D, 0, internalFormat, 1, 1, 0, format, type, null); 65 | gl.bindTexture(gl.TEXTURE_2D, null); 66 | return texture; 67 | } 68 | 69 | // 70 | // Ensures framebuffer has attached to a texture. 71 | // 72 | export function ensureFramebufferAttachment(gl: WebGLRenderingContext) { 73 | const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER); 74 | if (status != gl.FRAMEBUFFER_COMPLETE) { 75 | if (status === gl.FRAMEBUFFER_COMPLETE) { 76 | console.log('FRAMEBUFFER_COMPLETE'); 77 | } else if (status === gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT) { 78 | console.log('FRAMEBUFFER_INCOMPLETE_ATTACHMENT'); 79 | } else if (status === gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT) { 80 | console.log('FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT'); 81 | } else if (status === gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS) { 82 | console.log('FRAMEBUFFER_INCOMPLETE_DIMENSIONS'); 83 | } else if (status === gl.FRAMEBUFFER_UNSUPPORTED) { 84 | console.log('FRAMEBUFFER_UNSUPPORTED'); 85 | } else { 86 | console.error('Unknown error'); 87 | } 88 | throw new Error('Exception binding to framebuffer!'); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /src/tests/old_texture_test.ts: -------------------------------------------------------------------------------- 1 | import * as gles from '../.'; 2 | 3 | const gl = gles.createWebGLRenderingContext(); 4 | const gl2 = gl as WebGL2RenderingContext; 5 | gl.viewport(0, 0, 1, 1); 6 | 7 | function drawQuad( 8 | program: WebGLProgram, positionAttribName: string, positionAttribZ: number, 9 | positionAttribXYScale: number): void { 10 | const previousBuffer = gl.getParameter(gl.ARRAY_BUFFER_BINDING); 11 | const positionLocation = gl.getAttribLocation(program, positionAttribName); 12 | 13 | // TODO setup quad vertex buffer 14 | 15 | gl.vertexAttribPointer(positionLocation, 3, gl.FLOAT, false, 0, 0); 16 | gl.bindBuffer(gl.ARRAY_BUFFER, previousBuffer); 17 | gl.enableVertexAttribArray(positionLocation); 18 | gl.drawArrays(gl.TRIANGLES, 0, 6); 19 | gl.disableVertexAttribArray(positionLocation); 20 | gl.vertexAttribPointer(positionLocation, 4, gl.FLOAT, false, 0, 0); 21 | } 22 | 23 | const samplingVs = 'attribute vec4 position;\n' + 24 | 'varying vec2 texcoord;\n' + 25 | 'void main()\n' + 26 | '{\n' + 27 | ' gl_Position = vec4(position.xy, 0.0, 1.0);\n' + 28 | ' texcoord = (position.xy * 0.5) + 0.5;\n' + 29 | '}\n'; 30 | 31 | const vertexShader = gl.createShader(gl.VERTEX_SHADER); 32 | gl.shaderSource(vertexShader, samplingVs); 33 | gl.compileShader(vertexShader); 34 | if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) { 35 | console.log('shader compile failure: ' + gl.getShaderInfoLog(vertexShader)); 36 | } 37 | const samplingFs = 'precision mediump float;\n' + 38 | 'uniform sampler2D tex;\n' + 39 | 'uniform vec4 subtractor;\n' + 40 | 'varying vec2 texcoord;\n' + 41 | 'void main()\n' + 42 | '{\n' + 43 | ' vec4 color = texture2D(tex, texcoord);\n' + 44 | ' if (abs(color.r - subtractor.r) +\n' + 45 | ' abs(color.g - subtractor.g) +\n' + 46 | ' abs(color.b - subtractor.b) +\n' + 47 | ' abs(color.a - subtractor.a) < 8.0)\n' + 48 | ' {\n' + 49 | ' gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n' + 50 | ' }\n' + 51 | ' else\n' + 52 | ' {\n' + 53 | ' gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' + 54 | ' }\n' + 55 | '}\n'; 56 | 57 | const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER); 58 | gl.shaderSource(fragmentShader, samplingFs); 59 | gl.compileShader(fragmentShader); 60 | 61 | const program = gl.createProgram(); 62 | gl.attachShader(program, vertexShader); 63 | // gl.deleteShader(vertexShader); 64 | gl.attachShader(program, fragmentShader); 65 | // gl.deleteShader(fragmentShader); 66 | gl.linkProgram(program); 67 | if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { 68 | console.log('program link failure: ' + gl.getProgramInfoLog(program)); 69 | } 70 | 71 | gl.useProgram(program); 72 | 73 | const renderbuffer = gl.createRenderbuffer(); 74 | gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuffer); 75 | gl.renderbufferStorage(gl.RENDERBUFFER, gl2.RGBA8, 1, 1); 76 | 77 | const framebuffer = gl.createFramebuffer(); 78 | gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer); 79 | gl.framebufferRenderbuffer( 80 | gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.RENDERBUFFER, renderbuffer); 81 | 82 | const oes_ext = gl.getExtension('OES_texture_half_float'); 83 | 84 | const texture = gl.createTexture(); 85 | gl.bindTexture(gl.TEXTURE_2D, texture); 86 | const texData = new Float32Array([0, 1, 2, 3]); 87 | gl.texImage2D( 88 | gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, oes_ext.HALF_FLOAT_OES, 89 | texData); 90 | 91 | gl.uniform1i(gl.getUniformLocation(program, 'tex'), 0); 92 | 93 | const floatData = new Float32Array([7000.0, 100.0, 33.0, -1.0]); 94 | gl.uniform4fv(gl.getUniformLocation(program, 'subtractor'), floatData); 95 | 96 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 97 | gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 98 | 99 | drawQuad(program, 'position', 0.5, 1.0); 100 | // drawQuad() 101 | -------------------------------------------------------------------------------- /scripts/install.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2019 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | const cp = require('child_process'); 19 | const fs = require('fs'); 20 | const https = require('https'); 21 | const path = require('path'); 22 | const rimraf = require('rimraf'); 23 | const tar = require('tar'); 24 | const util = require('util'); 25 | const os = require('os'); 26 | const url = require('url'); 27 | const zip = require('adm-zip'); 28 | const HttpsProxyAgent = require('https-proxy-agent'); 29 | const ProgressBar = require('progress'); 30 | 31 | const mkdir = util.promisify(fs.mkdir); 32 | const exists = util.promisify(fs.exists); 33 | const rename = util.promisify(fs.rename); 34 | const unlink = util.promisify(fs.unlink); 35 | 36 | // Determine which tarball to download based on the OS platform and arch: 37 | const platform = os.platform().toLowerCase(); 38 | const platformArch = `${platform}-${os.arch().toLowerCase()}`; 39 | let ANGLE_BINARY_URI = 'https://storage.googleapis.com/angle-builds/'; 40 | if (platform === 'darwin') { 41 | // TODO(add debug flag?) 42 | ANGLE_BINARY_URI += `angle-3729-${platformArch}.tar.gz`; 43 | } else if (platform === 'linux') { 44 | // TODO(add debug flag?) 45 | ANGLE_BINARY_URI += `angle-3729-${platformArch}.tar.gz`; 46 | } else if (platform === 'win32') { 47 | ANGLE_BINARY_URI += `angle-3729-${platformArch}.zip`; 48 | } else { 49 | console.log('platform: ' + platform); 50 | throw new Error(`The platform ${platformArch} is not currently supported!`); 51 | } 52 | 53 | // Dependency storage paths: 54 | const depsPath = path.join(__dirname, '..', 'deps'); 55 | 56 | // 57 | // Ensures that a directory exists at a given path. 58 | // 59 | async function ensureDir(dirPath) { 60 | if (!await exists(dirPath)) { 61 | await mkdir(dirPath); 62 | } 63 | } 64 | 65 | // 66 | // Downloads the ANGLE tarball set at `ANGLE_BINARY_URI` with an optional 67 | // callback when downloading and extracting has finished. 68 | // 69 | async function downloadAngleLibs(callback) { 70 | console.error('* Downloading ANGLE'); 71 | await ensureDir(depsPath); 72 | 73 | // If HTTPS_PROXY, https_proxy, HTTP_PROXY, or http_proxy is set 74 | const proxy = process.env['HTTPS_PROXY'] || process.env['https_proxy'] || 75 | process.env['HTTP_PROXY'] || process.env['http_proxy'] || ''; 76 | 77 | // Using object destructuring to construct the options object for the 78 | // http request. the '...url.parse(ANGLE_BINARY_URI)' part fills in the host, 79 | // path, protocol, etc from the ANGLE_BINARY_URI and then we set the agent to 80 | // the default agent which is overridden a few lines down if there is a proxy 81 | const options = { 82 | ...url.parse(ANGLE_BINARY_URI), 83 | agent: https.globalAgent, 84 | headers: {'Cache-Control': 'no-cache'} 85 | }; 86 | 87 | if (proxy !== '') { 88 | options.agent = new HttpsProxyAgent(proxy); 89 | } 90 | 91 | const request = https.get(options, response => { 92 | const bar = new ProgressBar('[:bar] :rate/bps :percent :etas', { 93 | complete: '=', 94 | incomplete: ' ', 95 | width: 30, 96 | total: parseInt(response.headers['content-length'], 10) 97 | }); 98 | 99 | if (platform === 'win32') { 100 | // Save zip file to disk, extract, and delete the downloaded zip file. 101 | const tempFileName = path.join(__dirname, '_tmp.zip'); 102 | const outputFile = fs.createWriteStream(tempFileName); 103 | 104 | response.on('data', chunk => bar.tick(chunk.length)) 105 | .pipe(outputFile) 106 | .on('close', async () => { 107 | const zipFile = new zip(tempFileName); 108 | zipFile.extractAllTo(depsPath, true /* overwrite */); 109 | 110 | await unlink(tempFileName); 111 | 112 | // The .lib files for the two .dll files we care about have a name 113 | // the compiler doesn't like - rename them: 114 | await rename( 115 | path.join( 116 | depsPath, 'angle', 'out', 'Release', 'libGLESv2.dll.lib'), 117 | path.join( 118 | depsPath, 'angle', 'out', 'Release', 'libGLESv2.lib')); 119 | await rename( 120 | path.join( 121 | depsPath, 'angle', 'out', 'Release', 'libEGL.dll.lib'), 122 | path.join(depsPath, 'angle', 'out', 'Release', 'libEGL.lib')); 123 | 124 | if (callback !== undefined) { 125 | callback(); 126 | } 127 | }); 128 | } else { 129 | // All other platforms use a tarball: 130 | response 131 | .on('data', 132 | (chunk) => { 133 | bar.tick(chunk.length); 134 | }) 135 | .pipe(tar.x({C: depsPath, strict: true})) 136 | .on('close', () => { 137 | if (callback !== undefined) { 138 | callback(); 139 | } 140 | }); 141 | } 142 | }); 143 | 144 | request.end(); 145 | } 146 | 147 | // 148 | // Wraps and executes a node-gyp rebuild command. 149 | // 150 | async function buildBindings() { 151 | console.error('* Building ANGLE bindings') 152 | cp.execSync('node-gyp rebuild', (err) => { 153 | if (err) { 154 | throw new Error('node-gyp failed with: ' + err); 155 | } 156 | }); 157 | } 158 | 159 | // 160 | // Main execution function for this script. 161 | // 162 | async function run() { 163 | await downloadAngleLibs(buildBindings); 164 | } 165 | 166 | run(); 167 | -------------------------------------------------------------------------------- /binding/webgl_extensions.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | #ifndef NODEJS_GL_WEBGL_EXTENSIONS_H_ 19 | #define NODEJS_GL_WEBGL_EXTENSIONS_H_ 20 | 21 | #include 22 | 23 | #include "egl_context_wrapper.h" 24 | 25 | #ifndef NAPI_BOOTSTRAP_METHODS 26 | #define NAPI_BOOTSTRAP_METHODS \ 27 | public: \ 28 | static bool IsSupported(EGLContextWrapper* egl_context_wrapper); \ 29 | static napi_status Register(napi_env env, napi_value exports); \ 30 | static napi_status NewInstance(napi_env env, napi_value* instance, \ 31 | EGLContextWrapper* egl_context_wrapper); \ 32 | \ 33 | private: \ 34 | static napi_ref constructor_ref_; 35 | #endif 36 | 37 | namespace nodejsgl { 38 | 39 | // Base class for all GL Extensions 40 | class GLExtensionBase { 41 | // TODO(kreeger): Need a 'supported' method here! 42 | 43 | protected: 44 | GLExtensionBase(napi_env env) : env_(env), ref_(nullptr) {} 45 | virtual ~GLExtensionBase() { napi_delete_reference(env_, ref_); } 46 | 47 | // Returns a default JS object without wrapping a C++ object. Subclasses that 48 | // don't need to expose any methods should use this. 49 | static napi_value InitStubClass(napi_env env, napi_callback_info info); 50 | 51 | // Creates a new instance from a constructor ref. 52 | static napi_status NewInstanceBase(napi_env env, napi_ref constructor_ref, 53 | napi_value* instance); 54 | 55 | napi_env env_; 56 | napi_ref ref_; 57 | }; 58 | 59 | // TODO(kreeger): WebGL extensions enable a variety of core ANGLE extensions. 60 | // This directory contains the extensions Chrome enables through WebGL 61 | // extensions: 62 | // https://cs.chromium.org/chromium/src/third_party/blink/renderer/modules/webgl/ 63 | 64 | // Provides 'GL_ANGLE_instanced_array': 65 | // https://www.khronos.org/registry/OpenGL/extensions/ANGLE/ANGLE_instanced_arrays.txt 66 | class ANGLEInstancedArraysExtension : public GLExtensionBase { 67 | NAPI_BOOTSTRAP_METHODS 68 | 69 | protected: 70 | ANGLEInstancedArraysExtension(napi_env env); 71 | virtual ~ANGLEInstancedArraysExtension() {} 72 | }; 73 | 74 | // Provides 'EXT_blend_minmax': 75 | // https://www.khronos.org/registry/webgl/extensions/EXT_blend_minmax/ 76 | class EXTBlendMinmaxExtension : public GLExtensionBase { 77 | NAPI_BOOTSTRAP_METHODS 78 | 79 | protected: 80 | EXTBlendMinmaxExtension(napi_env env); 81 | virtual ~EXTBlendMinmaxExtension() {} 82 | }; 83 | 84 | // Provides 'EXT_color_buffer_float': 85 | // https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_float/ 86 | class EXTColorBufferFloatExtension : public GLExtensionBase { 87 | NAPI_BOOTSTRAP_METHODS 88 | 89 | protected: 90 | EXTColorBufferFloatExtension(napi_env env); 91 | virtual ~EXTColorBufferFloatExtension() {} 92 | }; 93 | 94 | // Provides 'EXT_color_buffer_half_float': 95 | // https://www.khronos.org/registry/webgl/extensions/EXT_color_buffer_half_float/ 96 | class EXTColorBufferHalfFloatExtension : public GLExtensionBase { 97 | NAPI_BOOTSTRAP_METHODS 98 | 99 | protected: 100 | EXTColorBufferHalfFloatExtension(napi_env env); 101 | virtual ~EXTColorBufferHalfFloatExtension() {} 102 | }; 103 | 104 | // Provides 'EXT_frag_depth': 105 | // https://www.khronos.org/registry/webgl/extensions/EXT_frag_depth/ 106 | class EXTFragDepthExtension : public GLExtensionBase { 107 | NAPI_BOOTSTRAP_METHODS 108 | 109 | protected: 110 | EXTFragDepthExtension(napi_env env); 111 | virtual ~EXTFragDepthExtension() {} 112 | }; 113 | 114 | // Provides 'EXT_shader_texture_lod': 115 | // https://www.khronos.org/registry/webgl/extensions/EXT_shader_texture_lod/ 116 | class EXTShaderTextureLodExtension : public GLExtensionBase { 117 | NAPI_BOOTSTRAP_METHODS 118 | 119 | protected: 120 | EXTShaderTextureLodExtension(napi_env env); 121 | virtual ~EXTShaderTextureLodExtension() {} 122 | }; 123 | 124 | // Provides 'EXT_sRGB': 125 | // https://www.khronos.org/registry/webgl/extensions/EXT_sRGB/ 126 | class EXTSRGBExtension : public GLExtensionBase { 127 | NAPI_BOOTSTRAP_METHODS 128 | 129 | protected: 130 | EXTSRGBExtension(napi_env env); 131 | virtual ~EXTSRGBExtension() {} 132 | }; 133 | 134 | // Provides 'EXT_texture_filter_anisotropic' 135 | // https://www.khronos.org/registry/webgl/extensions/EXT_texture_filter_anisotropic/ 136 | class EXTTextureFilterAnisotropicExtension : public GLExtensionBase { 137 | NAPI_BOOTSTRAP_METHODS 138 | 139 | protected: 140 | EXTTextureFilterAnisotropicExtension(napi_env env); 141 | virtual ~EXTTextureFilterAnisotropicExtension() {} 142 | }; 143 | 144 | // Provides 'OES_element_index_uint': 145 | // https://www.khronos.org/registry/webgl/extensions/OES_element_index_uint/ 146 | class OESElementIndexUintExtension : public GLExtensionBase { 147 | NAPI_BOOTSTRAP_METHODS 148 | 149 | protected: 150 | OESElementIndexUintExtension(napi_env env); 151 | virtual ~OESElementIndexUintExtension() {} 152 | }; 153 | 154 | // Provides 'OES_standard_derivatives': 155 | // https://www.khronos.org/registry/webgl/extensions/OES_standard_derivatives/ 156 | class OESStandardDerivativesExtension : public GLExtensionBase { 157 | NAPI_BOOTSTRAP_METHODS 158 | 159 | protected: 160 | OESStandardDerivativesExtension(napi_env env); 161 | virtual ~OESStandardDerivativesExtension() {} 162 | }; 163 | 164 | // Provides 'OES_texture_float': 165 | // https://www.khronos.org/registry/webgl/extensions/OES_texture_float/ 166 | class OESTextureFloatExtension : public GLExtensionBase { 167 | NAPI_BOOTSTRAP_METHODS 168 | 169 | protected: 170 | OESTextureFloatExtension(napi_env env); 171 | virtual ~OESTextureFloatExtension() {} 172 | }; 173 | 174 | // Provides 'OES_texture_float_linear': 175 | // https://www.khronos.org/registry/webgl/extensions/OES_texture_float_linear/ 176 | class OESTextureFloatLinearExtension : public GLExtensionBase { 177 | NAPI_BOOTSTRAP_METHODS 178 | 179 | protected: 180 | OESTextureFloatLinearExtension(napi_env env); 181 | virtual ~OESTextureFloatLinearExtension() {} 182 | }; 183 | 184 | // Provides 'OES_texture_half_float': 185 | // https://www.khronos.org/registry/webgl/extensions/OES_texture_half_float/ 186 | class OESTextureHalfFloatExtension : public GLExtensionBase { 187 | NAPI_BOOTSTRAP_METHODS 188 | 189 | protected: 190 | OESTextureHalfFloatExtension(napi_env env); 191 | virtual ~OESTextureHalfFloatExtension() {} 192 | }; 193 | 194 | // Provides 'OES_texture_half_float_linear': 195 | // https://www.khronos.org/registry/webgl/extensions/OES_texture_half_float_linear/ 196 | class OESTextureHalfFloatLinearExtension : public GLExtensionBase { 197 | NAPI_BOOTSTRAP_METHODS 198 | 199 | protected: 200 | OESTextureHalfFloatLinearExtension(napi_env env); 201 | virtual ~OESTextureHalfFloatLinearExtension() {} 202 | }; 203 | 204 | // Provides 'WEBGL_debug_renderer_info': 205 | // https://www.khronos.org/registry/webgl/extensions/WEBGL_debug_renderer_info/ 206 | class WebGLDebugRendererInfoExtension : public GLExtensionBase { 207 | NAPI_BOOTSTRAP_METHODS 208 | 209 | protected: 210 | WebGLDebugRendererInfoExtension(napi_env env); 211 | virtual ~WebGLDebugRendererInfoExtension() {} 212 | }; 213 | 214 | // Provides 'WEBGL_depth_texture': 215 | // https://www.khronos.org/registry/webgl/extensions/WEBGL_depth_texture/ 216 | class WebGLDepthTextureExtension : public GLExtensionBase { 217 | NAPI_BOOTSTRAP_METHODS 218 | 219 | protected: 220 | WebGLDepthTextureExtension(napi_env env); 221 | virtual ~WebGLDepthTextureExtension() {} 222 | }; 223 | 224 | // Provides the 'WEBGL_lose_context' extension: 225 | // https://www.khronos.org/registry/webgl/extensions/WEBGL_lose_context/ 226 | class WebGLLoseContextExtension : public GLExtensionBase { 227 | NAPI_BOOTSTRAP_METHODS 228 | 229 | protected: 230 | WebGLLoseContextExtension(napi_env env); 231 | virtual ~WebGLLoseContextExtension() {} 232 | 233 | // User facing methods: 234 | static napi_value LoseContext(napi_env env, napi_callback_info info); 235 | static napi_value RestoreContext(napi_env env, napi_callback_info info); 236 | 237 | private: 238 | static napi_value InitInternal(napi_env env, napi_callback_info info); 239 | static void Cleanup(napi_env env, void* native, void* hint); 240 | }; 241 | 242 | } // namespace nodejsgl 243 | 244 | #endif // NODEJS_GL_WEBGL_EXTENSIONS_H_ 245 | -------------------------------------------------------------------------------- /binding/egl_context_wrapper.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | #ifndef NODEJS_GL_EGL_CONTEXT_WRAPPER_H_ 19 | #define NODEJS_GL_EGL_CONTEXT_WRAPPER_H_ 20 | 21 | #include 22 | 23 | // Use generated EGL includes from ANGLE: 24 | #define EGL_EGL_PROTOTYPES 1 25 | 26 | #include "angle/include/EGL/egl.h" 27 | #include "angle/include/GLES2/gl2.h" 28 | #include "angle/include/GLES2/gl2ext.h" 29 | #include "angle/include/GLES3/gl3.h" 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | namespace nodejsgl { 36 | 37 | // Provides initialization of EGL/GL context options. 38 | struct GLContextOptions { 39 | bool webgl_compatibility = false; 40 | uint32_t client_major_es_version = 3; 41 | uint32_t client_minor_es_version = 0; 42 | uint32_t width = 1; 43 | uint32_t height = 1; 44 | }; 45 | 46 | // Provides lookup of EGL/GL extensions. 47 | class GLExtensionsWrapper { 48 | public: 49 | GLExtensionsWrapper(const char* extensions_str) 50 | : extensions_(extensions_str) {} 51 | 52 | bool HasExtension(const char* name) { 53 | return extensions_.find(name) != std::string::npos; 54 | } 55 | 56 | const char* GetExtensions() { return extensions_.c_str(); } 57 | 58 | #if DEBUG 59 | void LogExtensions() { 60 | std::string s(extensions_); 61 | std::string delim = " "; 62 | size_t pos = 0; 63 | std::string token; 64 | while ((pos = s.find(delim)) != std::string::npos) { 65 | token = s.substr(0, pos); 66 | s.erase(0, pos + delim.length()); 67 | std::cerr << token << std::endl; 68 | } 69 | } 70 | #endif 71 | 72 | private: 73 | std::string extensions_; 74 | }; 75 | 76 | // Wraps an EGLContext instance for off screen usage. 77 | class EGLContextWrapper { 78 | public: 79 | ~EGLContextWrapper(); 80 | 81 | // Creates and in 82 | static EGLContextWrapper* Create(napi_env env, 83 | const GLContextOptions& context_options); 84 | 85 | EGLContext context; 86 | EGLDisplay display; 87 | EGLConfig config; 88 | EGLSurface surface; 89 | 90 | std::unique_ptr egl_extensions; 91 | std::unique_ptr gl_extensions; 92 | std::unique_ptr angle_requestable_extensions; 93 | 94 | // Function pointers 95 | PFNGLACTIVETEXTUREPROC glActiveTexture; 96 | PFNGLATTACHSHADERPROC glAttachShader; 97 | PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; 98 | PFNGLBINDBUFFERPROC glBindBuffer; 99 | PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; 100 | PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; 101 | PFNGLBINDTEXTUREPROC glBindTexture; 102 | PFNGLBLENDCOLORPROC glBlendColor; 103 | PFNGLBLENDEQUATIONPROC glBlendEquation; 104 | PFNGLBLENDEQUATIONSEPARATEPROC glBlendEquationSeparate; 105 | PFNGLBLENDFUNCPROC glBlendFunc; 106 | PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate; 107 | PFNGLBUFFERDATAPROC glBufferData; 108 | PFNGLBUFFERSUBDATAPROC glBufferSubData; 109 | PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; 110 | PFNGLCLEARPROC glClear; 111 | PFNGLCLEARCOLORPROC glClearColor; 112 | PFNGLCLEARDEPTHFPROC glClearDepthf; 113 | PFNGLCLEARSTENCILPROC glClearStencil; 114 | PFNGLCLIENTWAITSYNCPROC glClientWaitSync; 115 | PFNGLCOLORMASKPROC glColorMask; 116 | PFNGLCOMPILESHADERPROC glCompileShader; 117 | PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D; 118 | PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glCompressedTexSubImage2D; 119 | PFNGLCOPYTEXIMAGE2DPROC glCopyTexImage2D; 120 | PFNGLCOPYTEXSUBIMAGE2DPROC glCopyTexSubImage2D; 121 | PFNGLCREATEPROGRAMPROC glCreateProgram; 122 | PFNGLCREATESHADERPROC glCreateShader; 123 | PFNGLCULLFACEPROC glCullFace; 124 | PFNGLDELETEBUFFERSPROC glDeleteBuffers; 125 | PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; 126 | PFNGLDELETEPROGRAMPROC glDeleteProgram; 127 | PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; 128 | PFNGLDELETESHADERPROC glDeleteShader; 129 | PFNGLDELETESYNCPROC glDeleteSync; 130 | PFNGLDELETETEXTURESPROC glDeleteTextures; 131 | PFNGLDEPTHFUNCPROC glDepthFunc; 132 | PFNGLDEPTHMASKPROC glDepthMask; 133 | PFNGLDEPTHRANGEFPROC glDepthRangef; 134 | PFNGLDETACHSHADERPROC glDetachShader; 135 | PFNGLDISABLEPROC glDisable; 136 | PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; 137 | PFNGLDRAWARRAYSPROC glDrawArrays; 138 | PFNGLDRAWELEMENTSPROC glDrawElements; 139 | PFNGLENABLEPROC glEnable; 140 | PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; 141 | PFNGLFENCESYNCPROC glFenceSync; 142 | PFNGLFINISHPROC glFinish; 143 | PFNGLFLUSHPROC glFlush; 144 | PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; 145 | PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; 146 | PFNGLFRONTFACEPROC glFrontFace; 147 | PFNGLGENERATEMIPMAPPROC glGenerateMipmap; 148 | PFNGLGENBUFFERSPROC glGenBuffers; 149 | PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; 150 | PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; 151 | PFNGLGENTEXTURESPROC glGenTextures; 152 | PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib; 153 | PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform; 154 | PFNGLGETATTACHEDSHADERSPROC glGetAttachedShaders; 155 | PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; 156 | PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv; 157 | /* PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData; */ 158 | PFNGLGETERRORPROC glGetError; 159 | PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC 160 | glGetFramebufferAttachmentParameteriv; 161 | PFNGLGETINTEGERVPROC glGetIntegerv; 162 | PFNGLGETPROGRAMIVPROC glGetProgramiv; 163 | PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog; 164 | PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv; 165 | PFNGLGETSHADERIVPROC glGetShaderiv; 166 | PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog; 167 | PFNGLGETSHADERPRECISIONFORMATPROC glGetShaderPrecisionFormat; 168 | PFNGLGETSTRINGPROC glGetString; 169 | PFNGLGETTEXPARAMETERFVPROC glGetTexParameterfv; 170 | PFNGLGETTEXPARAMETERIVPROC glGetTexParameteriv; 171 | PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; 172 | PFNGLHINTPROC glHint; 173 | PFNGLISBUFFERPROC glIsBuffer; 174 | PFNGLISENABLEDPROC glIsEnabled; 175 | PFNGLISFRAMEBUFFERPROC glIsFramebuffer; 176 | PFNGLISPROGRAMPROC glIsProgram; 177 | PFNGLISRENDERBUFFERPROC glIsRenderbuffer; 178 | PFNGLISSHADERPROC glIsShader; 179 | PFNGLISTEXTUREPROC glIsTexture; 180 | PFNGLLINEWIDTHPROC glLineWidth; 181 | PFNGLLINKPROGRAMPROC glLinkProgram; 182 | PFNGLMAPBUFFERRANGEPROC glMapBufferRange; 183 | PFNGLPIXELSTOREIPROC glPixelStorei; 184 | PFNGLPOLYGONOFFSETPROC glPolygonOffset; 185 | PFNGLREADPIXELSPROC glReadPixels; 186 | PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; 187 | PFNGLSAMPLECOVERAGEPROC glSampleCoverage; 188 | PFNGLSCISSORPROC glScissor; 189 | PFNGLSHADERSOURCEPROC glShaderSource; 190 | PFNGLSTENCILFUNCPROC glStencilFunc; 191 | PFNGLSTENCILFUNCSEPARATEPROC glStencilFuncSeparate; 192 | PFNGLSTENCILMASKPROC glStencilMask; 193 | PFNGLSTENCILMASKSEPARATEPROC glStencilMaskSeparate; 194 | PFNGLSTENCILOPPROC glStencilOp; 195 | PFNGLSTENCILOPSEPARATEPROC glStencilOpSeparate; 196 | PFNGLTEXIMAGE2DPROC glTexImage2D; 197 | PFNGLTEXPARAMETERIPROC glTexParameteri; 198 | PFNGLTEXPARAMETERFPROC glTexParameterf; 199 | PFNGLTEXSUBIMAGE2DPROC glTexSubImage2D; 200 | PFNGLUNIFORM1FPROC glUniform1f; 201 | PFNGLUNIFORM1FVPROC glUniform1fv; 202 | PFNGLUNIFORM1IPROC glUniform1i; 203 | PFNGLUNIFORM1IVPROC glUniform1iv; 204 | PFNGLUNIFORM2FPROC glUniform2f; 205 | PFNGLUNIFORM2FVPROC glUniform2fv; 206 | PFNGLUNIFORM2IPROC glUniform2i; 207 | PFNGLUNIFORM2IVPROC glUniform2iv; 208 | PFNGLUNIFORM3FPROC glUniform3f; 209 | PFNGLUNIFORM3FVPROC glUniform3fv; 210 | PFNGLUNIFORM3IPROC glUniform3i; 211 | PFNGLUNIFORM3IVPROC glUniform3iv; 212 | PFNGLUNIFORM4FPROC glUniform4f; 213 | PFNGLUNIFORM4FVPROC glUniform4fv; 214 | PFNGLUNIFORM4IPROC glUniform4i; 215 | PFNGLUNIFORM4IVPROC glUniform4iv; 216 | PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv; 217 | PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv; 218 | PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; 219 | PFNGLUNMAPBUFFERPROC glUnmapBuffer; 220 | PFNGLUSEPROGRAMPROC glUseProgram; 221 | PFNGLVALIDATEPROGRAMPROC glValidateProgram; 222 | PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f; 223 | PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv; 224 | PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f; 225 | PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv; 226 | PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f; 227 | PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv; 228 | PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f; 229 | PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv; 230 | PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; 231 | PFNGLVIEWPORTPROC glViewport; 232 | 233 | // ANGLE specific 234 | PFNGLREQUESTEXTENSIONANGLEPROC glRequestExtensionANGLE; 235 | 236 | // Refreshes extensions list: 237 | void RefreshGLExtensions(); 238 | 239 | private: 240 | EGLContextWrapper(napi_env env, const GLContextOptions& context_options); 241 | 242 | void InitEGL(napi_env env, const GLContextOptions& context_options); 243 | void BindProcAddresses(); 244 | }; 245 | 246 | } // namespace nodejsgl 247 | 248 | #endif // NODEJS_GL_EGL_CONTEXT_H_ 249 | -------------------------------------------------------------------------------- /binding/utils.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | #ifndef NODEJS_GL_UTILS_H_ 19 | #define NODEJS_GL_UTILS_H_ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0])) 26 | 27 | #define NAPI_STRING_SIZE 512 28 | 29 | #ifndef DEBUG 30 | #define DEBUG 0 31 | #endif 32 | 33 | #define LOG_CALLS 0 34 | 35 | #define DEBUG_LOG(message, file, lineNumber) \ 36 | do { \ 37 | if (DEBUG) \ 38 | fprintf(stderr, "** -%s:%zu\n-- %s\n", file, lineNumber, message); \ 39 | } while (0) 40 | 41 | #define LOG_CALL(message) \ 42 | do { \ 43 | if (LOG_CALLS) fprintf(stderr, " - %s\n", message); \ 44 | } while (0) 45 | 46 | #define NAPI_THROW_ERROR(env, message) \ 47 | NapiThrowError(env, message, __FILE__, __LINE__); 48 | 49 | inline void NapiThrowError(napi_env env, const char* message, const char* file, 50 | const size_t lineNumber) { 51 | DEBUG_LOG(message, file, lineNumber); 52 | napi_throw_error(env, nullptr, message); 53 | } 54 | 55 | #define ENSURE_NAPI_OK(env, status) \ 56 | if (!EnsureNapiOK(env, status, __FILE__, __LINE__)) return; 57 | #define ENSURE_NAPI_OK_RETVAL(env, status, retval) \ 58 | if (!EnsureNapiOK(env, status, __FILE__, __LINE__)) return retval; 59 | 60 | inline bool EnsureNapiOK(napi_env env, napi_status status, const char* file, 61 | const size_t lineNumber) { 62 | if (status != napi_ok) { 63 | const napi_extended_error_info* error_info = 0; 64 | napi_get_last_error_info(env, &error_info); 65 | 66 | std::ostringstream oss; 67 | if (error_info->error_message) { 68 | oss << "Invalid napi_status: " << error_info->error_message; 69 | } else { 70 | oss << "Invalid napi_status: UNKNOWN"; 71 | } 72 | NapiThrowError(env, oss.str().c_str(), file, lineNumber); 73 | } 74 | return status == napi_ok; 75 | } 76 | 77 | #define ENSURE_VALUE_IS_NOT_NULL(env, value) \ 78 | if (!EnsureValueIsNotNull(env, value, __FILE__, __LINE__)) return; 79 | #define ENSURE_VALUE_IS_NOT_NULL_RETVAL(env, value, retval) \ 80 | if (!EnsureValueIsNotNull(env, value, __FILE__, __LINE__)) return retval; 81 | 82 | inline bool EnsureValueIsNotNull(napi_env env, void* value, const char* file, 83 | const size_t lineNumber) { 84 | bool is_null = value == nullptr; 85 | if (is_null) { 86 | NapiThrowError(env, "Argument is null!", file, lineNumber); 87 | } 88 | return !is_null; 89 | } 90 | 91 | #define ENSURE_CONSTRUCTOR_CALL(env, info) \ 92 | if (!EnsureConstructorCall(env, info, __FILE__, __LINE__)) return; 93 | #define ENSURE_CONSTRUCTOR_CALL_RETVAL(env, info, retval) \ 94 | if (!EnsureConstructorCall(env, info, __FILE__, __LINE__)) return retval; 95 | 96 | inline bool EnsureConstructorCall(napi_env env, napi_callback_info info, 97 | const char* file, const size_t lineNumber) { 98 | napi_value js_target; 99 | napi_status nstatus = napi_get_new_target(env, info, &js_target); 100 | ENSURE_NAPI_OK_RETVAL(env, nstatus, false); 101 | bool is_target = js_target != nullptr; 102 | if (!is_target) { 103 | NapiThrowError(env, "Function not used as a constructor!", file, 104 | lineNumber); 105 | } 106 | return is_target; 107 | } 108 | 109 | #define ENSURE_VALUE_IS_OBJECT(env, value) \ 110 | if (!EnsureValueIsObject(env, value, __FILE__, __LINE__)) return; 111 | #define ENSURE_VALUE_IS_OBJECT_RETVAL(env, value, retval) \ 112 | if (!EnsureValueIsObject(env, value, __FILE__, __LINE__)) return retval; 113 | 114 | inline bool EnsureValueIsObject(napi_env env, napi_value value, 115 | const char* file, const size_t lineNumber) { 116 | napi_valuetype type; 117 | ENSURE_NAPI_OK_RETVAL(env, napi_typeof(env, value, &type), false); 118 | bool is_object = type == napi_object; 119 | if (!is_object) { 120 | NapiThrowError(env, "Argument is not an object!", file, lineNumber); 121 | } 122 | return is_object; 123 | } 124 | 125 | #define ENSURE_VALUE_IS_STRING(env, value) \ 126 | if (!EnsureValueIsString(env, value, __FILE__, __LINE__)) return; 127 | #define ENSURE_VALUE_IS_STRING_RETVAL(env, value, retval) \ 128 | if (!EnsureValueIsString(env, value, __FILE__, __LINE__)) return retval; 129 | 130 | inline bool EnsureValueIsString(napi_env env, napi_value value, 131 | const char* file, const size_t lineNumber) { 132 | napi_valuetype type; 133 | ENSURE_NAPI_OK_RETVAL(env, napi_typeof(env, value, &type), false); 134 | bool is_string = type == napi_string; 135 | if (!is_string) { 136 | NapiThrowError(env, "Argument is not a string!", file, lineNumber); 137 | } 138 | return is_string; 139 | } 140 | 141 | #define ENSURE_VALUE_IS_NUMBER(env, value) \ 142 | if (!EnsureValueIsNumber(env, value, __FILE__, __LINE__)) return; 143 | #define ENSURE_VALUE_IS_NUMBER_RETVAL(env, value, retval) \ 144 | if (!EnsureValueIsNumber(env, value, __FILE__, __LINE__)) return retval; 145 | 146 | inline bool EnsureValueIsNumber(napi_env env, napi_value value, 147 | const char* file, const size_t lineNumber) { 148 | napi_valuetype type; 149 | ENSURE_NAPI_OK_RETVAL(env, napi_typeof(env, value, &type), false); 150 | bool is_number = type == napi_number; 151 | if (!is_number) { 152 | NapiThrowError(env, "Argument is not a number!", file, lineNumber); 153 | } 154 | return is_number; 155 | } 156 | 157 | #define ENSURE_VALUE_IS_BOOLEAN(env, value) \ 158 | if (!EnsureValueIsBoolean(env, value, __FILE__, __LINE__)) return; 159 | #define ENSURE_VALUE_IS_BOOLEAN_RETVAL(env, value, retval) \ 160 | if (!EnsureValueIsBoolean(env, value, __FILE__, __LINE__)) return retval; 161 | 162 | inline bool EnsureValueIsBoolean(napi_env env, napi_value value, 163 | const char* file, const size_t lineNumber) { 164 | napi_valuetype type; 165 | ENSURE_NAPI_OK_RETVAL(env, napi_typeof(env, value, &type), false); 166 | bool is_boolean = type == napi_boolean; 167 | if (!is_boolean) { 168 | NapiThrowError(env, "Argument is not a boolean!", file, lineNumber); 169 | } 170 | return is_boolean; 171 | } 172 | 173 | #define ENSURE_VALUE_IS_ARRAY_LIKE(env, value) \ 174 | if (!EnsureValueIsArrayLike(env, value, __FILE__, __LINE__)) return; 175 | #define ENSURE_VALUE_IS_ARRAY_LIKE_RETVAL(env, value, retval) \ 176 | if (!EnsureValueIsArrayLike(env, value, __FILE__, __LINE__)) return retval; 177 | 178 | inline bool EnsureValueIsArrayLike(napi_env env, napi_value value, 179 | const char* file, const size_t line_number) { 180 | napi_status nstatus; 181 | 182 | bool is_array; 183 | nstatus = napi_is_array(env, value, &is_array); 184 | ENSURE_NAPI_OK_RETVAL(env, nstatus, false); 185 | if (is_array) { 186 | return true; 187 | } 188 | 189 | bool is_typedarray; 190 | nstatus = napi_is_typedarray(env, value, &is_typedarray); 191 | ENSURE_NAPI_OK_RETVAL(env, nstatus, false); 192 | if (is_typedarray) { 193 | return true; 194 | } 195 | 196 | return false; 197 | } 198 | 199 | #define ENSURE_VALUE_IS_ARRAY(env, value) \ 200 | if (!EnsureValueIsArray(env, value, __FILE__, __LINE__)) return; 201 | #define ENSURE_VALUE_IS_ARRAY_RETVAL(env, value, retval) \ 202 | if (!EnsureValueIsArray(env, value, __FILE__, __LINE__)) return retval; 203 | 204 | inline bool EnsureValueIsArray(napi_env env, napi_value value, const char* file, 205 | const size_t lineNumber) { 206 | bool is_array; 207 | ENSURE_NAPI_OK_RETVAL(env, napi_is_array(env, value, &is_array), false); 208 | if (!is_array) { 209 | NapiThrowError(env, "Argument is not an array!", file, lineNumber); 210 | } 211 | return is_array; 212 | } 213 | 214 | #define ENSURE_ARGC(env, argc, argc_exp) \ 215 | if (!EnsureArgc(env, argc, argc_exp, __FILE__, __LINE__)) return; 216 | #define ENSURE_ARGC_RETVAL(env, argc, argc_exp, retval) \ 217 | if (!EnsureArgc(env, argc, argc_exp, __FILE__, __LINE__)) return retval; 218 | 219 | inline bool EnsureArgc(napi_env env, size_t argc, size_t argc_exp, 220 | const char* file, const size_t lineNumber) { 221 | bool equals = argc == argc_exp; 222 | if (!equals) { 223 | std::ostringstream oss; 224 | oss << "Incorrect number of arguments (" << argc << " expected " << argc_exp 225 | << ")"; 226 | NapiThrowError(env, oss.str().c_str(), file, lineNumber); 227 | } 228 | return equals; 229 | } 230 | 231 | #define NAPI_DEFINE_METHOD(name, func) \ 232 | { (name), nullptr, (func), nullptr, nullptr, nullptr, napi_default, nullptr } 233 | 234 | inline napi_property_descriptor NapiDefineIntProperty(napi_env env, 235 | int32_t value, 236 | const char* name) { 237 | napi_value js_value; 238 | napi_status nstatus = napi_create_int32(env, value, &js_value); 239 | ENSURE_NAPI_OK_RETVAL(env, nstatus, {}); 240 | 241 | return {name, nullptr, nullptr, nullptr, 242 | nullptr, js_value, napi_default, nullptr}; 243 | } 244 | 245 | namespace nodejsgl { 246 | 247 | // Auto-class for alloc'ing and deleting heap allocations. 248 | template 249 | class AutoBuffer { 250 | public: 251 | AutoBuffer(const size_t length) { buffer = new T[length]; } 252 | 253 | ~AutoBuffer() { 254 | if (buffer) { 255 | delete buffer; 256 | } 257 | } 258 | 259 | T* get() { return buffer; } 260 | 261 | private: 262 | T* buffer; 263 | }; 264 | 265 | } // namespace nodejsgl 266 | 267 | #endif // NODEJS_GL_UTILS_H_ 268 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /binding/webgl_rendering_context.h: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | #ifndef NODEJS_GL_WEBGL_RENDERING_CONTEXT_H_ 19 | #define NODEJS_GL_WEBGL_RENDERING_CONTEXT_H_ 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include "egl_context_wrapper.h" 26 | 27 | namespace nodejsgl { 28 | 29 | class WebGLRenderingContext { 30 | public: 31 | static napi_status Register(napi_env env, napi_value exports); 32 | static napi_status NewInstance(napi_env env, napi_value* instance, 33 | napi_callback_info info); 34 | 35 | private: 36 | WebGLRenderingContext(napi_env env, GLContextOptions opts); 37 | ~WebGLRenderingContext(); 38 | 39 | static napi_value InitInternal(napi_env env, napi_callback_info info); 40 | static void Cleanup(napi_env env, void* native, void* hint); 41 | 42 | // User facing methods: 43 | static napi_value ActiveTexture(napi_env env, napi_callback_info info); 44 | static napi_value AttachShader(napi_env env, napi_callback_info info); 45 | static napi_value BindAttribLocation(napi_env env, napi_callback_info info); 46 | static napi_value BindBuffer(napi_env env, napi_callback_info info); 47 | static napi_value BindFramebuffer(napi_env env, napi_callback_info info); 48 | static napi_value BindRenderbuffer(napi_env env, napi_callback_info info); 49 | static napi_value BindTexture(napi_env env, napi_callback_info info); 50 | static napi_value BlendColor(napi_env env, napi_callback_info info); 51 | static napi_value BlendEquation(napi_env env, napi_callback_info info); 52 | static napi_value BlendEquationSeparate(napi_env env, 53 | napi_callback_info info); 54 | static napi_value BlendFunc(napi_env env, napi_callback_info info); 55 | static napi_value BlendFuncSeparate(napi_env env, napi_callback_info info); 56 | static napi_value BufferData(napi_env env, napi_callback_info info); 57 | static napi_value BufferSubData(napi_env env, napi_callback_info info); 58 | static napi_value CheckFramebufferStatus(napi_env env, 59 | napi_callback_info info); 60 | static napi_value Clear(napi_env env, napi_callback_info info); 61 | static napi_value ClearColor(napi_env env, napi_callback_info info); 62 | static napi_value ClearDepth(napi_env env, napi_callback_info info); 63 | static napi_value ClearStencil(napi_env env, napi_callback_info info); 64 | static napi_value ClientWaitSync(napi_env env, napi_callback_info info); 65 | static napi_value ColorMask(napi_env env, napi_callback_info info); 66 | static napi_value CompileShader(napi_env env, napi_callback_info info); 67 | static napi_value CompressedTexImage2D(napi_env env, napi_callback_info info); 68 | static napi_value CompressedTexSubImage2D(napi_env env, 69 | napi_callback_info info); 70 | static napi_value CopyTexImage2D(napi_env env, napi_callback_info info); 71 | static napi_value CopyTexSubImage2D(napi_env env, napi_callback_info info); 72 | static napi_value CreateBuffer(napi_env env, napi_callback_info info); 73 | static napi_value CreateFramebuffer(napi_env env, napi_callback_info info); 74 | static napi_value CreateProgram(napi_env env, napi_callback_info info); 75 | static napi_value CreateRenderbuffer(napi_env env, napi_callback_info info); 76 | static napi_value CreateShader(napi_env env, napi_callback_info info); 77 | static napi_value CreateTexture(napi_env env, napi_callback_info info); 78 | static napi_value CullFace(napi_env env, napi_callback_info info); 79 | static napi_value DeleteBuffer(napi_env env, napi_callback_info info); 80 | static napi_value DeleteFramebuffer(napi_env env, napi_callback_info info); 81 | static napi_value DeleteProgram(napi_env env, napi_callback_info info); 82 | static napi_value DeleteRenderbuffer(napi_env env, napi_callback_info info); 83 | static napi_value DeleteShader(napi_env env, napi_callback_info info); 84 | static napi_value DeleteTexture(napi_env env, napi_callback_info info); 85 | static napi_value DepthFunc(napi_env env, napi_callback_info info); 86 | static napi_value DepthMask(napi_env env, napi_callback_info info); 87 | static napi_value DepthRange(napi_env env, napi_callback_info info); 88 | static napi_value DetachShader(napi_env env, napi_callback_info info); 89 | static napi_value Disable(napi_env env, napi_callback_info info); 90 | static napi_value DisableVertexAttribArray(napi_env env, 91 | napi_callback_info info); 92 | static napi_value DrawArrays(napi_env env, napi_callback_info info); 93 | static napi_value DrawElements(napi_env env, napi_callback_info info); 94 | static napi_value Enable(napi_env env, napi_callback_info info); 95 | static napi_value EnableVertexAttribArray(napi_env env, 96 | napi_callback_info info); 97 | static napi_value FenceSynce(napi_env env, napi_callback_info info); 98 | // TODO(kreeger): Check alignment in CC file here 99 | static napi_value Finish(napi_env env, napi_callback_info info); 100 | static napi_value Flush(napi_env env, napi_callback_info info); 101 | static napi_value FramebufferRenderbuffer(napi_env env, 102 | napi_callback_info info); 103 | static napi_value FramebufferTexture2D(napi_env env, napi_callback_info info); 104 | static napi_value FrontFace(napi_env env, napi_callback_info info); 105 | static napi_value GenerateMipmap(napi_env env, napi_callback_info info); 106 | static napi_value GetAttachedShaders(napi_env env, napi_callback_info info); 107 | static napi_value GetAttribLocation(napi_env env, napi_callback_info info); 108 | static napi_value GetActiveAttrib(napi_env env, napi_callback_info info); 109 | static napi_value GetActiveUniform(napi_env env, napi_callback_info info); 110 | static napi_value GetBufferParameter(napi_env env, napi_callback_info info); 111 | static napi_value GetBufferSubData(napi_env env, napi_callback_info info); 112 | static napi_value GetContextAttributes(napi_env env, napi_callback_info info); 113 | static napi_value GetError(napi_env env, napi_callback_info info); 114 | static napi_value GetFramebufferAttachmentParameter(napi_env env, 115 | napi_callback_info info); 116 | static napi_value GetExtension(napi_env env, napi_callback_info info); 117 | static napi_value GetParameter(napi_env env, napi_callback_info info); 118 | static napi_value GetProgramInfoLog(napi_env env, napi_callback_info info); 119 | static napi_value GetProgramParameter(napi_env env, napi_callback_info info); 120 | static napi_value GetRenderbufferParameter(napi_env env, 121 | napi_callback_info info); 122 | static napi_value GetShaderPrecisionFormat(napi_env env, 123 | napi_callback_info info); 124 | static napi_value GetShaderInfoLog(napi_env env, napi_callback_info info); 125 | static napi_value GetShaderParameter(napi_env env, napi_callback_info info); 126 | static napi_value GetSupportedExtensions(napi_env env, 127 | napi_callback_info info); 128 | static napi_value GetTexParameter(napi_env env, napi_callback_info info); 129 | static napi_value GetUniformLocation(napi_env env, napi_callback_info info); 130 | static napi_value Hint(napi_env env, napi_callback_info info); 131 | static napi_value IsBuffer(napi_env env, napi_callback_info info); 132 | static napi_value IsContextLost(napi_env env, napi_callback_info info); 133 | static napi_value IsEnabled(napi_env env, napi_callback_info info); 134 | static napi_value IsFramebuffer(napi_env env, napi_callback_info info); 135 | static napi_value IsProgram(napi_env env, napi_callback_info info); 136 | static napi_value IsRenderbuffer(napi_env env, napi_callback_info info); 137 | static napi_value IsShader(napi_env env, napi_callback_info info); 138 | static napi_value IsTexture(napi_env env, napi_callback_info info); 139 | static napi_value LineWidth(napi_env env, napi_callback_info info); 140 | static napi_value LinkProgram(napi_env env, napi_callback_info info); 141 | static napi_value PixelStorei(napi_env env, napi_callback_info info); 142 | static napi_value PolygonOffset(napi_env env, napi_callback_info info); 143 | static napi_value ReadPixels(napi_env env, napi_callback_info info); 144 | static napi_value RenderbufferStorage(napi_env env, napi_callback_info info); 145 | static napi_value SampleCoverage(napi_env env, napi_callback_info info); 146 | static napi_value Scissor(napi_env env, napi_callback_info info); 147 | static napi_value ShaderSource(napi_env env, napi_callback_info info); 148 | static napi_value StencilFunc(napi_env env, napi_callback_info info); 149 | static napi_value StencilFuncSeparate(napi_env env, napi_callback_info info); 150 | static napi_value StencilMask(napi_env env, napi_callback_info info); 151 | static napi_value StencilMaskSeparate(napi_env env, napi_callback_info info); 152 | static napi_value StencilOp(napi_env env, napi_callback_info info); 153 | static napi_value StencilOpSeparate(napi_env env, napi_callback_info info); 154 | static napi_value TexImage2D(napi_env env, napi_callback_info info); 155 | static napi_value TexParameteri(napi_env env, napi_callback_info info); 156 | static napi_value TexParameterf(napi_env env, napi_callback_info info); 157 | static napi_value TexSubImage2D(napi_env env, napi_callback_info info); 158 | static napi_value Uniform1i(napi_env env, napi_callback_info info); 159 | static napi_value Uniform1iv(napi_env env, napi_callback_info info); 160 | static napi_value Uniform1f(napi_env env, napi_callback_info info); 161 | static napi_value Uniform1fv(napi_env env, napi_callback_info info); 162 | static napi_value Uniform2i(napi_env env, napi_callback_info info); 163 | static napi_value Uniform2f(napi_env env, napi_callback_info info); 164 | static napi_value Uniform2fv(napi_env env, napi_callback_info info); 165 | static napi_value Uniform2iv(napi_env env, napi_callback_info info); 166 | static napi_value Uniform3i(napi_env env, napi_callback_info info); 167 | static napi_value Uniform3iv(napi_env env, napi_callback_info info); 168 | static napi_value Uniform3f(napi_env env, napi_callback_info info); 169 | static napi_value Uniform3fv(napi_env env, napi_callback_info info); 170 | static napi_value Uniform4fv(napi_env env, napi_callback_info info); 171 | static napi_value Uniform4i(napi_env env, napi_callback_info info); 172 | static napi_value Uniform4iv(napi_env env, napi_callback_info info); 173 | static napi_value Uniform4f(napi_env env, napi_callback_info info); 174 | static napi_value UniformMatrix2fv(napi_env env, napi_callback_info info); 175 | static napi_value UniformMatrix3fv(napi_env env, napi_callback_info info); 176 | static napi_value UniformMatrix4fv(napi_env env, napi_callback_info info); 177 | static napi_value UseProgram(napi_env env, napi_callback_info info); 178 | static napi_value ValidateProgram(napi_env env, napi_callback_info info); 179 | static napi_value VertexAttrib1f(napi_env env, napi_callback_info info); 180 | static napi_value VertexAttrib1fv(napi_env env, napi_callback_info info); 181 | static napi_value VertexAttrib2f(napi_env env, napi_callback_info info); 182 | static napi_value VertexAttrib2fv(napi_env env, napi_callback_info info); 183 | static napi_value VertexAttrib3f(napi_env env, napi_callback_info info); 184 | static napi_value VertexAttrib3fv(napi_env env, napi_callback_info info); 185 | static napi_value VertexAttrib4f(napi_env env, napi_callback_info info); 186 | static napi_value VertexAttrib4fv(napi_env env, napi_callback_info info); 187 | static napi_value VertexAttribPointer(napi_env env, napi_callback_info info); 188 | static napi_value Viewport(napi_env env, napi_callback_info info); 189 | 190 | static napi_ref constructor_ref_; 191 | 192 | bool CheckForErrors(); 193 | 194 | napi_env env_; 195 | napi_ref ref_; 196 | EGLContextWrapper* eglContextWrapper_; 197 | 198 | std::atomic alloc_count_; 199 | }; 200 | 201 | } // namespace nodejsgl 202 | 203 | #endif // NODEJS_GL_WEBGL_RENDERING_CONTEXT_H_ 204 | -------------------------------------------------------------------------------- /binding/egl_context_wrapper.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | #include "egl_context_wrapper.h" 19 | 20 | #include "utils.h" 21 | 22 | #include "angle/include/EGL/egl.h" 23 | #include "angle/include/EGL/eglext.h" 24 | 25 | #include 26 | 27 | namespace nodejsgl { 28 | 29 | EGLContextWrapper::EGLContextWrapper(napi_env env, 30 | const GLContextOptions& context_options) { 31 | InitEGL(env, context_options); 32 | BindProcAddresses(); 33 | RefreshGLExtensions(); 34 | 35 | #if DEBUG 36 | std::cerr << "** GL_EXTENSIONS:" << std::endl; 37 | gl_extensions->LogExtensions(); 38 | std::cerr << std::endl; 39 | 40 | std::cerr << "** REQUESTABLE_EXTENSIONS:" << std::endl; 41 | angle_requestable_extensions->LogExtensions(); 42 | std::cerr << std::endl; 43 | #endif 44 | } 45 | 46 | void EGLContextWrapper::InitEGL(napi_env env, 47 | const GLContextOptions& context_options) { 48 | std::vector display_attributes; 49 | display_attributes.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE); 50 | // Most NVIDIA drivers will not work properly with 51 | // EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE, only enable this option on ARM 52 | // devices for now: 53 | #if defined(__arm__) 54 | display_attributes.push_back(EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE); 55 | #else 56 | display_attributes.push_back(EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE); 57 | #endif 58 | 59 | display_attributes.push_back(EGL_NONE); 60 | 61 | display = eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE, nullptr, 62 | &display_attributes[0]); 63 | if (display == EGL_NO_DISPLAY) { 64 | // TODO(kreeger): This is the default path for Mac OS. Determine why egl has 65 | // to be initialized this way on Mac OS. 66 | display = eglGetDisplay(EGL_DEFAULT_DISPLAY); 67 | if (display == EGL_NO_DISPLAY) { 68 | NAPI_THROW_ERROR(env, "No display"); 69 | return; 70 | } 71 | } 72 | 73 | EGLint major; 74 | EGLint minor; 75 | if (!eglInitialize(display, &major, &minor)) { 76 | NAPI_THROW_ERROR(env, "Could not initialize display"); 77 | return; 78 | } 79 | 80 | egl_extensions = std::unique_ptr( 81 | new GLExtensionsWrapper(eglQueryString(display, EGL_EXTENSIONS))); 82 | #if DEBUG 83 | std::cerr << "** EGL_EXTENSIONS:" << std::endl; 84 | egl_extensions->LogExtensions(); 85 | std::cerr << std::endl; 86 | #endif 87 | 88 | EGLint attrib_list[] = {EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 89 | EGL_RED_SIZE, 8, 90 | EGL_GREEN_SIZE, 8, 91 | EGL_BLUE_SIZE, 8, 92 | EGL_ALPHA_SIZE, 8, 93 | EGL_DEPTH_SIZE, 24, 94 | EGL_STENCIL_SIZE, 8, 95 | EGL_NONE}; 96 | 97 | EGLint num_config; 98 | if (!eglChooseConfig(display, attrib_list, &config, 1, &num_config)) { 99 | NAPI_THROW_ERROR(env, "Failed creating a config"); 100 | return; 101 | } 102 | 103 | eglBindAPI(EGL_OPENGL_ES_API); 104 | if (eglGetError() != EGL_SUCCESS) { 105 | NAPI_THROW_ERROR(env, "Failed to set OpenGL ES API"); 106 | return; 107 | } 108 | 109 | EGLint config_renderable_type; 110 | if (!eglGetConfigAttrib(display, config, EGL_RENDERABLE_TYPE, 111 | &config_renderable_type)) { 112 | NAPI_THROW_ERROR(env, "Failed to get EGL_RENDERABLE_TYPE"); 113 | return; 114 | } 115 | 116 | // If the requested context is ES3 but the config cannot support ES3, request 117 | // ES2 instead. 118 | EGLint major_version = context_options.client_major_es_version; 119 | EGLint minor_version = context_options.client_minor_es_version; 120 | if ((config_renderable_type & EGL_OPENGL_ES3_BIT) == 0 && 121 | major_version >= 3) { 122 | major_version = 2; 123 | minor_version = 0; 124 | } 125 | 126 | // Append attributes based on available features 127 | std::vector context_attributes; 128 | 129 | context_attributes.push_back(EGL_CONTEXT_MAJOR_VERSION_KHR); 130 | context_attributes.push_back(major_version); 131 | 132 | context_attributes.push_back(EGL_CONTEXT_MINOR_VERSION_KHR); 133 | context_attributes.push_back(minor_version); 134 | 135 | if (context_options.webgl_compatibility) { 136 | context_attributes.push_back(EGL_CONTEXT_WEBGL_COMPATIBILITY_ANGLE); 137 | context_attributes.push_back(EGL_TRUE); 138 | } 139 | 140 | // TODO(kreeger): This is only needed to avoid validation. 141 | // This is needed for OES_TEXTURE_HALF_FLOAT textures uploading as FLOAT 142 | context_attributes.push_back(EGL_CONTEXT_OPENGL_NO_ERROR_KHR); 143 | context_attributes.push_back(EGL_TRUE); 144 | 145 | context_attributes.push_back(EGL_NONE); 146 | 147 | context = eglCreateContext(display, config, EGL_NO_CONTEXT, 148 | context_attributes.data()); 149 | if (context == EGL_NO_CONTEXT) { 150 | NAPI_THROW_ERROR(env, "Could not create context"); 151 | return; 152 | } 153 | 154 | EGLint surface_attribs[] = {EGL_WIDTH, (EGLint)context_options.width, 155 | EGL_HEIGHT, (EGLint)context_options.height, 156 | EGL_NONE}; 157 | surface = eglCreatePbufferSurface(display, config, surface_attribs); 158 | if (surface == EGL_NO_SURFACE) { 159 | NAPI_THROW_ERROR(env, "Could not create surface"); 160 | return; 161 | } 162 | 163 | if (!eglMakeCurrent(display, surface, surface, context)) { 164 | NAPI_THROW_ERROR(env, "Could not make context current"); 165 | return; 166 | } 167 | } 168 | 169 | void EGLContextWrapper::BindProcAddresses() { 170 | // Bind runtime function pointers. 171 | glActiveTexture = reinterpret_cast( 172 | eglGetProcAddress("glActiveTexture")); 173 | glAttachShader = reinterpret_cast( 174 | eglGetProcAddress("glAttachShader")); 175 | glBindAttribLocation = reinterpret_cast( 176 | eglGetProcAddress("glBindAttribLocation")); 177 | glBindBuffer = 178 | reinterpret_cast(eglGetProcAddress("glBindBuffer")); 179 | glBindFramebuffer = reinterpret_cast( 180 | eglGetProcAddress("glBindFramebuffer")); 181 | glBindRenderbuffer = reinterpret_cast( 182 | eglGetProcAddress("glBindRenderbuffer")); 183 | glBindTexture = reinterpret_cast( 184 | eglGetProcAddress("glBindTexture")); 185 | glBlendColor = 186 | reinterpret_cast(eglGetProcAddress("glBlendColor")); 187 | glBlendEquation = reinterpret_cast( 188 | eglGetProcAddress("glBlendEquation")); 189 | glBlendEquationSeparate = reinterpret_cast( 190 | eglGetProcAddress("glBlendEquationSeparate")); 191 | glBlendFunc = 192 | reinterpret_cast(eglGetProcAddress("glBlendFunc")); 193 | glBlendFuncSeparate = reinterpret_cast( 194 | eglGetProcAddress("glBlendFuncSeparate")); 195 | glBufferData = 196 | reinterpret_cast(eglGetProcAddress("glBufferData")); 197 | glBufferSubData = reinterpret_cast( 198 | eglGetProcAddress("glBufferSubData")); 199 | glCheckFramebufferStatus = reinterpret_cast( 200 | eglGetProcAddress("glCheckFramebufferStatus")); 201 | glClear = reinterpret_cast(eglGetProcAddress("glClear")); 202 | glClearColor = 203 | reinterpret_cast(eglGetProcAddress("glClearColor")); 204 | glClearDepthf = reinterpret_cast( 205 | eglGetProcAddress("glClearDepthf")); 206 | glClearStencil = reinterpret_cast( 207 | eglGetProcAddress("glClearStencil")); 208 | glClientWaitSync = reinterpret_cast( 209 | eglGetProcAddress("glClientWaitSync")); 210 | glColorMask = 211 | reinterpret_cast(eglGetProcAddress("glColorMask")); 212 | glCompileShader = reinterpret_cast( 213 | eglGetProcAddress("glCompileShader")); 214 | glCompressedTexImage2D = reinterpret_cast( 215 | eglGetProcAddress("glCompressedTexImage2D")); 216 | glCompressedTexSubImage2D = 217 | reinterpret_cast( 218 | eglGetProcAddress("glCompressedTexSubImage2D")); 219 | glCopyTexImage2D = reinterpret_cast( 220 | eglGetProcAddress("glCopyTexImage2D")); 221 | glCopyTexSubImage2D = reinterpret_cast( 222 | eglGetProcAddress("glCopyTexSubImage2D")); 223 | glCreateProgram = reinterpret_cast( 224 | eglGetProcAddress("glCreateProgram")); 225 | glCreateShader = reinterpret_cast( 226 | eglGetProcAddress("glCreateShader")); 227 | glCullFace = 228 | reinterpret_cast(eglGetProcAddress("glCullFace")); 229 | glDeleteBuffers = reinterpret_cast( 230 | eglGetProcAddress("glDeleteBuffers")); 231 | glDeleteFramebuffers = reinterpret_cast( 232 | eglGetProcAddress("glDeleteFramebuffers")); 233 | glDeleteRenderbuffers = reinterpret_cast( 234 | eglGetProcAddress("glDeleteRenderbuffers")); 235 | glDeleteProgram = reinterpret_cast( 236 | eglGetProcAddress("glDeleteProgram")); 237 | glDeleteShader = reinterpret_cast( 238 | eglGetProcAddress("glDeleteShader")); 239 | glDeleteSync = 240 | reinterpret_cast(eglGetProcAddress("glDeleteSync")); 241 | glDeleteTextures = reinterpret_cast( 242 | eglGetProcAddress("glDeleteTextures")); 243 | glDepthFunc = 244 | reinterpret_cast(eglGetProcAddress("glDepthFunc")); 245 | glDepthMask = 246 | reinterpret_cast(eglGetProcAddress("glDepthMask")); 247 | glDepthRangef = reinterpret_cast( 248 | eglGetProcAddress("glDepthRangef")); 249 | glDrawArrays = 250 | reinterpret_cast(eglGetProcAddress("glDrawArrays")); 251 | glDrawElements = reinterpret_cast( 252 | eglGetProcAddress("glDrawElements")); 253 | glDetachShader = reinterpret_cast( 254 | eglGetProcAddress("glDetachShader")); 255 | glDisable = 256 | reinterpret_cast(eglGetProcAddress("glDisable")); 257 | glDisableVertexAttribArray = 258 | reinterpret_cast( 259 | eglGetProcAddress("glDisableVertexAttribArray")); 260 | glEnable = reinterpret_cast(eglGetProcAddress("glEnable")); 261 | glEnableVertexAttribArray = 262 | reinterpret_cast( 263 | eglGetProcAddress("glEnableVertexAttribArray")); 264 | glFenceSync = 265 | reinterpret_cast(eglGetProcAddress("glFenceSync")); 266 | glFinish = reinterpret_cast(eglGetProcAddress("glFinish")); 267 | glFlush = reinterpret_cast(eglGetProcAddress("glFlush")); 268 | glFramebufferRenderbuffer = 269 | reinterpret_cast( 270 | eglGetProcAddress("glFramebufferRenderbuffer")); 271 | glFramebufferTexture2D = reinterpret_cast( 272 | eglGetProcAddress("glFramebufferTexture2D")); 273 | glFrontFace = 274 | reinterpret_cast(eglGetProcAddress("glFrontFace")); 275 | glGenerateMipmap = reinterpret_cast( 276 | eglGetProcAddress("glGenerateMipmap")); 277 | glGenBuffers = 278 | reinterpret_cast(eglGetProcAddress("glGenBuffers")); 279 | glGenFramebuffers = reinterpret_cast( 280 | eglGetProcAddress("glGenFramebuffers")); 281 | glGenRenderbuffers = reinterpret_cast( 282 | eglGetProcAddress("glGenRenderbuffers")); 283 | glGetAttribLocation = reinterpret_cast( 284 | eglGetProcAddress("glGetAttribLocation")); 285 | glGetBufferParameteriv = reinterpret_cast( 286 | eglGetProcAddress("glGetBufferParameteriv")); 287 | glGetError = 288 | reinterpret_cast(eglGetProcAddress("glGetError")); 289 | glGetFramebufferAttachmentParameteriv = 290 | reinterpret_cast( 291 | eglGetProcAddress("glGetFramebufferAttachmentParameteriv")); 292 | glGetIntegerv = reinterpret_cast( 293 | eglGetProcAddress("glGetIntegerv")); 294 | glGenTextures = reinterpret_cast( 295 | eglGetProcAddress("glGenTextures")); 296 | glGetActiveAttrib = reinterpret_cast( 297 | eglGetProcAddress("glGetActiveAttrib")); 298 | glGetActiveUniform = reinterpret_cast( 299 | eglGetProcAddress("glGetActiveUniform")); 300 | glGetAttachedShaders = reinterpret_cast( 301 | eglGetProcAddress("glGetAttachedShaders")); 302 | glGetProgramiv = reinterpret_cast( 303 | eglGetProcAddress("glGetProgramiv")); 304 | glGetProgramInfoLog = reinterpret_cast( 305 | eglGetProcAddress("glGetProgramInfoLog")); 306 | glGetRenderbufferParameteriv = 307 | reinterpret_cast( 308 | eglGetProcAddress("glGetRenderbufferParameteriv")); 309 | glGetShaderiv = reinterpret_cast( 310 | eglGetProcAddress("glGetShaderiv")); 311 | glGetShaderInfoLog = reinterpret_cast( 312 | eglGetProcAddress("glGetShaderInfoLog")); 313 | glGetShaderPrecisionFormat = 314 | reinterpret_cast( 315 | eglGetProcAddress("glGetShaderPrecisionFormat")); 316 | glGetString = 317 | reinterpret_cast(eglGetProcAddress("glGetString")); 318 | glGetTexParameterfv = reinterpret_cast( 319 | eglGetProcAddress("glGetTexParameterfv")); 320 | glGetTexParameteriv = reinterpret_cast( 321 | eglGetProcAddress("glGetTexParameteriv")); 322 | glGetUniformLocation = reinterpret_cast( 323 | eglGetProcAddress("glGetUniformLocation")); 324 | glHint = reinterpret_cast(eglGetProcAddress("glHint")); 325 | glIsBuffer = 326 | reinterpret_cast(eglGetProcAddress("glIsBuffer")); 327 | glIsEnabled = 328 | reinterpret_cast(eglGetProcAddress("glIsEnabled")); 329 | glIsFramebuffer = reinterpret_cast( 330 | eglGetProcAddress("glIsFramebuffer")); 331 | glIsProgram = 332 | reinterpret_cast(eglGetProcAddress("glIsProgram")); 333 | glIsRenderbuffer = reinterpret_cast( 334 | eglGetProcAddress("glIsRenderbuffer")); 335 | glIsShader = 336 | reinterpret_cast(eglGetProcAddress("glIsShader")); 337 | glIsTexture = 338 | reinterpret_cast(eglGetProcAddress("glIsTexture")); 339 | glLineWidth = 340 | reinterpret_cast(eglGetProcAddress("glLineWidth")); 341 | glLinkProgram = reinterpret_cast( 342 | eglGetProcAddress("glLinkProgram")); 343 | glMapBufferRange = reinterpret_cast( 344 | eglGetProcAddress("glMapBufferRange")); 345 | glPixelStorei = reinterpret_cast( 346 | eglGetProcAddress("glPixelStorei")); 347 | glPolygonOffset = reinterpret_cast( 348 | eglGetProcAddress("glPolygonOffset")); 349 | glReadPixels = 350 | reinterpret_cast(eglGetProcAddress("glReadPixels")); 351 | glRenderbufferStorage = reinterpret_cast( 352 | eglGetProcAddress("glRenderbufferStorage")); 353 | glSampleCoverage = reinterpret_cast( 354 | eglGetProcAddress("glSampleCoverage")); 355 | glScissor = 356 | reinterpret_cast(eglGetProcAddress("glScissor")); 357 | glShaderSource = reinterpret_cast( 358 | eglGetProcAddress("glShaderSource")); 359 | glStencilMask = reinterpret_cast( 360 | eglGetProcAddress("glStencilMask")); 361 | glStencilMaskSeparate = reinterpret_cast( 362 | eglGetProcAddress("glStencilMaskSeparate")); 363 | glStencilFunc = reinterpret_cast( 364 | eglGetProcAddress("glStencilFunc")); 365 | glStencilFuncSeparate = reinterpret_cast( 366 | eglGetProcAddress("glStencilFuncSeparate")); 367 | glStencilOp = 368 | reinterpret_cast(eglGetProcAddress("glStencilOp")); 369 | glStencilOpSeparate = reinterpret_cast( 370 | eglGetProcAddress("glStencilOpSeparate")); 371 | glTexImage2D = 372 | reinterpret_cast(eglGetProcAddress("glTexImage2D")); 373 | glTexParameteri = reinterpret_cast( 374 | eglGetProcAddress("glTexParameteri")); 375 | glTexParameterf = reinterpret_cast( 376 | eglGetProcAddress("glTexParameterf")); 377 | glTexSubImage2D = reinterpret_cast( 378 | eglGetProcAddress("glTexSubImage2D")); 379 | glUniform1f = 380 | reinterpret_cast(eglGetProcAddress("glUniform1f")); 381 | glUniform1fv = 382 | reinterpret_cast(eglGetProcAddress("glUniform1fv")); 383 | glUniform1i = 384 | reinterpret_cast(eglGetProcAddress("glUniform1i")); 385 | glUniform1iv = 386 | reinterpret_cast(eglGetProcAddress("glUniform1iv")); 387 | glUniform2f = 388 | reinterpret_cast(eglGetProcAddress("glUniform2f")); 389 | glUniform2fv = 390 | reinterpret_cast(eglGetProcAddress("glUniform2fv")); 391 | glUniform2i = 392 | reinterpret_cast(eglGetProcAddress("glUniform2i")); 393 | glUniform2iv = 394 | reinterpret_cast(eglGetProcAddress("glUniform2iv")); 395 | glUniform3f = 396 | reinterpret_cast(eglGetProcAddress("glUniform3f")); 397 | glUniform3fv = 398 | reinterpret_cast(eglGetProcAddress("glUniform3fv")); 399 | glUniform3i = 400 | reinterpret_cast(eglGetProcAddress("glUniform3i")); 401 | glUniform3iv = 402 | reinterpret_cast(eglGetProcAddress("glUniform3iv")); 403 | glUniform4f = 404 | reinterpret_cast(eglGetProcAddress("glUniform4f")); 405 | glUniform4fv = 406 | reinterpret_cast(eglGetProcAddress("glUniform4fv")); 407 | glUniform4i = 408 | reinterpret_cast(eglGetProcAddress("glUniform4i")); 409 | glUniform4iv = 410 | reinterpret_cast(eglGetProcAddress("glUniform4iv")); 411 | glUniformMatrix2fv = reinterpret_cast( 412 | eglGetProcAddress("glUniformMatrix2fv")); 413 | glUniformMatrix3fv = reinterpret_cast( 414 | eglGetProcAddress("glUniformMatrix3fv")); 415 | glUniformMatrix4fv = reinterpret_cast( 416 | eglGetProcAddress("glUniformMatrix4fv")); 417 | glUnmapBuffer = reinterpret_cast( 418 | eglGetProcAddress("glUnmapBuffer")); 419 | glUseProgram = 420 | reinterpret_cast(eglGetProcAddress("glUseProgram")); 421 | glValidateProgram = reinterpret_cast( 422 | eglGetProcAddress("glValidateProgram")); 423 | glVertexAttrib1f = reinterpret_cast( 424 | eglGetProcAddress("glVertexAttrib1f")); 425 | glVertexAttrib1fv = reinterpret_cast( 426 | eglGetProcAddress("glVertexAttrib1fv")); 427 | glVertexAttrib2f = reinterpret_cast( 428 | eglGetProcAddress("glVertexAttrib2f")); 429 | glVertexAttrib2fv = reinterpret_cast( 430 | eglGetProcAddress("glVertexAttrib2fv")); 431 | glVertexAttrib3f = reinterpret_cast( 432 | eglGetProcAddress("glVertexAttrib3f")); 433 | glVertexAttrib3fv = reinterpret_cast( 434 | eglGetProcAddress("glVertexAttrib3fv")); 435 | glVertexAttrib4f = reinterpret_cast( 436 | eglGetProcAddress("glVertexAttrib4f")); 437 | glVertexAttrib4fv = reinterpret_cast( 438 | eglGetProcAddress("glVertexAttrib4fv")); 439 | glVertexAttribPointer = reinterpret_cast( 440 | eglGetProcAddress("glVertexAttribPointer")); 441 | glViewport = 442 | reinterpret_cast(eglGetProcAddress("glViewport")); 443 | 444 | // ANGLE specific 445 | glRequestExtensionANGLE = reinterpret_cast( 446 | eglGetProcAddress("glRequestExtensionANGLE")); 447 | } 448 | 449 | void EGLContextWrapper::RefreshGLExtensions() { 450 | gl_extensions = std::unique_ptr(new GLExtensionsWrapper( 451 | reinterpret_cast(glGetString(GL_EXTENSIONS)))); 452 | 453 | angle_requestable_extensions = std::unique_ptr( 454 | new GLExtensionsWrapper(reinterpret_cast( 455 | glGetString(GL_REQUESTABLE_EXTENSIONS_ANGLE)))); 456 | } 457 | 458 | EGLContextWrapper::~EGLContextWrapper() { 459 | if (context) { 460 | if (!eglDestroyContext(display, context)) { 461 | std::cerr << "Failed to delete EGL context: " << std::endl; 462 | } 463 | context = nullptr; 464 | } 465 | 466 | // TODO(kreeger): Close context attributes. 467 | // TODO(kreeger): Cleanup global objects. 468 | } 469 | 470 | EGLContextWrapper* EGLContextWrapper::Create( 471 | napi_env env, const GLContextOptions& context_options) { 472 | return new EGLContextWrapper(env, context_options); 473 | } 474 | 475 | } // namespace nodejsgl 476 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@types/bindings@^1.3.0": 6 | version "1.3.0" 7 | resolved "https://registry.yarnpkg.com/@types/bindings/-/bindings-1.3.0.tgz#e9cd75a96d7abc1ecba0dc7eecb09a9f96cd417c" 8 | integrity sha512-mTWOE6wC64MoEpv33otJNpQob81l5Pi+NsUkdiiP8EkESraQM94zuus/2s/Vz2Idy1qQkctNINYDZ61nfG1ngQ== 9 | 10 | "@types/node@*": 11 | version "10.12.15" 12 | resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.15.tgz#20e85651b62fd86656e57c9c9bc771ab1570bc59" 13 | integrity sha512-9kROxduaN98QghwwHmxXO2Xz3MaWf+I1sLVAA6KJDF5xix+IyXVhds0MAfdNwtcpSrzhaTsNB0/jnL86fgUhqA== 14 | 15 | "@types/node@^10.9.4": 16 | version "10.11.0" 17 | resolved "https://registry.yarnpkg.com/@types/node/-/node-10.11.0.tgz#ddd0d67a3b6c3810dd1a59e36675fa82de5e19ae" 18 | integrity sha512-R4Dvw6KjSYn/SpvjRchBOwXr14vVVcFXCtnM3f0aLvlJS8a599rrcEoihcP2/+Z/f75E5GNPd4aWM7j1yei9og== 19 | 20 | "@types/progress@^2.0.3": 21 | version "2.0.3" 22 | resolved "https://registry.yarnpkg.com/@types/progress/-/progress-2.0.3.tgz#7ccbd9c6d4d601319126c469e73b5bb90dfc8ccc" 23 | integrity sha512-bPOsfCZ4tsTlKiBjBhKnM8jpY5nmIll166IPD58D92hR7G7kZDfx5iB9wGF4NfZrdKolebjeAr3GouYkSGoJ/A== 24 | dependencies: 25 | "@types/node" "*" 26 | 27 | "@types/webgl2@^0.0.4": 28 | version "0.0.4" 29 | resolved "https://registry.yarnpkg.com/@types/webgl2/-/webgl2-0.0.4.tgz#c3b0f9d6b465c66138e84e64cb3bdf8373c2c279" 30 | integrity sha512-PACt1xdErJbMUOUweSrbVM7gSIYm1vTncW2hF6Os/EeWi6TXYAYMPp+8v6rzHmypE5gHrxaxZNXgMkJVIdZpHw== 31 | 32 | adm-zip@^0.4.13: 33 | version "0.4.13" 34 | resolved "https://registry.yarnpkg.com/adm-zip/-/adm-zip-0.4.13.tgz#597e2f8cc3672151e1307d3e95cddbc75672314a" 35 | integrity sha512-fERNJX8sOXfel6qCBCMPvZLzENBEhZTzKqg6vrOW5pvoEaQuJhRU4ndTAh6lHOxn1I6jnz2NHra56ZODM751uw== 36 | 37 | agent-base@^4.3.0: 38 | version "4.3.0" 39 | resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" 40 | integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== 41 | dependencies: 42 | es6-promisify "^5.0.0" 43 | 44 | ansi-regex@^2.0.0: 45 | version "2.1.1" 46 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" 47 | integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= 48 | 49 | array-union@^1.0.1: 50 | version "1.0.2" 51 | resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" 52 | integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= 53 | dependencies: 54 | array-uniq "^1.0.1" 55 | 56 | array-uniq@^1.0.1: 57 | version "1.0.3" 58 | resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" 59 | integrity sha1-r2rId6Jcx/dOBYiUdThY39sk/bY= 60 | 61 | arrify@^1.0.0: 62 | version "1.0.1" 63 | resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" 64 | integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= 65 | 66 | async@^1.5.2: 67 | version "1.5.2" 68 | resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" 69 | integrity sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo= 70 | 71 | balanced-match@^1.0.0: 72 | version "1.0.0" 73 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 74 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 75 | 76 | bindings@^1.3.0: 77 | version "1.3.0" 78 | resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.3.0.tgz#b346f6ecf6a95f5a815c5839fc7cdb22502f1ed7" 79 | integrity sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw== 80 | 81 | brace-expansion@^1.1.7: 82 | version "1.1.11" 83 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 84 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 85 | dependencies: 86 | balanced-match "^1.0.0" 87 | concat-map "0.0.1" 88 | 89 | buffer-from@^1.0.0, buffer-from@^1.1.0: 90 | version "1.1.1" 91 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" 92 | integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A== 93 | 94 | builtin-modules@^1.0.0: 95 | version "1.1.1" 96 | resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" 97 | integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= 98 | 99 | camelcase@^3.0.0: 100 | version "3.0.0" 101 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" 102 | integrity sha1-MvxLn82vhF/N9+c7uXysImHwqwo= 103 | 104 | chownr@^1.1.3: 105 | version "1.1.4" 106 | resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" 107 | integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== 108 | 109 | clang-format@^1.2.4: 110 | version "1.2.4" 111 | resolved "https://registry.yarnpkg.com/clang-format/-/clang-format-1.2.4.tgz#4bb4b0a98180428deb093cf20982e9fc1af20b6c" 112 | integrity sha512-sw+nrGUp3hvmANd1qF8vZPuezSYQAiXgGBiEtkXTtJnnu6b00fCqkkDIsnRKrNgg4nv6NYZE92ejvOMIXZoejw== 113 | dependencies: 114 | async "^1.5.2" 115 | glob "^7.0.0" 116 | resolve "^1.1.6" 117 | 118 | cliui@^3.2.0: 119 | version "3.2.0" 120 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" 121 | integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= 122 | dependencies: 123 | string-width "^1.0.1" 124 | strip-ansi "^3.0.1" 125 | wrap-ansi "^2.0.0" 126 | 127 | code-point-at@^1.0.0: 128 | version "1.1.0" 129 | resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" 130 | integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= 131 | 132 | concat-map@0.0.1: 133 | version "0.0.1" 134 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 135 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 136 | 137 | debug@^3.1.0: 138 | version "3.2.6" 139 | resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" 140 | integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== 141 | dependencies: 142 | ms "^2.1.1" 143 | 144 | decamelize@^1.1.1: 145 | version "1.2.0" 146 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 147 | integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 148 | 149 | del@^2.2.2: 150 | version "2.2.2" 151 | resolved "https://registry.yarnpkg.com/del/-/del-2.2.2.tgz#c12c981d067846c84bcaf862cff930d907ffd1a8" 152 | integrity sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag= 153 | dependencies: 154 | globby "^5.0.0" 155 | is-path-cwd "^1.0.0" 156 | is-path-in-cwd "^1.0.0" 157 | object-assign "^4.0.1" 158 | pify "^2.0.0" 159 | pinkie-promise "^2.0.0" 160 | rimraf "^2.2.8" 161 | 162 | diff@^3.1.0: 163 | version "3.5.0" 164 | resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" 165 | integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== 166 | 167 | error-ex@^1.2.0: 168 | version "1.3.2" 169 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" 170 | integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== 171 | dependencies: 172 | is-arrayish "^0.2.1" 173 | 174 | es6-promise@^4.0.3: 175 | version "4.2.5" 176 | resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.5.tgz#da6d0d5692efb461e082c14817fe2427d8f5d054" 177 | integrity sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg== 178 | 179 | es6-promisify@^5.0.0: 180 | version "5.0.0" 181 | resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203" 182 | integrity sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM= 183 | dependencies: 184 | es6-promise "^4.0.3" 185 | 186 | find-up@^1.0.0: 187 | version "1.1.2" 188 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" 189 | integrity sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8= 190 | dependencies: 191 | path-exists "^2.0.0" 192 | pinkie-promise "^2.0.0" 193 | 194 | fs-extra@^4.0.2: 195 | version "4.0.3" 196 | resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" 197 | integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== 198 | dependencies: 199 | graceful-fs "^4.1.2" 200 | jsonfile "^4.0.0" 201 | universalify "^0.1.0" 202 | 203 | fs-minipass@^2.0.0: 204 | version "2.1.0" 205 | resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" 206 | integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== 207 | dependencies: 208 | minipass "^3.0.0" 209 | 210 | fs.realpath@^1.0.0: 211 | version "1.0.0" 212 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 213 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 214 | 215 | get-caller-file@^1.0.1: 216 | version "1.0.3" 217 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" 218 | integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== 219 | 220 | glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.3: 221 | version "7.1.3" 222 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" 223 | integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== 224 | dependencies: 225 | fs.realpath "^1.0.0" 226 | inflight "^1.0.4" 227 | inherits "2" 228 | minimatch "^3.0.4" 229 | once "^1.3.0" 230 | path-is-absolute "^1.0.0" 231 | 232 | globby@^5.0.0: 233 | version "5.0.0" 234 | resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" 235 | integrity sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0= 236 | dependencies: 237 | array-union "^1.0.1" 238 | arrify "^1.0.0" 239 | glob "^7.0.3" 240 | object-assign "^4.0.1" 241 | pify "^2.0.0" 242 | pinkie-promise "^2.0.0" 243 | 244 | graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: 245 | version "4.1.15" 246 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" 247 | integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== 248 | 249 | hosted-git-info@^2.1.4: 250 | version "2.7.1" 251 | resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" 252 | integrity sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w== 253 | 254 | https-proxy-agent@^2.2.3: 255 | version "2.2.3" 256 | resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.3.tgz#fb6cd98ed5b9c35056b5a73cd01a8a721d7193d1" 257 | integrity sha512-Ytgnz23gm2DVftnzqRRz2dOXZbGd2uiajSw/95bPp6v53zPRspQjLm/AfBgqbJ2qfeRXWIOMVLpp86+/5yX39Q== 258 | dependencies: 259 | agent-base "^4.3.0" 260 | debug "^3.1.0" 261 | 262 | ignore-walk@^3.0.1: 263 | version "3.0.1" 264 | resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" 265 | integrity sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ== 266 | dependencies: 267 | minimatch "^3.0.4" 268 | 269 | ignore@^5.0.4: 270 | version "5.0.4" 271 | resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.0.4.tgz#33168af4a21e99b00c5d41cbadb6a6cb49903a45" 272 | integrity sha512-WLsTMEhsQuXpCiG173+f3aymI43SXa+fB1rSfbzyP4GkPP+ZFVuO0/3sFUGNBtifisPeDcl/uD/Y2NxZ7xFq4g== 273 | 274 | inflight@^1.0.4: 275 | version "1.0.6" 276 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 277 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 278 | dependencies: 279 | once "^1.3.0" 280 | wrappy "1" 281 | 282 | inherits@2: 283 | version "2.0.3" 284 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 285 | integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= 286 | 287 | invert-kv@^1.0.0: 288 | version "1.0.0" 289 | resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" 290 | integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= 291 | 292 | is-arrayish@^0.2.1: 293 | version "0.2.1" 294 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" 295 | integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= 296 | 297 | is-builtin-module@^1.0.0: 298 | version "1.0.0" 299 | resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" 300 | integrity sha1-VAVy0096wxGfj3bDDLwbHgN6/74= 301 | dependencies: 302 | builtin-modules "^1.0.0" 303 | 304 | is-fullwidth-code-point@^1.0.0: 305 | version "1.0.0" 306 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" 307 | integrity sha1-754xOG8DGn8NZDr4L95QxFfvAMs= 308 | dependencies: 309 | number-is-nan "^1.0.0" 310 | 311 | is-path-cwd@^1.0.0: 312 | version "1.0.0" 313 | resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" 314 | integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= 315 | 316 | is-path-in-cwd@^1.0.0: 317 | version "1.0.1" 318 | resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" 319 | integrity sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ== 320 | dependencies: 321 | is-path-inside "^1.0.0" 322 | 323 | is-path-inside@^1.0.0: 324 | version "1.0.1" 325 | resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" 326 | integrity sha1-jvW33lBDej/cprToZe96pVy0gDY= 327 | dependencies: 328 | path-is-inside "^1.0.1" 329 | 330 | is-utf8@^0.2.0: 331 | version "0.2.1" 332 | resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" 333 | integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= 334 | 335 | jsonfile@^4.0.0: 336 | version "4.0.0" 337 | resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" 338 | integrity sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss= 339 | optionalDependencies: 340 | graceful-fs "^4.1.6" 341 | 342 | lcid@^1.0.0: 343 | version "1.0.0" 344 | resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" 345 | integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= 346 | dependencies: 347 | invert-kv "^1.0.0" 348 | 349 | load-json-file@^1.0.0: 350 | version "1.1.0" 351 | resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" 352 | integrity sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA= 353 | dependencies: 354 | graceful-fs "^4.1.2" 355 | parse-json "^2.2.0" 356 | pify "^2.0.0" 357 | pinkie-promise "^2.0.0" 358 | strip-bom "^2.0.0" 359 | 360 | make-error@^1.1.1: 361 | version "1.3.5" 362 | resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.5.tgz#efe4e81f6db28cadd605c70f29c831b58ef776c8" 363 | integrity sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g== 364 | 365 | minimatch@^3.0.4: 366 | version "3.0.4" 367 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 368 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 369 | dependencies: 370 | brace-expansion "^1.1.7" 371 | 372 | minimist@0.0.8: 373 | version "0.0.8" 374 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" 375 | integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= 376 | 377 | minimist@^1.2.0: 378 | version "1.2.0" 379 | resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" 380 | integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ= 381 | 382 | minipass@^3.0.0: 383 | version "3.1.1" 384 | resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.1.tgz#7607ce778472a185ad6d89082aa2070f79cedcd5" 385 | integrity sha512-UFqVihv6PQgwj8/yTGvl9kPz7xIAY+R5z6XYjRInD3Gk3qx6QGSD6zEcpeG4Dy/lQnv1J6zv8ejV90hyYIKf3w== 386 | dependencies: 387 | yallist "^4.0.0" 388 | 389 | minizlib@^2.1.0: 390 | version "2.1.0" 391 | resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.0.tgz#fd52c645301ef09a63a2c209697c294c6ce02cf3" 392 | integrity sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA== 393 | dependencies: 394 | minipass "^3.0.0" 395 | yallist "^4.0.0" 396 | 397 | mkdirp@^0.5.1: 398 | version "0.5.1" 399 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" 400 | integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM= 401 | dependencies: 402 | minimist "0.0.8" 403 | 404 | mkdirp@^1.0.3: 405 | version "1.0.4" 406 | resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" 407 | integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== 408 | 409 | ms@^2.1.1: 410 | version "2.1.1" 411 | resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" 412 | integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== 413 | 414 | normalize-package-data@^2.3.2: 415 | version "2.4.0" 416 | resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" 417 | integrity sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw== 418 | dependencies: 419 | hosted-git-info "^2.1.4" 420 | is-builtin-module "^1.0.0" 421 | semver "2 || 3 || 4 || 5" 422 | validate-npm-package-license "^3.0.1" 423 | 424 | npm-bundled@^1.0.1: 425 | version "1.0.5" 426 | resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" 427 | integrity sha512-m/e6jgWu8/v5niCUKQi9qQl8QdeEduFA96xHDDzFGqly0OOjI7c+60KM/2sppfnUU9JJagf+zs+yGhqSOFj71g== 428 | 429 | npm-packlist-fixed@^1.1.12: 430 | version "1.1.12" 431 | resolved "https://registry.yarnpkg.com/npm-packlist-fixed/-/npm-packlist-fixed-1.1.12.tgz#0d9b0e5458d6977113432777af79df900c832d61" 432 | integrity sha512-PbQqWvKR5oxfQzK/+HyUPaWt1r92HSzTzuUYv5QDW4PmIBisrjr13CUKrCxyeKG/2ClpAxpCe74pWeyY1Pi7Lg== 433 | dependencies: 434 | ignore-walk "^3.0.1" 435 | npm-bundled "^1.0.1" 436 | 437 | number-is-nan@^1.0.0: 438 | version "1.0.1" 439 | resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" 440 | integrity sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0= 441 | 442 | object-assign@^4.0.1: 443 | version "4.1.1" 444 | resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" 445 | integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= 446 | 447 | once@^1.3.0: 448 | version "1.4.0" 449 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 450 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 451 | dependencies: 452 | wrappy "1" 453 | 454 | os-homedir@^1.0.0: 455 | version "1.0.2" 456 | resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" 457 | integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= 458 | 459 | os-locale@^1.4.0: 460 | version "1.4.0" 461 | resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" 462 | integrity sha1-IPnxeuKe00XoveWDsT0gCYA8FNk= 463 | dependencies: 464 | lcid "^1.0.0" 465 | 466 | parse-json@^2.2.0: 467 | version "2.2.0" 468 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" 469 | integrity sha1-9ID0BDTvgHQfhGkJn43qGPVaTck= 470 | dependencies: 471 | error-ex "^1.2.0" 472 | 473 | path-exists@^2.0.0: 474 | version "2.1.0" 475 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" 476 | integrity sha1-D+tsZPD8UY2adU3V77YscCJ2H0s= 477 | dependencies: 478 | pinkie-promise "^2.0.0" 479 | 480 | path-is-absolute@^1.0.0: 481 | version "1.0.1" 482 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 483 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 484 | 485 | path-is-inside@^1.0.1: 486 | version "1.0.2" 487 | resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" 488 | integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= 489 | 490 | path-parse@^1.0.5: 491 | version "1.0.6" 492 | resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.6.tgz#d62dbb5679405d72c4737ec58600e9ddcf06d24c" 493 | integrity sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw== 494 | 495 | path-type@^1.0.0: 496 | version "1.1.0" 497 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" 498 | integrity sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE= 499 | dependencies: 500 | graceful-fs "^4.1.2" 501 | pify "^2.0.0" 502 | pinkie-promise "^2.0.0" 503 | 504 | pify@^2.0.0: 505 | version "2.3.0" 506 | resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" 507 | integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= 508 | 509 | pinkie-promise@^2.0.0: 510 | version "2.0.1" 511 | resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" 512 | integrity sha1-ITXW36ejWMBprJsXh3YogihFD/o= 513 | dependencies: 514 | pinkie "^2.0.0" 515 | 516 | pinkie@^2.0.0: 517 | version "2.0.4" 518 | resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" 519 | integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= 520 | 521 | progress@^2.0.3: 522 | version "2.0.3" 523 | resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" 524 | integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== 525 | 526 | read-pkg-up@^1.0.1: 527 | version "1.0.1" 528 | resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" 529 | integrity sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI= 530 | dependencies: 531 | find-up "^1.0.0" 532 | read-pkg "^1.0.0" 533 | 534 | read-pkg@^1.0.0: 535 | version "1.1.0" 536 | resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" 537 | integrity sha1-9f+qXs0pyzHAR0vKfXVra7KePyg= 538 | dependencies: 539 | load-json-file "^1.0.0" 540 | normalize-package-data "^2.3.2" 541 | path-type "^1.0.0" 542 | 543 | require-directory@^2.1.1: 544 | version "2.1.1" 545 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 546 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 547 | 548 | require-main-filename@^1.0.1: 549 | version "1.0.1" 550 | resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" 551 | integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= 552 | 553 | resolve@^1.1.6: 554 | version "1.8.1" 555 | resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" 556 | integrity sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA== 557 | dependencies: 558 | path-parse "^1.0.5" 559 | 560 | rimraf@^2.2.8: 561 | version "2.6.3" 562 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.3.tgz#b2d104fe0d8fb27cf9e0a1cda8262dd3833c6cab" 563 | integrity sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA== 564 | dependencies: 565 | glob "^7.1.3" 566 | 567 | rimraf@^2.6.2: 568 | version "2.6.2" 569 | resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" 570 | integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== 571 | dependencies: 572 | glob "^7.0.5" 573 | 574 | "semver@2 || 3 || 4 || 5": 575 | version "5.6.0" 576 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" 577 | integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg== 578 | 579 | set-blocking@^2.0.0: 580 | version "2.0.0" 581 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 582 | integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= 583 | 584 | source-map-support@^0.5.6: 585 | version "0.5.9" 586 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" 587 | integrity sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA== 588 | dependencies: 589 | buffer-from "^1.0.0" 590 | source-map "^0.6.0" 591 | 592 | source-map@^0.6.0: 593 | version "0.6.1" 594 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" 595 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== 596 | 597 | spdx-correct@^3.0.0: 598 | version "3.1.0" 599 | resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" 600 | integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== 601 | dependencies: 602 | spdx-expression-parse "^3.0.0" 603 | spdx-license-ids "^3.0.0" 604 | 605 | spdx-exceptions@^2.1.0: 606 | version "2.2.0" 607 | resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977" 608 | integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA== 609 | 610 | spdx-expression-parse@^3.0.0: 611 | version "3.0.0" 612 | resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" 613 | integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== 614 | dependencies: 615 | spdx-exceptions "^2.1.0" 616 | spdx-license-ids "^3.0.0" 617 | 618 | spdx-license-ids@^3.0.0: 619 | version "3.0.3" 620 | resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz#81c0ce8f21474756148bbb5f3bfc0f36bf15d76e" 621 | integrity sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g== 622 | 623 | string-width@^1.0.1, string-width@^1.0.2: 624 | version "1.0.2" 625 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" 626 | integrity sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M= 627 | dependencies: 628 | code-point-at "^1.0.0" 629 | is-fullwidth-code-point "^1.0.0" 630 | strip-ansi "^3.0.0" 631 | 632 | strip-ansi@^3.0.0, strip-ansi@^3.0.1: 633 | version "3.0.1" 634 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" 635 | integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= 636 | dependencies: 637 | ansi-regex "^2.0.0" 638 | 639 | strip-bom@^2.0.0: 640 | version "2.0.0" 641 | resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" 642 | integrity sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4= 643 | dependencies: 644 | is-utf8 "^0.2.0" 645 | 646 | tar@^6.0.1: 647 | version "6.0.1" 648 | resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.1.tgz#7b3bd6c313cb6e0153770108f8d70ac298607efa" 649 | integrity sha512-bKhKrrz2FJJj5s7wynxy/fyxpE0CmCjmOQ1KV4KkgXFWOgoIT/NbTMnB1n+LFNrNk0SSBVGGxcK5AGsyC+pW5Q== 650 | dependencies: 651 | chownr "^1.1.3" 652 | fs-minipass "^2.0.0" 653 | minipass "^3.0.0" 654 | minizlib "^2.1.0" 655 | mkdirp "^1.0.3" 656 | yallist "^4.0.0" 657 | 658 | ts-node@^7.0.1: 659 | version "7.0.1" 660 | resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" 661 | integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== 662 | dependencies: 663 | arrify "^1.0.0" 664 | buffer-from "^1.1.0" 665 | diff "^3.1.0" 666 | make-error "^1.1.1" 667 | minimist "^1.2.0" 668 | mkdirp "^0.5.1" 669 | source-map-support "^0.5.6" 670 | yn "^2.0.0" 671 | 672 | typescript@^3.0.3: 673 | version "3.0.3" 674 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.0.3.tgz#4853b3e275ecdaa27f78fda46dc273a7eb7fc1c8" 675 | integrity sha512-kk80vLW9iGtjMnIv11qyxLqZm20UklzuR2tL0QAnDIygIUIemcZMxlMWudl9OOt76H3ntVzcTiddQ1/pAAJMYg== 676 | 677 | universalify@^0.1.0: 678 | version "0.1.2" 679 | resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" 680 | integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== 681 | 682 | user-home@^2.0.0: 683 | version "2.0.0" 684 | resolved "https://registry.yarnpkg.com/user-home/-/user-home-2.0.0.tgz#9c70bfd8169bc1dcbf48604e0f04b8b49cde9e9f" 685 | integrity sha1-nHC/2Babwdy/SGBODwS4tJzenp8= 686 | dependencies: 687 | os-homedir "^1.0.0" 688 | 689 | validate-npm-package-license@^3.0.1: 690 | version "3.0.4" 691 | resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" 692 | integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== 693 | dependencies: 694 | spdx-correct "^3.0.0" 695 | spdx-expression-parse "^3.0.0" 696 | 697 | which-module@^1.0.0: 698 | version "1.0.0" 699 | resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" 700 | integrity sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8= 701 | 702 | wrap-ansi@^2.0.0: 703 | version "2.1.0" 704 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" 705 | integrity sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU= 706 | dependencies: 707 | string-width "^1.0.1" 708 | strip-ansi "^3.0.1" 709 | 710 | wrappy@1: 711 | version "1.0.2" 712 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 713 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 714 | 715 | y18n@^3.2.1: 716 | version "3.2.1" 717 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" 718 | integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= 719 | 720 | yalc@^1.0.0-pre.27: 721 | version "1.0.0-pre.27" 722 | resolved "https://registry.yarnpkg.com/yalc/-/yalc-1.0.0-pre.27.tgz#ebc85f1e22772e21122e4e062a0a1671795019b7" 723 | integrity sha512-PyXf4XtnQIOXgoW3HLnf5Mg3wH8g5q25HmCEgCzlcie0gui6xAGLxnoU4BSCDIAU4vbbrtKE8FJuZPhigaaphg== 724 | dependencies: 725 | del "^2.2.2" 726 | fs-extra "^4.0.2" 727 | graceful-fs "^4.1.15" 728 | ignore "^5.0.4" 729 | npm-packlist-fixed "^1.1.12" 730 | user-home "^2.0.0" 731 | yargs "^7.1.0" 732 | 733 | yallist@^4.0.0: 734 | version "4.0.0" 735 | resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" 736 | integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== 737 | 738 | yargs-parser@^5.0.0: 739 | version "5.0.0" 740 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" 741 | integrity sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo= 742 | dependencies: 743 | camelcase "^3.0.0" 744 | 745 | yargs@^7.1.0: 746 | version "7.1.0" 747 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8" 748 | integrity sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg= 749 | dependencies: 750 | camelcase "^3.0.0" 751 | cliui "^3.2.0" 752 | decamelize "^1.1.1" 753 | get-caller-file "^1.0.1" 754 | os-locale "^1.4.0" 755 | read-pkg-up "^1.0.1" 756 | require-directory "^2.1.1" 757 | require-main-filename "^1.0.1" 758 | set-blocking "^2.0.0" 759 | string-width "^1.0.2" 760 | which-module "^1.0.0" 761 | y18n "^3.2.1" 762 | yargs-parser "^5.0.0" 763 | 764 | yn@^2.0.0: 765 | version "2.0.0" 766 | resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" 767 | integrity sha1-5a2ryKz0CPY4X8dklWhMiOavaJo= 768 | -------------------------------------------------------------------------------- /binding/webgl_extensions.cc: -------------------------------------------------------------------------------- 1 | /** 2 | * @license 3 | * Copyright 2018 Google Inc. All Rights Reserved. 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | * ============================================================================= 16 | */ 17 | 18 | #include "webgl_extensions.h" 19 | 20 | #include "angle/include/GLES2/gl2.h" 21 | #include "angle/include/GLES2/gl2ext.h" 22 | 23 | #include "utils.h" 24 | 25 | namespace nodejsgl { 26 | 27 | // Throws error if extension is not supported: 28 | #ifndef ENSURE_EXTENSION_IS_SUPPORTED 29 | #define ENSURE_EXTENSION_IS_SUPPORTED \ 30 | if (!IsSupported(egl_context_wrapper)) { \ 31 | NAPI_THROW_ERROR(env, "Unsupported extension"); \ 32 | return napi_invalid_arg; \ 33 | } 34 | #endif 35 | 36 | // Returns true if extension is requestable or enabled: 37 | #ifndef IS_EXTENSION_NAME_AVAILABLE 38 | #define IS_EXTENSION_NAME_AVAILABLE(ext_name) \ 39 | return egl_context_wrapper->angle_requestable_extensions->HasExtension( \ 40 | ext_name) || \ 41 | egl_context_wrapper->gl_extensions->HasExtension(ext_name); 42 | #endif 43 | 44 | //============================================================================== 45 | // GLExtensionBase 46 | 47 | /* static */ 48 | napi_value GLExtensionBase::InitStubClass(napi_env env, 49 | napi_callback_info info) { 50 | ENSURE_CONSTRUCTOR_CALL_RETVAL(env, info, nullptr); 51 | 52 | napi_status nstatus; 53 | napi_value js_this; 54 | nstatus = napi_get_cb_info(env, info, 0, nullptr, &js_this, nullptr); 55 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nullptr); 56 | 57 | return js_this; 58 | } 59 | 60 | /* static */ 61 | napi_status GLExtensionBase::NewInstanceBase(napi_env env, 62 | napi_ref constructor_ref, 63 | napi_value* instance) { 64 | napi_status nstatus; 65 | 66 | napi_value ctor_value; 67 | nstatus = napi_get_reference_value(env, constructor_ref, &ctor_value); 68 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 69 | 70 | nstatus = napi_new_instance(env, ctor_value, 0, nullptr, instance); 71 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 72 | 73 | return napi_ok; 74 | } 75 | 76 | //============================================================================== 77 | // ANGLEInstancedArraysExtension 78 | 79 | napi_ref ANGLEInstancedArraysExtension::constructor_ref_; 80 | 81 | ANGLEInstancedArraysExtension::ANGLEInstancedArraysExtension(napi_env env) 82 | : GLExtensionBase(env) {} 83 | 84 | /* static */ 85 | bool ANGLEInstancedArraysExtension::IsSupported( 86 | EGLContextWrapper* egl_context_wrapper) { 87 | IS_EXTENSION_NAME_AVAILABLE("GL_ANGLE_instanced_arrays"); 88 | } 89 | 90 | /* static */ 91 | napi_status ANGLEInstancedArraysExtension::Register(napi_env env, 92 | napi_value exports) { 93 | napi_status nstatus; 94 | 95 | napi_value ctor_value; 96 | nstatus = napi_define_class(env, "GL_ANGLE_instanced_arrays", 97 | NAPI_AUTO_LENGTH, GLExtensionBase::InitStubClass, 98 | nullptr, 0, nullptr, &ctor_value); 99 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 100 | 101 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 102 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 103 | 104 | return napi_ok; 105 | } 106 | 107 | /* static */ 108 | napi_status ANGLEInstancedArraysExtension::NewInstance( 109 | napi_env env, napi_value* instance, 110 | EGLContextWrapper* egl_context_wrapper) { 111 | ENSURE_EXTENSION_IS_SUPPORTED 112 | 113 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 114 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 115 | 116 | egl_context_wrapper->glRequestExtensionANGLE("GL_ANGLE_instanced_arrays"); 117 | egl_context_wrapper->RefreshGLExtensions(); 118 | 119 | return napi_ok; 120 | } 121 | 122 | //============================================================================== 123 | // EXTBlendMinmaxExtension 124 | 125 | napi_ref EXTBlendMinmaxExtension::constructor_ref_; 126 | 127 | EXTBlendMinmaxExtension::EXTBlendMinmaxExtension(napi_env env) 128 | : GLExtensionBase(env) {} 129 | 130 | /* static */ 131 | bool EXTBlendMinmaxExtension::IsSupported( 132 | EGLContextWrapper* egl_context_wrapper) { 133 | IS_EXTENSION_NAME_AVAILABLE("GL_EXT_blend_minmax"); 134 | } 135 | 136 | /* static */ 137 | napi_status EXTBlendMinmaxExtension::Register(napi_env env, 138 | napi_value exports) { 139 | napi_status nstatus; 140 | 141 | napi_property_descriptor properties[] = { 142 | NapiDefineIntProperty(env, GL_MAX_EXT, "MAX_EXT"), 143 | NapiDefineIntProperty(env, GL_MIN_EXT, "MIN_EXT")}; 144 | 145 | napi_value ctor_value; 146 | nstatus = napi_define_class(env, "EXT_blend_minmax", NAPI_AUTO_LENGTH, 147 | GLExtensionBase::InitStubClass, nullptr, 148 | ARRAY_SIZE(properties), properties, &ctor_value); 149 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 150 | 151 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 152 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 153 | 154 | return napi_ok; 155 | } 156 | 157 | /* static */ 158 | napi_status EXTBlendMinmaxExtension::NewInstance( 159 | napi_env env, napi_value* instance, 160 | EGLContextWrapper* egl_context_wrapper) { 161 | ENSURE_EXTENSION_IS_SUPPORTED 162 | 163 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 164 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 165 | 166 | egl_context_wrapper->glRequestExtensionANGLE("GL_EXT_blend_minmax"); 167 | egl_context_wrapper->RefreshGLExtensions(); 168 | 169 | return napi_ok; 170 | } 171 | 172 | //============================================================================== 173 | // EXTColorBufferFloatExtension 174 | 175 | napi_ref EXTColorBufferFloatExtension::constructor_ref_; 176 | 177 | EXTColorBufferFloatExtension::EXTColorBufferFloatExtension(napi_env env) 178 | : GLExtensionBase(env) {} 179 | 180 | /* static */ 181 | bool EXTColorBufferFloatExtension::IsSupported( 182 | EGLContextWrapper* egl_context_wrapper) { 183 | IS_EXTENSION_NAME_AVAILABLE("GL_EXT_color_buffer_float"); 184 | } 185 | 186 | /* static */ 187 | napi_status EXTColorBufferFloatExtension::Register(napi_env env, 188 | napi_value exports) { 189 | napi_status nstatus; 190 | 191 | napi_value ctor_value; 192 | nstatus = napi_define_class(env, "EXT_color_buffer_float", NAPI_AUTO_LENGTH, 193 | GLExtensionBase::InitStubClass, nullptr, 0, 194 | nullptr, &ctor_value); 195 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 196 | 197 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 198 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 199 | 200 | return napi_ok; 201 | } 202 | 203 | /* static */ 204 | napi_status EXTColorBufferFloatExtension::NewInstance( 205 | napi_env env, napi_value* instance, 206 | EGLContextWrapper* egl_context_wrapper) { 207 | ENSURE_EXTENSION_IS_SUPPORTED 208 | 209 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 210 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 211 | 212 | egl_context_wrapper->glRequestExtensionANGLE("GL_EXT_color_buffer_float"); 213 | egl_context_wrapper->RefreshGLExtensions(); 214 | 215 | return napi_ok; 216 | } 217 | 218 | //============================================================================== 219 | // EXTColorBufferHalfFloatExtension 220 | 221 | napi_ref EXTColorBufferHalfFloatExtension::constructor_ref_; 222 | 223 | EXTColorBufferHalfFloatExtension::EXTColorBufferHalfFloatExtension(napi_env env) 224 | : GLExtensionBase(env) {} 225 | 226 | /* static */ 227 | bool EXTColorBufferHalfFloatExtension::IsSupported( 228 | EGLContextWrapper* egl_context_wrapper) { 229 | IS_EXTENSION_NAME_AVAILABLE("GL_EXT_color_buffer_half_float"); 230 | } 231 | 232 | /* static */ 233 | napi_status EXTColorBufferHalfFloatExtension::Register(napi_env env, 234 | napi_value exports) { 235 | napi_status nstatus; 236 | 237 | napi_value ctor_value; 238 | nstatus = napi_define_class(env, "EXT_color_buffer_half_float", 239 | NAPI_AUTO_LENGTH, GLExtensionBase::InitStubClass, 240 | nullptr, 0, nullptr, &ctor_value); 241 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 242 | 243 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 244 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 245 | 246 | return napi_ok; 247 | } 248 | 249 | /* static */ 250 | napi_status EXTColorBufferHalfFloatExtension::NewInstance( 251 | napi_env env, napi_value* instance, 252 | EGLContextWrapper* egl_context_wrapper) { 253 | ENSURE_EXTENSION_IS_SUPPORTED 254 | 255 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 256 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 257 | 258 | egl_context_wrapper->glRequestExtensionANGLE( 259 | "GL_EXT_color_buffer_half_float"); 260 | egl_context_wrapper->RefreshGLExtensions(); 261 | 262 | return napi_ok; 263 | } 264 | 265 | //============================================================================== 266 | // EXTFragDepthExtension 267 | 268 | napi_ref EXTFragDepthExtension::constructor_ref_; 269 | 270 | EXTFragDepthExtension::EXTFragDepthExtension(napi_env env) 271 | : GLExtensionBase(env) {} 272 | 273 | /* static */ 274 | bool EXTFragDepthExtension::IsSupported( 275 | EGLContextWrapper* egl_context_wrapper) { 276 | IS_EXTENSION_NAME_AVAILABLE("GL_EXT_frag_depth"); 277 | } 278 | 279 | /* static */ 280 | napi_status EXTFragDepthExtension::Register(napi_env env, napi_value exports) { 281 | napi_status nstatus; 282 | 283 | napi_value ctor_value; 284 | nstatus = napi_define_class(env, "EXT_frag_depth", NAPI_AUTO_LENGTH, 285 | GLExtensionBase::InitStubClass, nullptr, 0, 286 | nullptr, &ctor_value); 287 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 288 | 289 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 290 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 291 | 292 | return napi_ok; 293 | } 294 | 295 | /* static */ 296 | napi_status EXTFragDepthExtension::NewInstance( 297 | napi_env env, napi_value* instance, 298 | EGLContextWrapper* egl_context_wrapper) { 299 | ENSURE_EXTENSION_IS_SUPPORTED 300 | 301 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 302 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 303 | 304 | egl_context_wrapper->glRequestExtensionANGLE("GL_EXT_frag_depth"); 305 | egl_context_wrapper->RefreshGLExtensions(); 306 | 307 | return napi_ok; 308 | } 309 | 310 | //============================================================================== 311 | // EXTShaderTextureLodExtension 312 | 313 | napi_ref EXTShaderTextureLodExtension::constructor_ref_; 314 | 315 | EXTShaderTextureLodExtension::EXTShaderTextureLodExtension(napi_env env) 316 | : GLExtensionBase(env) {} 317 | 318 | /* static */ 319 | bool EXTShaderTextureLodExtension::IsSupported( 320 | EGLContextWrapper* egl_context_wrapper) { 321 | IS_EXTENSION_NAME_AVAILABLE("GL_EXT_shader_texture_lod"); 322 | } 323 | 324 | /* static */ 325 | napi_status EXTShaderTextureLodExtension::Register(napi_env env, 326 | napi_value exports) { 327 | napi_status nstatus; 328 | 329 | napi_value ctor_value; 330 | nstatus = napi_define_class(env, "EXT_shader_texture_lod", NAPI_AUTO_LENGTH, 331 | GLExtensionBase::InitStubClass, nullptr, 0, 332 | nullptr, &ctor_value); 333 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 334 | 335 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 336 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 337 | 338 | return napi_ok; 339 | } 340 | 341 | /* static */ 342 | napi_status EXTShaderTextureLodExtension::NewInstance( 343 | napi_env env, napi_value* instance, 344 | EGLContextWrapper* egl_context_wrapper) { 345 | ENSURE_EXTENSION_IS_SUPPORTED 346 | 347 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 348 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 349 | 350 | egl_context_wrapper->glRequestExtensionANGLE("GL_EXT_shader_texture_lod"); 351 | egl_context_wrapper->RefreshGLExtensions(); 352 | 353 | return napi_ok; 354 | } 355 | 356 | //============================================================================== 357 | // EXTSRGBExtension 358 | 359 | napi_ref EXTSRGBExtension::constructor_ref_; 360 | 361 | EXTSRGBExtension::EXTSRGBExtension(napi_env env) : GLExtensionBase(env) {} 362 | 363 | /* static */ 364 | bool EXTSRGBExtension::IsSupported(EGLContextWrapper* egl_context_wrapper) { 365 | IS_EXTENSION_NAME_AVAILABLE("GL_EXT_sRGB"); 366 | } 367 | 368 | /* static */ 369 | napi_status EXTSRGBExtension::Register(napi_env env, napi_value exports) { 370 | napi_status nstatus; 371 | 372 | napi_property_descriptor properties[] = { 373 | NapiDefineIntProperty(env, GL_SRGB_EXT, "SRGB_EXT"), 374 | NapiDefineIntProperty(env, GL_SRGB_ALPHA_EXT, "SRGB_ALPHA_EXT"), 375 | NapiDefineIntProperty(env, GL_SRGB8_ALPHA8_EXT, "SRGB8_ALPHA8_EXT"), 376 | NapiDefineIntProperty(env, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT, 377 | "FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING_EXT"), 378 | }; 379 | 380 | napi_value ctor_value; 381 | nstatus = napi_define_class(env, "EXT_sRGB", NAPI_AUTO_LENGTH, 382 | GLExtensionBase::InitStubClass, nullptr, 383 | ARRAY_SIZE(properties), properties, &ctor_value); 384 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 385 | 386 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 387 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 388 | 389 | return napi_ok; 390 | } 391 | 392 | /* static */ 393 | napi_status EXTSRGBExtension::NewInstance( 394 | napi_env env, napi_value* instance, 395 | EGLContextWrapper* egl_context_wrapper) { 396 | ENSURE_EXTENSION_IS_SUPPORTED 397 | 398 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 399 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 400 | 401 | egl_context_wrapper->glRequestExtensionANGLE("GL_EXT_sRGB"); 402 | egl_context_wrapper->RefreshGLExtensions(); 403 | 404 | return napi_ok; 405 | } 406 | 407 | //============================================================================== 408 | // EXTTextureFilterAnisotropicExtension 409 | 410 | napi_ref EXTTextureFilterAnisotropicExtension::constructor_ref_; 411 | 412 | EXTTextureFilterAnisotropicExtension::EXTTextureFilterAnisotropicExtension( 413 | napi_env env) 414 | : GLExtensionBase(env) {} 415 | 416 | /* static */ 417 | bool EXTTextureFilterAnisotropicExtension::IsSupported( 418 | EGLContextWrapper* egl_context_wrapper) { 419 | IS_EXTENSION_NAME_AVAILABLE("GL_EXT_texture_filter_anisotropic"); 420 | } 421 | 422 | /* static */ 423 | napi_status EXTTextureFilterAnisotropicExtension::Register(napi_env env, 424 | napi_value exports) { 425 | napi_status nstatus; 426 | 427 | napi_property_descriptor properties[] = { 428 | NapiDefineIntProperty(env, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, 429 | "MAX_TEXTURE_MAX_ANISOTROPY_EXT"), 430 | NapiDefineIntProperty(env, GL_TEXTURE_MAX_ANISOTROPY_EXT, 431 | "TEXTURE_MAX_ANISOTROPY_EXT"), 432 | }; 433 | 434 | napi_value ctor_value; 435 | nstatus = 436 | napi_define_class(env, "EXT_texture_filter_anisotropic", NAPI_AUTO_LENGTH, 437 | GLExtensionBase::InitStubClass, nullptr, 438 | ARRAY_SIZE(properties), properties, &ctor_value); 439 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 440 | 441 | nstatus = napi_create_reference(env, ctor_value, 2, &constructor_ref_); 442 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 443 | 444 | return napi_ok; 445 | } 446 | 447 | /* static */ 448 | napi_status EXTTextureFilterAnisotropicExtension::NewInstance( 449 | napi_env env, napi_value* instance, 450 | EGLContextWrapper* egl_context_wrapper) { 451 | ENSURE_EXTENSION_IS_SUPPORTED 452 | 453 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 454 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 455 | 456 | egl_context_wrapper->glRequestExtensionANGLE( 457 | "GL_EXT_texture_filter_anisotropic"); 458 | egl_context_wrapper->RefreshGLExtensions(); 459 | 460 | return napi_ok; 461 | } 462 | 463 | //============================================================================== 464 | // OESElementIndexUintExtension 465 | 466 | napi_ref OESElementIndexUintExtension::constructor_ref_; 467 | 468 | OESElementIndexUintExtension::OESElementIndexUintExtension(napi_env env) 469 | : GLExtensionBase(env) {} 470 | 471 | /* static */ 472 | bool OESElementIndexUintExtension::IsSupported( 473 | EGLContextWrapper* egl_context_wrapper) { 474 | IS_EXTENSION_NAME_AVAILABLE("GL_OES_element_index_uint"); 475 | } 476 | 477 | /* static */ 478 | napi_status OESElementIndexUintExtension::Register(napi_env env, 479 | napi_value exports) { 480 | napi_status nstatus; 481 | 482 | napi_value ctor_value; 483 | nstatus = napi_define_class(env, "OES_element_index_uint", NAPI_AUTO_LENGTH, 484 | GLExtensionBase::InitStubClass, nullptr, 0, 485 | nullptr, &ctor_value); 486 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 487 | 488 | nstatus = napi_create_reference(env, ctor_value, 2, &constructor_ref_); 489 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 490 | 491 | return napi_ok; 492 | } 493 | 494 | /* static */ 495 | napi_status OESElementIndexUintExtension::NewInstance( 496 | napi_env env, napi_value* instance, 497 | EGLContextWrapper* egl_context_wrapper) { 498 | ENSURE_EXTENSION_IS_SUPPORTED 499 | 500 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 501 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 502 | 503 | egl_context_wrapper->glRequestExtensionANGLE("GL_OES_element_index_uint"); 504 | egl_context_wrapper->RefreshGLExtensions(); 505 | 506 | return napi_ok; 507 | } 508 | 509 | //============================================================================== 510 | // OESStandardDerivativesExtension 511 | 512 | napi_ref OESStandardDerivativesExtension::constructor_ref_; 513 | 514 | OESStandardDerivativesExtension::OESStandardDerivativesExtension(napi_env env) 515 | : GLExtensionBase(env) {} 516 | 517 | /* static */ 518 | bool OESStandardDerivativesExtension::IsSupported( 519 | EGLContextWrapper* egl_context_wrapper) { 520 | IS_EXTENSION_NAME_AVAILABLE("GL_OES_standard_derivatives"); 521 | } 522 | 523 | /* static */ 524 | napi_status OESStandardDerivativesExtension::Register(napi_env env, 525 | napi_value exports) { 526 | napi_status nstatus; 527 | 528 | napi_property_descriptor properties[] = { 529 | NapiDefineIntProperty(env, GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES, 530 | "FRAGMENT_SHADER_DERIVATIVE_HINT_OES")}; 531 | 532 | napi_value ctor_value; 533 | nstatus = napi_define_class(env, "OES_standard_derivatives", NAPI_AUTO_LENGTH, 534 | GLExtensionBase::InitStubClass, nullptr, 535 | ARRAY_SIZE(properties), properties, &ctor_value); 536 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 537 | 538 | nstatus = napi_create_reference(env, ctor_value, 2, &constructor_ref_); 539 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 540 | 541 | return napi_ok; 542 | } 543 | 544 | /* static */ 545 | napi_status OESStandardDerivativesExtension::NewInstance( 546 | napi_env env, napi_value* instance, 547 | EGLContextWrapper* egl_context_wrapper) { 548 | ENSURE_EXTENSION_IS_SUPPORTED 549 | 550 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 551 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 552 | 553 | egl_context_wrapper->glRequestExtensionANGLE("GL_OES_standard_derivatives"); 554 | egl_context_wrapper->RefreshGLExtensions(); 555 | 556 | return napi_ok; 557 | } 558 | 559 | //============================================================================== 560 | // OESTextureFloatExtension 561 | 562 | napi_ref OESTextureFloatExtension::constructor_ref_; 563 | 564 | OESTextureFloatExtension::OESTextureFloatExtension(napi_env env) 565 | : GLExtensionBase(env) {} 566 | 567 | /* static */ 568 | bool OESTextureFloatExtension::IsSupported( 569 | EGLContextWrapper* egl_context_wrapper) { 570 | IS_EXTENSION_NAME_AVAILABLE("GL_OES_texture_float"); 571 | } 572 | 573 | /* static */ 574 | napi_status OESTextureFloatExtension::Register(napi_env env, 575 | napi_value exports) { 576 | napi_status nstatus; 577 | 578 | napi_value ctor_value; 579 | nstatus = napi_define_class(env, "OES_texture_float", NAPI_AUTO_LENGTH, 580 | GLExtensionBase::InitStubClass, nullptr, 0, 581 | nullptr, &ctor_value); 582 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 583 | 584 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 585 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 586 | 587 | return napi_ok; 588 | } 589 | 590 | /* static */ 591 | napi_status OESTextureFloatExtension::NewInstance( 592 | napi_env env, napi_value* instance, 593 | EGLContextWrapper* egl_context_wrapper) { 594 | ENSURE_EXTENSION_IS_SUPPORTED 595 | 596 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 597 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 598 | 599 | egl_context_wrapper->glRequestExtensionANGLE("GL_OES_texture_float"); 600 | egl_context_wrapper->glRequestExtensionANGLE( 601 | "GL_CHROMIUM_color_buffer_float_rgba"); 602 | egl_context_wrapper->glRequestExtensionANGLE( 603 | "GL_CHROMIUM_color_buffer_float_rgb"); 604 | egl_context_wrapper->RefreshGLExtensions(); 605 | 606 | return napi_ok; 607 | } 608 | 609 | //============================================================================== 610 | // OESTextureFloatLinearExtension 611 | 612 | napi_ref OESTextureFloatLinearExtension::constructor_ref_; 613 | 614 | OESTextureFloatLinearExtension::OESTextureFloatLinearExtension(napi_env env) 615 | : GLExtensionBase(env) {} 616 | 617 | /* static */ 618 | bool OESTextureFloatLinearExtension::IsSupported( 619 | EGLContextWrapper* egl_context_wrapper) { 620 | IS_EXTENSION_NAME_AVAILABLE("GL_OES_texture_float_linear"); 621 | } 622 | 623 | /* static */ 624 | napi_status OESTextureFloatLinearExtension::Register(napi_env env, 625 | napi_value exports) { 626 | napi_status nstatus; 627 | 628 | napi_value ctor_value; 629 | nstatus = napi_define_class(env, "OES_texture_float_linear", NAPI_AUTO_LENGTH, 630 | GLExtensionBase::InitStubClass, nullptr, 0, 631 | nullptr, &ctor_value); 632 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 633 | 634 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 635 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 636 | 637 | return napi_ok; 638 | } 639 | 640 | /* static */ 641 | napi_status OESTextureFloatLinearExtension::NewInstance( 642 | napi_env env, napi_value* instance, 643 | EGLContextWrapper* egl_context_wrapper) { 644 | ENSURE_EXTENSION_IS_SUPPORTED 645 | 646 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 647 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 648 | 649 | egl_context_wrapper->glRequestExtensionANGLE("GL_OES_texture_float_linear"); 650 | egl_context_wrapper->RefreshGLExtensions(); 651 | return napi_ok; 652 | } 653 | 654 | //============================================================================== 655 | // OESTextureHalfFloatExtension 656 | 657 | napi_ref OESTextureHalfFloatExtension::constructor_ref_; 658 | 659 | OESTextureHalfFloatExtension::OESTextureHalfFloatExtension(napi_env env) 660 | : GLExtensionBase(env) {} 661 | 662 | /* static */ 663 | bool OESTextureHalfFloatExtension::IsSupported( 664 | EGLContextWrapper* egl_context_wrapper) { 665 | IS_EXTENSION_NAME_AVAILABLE("GL_OES_texture_half_float"); 666 | } 667 | 668 | /* static */ 669 | napi_status OESTextureHalfFloatExtension::Register(napi_env env, 670 | napi_value exports) { 671 | napi_status nstatus; 672 | 673 | napi_property_descriptor properties[] = { 674 | NapiDefineIntProperty(env, GL_HALF_FLOAT_OES, "HALF_FLOAT_OES")}; 675 | 676 | napi_value ctor_value; 677 | nstatus = napi_define_class(env, "OES_texture_half_float", NAPI_AUTO_LENGTH, 678 | GLExtensionBase::InitStubClass, nullptr, 679 | ARRAY_SIZE(properties), properties, &ctor_value); 680 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 681 | 682 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 683 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 684 | 685 | return napi_ok; 686 | } 687 | 688 | /* static */ 689 | napi_status OESTextureHalfFloatExtension::NewInstance( 690 | napi_env env, napi_value* instance, 691 | EGLContextWrapper* egl_context_wrapper) { 692 | ENSURE_EXTENSION_IS_SUPPORTED 693 | 694 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 695 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 696 | 697 | egl_context_wrapper->glRequestExtensionANGLE("GL_OES_texture_half_float"); 698 | 699 | if (egl_context_wrapper->angle_requestable_extensions->HasExtension( 700 | "GL_EXT_color_buffer_half_float")) { 701 | egl_context_wrapper->glRequestExtensionANGLE( 702 | "GL_EXT_color_buffer_half_float"); 703 | } 704 | 705 | egl_context_wrapper->RefreshGLExtensions(); 706 | return napi_ok; 707 | } 708 | 709 | //============================================================================== 710 | // OESTextureHalfFloatLinearExtension 711 | 712 | napi_ref OESTextureHalfFloatLinearExtension::constructor_ref_; 713 | 714 | OESTextureHalfFloatLinearExtension::OESTextureHalfFloatLinearExtension( 715 | napi_env env) 716 | : GLExtensionBase(env) {} 717 | 718 | /* static */ 719 | bool OESTextureHalfFloatLinearExtension::IsSupported( 720 | EGLContextWrapper* egl_context_wrapper) { 721 | IS_EXTENSION_NAME_AVAILABLE("GL_OES_texture_half_float_linear"); 722 | } 723 | 724 | /* static */ 725 | napi_status OESTextureHalfFloatLinearExtension::Register(napi_env env, 726 | napi_value exports) { 727 | napi_status nstatus; 728 | 729 | napi_value ctor_value; 730 | nstatus = napi_define_class(env, "OES_texture_half_float_linear", 731 | NAPI_AUTO_LENGTH, GLExtensionBase::InitStubClass, 732 | nullptr, 0, nullptr, &ctor_value); 733 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 734 | 735 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 736 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 737 | 738 | return napi_ok; 739 | } 740 | 741 | /* static */ 742 | napi_status OESTextureHalfFloatLinearExtension::NewInstance( 743 | napi_env env, napi_value* instance, 744 | EGLContextWrapper* egl_context_wrapper) { 745 | ENSURE_EXTENSION_IS_SUPPORTED 746 | 747 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 748 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 749 | 750 | egl_context_wrapper->glRequestExtensionANGLE( 751 | "GL_OES_texture_half_float_linear"); 752 | egl_context_wrapper->RefreshGLExtensions(); 753 | return napi_ok; 754 | } 755 | 756 | //============================================================================== 757 | // WebGLDebugRendererInfoExtension 758 | 759 | napi_ref WebGLDebugRendererInfoExtension::constructor_ref_; 760 | 761 | WebGLDebugRendererInfoExtension::WebGLDebugRendererInfoExtension(napi_env env) 762 | : GLExtensionBase(env) {} 763 | 764 | /* static */ 765 | bool WebGLDebugRendererInfoExtension::IsSupported( 766 | EGLContextWrapper* egl_context_wrapper) { 767 | return true; 768 | } 769 | 770 | /* static */ 771 | napi_status WebGLDebugRendererInfoExtension::Register(napi_env env, 772 | napi_value exports) { 773 | napi_status nstatus; 774 | 775 | napi_property_descriptor properties[] = { 776 | NapiDefineIntProperty(env, GL_VENDOR, "UNMASKED_VENDOR_WEBGL"), 777 | NapiDefineIntProperty(env, GL_RENDERER, "UNMASKED_RENDERER_WEBGL")}; 778 | 779 | napi_value ctor_value; 780 | nstatus = 781 | napi_define_class(env, "WEBGL_debug_renderer_info", NAPI_AUTO_LENGTH, 782 | GLExtensionBase::InitStubClass, nullptr, 783 | ARRAY_SIZE(properties), properties, &ctor_value); 784 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 785 | 786 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 787 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 788 | 789 | return napi_ok; 790 | } 791 | 792 | /* static */ 793 | napi_status WebGLDebugRendererInfoExtension::NewInstance( 794 | napi_env env, napi_value* instance, 795 | EGLContextWrapper* egl_context_wrapper) { 796 | ENSURE_EXTENSION_IS_SUPPORTED 797 | 798 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 799 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 800 | 801 | return napi_ok; 802 | } 803 | 804 | //============================================================================== 805 | // WebGLDepthTextureExtension 806 | 807 | napi_ref WebGLDepthTextureExtension::constructor_ref_; 808 | 809 | WebGLDepthTextureExtension::WebGLDepthTextureExtension(napi_env env) 810 | : GLExtensionBase(env) {} 811 | 812 | /* static */ 813 | bool WebGLDepthTextureExtension::IsSupported( 814 | EGLContextWrapper* egl_context_wrapper) { 815 | IS_EXTENSION_NAME_AVAILABLE("GL_OES_packed_depth_stencil"); 816 | IS_EXTENSION_NAME_AVAILABLE("GL_ANGLE_depth_texture"); 817 | } 818 | 819 | /* static */ 820 | napi_status WebGLDepthTextureExtension::Register(napi_env env, 821 | napi_value exports) { 822 | napi_status nstatus; 823 | 824 | napi_property_descriptor properties[] = {NapiDefineIntProperty( 825 | env, GL_UNSIGNED_INT_24_8_OES, "UNSIGNED_INT_24_8_WEBGL")}; 826 | 827 | napi_value ctor_value; 828 | nstatus = napi_define_class(env, "WEBGL_depth_texture", NAPI_AUTO_LENGTH, 829 | GLExtensionBase::InitStubClass, nullptr, 830 | ARRAY_SIZE(properties), properties, &ctor_value); 831 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 832 | 833 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 834 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 835 | 836 | return napi_ok; 837 | } 838 | 839 | /* static */ 840 | napi_status WebGLDepthTextureExtension::NewInstance( 841 | napi_env env, napi_value* instance, 842 | EGLContextWrapper* egl_context_wrapper) { 843 | ENSURE_EXTENSION_IS_SUPPORTED 844 | 845 | napi_status nstatus = NewInstanceBase(env, constructor_ref_, instance); 846 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 847 | 848 | egl_context_wrapper->glRequestExtensionANGLE("GL_ANGLE_depth_texture"); 849 | egl_context_wrapper->RefreshGLExtensions(); 850 | 851 | return napi_ok; 852 | } 853 | 854 | //============================================================================== 855 | // WebGLLoseContextExtension 856 | 857 | napi_ref WebGLLoseContextExtension::constructor_ref_; 858 | 859 | WebGLLoseContextExtension::WebGLLoseContextExtension(napi_env env) 860 | : GLExtensionBase(env) {} 861 | 862 | /* static */ 863 | bool WebGLLoseContextExtension::IsSupported( 864 | EGLContextWrapper* egl_context_wrapper) { 865 | // This extension is purely a stub in Node - return true. 866 | return true; 867 | } 868 | 869 | /* static */ 870 | napi_status WebGLLoseContextExtension::Register(napi_env env, 871 | napi_value exports) { 872 | napi_status nstatus; 873 | 874 | napi_property_descriptor properties[] = { 875 | NAPI_DEFINE_METHOD("loseContext", LoseContext), 876 | NAPI_DEFINE_METHOD("restoreContext", RestoreContext), 877 | }; 878 | 879 | napi_value ctor_value; 880 | nstatus = napi_define_class(env, "WEBGL_lose_context", NAPI_AUTO_LENGTH, 881 | WebGLLoseContextExtension::InitInternal, nullptr, 882 | ARRAY_SIZE(properties), properties, &ctor_value); 883 | 884 | nstatus = napi_create_reference(env, ctor_value, 1, &constructor_ref_); 885 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nstatus); 886 | 887 | return napi_ok; 888 | } 889 | 890 | /* static */ 891 | napi_status WebGLLoseContextExtension::NewInstance( 892 | napi_env env, napi_value* instance, 893 | EGLContextWrapper* egl_context_wrapper) { 894 | return NewInstanceBase(env, constructor_ref_, instance); 895 | } 896 | 897 | /* static */ 898 | napi_value WebGLLoseContextExtension::InitInternal(napi_env env, 899 | napi_callback_info info) { 900 | napi_status nstatus; 901 | 902 | ENSURE_CONSTRUCTOR_CALL_RETVAL(env, info, nullptr); 903 | 904 | napi_value js_this; 905 | nstatus = napi_get_cb_info(env, info, 0, nullptr, &js_this, nullptr); 906 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nullptr); 907 | 908 | WebGLLoseContextExtension* context = new WebGLLoseContextExtension(env); 909 | ENSURE_VALUE_IS_NOT_NULL_RETVAL(env, context, nullptr); 910 | 911 | nstatus = napi_wrap(env, js_this, context, Cleanup, nullptr, &context->ref_); 912 | ENSURE_NAPI_OK_RETVAL(env, nstatus, nullptr); 913 | 914 | return js_this; 915 | } 916 | 917 | /* static */ 918 | void WebGLLoseContextExtension::Cleanup(napi_env env, void* native, 919 | void* hint) { 920 | WebGLLoseContextExtension* extension = 921 | static_cast(native); 922 | delete extension; 923 | } 924 | 925 | /* static */ 926 | napi_value WebGLLoseContextExtension::LoseContext(napi_env env, 927 | napi_callback_info info) { 928 | // Pure stub extension - no-op. 929 | return nullptr; 930 | } 931 | 932 | /* static */ 933 | napi_value WebGLLoseContextExtension::RestoreContext(napi_env env, 934 | napi_callback_info info) { 935 | // Pure stub extension - no-op. 936 | return nullptr; 937 | } 938 | 939 | } // namespace nodejsgl 940 | --------------------------------------------------------------------------------