Skip to content

Commit

Permalink
fix: #178 add in cache for stencils so calls aren't as excessive
Browse files Browse the repository at this point in the history
  • Loading branch information
robertleeplummerjr authored and dhritzkiv committed Jan 7, 2020
1 parent 53766a1 commit 8667ce0
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 2 deletions.
2 changes: 2 additions & 0 deletions src/javascript/node-index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
16 changes: 14 additions & 2 deletions src/javascript/webgl-rendering-context.js
Original file line number Diff line number Diff line change
Expand Up @@ -194,16 +194,21 @@ 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) !==
this.getParameter(gl.STENCIL_BACK_VALUE_MASK) ||
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) {
Expand Down Expand Up @@ -1396,6 +1401,7 @@ class WebGLRenderingContext extends NativeWebGLRenderingContext {
}

clearStencil (s) {
this._checkStencil = false
return super.clearStencil(s | 0)
}

Expand Down Expand Up @@ -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)
}

Expand Down
2 changes: 2 additions & 0 deletions test/misc.js
Original file line number Diff line number Diff line change
Expand Up @@ -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')
110 changes: 110 additions & 0 deletions test/util/stencil-check-cache.js
Original file line number Diff line number Diff line change
@@ -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()
})

0 comments on commit 8667ce0

Please sign in to comment.