Skip to content

Commit b15f442

Browse files
Lubrsigmta
authored andcommitted
LibWeb/WebGL: Implement the EXT_texture_filter_anisotropic extension
1 parent d08915a commit b15f442

13 files changed

+166
-2
lines changed

Libraries/LibWeb/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1024,6 +1024,7 @@ set(SOURCES
10241024
WebGL/Extensions/EXTBlendMinMax.cpp
10251025
WebGL/Extensions/EXTColorBufferFloat.cpp
10261026
WebGL/Extensions/EXTRenderSnorm.cpp
1027+
WebGL/Extensions/EXTTextureFilterAnisotropic.cpp
10271028
WebGL/Extensions/EXTTextureNorm16.cpp
10281029
WebGL/Extensions/OESVertexArrayObject.cpp
10291030
WebGL/Extensions/WebGLCompressedTextureS3tc.cpp

Libraries/LibWeb/Forward.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,7 @@ class ANGLEInstancedArrays;
12251225
class EXTBlendMinMax;
12261226
class EXTColorBufferFloat;
12271227
class EXTRenderSnorm;
1228+
class EXTTextureFilterAnisotropic;
12281229
class EXTTextureNorm16;
12291230
class OESVertexArrayObject;
12301231
class WebGLCompressedTextureS3tc;
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* Copyright (c) 2025, Luke Wilde <luke@ladybird.org>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#include <LibJS/Runtime/Realm.h>
8+
#include <LibWeb/Bindings/EXTTextureFilterAnisotropicPrototype.h>
9+
#include <LibWeb/Bindings/Intrinsics.h>
10+
#include <LibWeb/WebGL/Extensions/EXTTextureFilterAnisotropic.h>
11+
#include <LibWeb/WebGL/OpenGLContext.h>
12+
13+
namespace Web::WebGL::Extensions {
14+
15+
GC_DEFINE_ALLOCATOR(EXTTextureFilterAnisotropic);
16+
17+
JS::ThrowCompletionOr<GC::Ptr<EXTTextureFilterAnisotropic>> EXTTextureFilterAnisotropic::create(JS::Realm& realm, WebGLRenderingContextBase* context)
18+
{
19+
return realm.create<EXTTextureFilterAnisotropic>(realm, context);
20+
}
21+
22+
EXTTextureFilterAnisotropic::EXTTextureFilterAnisotropic(JS::Realm& realm, WebGLRenderingContextBase* context)
23+
: PlatformObject(realm)
24+
, m_context(context)
25+
{
26+
m_context->context().request_extension("GL_EXT_texture_filter_anisotropic");
27+
}
28+
29+
void EXTTextureFilterAnisotropic::initialize(JS::Realm& realm)
30+
{
31+
WEB_SET_PROTOTYPE_FOR_INTERFACE(EXTTextureFilterAnisotropic);
32+
Base::initialize(realm);
33+
}
34+
35+
void EXTTextureFilterAnisotropic::visit_edges(Visitor& visitor)
36+
{
37+
Base::visit_edges(visitor);
38+
visitor.visit(m_context->gc_cell());
39+
}
40+
41+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Copyright (c) 2025, Luke Wilde <luke@ladybird.org>
3+
*
4+
* SPDX-License-Identifier: BSD-2-Clause
5+
*/
6+
7+
#pragma once
8+
9+
#include <LibWeb/Bindings/PlatformObject.h>
10+
#include <LibWeb/Forward.h>
11+
#include <LibWeb/WebGL/WebGLRenderingContextBase.h>
12+
13+
namespace Web::WebGL::Extensions {
14+
15+
class EXTTextureFilterAnisotropic : public Bindings::PlatformObject {
16+
WEB_PLATFORM_OBJECT(EXTTextureFilterAnisotropic, Bindings::PlatformObject);
17+
GC_DECLARE_ALLOCATOR(EXTTextureFilterAnisotropic);
18+
19+
public:
20+
static JS::ThrowCompletionOr<GC::Ptr<EXTTextureFilterAnisotropic>> create(JS::Realm&, WebGLRenderingContextBase*);
21+
22+
protected:
23+
void initialize(JS::Realm&) override;
24+
void visit_edges(Visitor&) override;
25+
26+
private:
27+
EXTTextureFilterAnisotropic(JS::Realm&, WebGLRenderingContextBase*);
28+
29+
// FIXME: It should be GC::Ptr instead of raw pointer, but we need to make WebGLRenderingContextBase inherit from PlatformObject first.
30+
WebGLRenderingContextBase* m_context;
31+
};
32+
33+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#import <WebGL/Types.idl>
2+
3+
// https://registry.khronos.org/webgl/extensions/EXT_texture_filter_anisotropic/
4+
// NOTE: Original EXT_texture_filter_anisotropic name is changed to title case,
5+
// so it matches corresponding C++ class name, and does not require
6+
// IDL generator to handle snake_case to TitleCase conversion.
7+
// Having a different name is totally fine, because LegacyNoInterfaceObject
8+
// prevents the name from being exposed to JavaScript.
9+
[Exposed=(Window,Worker), LegacyNoInterfaceObject]
10+
interface EXTTextureFilterAnisotropic {
11+
const GLenum TEXTURE_MAX_ANISOTROPY_EXT = 0x84FE;
12+
const GLenum MAX_TEXTURE_MAX_ANISOTROPY_EXT = 0x84FF;
13+
};

Libraries/LibWeb/WebGL/WebGL2RenderingContext.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <LibWeb/WebGL/EventNames.h>
1818
#include <LibWeb/WebGL/Extensions/EXTColorBufferFloat.h>
1919
#include <LibWeb/WebGL/Extensions/EXTRenderSnorm.h>
20+
#include <LibWeb/WebGL/Extensions/EXTTextureFilterAnisotropic.h>
2021
#include <LibWeb/WebGL/Extensions/EXTTextureNorm16.h>
2122
#include <LibWeb/WebGL/Extensions/WebGLCompressedTextureS3tc.h>
2223
#include <LibWeb/WebGL/Extensions/WebGLCompressedTextureS3tcSrgb.h>
@@ -79,6 +80,7 @@ void WebGL2RenderingContext::visit_edges(Cell::Visitor& visitor)
7980
visitor.visit(m_canvas_element);
8081
visitor.visit(m_ext_color_buffer_float_extension);
8182
visitor.visit(m_ext_render_snorm);
83+
visitor.visit(m_ext_texture_filter_anisotropic);
8284
visitor.visit(m_ext_texture_norm16);
8385
visitor.visit(m_webgl_compressed_texture_s3tc_extension);
8486
visitor.visit(m_webgl_compressed_texture_s3tc_srgb_extension);
@@ -206,6 +208,15 @@ JS::Object* WebGL2RenderingContext::get_extension(String const& name)
206208
return m_ext_render_snorm;
207209
}
208210

211+
if (name.equals_ignoring_ascii_case("EXT_texture_filter_anisotropic"sv)) {
212+
if (!m_ext_texture_filter_anisotropic) {
213+
m_ext_texture_filter_anisotropic = MUST(Extensions::EXTTextureFilterAnisotropic::create(realm(), this));
214+
}
215+
216+
VERIFY(m_ext_texture_filter_anisotropic);
217+
return m_ext_texture_filter_anisotropic;
218+
}
219+
209220
if (name.equals_ignoring_ascii_case("EXT_texture_norm16"sv)) {
210221
if (!m_ext_texture_norm16) {
211222
m_ext_texture_norm16 = MUST(Extensions::EXTTextureNorm16::create(realm(), *this));
@@ -230,4 +241,9 @@ WebIDL::Long WebGL2RenderingContext::drawing_buffer_height() const
230241
return size.height();
231242
}
232243

244+
bool WebGL2RenderingContext::ext_texture_filter_anisotropic_extension_enabled() const
245+
{
246+
return !!m_ext_texture_filter_anisotropic;
247+
}
248+
233249
}

Libraries/LibWeb/WebGL/WebGL2RenderingContext.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
namespace Web::WebGL {
1919

20-
class WebGL2RenderingContext : public Bindings::PlatformObject
20+
class WebGL2RenderingContext final : public Bindings::PlatformObject
2121
, public WebGL2RenderingContextImpl {
2222
WEB_PLATFORM_OBJECT(WebGL2RenderingContext, Bindings::PlatformObject);
2323
GC_DECLARE_ALLOCATOR(WebGL2RenderingContext);
@@ -51,6 +51,8 @@ class WebGL2RenderingContext : public Bindings::PlatformObject
5151
WebIDL::Long drawing_buffer_width() const;
5252
WebIDL::Long drawing_buffer_height() const;
5353

54+
virtual bool ext_texture_filter_anisotropic_extension_enabled() const override;
55+
5456
private:
5557
virtual void initialize(JS::Realm&) override;
5658

@@ -84,6 +86,7 @@ class WebGL2RenderingContext : public Bindings::PlatformObject
8486
// "Multiple calls to getExtension with the same extension string, taking into account case-insensitive comparison, must return the same object as long as the extension is enabled."
8587
GC::Ptr<Extensions::EXTColorBufferFloat> m_ext_color_buffer_float_extension;
8688
GC::Ptr<Extensions::EXTRenderSnorm> m_ext_render_snorm;
89+
GC::Ptr<Extensions::EXTTextureFilterAnisotropic> m_ext_texture_filter_anisotropic;
8790
GC::Ptr<Extensions::EXTTextureNorm16> m_ext_texture_norm16;
8891
GC::Ptr<Extensions::WebGLCompressedTextureS3tc> m_webgl_compressed_texture_s3tc_extension;
8992
GC::Ptr<Extensions::WebGLCompressedTextureS3tcSrgb> m_webgl_compressed_texture_s3tc_srgb_extension;

Libraries/LibWeb/WebGL/WebGL2RenderingContextImpl.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define GL_GLEXT_PROTOTYPES 1
99
#include <GLES3/gl3.h>
1010
extern "C" {
11+
#include <GLES2/gl2ext.h>
1112
#include <GLES2/gl2ext_angle.h>
1213
}
1314

@@ -394,6 +395,13 @@ void WebGL2RenderingContextImpl::sampler_parameteri(GC::Root<WebGLSampler> sampl
394395
case GL_TEXTURE_WRAP_S:
395396
case GL_TEXTURE_WRAP_T:
396397
break;
398+
case GL_TEXTURE_MAX_ANISOTROPY_EXT: {
399+
if (ext_texture_filter_anisotropic_extension_enabled())
400+
break;
401+
402+
set_error(GL_INVALID_ENUM);
403+
return;
404+
}
397405
default:
398406
dbgln("Unknown WebGL sampler parameter name: 0x{:04x}", pname);
399407
set_error(GL_INVALID_ENUM);
@@ -427,6 +435,13 @@ void WebGL2RenderingContextImpl::sampler_parameterf(GC::Root<WebGLSampler> sampl
427435
case GL_TEXTURE_WRAP_S:
428436
case GL_TEXTURE_WRAP_T:
429437
break;
438+
case GL_TEXTURE_MAX_ANISOTROPY_EXT: {
439+
if (ext_texture_filter_anisotropic_extension_enabled())
440+
break;
441+
442+
set_error(GL_INVALID_ENUM);
443+
return;
444+
}
430445
default:
431446
dbgln("Unknown WebGL sampler parameter name: 0x{:04x}", pname);
432447
set_error(GL_INVALID_ENUM);
@@ -2571,6 +2586,16 @@ JS::Value WebGL2RenderingContextImpl::get_parameter(WebIDL::UnsignedLong pname)
25712586
glGetInteger64vRobustANGLE(GL_MAX_SERVER_WAIT_TIMEOUT, 1, nullptr, &result);
25722587
return JS::Value(static_cast<double>(result));
25732588
}
2589+
case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: {
2590+
if (ext_texture_filter_anisotropic_extension_enabled()) {
2591+
GLfloat result { 0.0f };
2592+
glGetFloatvRobustANGLE(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, 1, nullptr, &result);
2593+
return JS::Value(result);
2594+
}
2595+
2596+
set_error(GL_INVALID_ENUM);
2597+
return JS::js_null();
2598+
}
25742599
default:
25752600
dbgln("Unknown WebGL parameter name: {:x}", pname);
25762601
set_error(GL_INVALID_ENUM);

Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <LibWeb/WebGL/EventNames.h>
1717
#include <LibWeb/WebGL/Extensions/ANGLEInstancedArrays.h>
1818
#include <LibWeb/WebGL/Extensions/EXTBlendMinMax.h>
19+
#include <LibWeb/WebGL/Extensions/EXTTextureFilterAnisotropic.h>
1920
#include <LibWeb/WebGL/Extensions/OESVertexArrayObject.h>
2021
#include <LibWeb/WebGL/Extensions/WebGLCompressedTextureS3tc.h>
2122
#include <LibWeb/WebGL/Extensions/WebGLCompressedTextureS3tcSrgb.h>
@@ -96,6 +97,7 @@ void WebGLRenderingContext::visit_edges(Cell::Visitor& visitor)
9697
visitor.visit(m_canvas_element);
9798
visitor.visit(m_angle_instanced_arrays_extension);
9899
visitor.visit(m_ext_blend_min_max_extension);
100+
visitor.visit(m_ext_texture_filter_anisotropic);
99101
visitor.visit(m_oes_vertex_array_object_extension);
100102
visitor.visit(m_webgl_compressed_texture_s3tc_extension);
101103
visitor.visit(m_webgl_compressed_texture_s3tc_srgb_extension);
@@ -206,6 +208,15 @@ JS::Object* WebGLRenderingContext::get_extension(String const& name)
206208
return m_ext_blend_min_max_extension;
207209
}
208210

211+
if (name.equals_ignoring_ascii_case("EXT_texture_filter_anisotropic"sv)) {
212+
if (!m_ext_texture_filter_anisotropic) {
213+
m_ext_texture_filter_anisotropic = MUST(Extensions::EXTTextureFilterAnisotropic::create(realm(), this));
214+
}
215+
216+
VERIFY(m_ext_texture_filter_anisotropic);
217+
return m_ext_texture_filter_anisotropic;
218+
}
219+
209220
if (name.equals_ignoring_ascii_case("OES_vertex_array_object"sv)) {
210221
if (!m_oes_vertex_array_object_extension) {
211222
m_oes_vertex_array_object_extension = MUST(Extensions::OESVertexArrayObject::create(realm(), *this));
@@ -257,4 +268,9 @@ WebIDL::Long WebGLRenderingContext::drawing_buffer_height() const
257268
return size.height();
258269
}
259270

271+
bool WebGLRenderingContext::ext_texture_filter_anisotropic_extension_enabled() const
272+
{
273+
return !!m_ext_texture_filter_anisotropic;
274+
}
275+
260276
}

Libraries/LibWeb/WebGL/WebGLRenderingContext.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
namespace Web::WebGL {
1818

19-
class WebGLRenderingContext : public Bindings::PlatformObject
19+
class WebGLRenderingContext final : public Bindings::PlatformObject
2020
, public WebGLRenderingContextImpl {
2121
WEB_PLATFORM_OBJECT(WebGLRenderingContext, Bindings::PlatformObject);
2222
GC_DECLARE_ALLOCATOR(WebGLRenderingContext);
@@ -50,6 +50,8 @@ class WebGLRenderingContext : public Bindings::PlatformObject
5050
WebIDL::Long drawing_buffer_width() const;
5151
WebIDL::Long drawing_buffer_height() const;
5252

53+
virtual bool ext_texture_filter_anisotropic_extension_enabled() const override;
54+
5355
private:
5456
virtual void initialize(JS::Realm&) override;
5557

@@ -83,6 +85,7 @@ class WebGLRenderingContext : public Bindings::PlatformObject
8385
// "Multiple calls to getExtension with the same extension string, taking into account case-insensitive comparison, must return the same object as long as the extension is enabled."
8486
GC::Ptr<Extensions::ANGLEInstancedArrays> m_angle_instanced_arrays_extension;
8587
GC::Ptr<Extensions::EXTBlendMinMax> m_ext_blend_min_max_extension;
88+
GC::Ptr<Extensions::EXTTextureFilterAnisotropic> m_ext_texture_filter_anisotropic;
8689
GC::Ptr<Extensions::OESVertexArrayObject> m_oes_vertex_array_object_extension;
8790
GC::Ptr<Extensions::WebGLCompressedTextureS3tc> m_webgl_compressed_texture_s3tc_extension;
8891
GC::Ptr<Extensions::WebGLCompressedTextureS3tcSrgb> m_webgl_compressed_texture_s3tc_srgb_extension;

0 commit comments

Comments
 (0)