Skip to content
1 change: 1 addition & 0 deletions Libraries/LibWeb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,7 @@ set(SOURCES
WebGL/Extensions/EXTRenderSnorm.cpp
WebGL/Extensions/EXTTextureFilterAnisotropic.cpp
WebGL/Extensions/EXTTextureNorm16.cpp
WebGL/Extensions/OESElementIndexUint.cpp
WebGL/Extensions/OESStandardDerivatives.cpp
WebGL/Extensions/OESVertexArrayObject.cpp
WebGL/Extensions/WebGLCompressedTextureS3tc.cpp
Expand Down
1 change: 1 addition & 0 deletions Libraries/LibWeb/Forward.h
Original file line number Diff line number Diff line change
Expand Up @@ -1254,6 +1254,7 @@ class EXTColorBufferFloat;
class EXTRenderSnorm;
class EXTTextureFilterAnisotropic;
class EXTTextureNorm16;
class OESElementIndexUint;
class OESStandardDerivatives;
class OESVertexArrayObject;
class WebGLCompressedTextureS3tc;
Expand Down
42 changes: 42 additions & 0 deletions Libraries/LibWeb/WebGL/Extensions/OESElementIndexUint.cpp
Original file line number Diff line number Diff line change
@@ -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/OESElementIndexUintPrototype.h>
#include <LibWeb/WebGL/Extensions/OESElementIndexUint.h>
#include <LibWeb/WebGL/OpenGLContext.h>
#include <LibWeb/WebGL/WebGLRenderingContext.h>

namespace Web::WebGL::Extensions {

GC_DEFINE_ALLOCATOR(OESElementIndexUint);

JS::ThrowCompletionOr<GC::Ptr<OESElementIndexUint>> OESElementIndexUint::create(JS::Realm& realm, GC::Ref<WebGLRenderingContext> context)
{
return realm.create<OESElementIndexUint>(realm, context);
}

OESElementIndexUint::OESElementIndexUint(JS::Realm& realm, GC::Ref<WebGLRenderingContext> context)
: PlatformObject(realm)
, m_context(context)
{
m_context->context().request_extension("GL_OES_element_index_uint");
}

void OESElementIndexUint::initialize(JS::Realm& realm)
{
WEB_SET_PROTOTYPE_FOR_INTERFACE(OESElementIndexUint);
Base::initialize(realm);
}

void OESElementIndexUint::visit_edges(Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_context);
}

}
31 changes: 31 additions & 0 deletions Libraries/LibWeb/WebGL/Extensions/OESElementIndexUint.h
Original file line number Diff line number Diff line change
@@ -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 OESElementIndexUint : public Bindings::PlatformObject {
WEB_PLATFORM_OBJECT(OESElementIndexUint, Bindings::PlatformObject);
GC_DECLARE_ALLOCATOR(OESElementIndexUint);

public:
static JS::ThrowCompletionOr<GC::Ptr<OESElementIndexUint>> create(JS::Realm&, GC::Ref<WebGLRenderingContext>);

protected:
void initialize(JS::Realm&) override;
void visit_edges(Visitor&) override;

private:
OESElementIndexUint(JS::Realm&, GC::Ref<WebGLRenderingContext>);

GC::Ref<WebGLRenderingContext> m_context;
};

}
9 changes: 9 additions & 0 deletions Libraries/LibWeb/WebGL/Extensions/OESElementIndexUint.idl
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// https://registry.khronos.org/webgl/extensions/OES_element_index_uint/
// NOTE: Original OES_element_index_uint 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 OESElementIndexUint {
};
2 changes: 1 addition & 1 deletion Libraries/LibWeb/WebGL/WebGL2RenderingContextBase.idl
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@ interface mixin WebGL2RenderingContextBase {
[FIXME] GLboolean isQuery(WebGLQuery? query); // [WebGLHandlesContextLoss]
undefined beginQuery(GLenum target, WebGLQuery query);
undefined endQuery(GLenum target);
[FIXME] WebGLQuery? getQuery(GLenum target, GLenum pname);
WebGLQuery? getQuery(GLenum target, GLenum pname);
any getQueryParameter(WebGLQuery query, GLenum pname);

// Sampler Objects
Expand Down
45 changes: 45 additions & 0 deletions Libraries/LibWeb/WebGL/WebGL2RenderingContextImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,15 +661,60 @@ void WebGL2RenderingContextImpl::begin_query(WebIDL::UnsignedLong target, GC::Ro
query_handle = handle_or_error.release_value();
}

switch (target) {
case GL_ANY_SAMPLES_PASSED:
m_any_samples_passed = query;
break;
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
m_any_samples_passed_conservative = query;
break;
case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
m_transform_feedback_primitives_written = query;
break;
}

glBeginQuery(target, query_handle);
}

void WebGL2RenderingContextImpl::end_query(WebIDL::UnsignedLong target)
{
m_context->make_current();

switch (target) {
case GL_ANY_SAMPLES_PASSED:
m_any_samples_passed = nullptr;
break;
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
m_any_samples_passed_conservative = nullptr;
break;
case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
m_transform_feedback_primitives_written = nullptr;
break;
}

glEndQuery(target);
}

