From 19b0fabe6eb6e0d42fc976291828d9db2bbaab0f Mon Sep 17 00:00:00 2001 From: Kelsey Gilbert Date: Wed, 17 Jul 2024 21:12:23 +0000 Subject: [PATCH] Bug 1885032 - Support EXT_depth_clamp in webgl. r=gfx-reviewers,webidl,lsalzman,smaug Differential Revision: https://phabricator.services.mozilla.com/D215713 --- dom/bindings/Bindings.conf | 5 +++++ dom/canvas/ClientWebGLContext.cpp | 15 ++++++++++----- dom/canvas/ClientWebGLContext.h | 2 +- dom/canvas/ClientWebGLExtensions.cpp | 15 +++++++++++++++ dom/canvas/ClientWebGLExtensions.h | 2 ++ dom/canvas/WebGLContext.cpp | 7 +++++++ dom/canvas/WebGLContext.h | 3 +++ dom/canvas/WebGLContextExtensions.cpp | 9 +++++++++ dom/canvas/WebGLContextState.cpp | 8 +------- dom/canvas/WebGLExtensions.cpp | 7 +++++++ dom/canvas/WebGLExtensions.h | 5 +++++ dom/canvas/WebGLTypes.h | 1 + .../ensure-exts/test_EXT_depth_clamp.html | 18 ++++++++++++++++++ .../ensure-exts/test_common.html | 1 + dom/canvas/test/webgl-mochitest/mochitest.toml | 6 ++++++ dom/webidl/WebGLRenderingContext.webidl | 5 +++++ gfx/gl/GLContext.cpp | 2 ++ gfx/gl/GLContext.h | 3 +++ gfx/gl/GLContextFeatures.cpp | 6 ++++++ 19 files changed, 107 insertions(+), 13 deletions(-) create mode 100644 dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_depth_clamp.html diff --git a/dom/bindings/Bindings.conf b/dom/bindings/Bindings.conf index 8271f31e0323..6935da95fb6c 100644 --- a/dom/bindings/Bindings.conf +++ b/dom/bindings/Bindings.conf @@ -1155,6 +1155,11 @@ DOMInterfaces = { 'headerFile': 'ClientWebGLExtensions.h' }, +'EXT_depth_clamp': { + 'nativeType': 'mozilla::ClientWebGLExtensionDepthClamp', + 'headerFile': 'ClientWebGLExtensions.h' +}, + 'EXT_disjoint_timer_query': { 'nativeType': 'mozilla::ClientWebGLExtensionDisjointTimerQuery', 'headerFile': 'ClientWebGLExtensions.h' diff --git a/dom/canvas/ClientWebGLContext.cpp b/dom/canvas/ClientWebGLContext.cpp index 1a76b8ce16a9..94cfc2b486e9 100644 --- a/dom/canvas/ClientWebGLContext.cpp +++ b/dom/canvas/ClientWebGLContext.cpp @@ -939,6 +939,8 @@ bool ClientWebGLContext::CreateHostContext(const uvec2& requestedSize) { // Init state const auto& limits = Limits(); auto& state = State(); + state.mIsEnabledMap = webgl::MakeIsEnabledMap(mIsWebGL2); + state.mDefaultTfo = new WebGLTransformFeedbackJS(*this); state.mDefaultVao = new WebGLVertexArrayJS(this); @@ -978,8 +980,6 @@ bool ClientWebGLContext::CreateHostContext(const uvec2& requestedSize) { .mCurrentQueryByTarget[LOCAL_GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN]; } - state.mIsEnabledMap = Some(webgl::MakeIsEnabledMap(mIsWebGL2)); - return true; } @@ -1934,7 +1934,7 @@ void ClientWebGLContext::SetEnabledI(const GLenum cap, const Maybe i, const FuncScope funcScope(*this, "enable/disable"); if (IsContextLost()) return; - auto& map = *mNotLost->state.mIsEnabledMap; + auto& map = mNotLost->state.mIsEnabledMap; auto slot = MaybeFind(map, cap); if (i && cap != LOCAL_GL_BLEND) { slot = nullptr; @@ -1955,7 +1955,7 @@ bool ClientWebGLContext::IsEnabled(const GLenum cap) const { const FuncScope funcScope(*this, "isEnabled"); if (IsContextLost()) return false; - const auto& map = *mNotLost->state.mIsEnabledMap; + const auto& map = mNotLost->state.mIsEnabledMap; const auto slot = MaybeFind(map, cap); if (!slot) { EnqueueError_ArgEnum("cap", cap); @@ -2163,6 +2163,11 @@ void ClientWebGLContext::GetParameter(JSContext* cx, GLenum pname, retval.set(JS::NumberValue(UnderlyingValue(state.mProvokingVertex))); return; + case LOCAL_GL_DEPTH_CLAMP: + if (!IsExtensionEnabled(WebGLExtensionID::EXT_depth_clamp)) break; + retval.set(JS::BooleanValue(state.mIsEnabledMap[LOCAL_GL_DEPTH_CLAMP])); + return; + // - // Array returns @@ -2318,7 +2323,7 @@ void ClientWebGLContext::GetParameter(JSContext* cx, GLenum pname, retval.set(JS::NumberValue(state.mPixelUnpackState.skipRows)); return; } // switch pname - } // if webgl2 + } // if webgl2 // - diff --git a/dom/canvas/ClientWebGLContext.h b/dom/canvas/ClientWebGLContext.h index 6ff992028250..015afb076b77 100644 --- a/dom/canvas/ClientWebGLContext.h +++ b/dom/canvas/ClientWebGLContext.h @@ -177,7 +177,7 @@ class ContextGenerationInfo final { webgl::ProvokingVertex mProvokingVertex = webgl::ProvokingVertex::LastVertex; - mutable Maybe> mIsEnabledMap; + mutable std::unordered_map mIsEnabledMap; }; // - diff --git a/dom/canvas/ClientWebGLExtensions.cpp b/dom/canvas/ClientWebGLExtensions.cpp index a7e2d7a70ae3..78f661851f86 100644 --- a/dom/canvas/ClientWebGLExtensions.cpp +++ b/dom/canvas/ClientWebGLExtensions.cpp @@ -57,6 +57,21 @@ DEFINE_WEBGL_EXTENSION_GOOP(WEBGL_provoking_vertex, // -------------- +JSObject* ClientWebGLExtensionDepthClamp::WrapObject( + JSContext* cx, JS::Handle givenProto) { + return dom::EXT_depth_clamp_Binding::Wrap(cx, this, givenProto); +} + +ClientWebGLExtensionDepthClamp::ClientWebGLExtensionDepthClamp( + ClientWebGLContext& webgl) + : ClientWebGLExtensionBase(webgl) { + auto& state = webgl.State(); + // Add slot for new key: + state.mIsEnabledMap[LOCAL_GL_DEPTH_CLAMP] = false; +} + +// -------------- + JSObject* ClientWebGLExtensionDisjointTimerQuery::WrapObject( JSContext* cx, JS::Handle givenProto) { return dom::EXT_disjoint_timer_query_Binding::Wrap(cx, this, givenProto); diff --git a/dom/canvas/ClientWebGLExtensions.h b/dom/canvas/ClientWebGLExtensions.h index 460dcd62b056..f7f0f745b913 100644 --- a/dom/canvas/ClientWebGLExtensions.h +++ b/dom/canvas/ClientWebGLExtensions.h @@ -105,6 +105,8 @@ class ClientWebGLExtensionDebugShaders : public ClientWebGLExtensionBase { } }; +DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionDepthClamp) + DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionDepthTexture) DECLARE_SIMPLE_WEBGL_EXTENSION(WebGLExtensionElementIndexUint) diff --git a/dom/canvas/WebGLContext.cpp b/dom/canvas/WebGLContext.cpp index 69450953ccb4..24c42e03e8e5 100644 --- a/dom/canvas/WebGLContext.cpp +++ b/dom/canvas/WebGLContext.cpp @@ -697,6 +697,13 @@ void WebGLContext::FinishInit() { mScissorRect = {0, 0, size.width, size.height}; mScissorRect.Apply(*gl); + { + const auto& isEnabledMap = webgl::MakeIsEnabledMap(IsWebGL2()); + for (const auto& pair : isEnabledMap) { + mIsEnabledMapKeys.insert(pair.first); + } + } + ////// // Check everything diff --git a/dom/canvas/WebGLContext.h b/dom/canvas/WebGLContext.h index 0f45bd0e957b..5b60ed19da7f 100644 --- a/dom/canvas/WebGLContext.h +++ b/dom/canvas/WebGLContext.h @@ -207,6 +207,7 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr { friend class WebGLExtensionCompressedTextureRGTC; friend class WebGLExtensionCompressedTextureS3TC; friend class WebGLExtensionCompressedTextureS3TC_SRGB; + friend class WebGLExtensionDepthClamp; friend class WebGLExtensionDepthTexture; friend class WebGLExtensionDisjointTimerQuery; friend class WebGLExtensionDrawBuffers; @@ -1237,6 +1238,8 @@ class WebGLContext : public VRefCounted, public SupportsWeakPtr { std::bitset mColorWriteMaskNonzero = -1; std::bitset mBlendEnabled = 0; + std::unordered_set mIsEnabledMapKeys; + GLint mViewportX = 0; GLint mViewportY = 0; GLsizei mViewportWidth = 0; diff --git a/dom/canvas/WebGLContextExtensions.cpp b/dom/canvas/WebGLContextExtensions.cpp index 1a75ba827b57..59d1ef989812 100644 --- a/dom/canvas/WebGLContextExtensions.cpp +++ b/dom/canvas/WebGLContextExtensions.cpp @@ -26,6 +26,7 @@ const char* GetExtensionName(const WebGLExtensionID ext) { WEBGL_EXTENSION_IDENTIFIER(EXT_blend_minmax) WEBGL_EXTENSION_IDENTIFIER(EXT_color_buffer_float) WEBGL_EXTENSION_IDENTIFIER(EXT_color_buffer_half_float) + WEBGL_EXTENSION_IDENTIFIER(EXT_depth_clamp) WEBGL_EXTENSION_IDENTIFIER(EXT_disjoint_timer_query) WEBGL_EXTENSION_IDENTIFIER(EXT_float_blend) WEBGL_EXTENSION_IDENTIFIER(EXT_frag_depth) @@ -137,6 +138,8 @@ RefPtr ClientWebGLContext::GetExtension( return new ClientWebGLExtensionEXTColorBufferFloat(*this); case WebGLExtensionID::EXT_color_buffer_half_float: return new ClientWebGLExtensionColorBufferHalfFloat(*this); + case WebGLExtensionID::EXT_depth_clamp: + return new ClientWebGLExtensionDepthClamp(*this); case WebGLExtensionID::EXT_disjoint_timer_query: return new ClientWebGLExtensionDisjointTimerQuery(*this); case WebGLExtensionID::EXT_float_blend: @@ -258,6 +261,9 @@ bool WebGLContext::IsExtensionSupported(WebGLExtensionID ext) const { case WebGLExtensionID::EXT_color_buffer_half_float: return WebGLExtensionColorBufferHalfFloat::IsSupported(this); + case WebGLExtensionID::EXT_depth_clamp: + return gl->IsSupported(gl::GLFeature::depth_clamp); + case WebGLExtensionID::EXT_disjoint_timer_query: return WebGLExtensionDisjointTimerQuery::IsSupported(this); @@ -414,6 +420,9 @@ void WebGLContext::RequestExtension(const WebGLExtensionID ext, case WebGLExtensionID::EXT_color_buffer_half_float: slot.reset(new WebGLExtensionColorBufferHalfFloat(this)); break; + case WebGLExtensionID::EXT_depth_clamp: + slot.reset(new WebGLExtensionDepthClamp(this)); + break; case WebGLExtensionID::EXT_disjoint_timer_query: slot.reset(new WebGLExtensionDisjointTimerQuery(this)); break; diff --git a/dom/canvas/WebGLContextState.cpp b/dom/canvas/WebGLContextState.cpp index e057a0195b43..8a7a5b4b4b7c 100644 --- a/dom/canvas/WebGLContextState.cpp +++ b/dom/canvas/WebGLContextState.cpp @@ -27,13 +27,7 @@ void WebGLContext::SetEnabled(const GLenum cap, const Maybe i, const FuncScope funcScope(*this, "enable(i)/disable(i)"); if (IsContextLost()) return; - static const auto webgl1Map = webgl::MakeIsEnabledMap(false); - static const auto webgl2Map = webgl::MakeIsEnabledMap(true); - const auto* map = &webgl2Map; - if (!IsWebGL2()) { - map = &webgl1Map; - } - if (!MaybeFind(*map, cap)) { + if (!mIsEnabledMapKeys.count(cap)) { MOZ_ASSERT(false, "Bad cap."); return; } diff --git a/dom/canvas/WebGLExtensions.cpp b/dom/canvas/WebGLExtensions.cpp index bb5692c92b2f..1eaaea7dfd90 100644 --- a/dom/canvas/WebGLExtensions.cpp +++ b/dom/canvas/WebGLExtensions.cpp @@ -433,6 +433,13 @@ bool WebGLExtensionCompressedTextureS3TC_SRGB::IsSupported( // - +WebGLExtensionDepthClamp::WebGLExtensionDepthClamp(WebGLContext* const webgl) + : WebGLExtensionBase(webgl) { + webgl->mIsEnabledMapKeys.insert(LOCAL_GL_DEPTH_CLAMP); +} + +// - + WebGLExtensionDepthTexture::WebGLExtensionDepthTexture( WebGLContext* const webgl) : WebGLExtensionBase(webgl) { diff --git a/dom/canvas/WebGLExtensions.h b/dom/canvas/WebGLExtensions.h index c8b4fda22dbe..449bb335b6bf 100644 --- a/dom/canvas/WebGLExtensions.h +++ b/dom/canvas/WebGLExtensions.h @@ -118,6 +118,11 @@ class WebGLExtensionDebugShaders : public WebGLExtensionBase { : WebGLExtensionBase(webgl) {} }; +class WebGLExtensionDepthClamp : public WebGLExtensionBase { + public: + explicit WebGLExtensionDepthClamp(WebGLContext* webgl); +}; + class WebGLExtensionDepthTexture : public WebGLExtensionBase { public: explicit WebGLExtensionDepthTexture(WebGLContext*); diff --git a/dom/canvas/WebGLTypes.h b/dom/canvas/WebGLTypes.h index 2f1d9331a750..071d4bea07f8 100644 --- a/dom/canvas/WebGLTypes.h +++ b/dom/canvas/WebGLTypes.h @@ -215,6 +215,7 @@ enum class WebGLExtensionID : uint8_t { EXT_blend_minmax, EXT_color_buffer_float, EXT_color_buffer_half_float, + EXT_depth_clamp, EXT_disjoint_timer_query, EXT_float_blend, EXT_frag_depth, diff --git a/dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_depth_clamp.html b/dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_depth_clamp.html new file mode 100644 index 000000000000..ea75b42bd483 --- /dev/null +++ b/dom/canvas/test/webgl-mochitest/ensure-exts/test_EXT_depth_clamp.html @@ -0,0 +1,18 @@ + + + + + + + + + + + + diff --git a/dom/canvas/test/webgl-mochitest/ensure-exts/test_common.html b/dom/canvas/test/webgl-mochitest/ensure-exts/test_common.html index 8620a66f833e..ce2ee33d3820 100644 --- a/dom/canvas/test/webgl-mochitest/ensure-exts/test_common.html +++ b/dom/canvas/test/webgl-mochitest/ensure-exts/test_common.html @@ -40,6 +40,7 @@ var defaultExts = [ // Community Approved ['EXT_color_buffer_float' , [FORBID , ENSURE ]], ['EXT_color_buffer_half_float' , [MACHINE_SPECIFIC, FORBID ]], + ['EXT_depth_clamp' , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]], ['EXT_disjoint_timer_query' , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]], ['EXT_float_blend' , [MACHINE_SPECIFIC, MACHINE_SPECIFIC]], ['EXT_sRGB' , [MACHINE_SPECIFIC, FORBID ]], diff --git a/dom/canvas/test/webgl-mochitest/mochitest.toml b/dom/canvas/test/webgl-mochitest/mochitest.toml index c49e5eda2071..fd043578d2a8 100644 --- a/dom/canvas/test/webgl-mochitest/mochitest.toml +++ b/dom/canvas/test/webgl-mochitest/mochitest.toml @@ -18,6 +18,12 @@ support-files = [ ["ensure-exts/test_EXT_color_buffer_half_float.html"] +["ensure-exts/test_EXT_depth_clamp.html"] +fail-if = [ + "os == 'android'", + "os == 'win'", +] + ["ensure-exts/test_EXT_disjoint_timer_query.html"] fail-if = ["true"] diff --git a/dom/webidl/WebGLRenderingContext.webidl b/dom/webidl/WebGLRenderingContext.webidl index df04cf8e8754..b22eac7b9141 100644 --- a/dom/webidl/WebGLRenderingContext.webidl +++ b/dom/webidl/WebGLRenderingContext.webidl @@ -1229,6 +1229,11 @@ interface WEBGL_provoking_vertex { undefined provokingVertexWEBGL(GLenum provokeMode); }; +[Exposed=(Window,Worker), LegacyNoInterfaceObject] +interface EXT_depth_clamp { + const GLenum DEPTH_CLAMP_EXT = 0x864F; +}; + // https://immersive-web.github.io/webxr/#dom-webglcontextattributes-xrcompatible partial dictionary WebGLContextAttributes { [Pref="dom.vr.webxr.enabled"] diff --git a/gfx/gl/GLContext.cpp b/gfx/gl/GLContext.cpp index 5eba6c58aa6c..6936333c4471 100644 --- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -102,6 +102,7 @@ static const char* const sExtensionNames[] = { "GL_ARB_color_buffer_float", "GL_ARB_compatibility", "GL_ARB_copy_buffer", + "GL_ARB_depth_clamp", "GL_ARB_depth_texture", "GL_ARB_draw_buffers", "GL_ARB_draw_instanced", @@ -142,6 +143,7 @@ static const char* const sExtensionNames[] = { "GL_EXT_color_buffer_float", "GL_EXT_color_buffer_half_float", "GL_EXT_copy_texture", + "GL_EXT_depth_clamp", "GL_EXT_disjoint_timer_query", "GL_EXT_draw_buffers", "GL_EXT_draw_buffers2", diff --git a/gfx/gl/GLContext.h b/gfx/gl/GLContext.h index 4ee256b0530a..d47eb7219409 100644 --- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -83,6 +83,7 @@ enum class GLFeature { blend_minmax, clear_buffers, copy_buffer, + depth_clamp, depth_texture, draw_buffers, draw_buffers_indexed, @@ -380,6 +381,7 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr { ARB_color_buffer_float, ARB_compatibility, ARB_copy_buffer, + ARB_depth_clamp, ARB_depth_texture, ARB_draw_buffers, ARB_draw_instanced, @@ -420,6 +422,7 @@ class GLContext : public GenericAtomicRefCounted, public SupportsWeakPtr { EXT_color_buffer_float, EXT_color_buffer_half_float, EXT_copy_texture, + EXT_depth_clamp, EXT_disjoint_timer_query, EXT_draw_buffers, EXT_draw_buffers2, diff --git a/gfx/gl/GLContextFeatures.cpp b/gfx/gl/GLContextFeatures.cpp index b66e6b6bbf52..20b9f9decb3e 100644 --- a/gfx/gl/GLContextFeatures.cpp +++ b/gfx/gl/GLContextFeatures.cpp @@ -90,6 +90,12 @@ static const FeatureInfo sFeatureInfoArr[] = { GLESVersion::ES3, GLContext::ARB_copy_buffer, {GLContext::Extensions_End}}, + {"depth_clamp", + GLVersion::GL3_2, + GLESVersion::NONE, + GLContext::Extension_None, + {GLContext::ARB_depth_clamp, GLContext::EXT_depth_clamp, + GLContext::Extensions_End}}, {"depth_texture", GLVersion::GL2, GLESVersion::ES3,