Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup of WebGLGraphicsDevice to strip out WebGL1 code #6312

Merged
merged 3 commits into from
Apr 30, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
160 changes: 68 additions & 92 deletions src/platform/graphics/webgl/webgl-graphics-device.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,10 +192,7 @@ function testTextureFloatHighPrecision(device) {
*/
class WebglGraphicsDevice extends GraphicsDevice {
/**
* The WebGL context managed by the graphics device. The type could also technically be
* `WebGLRenderingContext` if WebGL 2.0 is not available. But in order for IntelliSense to be
* able to function for all WebGL calls in the codebase, we specify `WebGL2RenderingContext`
* here instead.
* The WebGL2 context managed by the graphics device.
Copy link
Contributor

@willeastcott willeastcott Apr 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should really say Create a new WebglGraphicsDevice instance. And the class description should be update to cover what the WebglGraphicsDevice is about (including talking about the fact that it's a WebGL 2.0-based device with no support for WebGL 1.0. At this moment, the class description is copy+pasted from GraphicsDevice.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a doc for the constructor, but just a gl member. The rest is as you described already.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, yeah, not sure why I misread that. Anyway, this class should have its own class description instead of cloning the GraphicsDevice one. That comment still stands.

*
* @type {WebGL2RenderingContext}
* @ignore
Expand Down Expand Up @@ -254,7 +251,7 @@ class WebglGraphicsDevice extends GraphicsDevice {
* latency by desynchronizing the canvas paint cycle from the event loop. Defaults to false.
* @param {boolean} [options.xrCompatible] - Boolean that hints to the user agent to use a
* compatible graphics adapter for an immersive XR device.
* @param {WebGLRenderingContext | WebGL2RenderingContext} [options.gl] - The rendering context
* @param {WebGL2RenderingContext} [options.gl] - The rendering context
* to use. If not specified, a new context will be created.
*/
constructor(canvas, options = {}) {
Expand Down Expand Up @@ -348,22 +345,18 @@ class WebglGraphicsDevice extends GraphicsDevice {

// supported sampler types
this._samplerTypes = new Set([
...[
gl.SAMPLER_2D,
gl.SAMPLER_CUBE
],
...(this.isWebGL2 ? [
gl.UNSIGNED_INT_SAMPLER_2D,
gl.INT_SAMPLER_2D,
gl.SAMPLER_2D_SHADOW,
gl.SAMPLER_CUBE_SHADOW,
gl.SAMPLER_3D,
gl.INT_SAMPLER_3D,
gl.UNSIGNED_INT_SAMPLER_3D,
gl.SAMPLER_2D_ARRAY,
gl.INT_SAMPLER_2D_ARRAY,
gl.UNSIGNED_INT_SAMPLER_2D_ARRAY
] : [])
gl.SAMPLER_2D,
gl.SAMPLER_CUBE,
gl.UNSIGNED_INT_SAMPLER_2D,
gl.INT_SAMPLER_2D,
gl.SAMPLER_2D_SHADOW,
gl.SAMPLER_CUBE_SHADOW,
gl.SAMPLER_3D,
gl.INT_SAMPLER_3D,
gl.UNSIGNED_INT_SAMPLER_3D,
gl.SAMPLER_2D_ARRAY,
gl.INT_SAMPLER_2D_ARRAY,
gl.UNSIGNED_INT_SAMPLER_2D_ARRAY
]);

this.glAddress = [
Expand All @@ -376,8 +369,8 @@ class WebglGraphicsDevice extends GraphicsDevice {
gl.FUNC_ADD,
gl.FUNC_SUBTRACT,
gl.FUNC_REVERSE_SUBTRACT,
this.isWebGL2 ? gl.MIN : this.extBlendMinmax ? this.extBlendMinmax.MIN_EXT : gl.FUNC_ADD,
this.isWebGL2 ? gl.MAX : this.extBlendMinmax ? this.extBlendMinmax.MAX_EXT : gl.FUNC_ADD
gl.MIN,
gl.MAX
];

this.glBlendFunctionColor = [
Expand Down Expand Up @@ -505,24 +498,22 @@ class WebglGraphicsDevice extends GraphicsDevice {
this.pcUniformType[gl.UNSIGNED_INT_VEC3] = UNIFORMTYPE_UVEC3;
this.pcUniformType[gl.UNSIGNED_INT_VEC4] = UNIFORMTYPE_UVEC4;

if (this.isWebGL2) {
this.pcUniformType[gl.SAMPLER_2D_SHADOW] = UNIFORMTYPE_TEXTURE2D_SHADOW;
this.pcUniformType[gl.SAMPLER_CUBE_SHADOW] = UNIFORMTYPE_TEXTURECUBE_SHADOW;
this.pcUniformType[gl.SAMPLER_2D_ARRAY] = UNIFORMTYPE_TEXTURE2D_ARRAY;
this.pcUniformType[gl.SAMPLER_3D] = UNIFORMTYPE_TEXTURE3D;
this.pcUniformType[gl.SAMPLER_2D_SHADOW] = UNIFORMTYPE_TEXTURE2D_SHADOW;
this.pcUniformType[gl.SAMPLER_CUBE_SHADOW] = UNIFORMTYPE_TEXTURECUBE_SHADOW;
this.pcUniformType[gl.SAMPLER_2D_ARRAY] = UNIFORMTYPE_TEXTURE2D_ARRAY;
this.pcUniformType[gl.SAMPLER_3D] = UNIFORMTYPE_TEXTURE3D;

this.pcUniformType[gl.INT_SAMPLER_2D] = UNIFORMTYPE_ITEXTURE2D;
this.pcUniformType[gl.UNSIGNED_INT_SAMPLER_2D] = UNIFORMTYPE_UTEXTURE2D;
this.pcUniformType[gl.INT_SAMPLER_2D] = UNIFORMTYPE_ITEXTURE2D;
this.pcUniformType[gl.UNSIGNED_INT_SAMPLER_2D] = UNIFORMTYPE_UTEXTURE2D;

this.pcUniformType[gl.INT_SAMPLER_CUBE] = UNIFORMTYPE_ITEXTURECUBE;
this.pcUniformType[gl.UNSIGNED_INT_SAMPLER_2D] = UNIFORMTYPE_UTEXTURECUBE;
this.pcUniformType[gl.INT_SAMPLER_CUBE] = UNIFORMTYPE_ITEXTURECUBE;
this.pcUniformType[gl.UNSIGNED_INT_SAMPLER_2D] = UNIFORMTYPE_UTEXTURECUBE;

this.pcUniformType[gl.INT_SAMPLER_3D] = UNIFORMTYPE_ITEXTURE3D;
this.pcUniformType[gl.UNSIGNED_INT_SAMPLER_3D] = UNIFORMTYPE_UTEXTURE3D;
this.pcUniformType[gl.INT_SAMPLER_3D] = UNIFORMTYPE_ITEXTURE3D;
this.pcUniformType[gl.UNSIGNED_INT_SAMPLER_3D] = UNIFORMTYPE_UTEXTURE3D;

this.pcUniformType[gl.INT_SAMPLER_2D_ARRAY] = UNIFORMTYPE_ITEXTURE2D_ARRAY;
this.pcUniformType[gl.UNSIGNED_INT_SAMPLER_2D_ARRAY] = UNIFORMTYPE_UTEXTURE2D_ARRAY;
}
this.pcUniformType[gl.INT_SAMPLER_2D_ARRAY] = UNIFORMTYPE_ITEXTURE2D_ARRAY;
this.pcUniformType[gl.UNSIGNED_INT_SAMPLER_2D_ARRAY] = UNIFORMTYPE_UTEXTURE2D_ARRAY;

this.targetToSlot = {};
this.targetToSlot[gl.TEXTURE_2D] = 0;
Expand Down Expand Up @@ -788,7 +779,7 @@ class WebglGraphicsDevice extends GraphicsDevice {
super.destroy();
const gl = this.gl;

if (this.isWebGL2 && this.feedback) {
if (this.feedback) {
gl.deleteTransformFeedback(this.feedback);
}

Expand Down Expand Up @@ -940,10 +931,8 @@ class WebglGraphicsDevice extends GraphicsDevice {
get extDisjointTimerQuery() {
// lazy evaluation as this is not typically used
if (!this._extDisjointTimerQuery) {
if (this.isWebGL2) {
// Note that Firefox exposes EXT_disjoint_timer_query under WebGL2 rather than EXT_disjoint_timer_query_webgl2
this._extDisjointTimerQuery = this.getExtension('EXT_disjoint_timer_query_webgl2', 'EXT_disjoint_timer_query');
}
// Note that Firefox exposes EXT_disjoint_timer_query under WebGL2 rather than EXT_disjoint_timer_query_webgl2
this._extDisjointTimerQuery = this.getExtension('EXT_disjoint_timer_query_webgl2', 'EXT_disjoint_timer_query');
}
return this._extDisjointTimerQuery;
}
Expand Down Expand Up @@ -1066,7 +1055,7 @@ class WebglGraphicsDevice extends GraphicsDevice {
ext = this.extTextureFilterAnisotropic;
this.maxAnisotropy = ext ? gl.getParameter(ext.MAX_TEXTURE_MAX_ANISOTROPY_EXT) : 1;

const antialiasSupported = this.isWebGL2 && !this.forceDisableMultisampling;
const antialiasSupported = !this.forceDisableMultisampling;
this.maxSamples = antialiasSupported ? gl.getParameter(gl.MAX_SAMPLES) : 1;

// some devices incorrectly report max samples larger than 4
Expand All @@ -1076,7 +1065,7 @@ class WebglGraphicsDevice extends GraphicsDevice {
this.samples = antialiasSupported && this.backBufferAntialias ? this.maxSamples : 1;

// Don't allow area lights on old android devices, they often fail to compile the shader, run it incorrectly or are very slow.
this.supportsAreaLights = this.isWebGL2 || !platform.android;
this.supportsAreaLights = !platform.android;

// supports texture fetch instruction
this.supportsTextureFetch = this.isWebGL2;
Expand Down Expand Up @@ -1135,10 +1124,8 @@ class WebglGraphicsDevice extends GraphicsDevice {

this.alphaToCoverage = false;
this.raster = true;
if (this.isWebGL2) {
gl.disable(gl.SAMPLE_ALPHA_TO_COVERAGE);
gl.disable(gl.RASTERIZER_DISCARD);
}
gl.disable(gl.SAMPLE_ALPHA_TO_COVERAGE);
gl.disable(gl.RASTERIZER_DISCARD);

this.depthBiasEnabled = false;
gl.disable(gl.POLYGON_OFFSET_FILL);
Expand Down Expand Up @@ -1289,10 +1276,6 @@ class WebglGraphicsDevice extends GraphicsDevice {
source = null;
}

if (!this.isWebGL2 && depth) {
Debug.error("Depth is not copyable on WebGL 1.0");
return false;
}
if (color) {
if (!dest) {
// copying to backbuffer
Expand Down Expand Up @@ -1472,43 +1455,41 @@ class WebglGraphicsDevice extends GraphicsDevice {
if (target) {

// invalidate buffers to stop them being written to on tiled architectures
if (this.isWebGL2) {
invalidateAttachments.length = 0;
const gl = this.gl;
invalidateAttachments.length = 0;
const gl = this.gl;

// color buffers
for (let i = 0; i < colorBufferCount; i++) {
const colorOps = renderPass.colorArrayOps[i];
// color buffers
for (let i = 0; i < colorBufferCount; i++) {
const colorOps = renderPass.colorArrayOps[i];

// invalidate color only if we don't need to resolve it
if (!(colorOps.store || colorOps.resolve)) {
invalidateAttachments.push(gl.COLOR_ATTACHMENT0 + i);
}
// invalidate color only if we don't need to resolve it
if (!(colorOps.store || colorOps.resolve)) {
invalidateAttachments.push(gl.COLOR_ATTACHMENT0 + i);
}
}

// we cannot invalidate depth/stencil buffers of the backbuffer
if (target !== this.backBuffer) {
if (!renderPass.depthStencilOps.storeDepth) {
invalidateAttachments.push(gl.DEPTH_ATTACHMENT);
}
if (!renderPass.depthStencilOps.storeStencil) {
invalidateAttachments.push(gl.STENCIL_ATTACHMENT);
}
// we cannot invalidate depth/stencil buffers of the backbuffer
if (target !== this.backBuffer) {
if (!renderPass.depthStencilOps.storeDepth) {
invalidateAttachments.push(gl.DEPTH_ATTACHMENT);
}
if (!renderPass.depthStencilOps.storeStencil) {
invalidateAttachments.push(gl.STENCIL_ATTACHMENT);
}
}

if (invalidateAttachments.length > 0) {
if (invalidateAttachments.length > 0) {

// invalidate the whole buffer
// TODO: we could handle viewport invalidation as well
if (renderPass.fullSizeClearRect) {
gl.invalidateFramebuffer(gl.DRAW_FRAMEBUFFER, invalidateAttachments);
}
// invalidate the whole buffer
// TODO: we could handle viewport invalidation as well
if (renderPass.fullSizeClearRect) {
gl.invalidateFramebuffer(gl.DRAW_FRAMEBUFFER, invalidateAttachments);
}
}

// resolve the color buffer (this resolves all MRT color buffers at once)
if (renderPass.colorOps?.resolve) {
if (this.isWebGL2 && renderPass.samples > 1 && target.autoResolve) {
if (renderPass.samples > 1 && target.autoResolve) {
target.resolve(true, false);
}
}
Expand All @@ -1518,7 +1499,7 @@ class WebglGraphicsDevice extends GraphicsDevice {
const colorOps = renderPass.colorArrayOps[i];
if (colorOps.mipmaps) {
const colorBuffer = target._colorBuffers[i];
if (colorBuffer && colorBuffer.impl._glTexture && colorBuffer.mipmaps && (colorBuffer.pot || this.isWebGL2)) {
if (colorBuffer && colorBuffer.impl._glTexture && colorBuffer.mipmaps) {

DebugGraphics.pushGpuMarker(this, `MIPS${i}`);

Expand Down Expand Up @@ -1604,13 +1585,13 @@ class WebglGraphicsDevice extends GraphicsDevice {
const target = this.renderTarget;
if (target && target !== this.backBuffer) {
// Resolve MSAA if needed
if (this.isWebGL2 && target._samples > 1 && target.autoResolve) {
if (target._samples > 1 && target.autoResolve) {
target.resolve();
}

// If the active render target is auto-mipmapped, generate its mip chain
const colorBuffer = target._colorBuffer;
if (colorBuffer && colorBuffer.impl._glTexture && colorBuffer.mipmaps && (colorBuffer.pot || this.isWebGL2)) {
if (colorBuffer && colorBuffer.impl._glTexture && colorBuffer.mipmaps) {
// FIXME: if colorBuffer is a cubemap currently we're re-generating mipmaps after
// updating each face!
this.activeTexture(this.maxCombinedTextures - 1);
Expand Down Expand Up @@ -1721,7 +1702,7 @@ class WebglGraphicsDevice extends GraphicsDevice {

if (flags & 1) {
let filter = texture._minFilter;
if ((!texture.pot && !this.isWebGL2) || !texture._mipmaps || (texture._compressed && texture._levels.length === 1)) {
if (!texture._mipmaps || (texture._compressed && texture._levels.length === 1)) {
if (filter === FILTER_NEAREST_MIPMAP_NEAREST || filter === FILTER_NEAREST_MIPMAP_LINEAR) {
filter = FILTER_NEAREST;
} else if (filter === FILTER_LINEAR_MIPMAP_NEAREST || filter === FILTER_LINEAR_MIPMAP_LINEAR) {
Expand Down Expand Up @@ -2056,7 +2037,7 @@ class WebglGraphicsDevice extends GraphicsDevice {
}
}

if (this.isWebGL2 && this.transformFeedbackBuffer) {
if (this.transformFeedbackBuffer) {
// Enable TF, start writing to out buffer
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, this.transformFeedbackBuffer.impl.bufferId);
gl.beginTransformFeedback(gl.POINTS);
Expand Down Expand Up @@ -2087,7 +2068,7 @@ class WebglGraphicsDevice extends GraphicsDevice {
}
}

if (this.isWebGL2 && this.transformFeedbackBuffer) {
if (this.transformFeedbackBuffer) {
// disable TF
gl.endTransformFeedback();
gl.bindBufferBase(gl.TRANSFORM_FEEDBACK_BUFFER, 0, null);
Expand Down Expand Up @@ -2290,12 +2271,9 @@ class WebglGraphicsDevice extends GraphicsDevice {
* @ignore
*/
setTransformFeedbackBuffer(tf) {
if (this.transformFeedbackBuffer === tf)
return;

this.transformFeedbackBuffer = tf;
if (this.transformFeedbackBuffer !== tf) {
this.transformFeedbackBuffer = tf;

if (this.isWebGL2) {
const gl = this.gl;
if (tf) {
if (!this.feedback) {
Expand All @@ -2316,11 +2294,9 @@ class WebglGraphicsDevice extends GraphicsDevice {
* @ignore
*/
setRaster(on) {
if (this.raster === on) return;
if (this.raster !== on) {
this.raster = on;

this.raster = on;

if (this.isWebGL2) {
if (on) {
this.gl.disable(this.gl.RASTERIZER_DISCARD);
} else {
Expand Down