Convert 'force GPU' flag into 'useGpuMode' enum

This commit is contained in:
Christopher Willis-Ford
2019-02-06 10:47:49 -08:00
parent 028b4eba3f
commit c390124df4
2 changed files with 44 additions and 17 deletions

View File

@@ -132,6 +132,9 @@ class RenderWebGL extends EventEmitter {
throw new Error('Could not get WebGL context: this browser or environment may not support WebGL.'); throw new Error('Could not get WebGL context: this browser or environment may not support WebGL.');
} }
/** @type {RenderWebGL.UseGpuModes} */
this._useGpuMode = RenderWebGL.UseGpuModes.Automatic;
/** @type {Drawable[]} */ /** @type {Drawable[]} */
this._allDrawables = []; this._allDrawables = [];
@@ -244,18 +247,11 @@ class RenderWebGL extends EventEmitter {
} }
/** /**
* Force "touching color" operations to use (or not use) the GPU. By default the renderer will decide. * Control the use of the GPU or CPU paths in `isTouchingColor`.
* @param {boolean} forceGPU - true to force the renderer to use the GPU, false to force CPU. * @param {RenderWebGL.UseGpuModes} useGpuMode - automatically decide, force CPU, or force GPU.
*/ */
setForceGPU (forceGPU) { setUseGpuMode (useGpuMode) {
this._forceGPU = !!forceGPU; this._useGpuMode = useGpuMode;
}
/**
* Clear any value set by `setForceGPU`, allowing the renderer to decide.
*/
clearForceGPU () {
this._forceGPU = null;
} }
/** /**
@@ -732,9 +728,7 @@ class RenderWebGL extends EventEmitter {
const bounds = this._candidatesBounds(candidates); const bounds = this._candidatesBounds(candidates);
const maxPixelsForCPU = (typeof this._forceGPU === 'boolean') ? const maxPixelsForCPU = this._getMaxPixelsForCPU();
(this._forceGPU ? 0 : Infinity) :
__cpuTouchingColorPixelCount;
const debugCanvasContext = this._debugCanvas && this._debugCanvas.getContext('2d'); const debugCanvasContext = this._debugCanvas && this._debugCanvas.getContext('2d');
if (debugCanvasContext) { if (debugCanvasContext) {
@@ -779,6 +773,18 @@ class RenderWebGL extends EventEmitter {
return false; return false;
} }
_getMaxPixelsForCPU () {
switch (this._useGpuMode) {
case RenderWebGL.UseGpuModes.ForceCPU:
return Infinity;
case RenderWebGL.UseGpuModes.ForceGPU:
return 0;
case RenderWebGL.UseGpuModes.Automatic:
default:
return __cpuTouchingColorPixelCount;
}
}
_isTouchingColorGpuStart (drawableID, candidateIDs, bounds, color3b, mask3b) { _isTouchingColorGpuStart (drawableID, candidateIDs, bounds, color3b, mask3b) {
this._doExitDrawRegion(); this._doExitDrawRegion();
@@ -1798,4 +1804,25 @@ class RenderWebGL extends EventEmitter {
// :3 // :3
RenderWebGL.prototype.canHazPixels = RenderWebGL.prototype.extractDrawable; RenderWebGL.prototype.canHazPixels = RenderWebGL.prototype.extractDrawable;
/**
* Values for setUseGPU()
* @enum {string}
*/
RenderWebGL.UseGpuModes = {
/**
* Heuristically decide whether to use the GPU path, the CPU path, or a dynamic mixture of the two.
*/
Automatic: 'Automatic',
/**
* Always use the GPU path.
*/
ForceGPU: 'ForceGPU',
/**
* Always use the CPU path.
*/
ForceCPU: 'ForceCPU'
};
module.exports = RenderWebGL; module.exports = RenderWebGL;

View File

@@ -51,21 +51,21 @@ const handleCursorPositionChanged = () => {
position: [cursorX, cursorY] position: [cursorX, cursorY]
}); });
renderer.setForceGPU(true); renderer.setUseGpuMode(ScratchRender.UseGpuModes.ForceGPU);
renderer.setDebugCanvas(gpuQueryCanvas); renderer.setDebugCanvas(gpuQueryCanvas);
const isGpuTouchingA = renderer.isTouchingColor(drawables.cursor, colors.patternA); const isGpuTouchingA = renderer.isTouchingColor(drawables.cursor, colors.patternA);
const isGpuTouchingB = renderer.isTouchingColor(drawables.cursor, colors.patternB); const isGpuTouchingB = renderer.isTouchingColor(drawables.cursor, colors.patternB);
labelGpuTouchingA.innerHTML = isGpuTouchingA ? 'yes' : 'no'; labelGpuTouchingA.innerHTML = isGpuTouchingA ? 'yes' : 'no';
labelGpuTouchingB.innerHTML = isGpuTouchingB ? 'yes' : 'no'; labelGpuTouchingB.innerHTML = isGpuTouchingB ? 'yes' : 'no';
renderer.setForceGPU(false); renderer.setUseGpuMode(ScratchRender.UseGpuModes.ForceCPU);
renderer.setDebugCanvas(cpuQueryCanvas); renderer.setDebugCanvas(cpuQueryCanvas);
const isCpuTouchingA = renderer.isTouchingColor(drawables.cursor, colors.patternA); const isCpuTouchingA = renderer.isTouchingColor(drawables.cursor, colors.patternA);
const isCpuTouchingB = renderer.isTouchingColor(drawables.cursor, colors.patternB); const isCpuTouchingB = renderer.isTouchingColor(drawables.cursor, colors.patternB);
labelCpuTouchingA.innerHTML = isCpuTouchingA ? 'yes' : 'no'; labelCpuTouchingA.innerHTML = isCpuTouchingA ? 'yes' : 'no';
labelCpuTouchingB.innerHTML = isCpuTouchingB ? 'yes' : 'no'; labelCpuTouchingB.innerHTML = isCpuTouchingB ? 'yes' : 'no';
renderer.clearForceGPU(); renderer.setUseGpuMode(ScratchRender.UseGpuModes.Automatic);
} }
}; };
inputCursorX.addEventListener('change', handleCursorPositionChanged); inputCursorX.addEventListener('change', handleCursorPositionChanged);