From 8667ce0b5b0bd88689a57473409571207bdf1db0 Mon Sep 17 00:00:00 2001 From: Robert Plummer Date: Fri, 27 Dec 2019 08:00:46 -0500 Subject: [PATCH] fix: #178 add in cache for stencils so calls aren't as excessive --- src/javascript/node-index.js | 2 + src/javascript/webgl-rendering-context.js | 16 +++- test/misc.js | 2 + test/util/stencil-check-cache.js | 110 ++++++++++++++++++++++ 4 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 test/util/stencil-check-cache.js diff --git a/src/javascript/node-index.js b/src/javascript/node-index.js index 43ac5e39..f55c6ee0 100644 --- a/src/javascript/node-index.js +++ b/src/javascript/node-index.js @@ -72,6 +72,8 @@ function createContext (width, height, options) { ctx._activeArrayBuffer = null ctx._activeElementArrayBuffer = null ctx._activeRenderbuffer = null + ctx._checkStencil = false + ctx._stencilState = true // Initialize texture units const numTextures = ctx.getParameter(ctx.MAX_COMBINED_TEXTURE_IMAGE_UNITS) diff --git a/src/javascript/webgl-rendering-context.js b/src/javascript/webgl-rendering-context.js index ee35de6a..a4e6a81a 100644 --- a/src/javascript/webgl-rendering-context.js +++ b/src/javascript/webgl-rendering-context.js @@ -194,6 +194,11 @@ class WebGLRenderingContext extends NativeWebGLRenderingContext { } _checkStencilState () { + if (!this._checkStencil) { + return this._stencilState + } + this._checkStencil = false + this._stencilState = true if (this.getParameter(gl.STENCIL_WRITEMASK) !== this.getParameter(gl.STENCIL_BACK_WRITEMASK) || this.getParameter(gl.STENCIL_VALUE_MASK) !== @@ -201,9 +206,9 @@ class WebGLRenderingContext extends NativeWebGLRenderingContext { this.getParameter(gl.STENCIL_REF) !== this.getParameter(gl.STENCIL_BACK_REF)) { this.setError(gl.INVALID_OPERATION) - return false + this._stencilState = false } - return true + return this._stencilState } _checkTextureTarget (target) { @@ -1396,6 +1401,7 @@ class WebGLRenderingContext extends NativeWebGLRenderingContext { } clearStencil (s) { + this._checkStencil = false return super.clearStencil(s | 0) } @@ -3034,26 +3040,32 @@ class WebGLRenderingContext extends NativeWebGLRenderingContext { } stencilFunc (func, ref, mask) { + this._checkStencil = true return super.stencilFunc(func | 0, ref | 0, mask | 0) } stencilFuncSeparate (face, func, ref, mask) { + this._checkStencil = true return super.stencilFuncSeparate(face | 0, func | 0, ref | 0, mask | 0) } stencilMask (mask) { + this._checkStencil = true return super.stencilMask(mask | 0) } stencilMaskSeparate (face, mask) { + this._checkStencil = true return super.stencilMaskSeparate(face | 0, mask | 0) } stencilOp (fail, zfail, zpass) { + this._checkStencil = true return super.stencilOp(fail | 0, zfail | 0, zpass | 0) } stencilOpSeparate (face, fail, zfail, zpass) { + this._checkStencil = true return super.stencilOpSeparate(face | 0, fail | 0, zfail | 0, zpass | 0) } diff --git a/test/misc.js b/test/misc.js index e1a93801..20413d81 100644 --- a/test/misc.js +++ b/test/misc.js @@ -7,3 +7,5 @@ var BLACKLIST = [ require('./util/conformance')(function (str) { return str.indexOf('misc') === 0 && BLACKLIST.indexOf(str) < 0 }) + +require('./util/stencil-check-cache') diff --git a/test/util/stencil-check-cache.js b/test/util/stencil-check-cache.js new file mode 100644 index 00000000..a5f5ec98 --- /dev/null +++ b/test/util/stencil-check-cache.js @@ -0,0 +1,110 @@ +var tape = require('tape') +var { WebGLRenderingContext } = require('../../src/javascript/webgl-rendering-context') +var createContext = require('../../src/javascript/node-index') + +tape('stencil check cache - gl.stencilFunc()', function (t) { + var gl = new WebGLRenderingContext() + t.equals(gl._checkStencil, undefined, 'gl._checkStencil starts undefined') + gl.destroy() + t.end() +}) + +tape('stencil check cache - gl.stencilFunc()', function (t) { + var gl = new WebGLRenderingContext() + gl.stencilFunc() + t.equals(gl._checkStencil, true, 'gl.stencilFunc() calls set gl._checkStencil to true') + gl.destroy() + t.end() +}) + +tape('stencil check cache - gl.stencilFuncSeparate()', function (t) { + var gl = new WebGLRenderingContext() + gl.stencilFuncSeparate() + t.equals(gl._checkStencil, true, 'gl.stencilFuncSeparate() calls set gl._checkStencil to true') + gl.destroy() + t.end() +}) + +tape('stencil check cache - gl.stencilMask()', function (t) { + var gl = new WebGLRenderingContext() + gl.stencilMask() + t.equals(gl._checkStencil, true, 'gl.stencilMask() calls set gl._checkStencil to true') + gl.destroy() + t.end() +}) + +tape('stencil check cache - gl.stencilMaskSeparate()', function (t) { + var gl = new WebGLRenderingContext() + gl.stencilMaskSeparate() + t.equals(gl._checkStencil, true, 'gl.stencilMaskSeparate() calls set gl._checkStencil to true') + gl.destroy() + t.end() +}) + +tape('stencil check cache - gl.stencilOp()', function (t) { + var gl = new WebGLRenderingContext() + gl.stencilOp() + t.equals(gl._checkStencil, true, 'gl.stencilOp() calls set gl._checkStencil to true') + gl.destroy() + t.end() +}) + +tape('stencil check cache - gl.stencilOpSeparate()', function (t) { + var gl = new WebGLRenderingContext() + gl.stencilOpSeparate() + t.equals(gl._checkStencil, true, 'gl.stencilOpSeparate() calls set gl._checkStencil to true') + gl.destroy() + t.end() +}) + +tape('stencil check cache - gl.clearStencil()', function (t) { + var gl = new WebGLRenderingContext() + gl.clearStencil() + t.equals(gl._checkStencil, false, 'gl.clearStencil() calls set gl._checkStencil to false') + gl.destroy() + t.end() +}) + +tape('stencil check cache - gl._checkStencilState() without errors', function (t) { + var gl = new WebGLRenderingContext() + gl._checkStencil = true + t.equals(gl._checkStencilState(), true, 'gl._checkStencilState() value is cached and returned') + t.equals(gl._checkStencil, false, 'gl._checkStencilState() calls set gl._checkStencil to false') + t.equals(gl._stencilState, true, 'gl._checkStencilState() calls set gl._stencilState to true') + gl._stencilState = 'test value' + gl.getParameter = function () { + throw new Error('should not be called!') + } + t.equals(gl._checkStencilState(), 'test value', 'subsequent gl._checkStencilState() calls use the cached state stored in gl._stencilState') + gl.destroy() + t.end() +}) + +tape('stencil check cache - gl._checkStencilState() with errors', function (t) { + var gl = new WebGLRenderingContext() + gl._checkStencil = true + gl.getParameter = function (stencil) { + if (stencil === gl.STENCIL_WRITEMASK) return 1 + } + t.equals(gl._checkStencilState(), false, 'gl._checkStencilState() value is cached and returned') + t.equals(gl._checkStencil, false, 'gl._checkStencilState() calls set gl._checkStencil to false') + t.equals(gl._stencilState, false, 'gl._checkStencilState() calls set gl._stencilState to true') + gl._stencilState = 'test value' + gl.getParameter = function () { + throw new Error('should not be called!') + } + t.equals(gl._checkStencilState(), 'test value', 'subsequent gl._checkStencilState() calls use the cached state stored in gl._stencilState') + gl.destroy() + t.end() +}) + +tape('stencil check cache - createContext initial state', function (t) { + var gl = createContext(1, 1) + gl.getParameter = function () { + throw new Error('should not be called!') + } + gl._stencilState = 'test value' + t.equals(gl._checkStencilState(), true, 'initial call to createContext()._checkStencilState() return gl._stencilState and not call gl.getParameter()') + gl.destroy() + t.end() +})