GC::Root<WebGLQuery> WebGL2RenderingContextImpl::get_query(WebIDL::UnsignedLong target, WebIDL::UnsignedLong pname)
{
if (pname != GL_CURRENT_QUERY) {
set_error(GL_INVALID_ENUM);
return nullptr;
}

switch (target) {
case GL_ANY_SAMPLES_PASSED:
return m_any_samples_passed;
case GL_ANY_SAMPLES_PASSED_CONSERVATIVE:
return m_any_samples_passed_conservative;
case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
return m_transform_feedback_primitives_written;
}

set_error(GL_INVALID_ENUM);
return nullptr;
}

JS::Value WebGL2RenderingContextImpl::get_query_parameter(GC::Root<WebGLQuery> query, WebIDL::UnsignedLong pname)
{
m_context->make_current();
Expand Down
1 change: 1 addition & 0 deletions Libraries/LibWeb/WebGL/WebGL2RenderingContextImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class WebGL2RenderingContextImpl : public WebGLRenderingContextImpl {
void delete_query(GC::Root<WebGLQuery> query);
void begin_query(WebIDL::UnsignedLong target, GC::Root<WebGLQuery> query);
void end_query(WebIDL::UnsignedLong target);
GC::Root<WebGLQuery> get_query(WebIDL::UnsignedLong target, WebIDL::UnsignedLong pname);
JS::Value get_query_parameter(GC::Root<WebGLQuery> query, WebIDL::UnsignedLong pname);
GC::Root<WebGLSampler> create_sampler();
void delete_sampler(GC::Root<WebGLSampler> sampler);
Expand Down
1 change: 1 addition & 0 deletions Libraries/LibWeb/WebGL/WebGL2RenderingContextOverloads.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,7 @@ void WebGL2RenderingContextOverloads::read_pixels(WebIDL::Long x, WebIDL::Long y
m_context->make_current();

if (!pixels) {
set_error(GL_INVALID_VALUE);
return;
}

Expand Down
11 changes: 11 additions & 0 deletions Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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/OESElementIndexUint.h>
#include <LibWeb/WebGL/Extensions/OESStandardDerivatives.h>
#include <LibWeb/WebGL/Extensions/OESVertexArrayObject.h>
#include <LibWeb/WebGL/Extensions/WebGLCompressedTextureS3tc.h>
Expand Down Expand Up @@ -99,6 +100,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_element_index_uint_object_extension);
visitor.visit(m_oes_standard_derivatives_object_extension);
visitor.visit(m_oes_vertex_array_object_extension);
visitor.visit(m_webgl_compressed_texture_s3tc_extension);
Expand Down Expand Up @@ -210,6 +212,15 @@ JS::Object* WebGLRenderingContext::get_extension(String const& name)
return m_ext_texture_filter_anisotropic;
}

if (name.equals_ignoring_ascii_case("OES_element_index_uint"sv)) {
if (!m_oes_element_index_uint_object_extension) {
m_oes_element_index_uint_object_extension = MUST(Extensions::OESElementIndexUint::create(realm(), *this));
}

VERIFY(m_oes_element_index_uint_object_extension);
return m_oes_element_index_uint_object_extension;
}

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));
Expand Down
1 change: 1 addition & 0 deletions Libraries/LibWeb/WebGL/WebGLRenderingContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ class WebGLRenderingContext final : public Bindings::PlatformObject
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::OESElementIndexUint> m_oes_element_index_uint_object_extension;
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;
Expand Down
11 changes: 11 additions & 0 deletions Libraries/LibWeb/WebGL/WebGLRenderingContextBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ namespace Web::WebGL {
static constexpr int COMPRESSED_TEXTURE_FORMATS = 0x86A3;
static constexpr int UNPACK_FLIP_Y_WEBGL = 0x9240;
static constexpr int UNPACK_PREMULTIPLY_ALPHA_WEBGL = 0x9241;
static constexpr int UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
static constexpr int BROWSER_DEFAULT_WEBGL = 0x9244;
static constexpr int MAX_CLIENT_WAIT_TIMEOUT_WEBGL = 0x9247;

// NOTE: This is the Variant created by the IDL wrapper generator, and needs to be updated accordingly.
Expand Down Expand Up @@ -151,6 +153,15 @@ class WebGLRenderingContextBase {
// Any non-zero value is interpreted as true.
bool m_unpack_premultiply_alpha { false };

// UNPACK_COLORSPACE_CONVERSION_WEBGL of type unsigned long
// If set to BROWSER_DEFAULT_WEBGL, then the browser's default colorspace conversion (e.g. converting a display-p3
// image to srgb) is applied during subsequent texture data upload calls (e.g. texImage2D and texSubImage2D) that
// take an argument of TexImageSource. The precise conversions may be specific to both the browser and file type.
// If set to NONE, no colorspace conversion is applied, other than conversion to RGBA. (For example, a rec709 YUV
// video is still converted to rec709 RGB data, but not then converted to e.g. srgb RGB data) The initial value is
// BROWSER_DEFAULT_WEBGL.
GLenum m_unpack_colorspace_conversion { BROWSER_DEFAULT_WEBGL };

private:
GLenum m_error { 0 };
};
Expand Down
2 changes: 1 addition & 1 deletion Libraries/LibWeb/WebGL/WebGLRenderingContextBase.idl
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ interface mixin WebGLRenderingContextBase {

DOMString? getShaderSource(WebGLShader shader);

[FIXME] any getTexParameter(GLenum target, GLenum pname);
any getTexParameter(GLenum target, GLenum pname);

any getUniform(WebGLProgram program, WebGLUniformLocation location);

Expand Down
Loading
Loading