LibWeb: Implement WebGL extension OES_standard_derivatives

This commit is contained in:
Undefine 2025-11-05 21:38:41 +01:00 committed by Andreas Kling
parent 2bf35881f9
commit d4ac9fc5c6
Notes: github-actions[bot] 2025-11-06 18:04:25 +00:00
12 changed files with 115 additions and 2 deletions

View file

@ -1031,6 +1031,7 @@ set(SOURCES
WebGL/Extensions/EXTRenderSnorm.cpp
WebGL/Extensions/EXTTextureFilterAnisotropic.cpp
WebGL/Extensions/EXTTextureNorm16.cpp
WebGL/Extensions/OESStandardDerivatives.cpp
WebGL/Extensions/OESVertexArrayObject.cpp
WebGL/Extensions/WebGLCompressedTextureS3tc.cpp
WebGL/Extensions/WebGLCompressedTextureS3tcSrgb.cpp

View file

@ -1236,6 +1236,7 @@ class EXTColorBufferFloat;
class EXTRenderSnorm;
class EXTTextureFilterAnisotropic;
class EXTTextureNorm16;
class OESStandardDerivatives;
class OESVertexArrayObject;
class WebGLCompressedTextureS3tc;
class WebGLCompressedTextureS3tcSrgb;

View file

@ -0,0 +1,42 @@
/*
* Copyright (c) 2025, Undefine <undefine@undefine.pl>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibJS/Runtime/Realm.h>
#include <LibWeb/Bindings/Intrinsics.h>
#include <LibWeb/Bindings/OESStandardDerivativesPrototype.h>
#include <LibWeb/WebGL/Extensions/OESStandardDerivatives.h>
#include <LibWeb/WebGL/OpenGLContext.h>
#include <LibWeb/WebGL/WebGLRenderingContext.h>
namespace Web::WebGL::Extensions {
GC_DEFINE_ALLOCATOR(OESStandardDerivatives);
JS::ThrowCompletionOr<GC::Ptr<OESStandardDerivatives>> OESStandardDerivatives::create(JS::Realm& realm, GC::Ref<WebGLRenderingContext> context)
{
return realm.create<OESStandardDerivatives>(realm, context);
}
OESStandardDerivatives::OESStandardDerivatives(JS::Realm& realm, GC::Ref<WebGLRenderingContext> context)
: PlatformObject(realm)
, m_context(context)
{
m_context->context().request_extension("GL_OES_standard_derivatives");
}
void OESStandardDerivatives::initialize(JS::Realm& realm)
{
WEB_SET_PROTOTYPE_FOR_INTERFACE(OESStandardDerivatives);
Base::initialize(realm);
}
void OESStandardDerivatives::visit_edges(Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_context);
}
}

View file

@ -0,0 +1,31 @@
/*
* Copyright (c) 2025, Undefine <undefine@undefine.pl>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/Forward.h>
namespace Web::WebGL::Extensions {
class OESStandardDerivatives : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(OESStandardDerivatives, Bindings::PlatformObject);
GC_DECLARE_ALLOCATOR(OESStandardDerivatives);
public:
static JS::ThrowCompletionOr<GC::Ptr<OESStandardDerivatives>> create(JS::Realm&, GC::Ref<WebGLRenderingContext>);
protected:
void initialize(JS::Realm&) override;
void visit_edges(Visitor&) override;
private:
OESStandardDerivatives(JS::Realm&, GC::Ref<WebGLRenderingContext>);
GC::Ref<WebGLRenderingContext> m_context;
};
}

View file

@ -0,0 +1,12 @@
#import <WebGL/Types.idl>
// https://registry.khronos.org/webgl/extensions/OES_standard_derivatives/
// NOTE: Original OES_standard_derivatives name is changed to title case,
// so it matches corresponding C++ class name, and does not require
// IDL generator to handle snake_case to TitleCase conversion.
// Having a different name is totally fine, because LegacyNoInterfaceObject
// prevents the name from being exposed to JavaScript.
[Exposed=(Window,Worker), LegacyNoInterfaceObject]
interface OESStandardDerivatives {
const GLenum FRAGMENT_SHADER_DERIVATIVE_HINT_OES = 0x8B8B;
};

View file

@ -252,6 +252,11 @@ bool WebGL2RenderingContext::angle_instanced_arrays_extension_enabled() const
return false;
}
bool WebGL2RenderingContext::oes_standard_derivatives_extension_enabled() const
{
return false;
}
ReadonlySpan<WebIDL::UnsignedLong> WebGL2RenderingContext::enabled_compressed_texture_formats() const
{
return m_enabled_compressed_texture_formats;

View file

@ -53,6 +53,7 @@ public:
virtual bool ext_texture_filter_anisotropic_extension_enabled() const override;
virtual bool angle_instanced_arrays_extension_enabled() const override;
virtual bool oes_standard_derivatives_extension_enabled() const override;
virtual ReadonlySpan<WebIDL::UnsignedLong> enabled_compressed_texture_formats() const override;
private:

View file

@ -17,6 +17,7 @@
#include <LibWeb/WebGL/Extensions/ANGLEInstancedArrays.h>
#include <LibWeb/WebGL/Extensions/EXTBlendMinMax.h>
#include <LibWeb/WebGL/Extensions/EXTTextureFilterAnisotropic.h>
#include <LibWeb/WebGL/Extensions/OESStandardDerivatives.h>
#include <LibWeb/WebGL/Extensions/OESVertexArrayObject.h>
#include <LibWeb/WebGL/Extensions/WebGLCompressedTextureS3tc.h>
#include <LibWeb/WebGL/Extensions/WebGLCompressedTextureS3tcSrgb.h>
@ -98,6 +99,7 @@ void WebGLRenderingContext::visit_edges(Cell::Visitor& visitor)
visitor.visit(m_angle_instanced_arrays_extension);
visitor.visit(m_ext_blend_min_max_extension);
visitor.visit(m_ext_texture_filter_anisotropic);
visitor.visit(m_oes_standard_derivatives_object_extension);
visitor.visit(m_oes_vertex_array_object_extension);
visitor.visit(m_webgl_compressed_texture_s3tc_extension);
visitor.visit(m_webgl_compressed_texture_s3tc_srgb_extension);
@ -208,6 +210,15 @@ JS::Object* WebGLRenderingContext::get_extension(String const& name)
return m_ext_texture_filter_anisotropic;
}
if (name.equals_ignoring_ascii_case("OES_standard_derivatives"sv)) {
if (!m_oes_standard_derivatives_object_extension) {
m_oes_standard_derivatives_object_extension = MUST(Extensions::OESStandardDerivatives::create(realm(), *this));
}
VERIFY(m_oes_standard_derivatives_object_extension);
return m_oes_standard_derivatives_object_extension;
}
if (name.equals_ignoring_ascii_case("OES_vertex_array_object"sv)) {
if (!m_oes_vertex_array_object_extension) {
m_oes_vertex_array_object_extension = MUST(Extensions::OESVertexArrayObject::create(realm(), *this));
@ -279,6 +290,11 @@ bool WebGLRenderingContext::angle_instanced_arrays_extension_enabled() const
return !!m_angle_instanced_arrays_extension;
}
bool WebGLRenderingContext::oes_standard_derivatives_extension_enabled() const
{
return !!m_oes_standard_derivatives_object_extension;
}
ReadonlySpan<WebIDL::UnsignedLong> WebGLRenderingContext::enabled_compressed_texture_formats() const
{
return m_enabled_compressed_texture_formats;

View file

@ -52,6 +52,7 @@ public:
virtual bool ext_texture_filter_anisotropic_extension_enabled() const override;
virtual bool angle_instanced_arrays_extension_enabled() const override;
virtual bool oes_standard_derivatives_extension_enabled() const override;
virtual ReadonlySpan<WebIDL::UnsignedLong> enabled_compressed_texture_formats() const override;
private:
@ -88,6 +89,7 @@ private:
GC::Ptr<Extensions::ANGLEInstancedArrays> m_angle_instanced_arrays_extension;
GC::Ptr<Extensions::EXTBlendMinMax> m_ext_blend_min_max_extension;
GC::Ptr<Extensions::EXTTextureFilterAnisotropic> m_ext_texture_filter_anisotropic;
GC::Ptr<Extensions::OESStandardDerivatives> m_oes_standard_derivatives_object_extension;
GC::Ptr<Extensions::OESVertexArrayObject> m_oes_vertex_array_object_extension;
GC::Ptr<Extensions::WebGLCompressedTextureS3tc> m_webgl_compressed_texture_s3tc_extension;
GC::Ptr<Extensions::WebGLCompressedTextureS3tcSrgb> m_webgl_compressed_texture_s3tc_srgb_extension;

View file

@ -46,6 +46,7 @@ public:
virtual OpenGLContext& context() = 0;
virtual bool ext_texture_filter_anisotropic_extension_enabled() const = 0;
virtual bool angle_instanced_arrays_extension_enabled() const = 0;
virtual bool oes_standard_derivatives_extension_enabled() const = 0;
virtual ReadonlySpan<WebIDL::UnsignedLong> enabled_compressed_texture_formats() const = 0;
template<typename T>

View file

@ -1236,8 +1236,8 @@ JS::Value WebGLRenderingContextImpl::get_parameter(WebIDL::UnsignedLong pname)
return JS::Int32Array::create(m_realm, 4, array_buffer);
}
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: {
if (m_context->webgl_version() == OpenGLContext::WebGLVersion::WebGL2) { // FIXME: Allow this code path for GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: { // NOTE: This has the same value as GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES
if (oes_standard_derivatives_extension_enabled() || m_context->webgl_version() == OpenGLContext::WebGLVersion::WebGL2) {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, 1, nullptr, &result);
return JS::Value(result);

View file

@ -475,6 +475,7 @@ libweb_js_bindings(WebGL/Extensions/EXTColorBufferFloat)
libweb_js_bindings(WebGL/Extensions/EXTRenderSnorm)
libweb_js_bindings(WebGL/Extensions/EXTTextureFilterAnisotropic)
libweb_js_bindings(WebGL/Extensions/EXTTextureNorm16)
libweb_js_bindings(WebGL/Extensions/OESStandardDerivatives)
libweb_js_bindings(WebGL/Extensions/OESVertexArrayObject)
libweb_js_bindings(WebGL/Extensions/WebGLCompressedTextureS3tc)
libweb_js_bindings(WebGL/Extensions/WebGLCompressedTextureS3tcSrgb)