diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index 2a35012bdc3..2c0ec8c0a1f 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -804,6 +804,7 @@ set(SOURCES WebDriver/TimeoutsConfiguration.cpp WebGL/EventNames.cpp WebGL/OpenGLContext.cpp + WebGL/WebGL2RenderingContext.cpp WebGL/WebGLActiveInfo.cpp WebGL/WebGLBuffer.cpp WebGL/WebGLContextAttributes.cpp @@ -871,6 +872,18 @@ invoke_generator( dependencies WebGL/WebGLRenderingContextBase.idl WebGL/WebGLRenderingContextOverloads.idl CSS/GeneratedCSSStyleProperties.idl ) +invoke_generator( + "WebGL2RenderingContextImpl.cpp" + Lagom::GenerateWebGLRenderingContext + "${CMAKE_CURRENT_SOURCE_DIR}/WebGL/WebGL2RenderingContextBase.idl" + "WebGL/WebGL2RenderingContextImpl.h" + "WebGL/WebGL2RenderingContextImpl.cpp" + arguments -b "${CMAKE_CURRENT_SOURCE_DIR}" -b "${CMAKE_CURRENT_BINARY_DIR}" -i "${CMAKE_CURRENT_SOURCE_DIR}/WebGL/WebGL2RenderingContext.idl" + # NOTE: GeneratedCSSStyleProperties.idl is listed because it's transitively included by WebGLRenderingContextBase.idl + # and we need to make sure it's generated before we generate the WebGLRenderingContext implementation. + dependencies WebGL/WebGL2RenderingContextBase.idl WebGL/WebGL2RenderingContextOverloads.idl WebGL/WebGLRenderingContextBase.idl WebGL/WebGLRenderingContextOverloads.idl CSS/GeneratedCSSStyleProperties.idl +) + set(GENERATED_SOURCES ARIA/AriaRoles.cpp CSS/DefaultStyleSheetSource.cpp @@ -886,6 +899,7 @@ set(GENERATED_SOURCES CSS/TransformFunctions.cpp MathML/MathMLStyleSheetSource.cpp SVG/SVGStyleSheetSource.cpp + WebGL/WebGL2RenderingContextImpl.cpp WebGL/WebGLRenderingContextImpl.cpp Worker/WebWorkerClientEndpoint.h Worker/WebWorkerServerEndpoint.h diff --git a/Libraries/LibWeb/Forward.h b/Libraries/LibWeb/Forward.h index 91174df843e..b4332cf8850 100644 --- a/Libraries/LibWeb/Forward.h +++ b/Libraries/LibWeb/Forward.h @@ -832,6 +832,7 @@ struct OscillatorOptions; namespace Web::WebGL { class OpenGLContext; +class WebGL2RenderingContext; class WebGLActiveInfo; class WebGLBuffer; class WebGLContextEvent; diff --git a/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp b/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp index 05e9cb80bcf..0b3a630d437 100644 --- a/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -57,6 +58,9 @@ void HTMLCanvasElement::visit_edges(Cell::Visitor& visitor) [&](GC::Ref& context) { visitor.visit(context); }, + [&](GC::Ref& context) { + visitor.visit(context); + }, [](Empty) { }); } @@ -124,6 +128,9 @@ void HTMLCanvasElement::reset_context_to_default_state() [](GC::Ref& context) { context->reset_to_default_state(); }, + [](GC::Ref& context) { + context->reset_to_default_state(); + }, [](Empty) { // Do nothing. }); @@ -138,6 +145,9 @@ void HTMLCanvasElement::notify_context_about_canvas_size_change() [&](GC::Ref& context) { context->set_size(bitmap_size_for_canvas()); }, + [&](GC::Ref& context) { + context->set_size(bitmap_size_for_canvas()); + }, [](Empty) { // Do nothing. }); @@ -186,16 +196,17 @@ HTMLCanvasElement::HasOrCreatedContext HTMLCanvasElement::create_2d_context() return HasOrCreatedContext::Yes; } +template JS::ThrowCompletionOr HTMLCanvasElement::create_webgl_context(JS::Value options) { if (!m_context.has()) - return m_context.has>() ? HasOrCreatedContext::Yes : HasOrCreatedContext::No; + return m_context.has>() ? HasOrCreatedContext::Yes : HasOrCreatedContext::No; - auto maybe_context = TRY(WebGL::WebGLRenderingContext::create(realm(), *this, options)); + auto maybe_context = TRY(ContextType::create(realm(), *this, options)); if (!maybe_context) return HasOrCreatedContext::No; - m_context = GC::Ref(*maybe_context); + m_context = GC::Ref(*maybe_context); return HasOrCreatedContext::Yes; } @@ -220,12 +231,19 @@ JS::ThrowCompletionOr HTMLCanvasElement::ge // NOTE: The WebGL spec says "experimental-webgl" is also acceptable and must be equivalent to "webgl". Other engines accept this, so we do too. if (type.is_one_of("webgl"sv, "experimental-webgl"sv)) { - if (TRY(create_webgl_context(options)) == HasOrCreatedContext::Yes) + if (TRY(create_webgl_context(options)) == HasOrCreatedContext::Yes) return GC::make_root(*m_context.get>()); return Empty {}; } + if (type == "webgl2"sv) { + if (TRY(create_webgl_context(options)) == HasOrCreatedContext::Yes) + return GC::make_root(*m_context.get>()); + + return Empty {}; + } + return Empty {}; } @@ -380,6 +398,9 @@ void HTMLCanvasElement::present() [](GC::Ref& context) { context->present(); }, + [](GC::Ref& context) { + context->present(); + }, [](Empty) { // Do nothing. }); @@ -394,6 +415,9 @@ RefPtr HTMLCanvasElement::surface() const [&](GC::Ref const& context) -> RefPtr { return context->surface(); }, + [&](GC::Ref const& context) -> RefPtr { + return context->surface(); + }, [](Empty) -> RefPtr { return {}; }); @@ -408,6 +432,9 @@ void HTMLCanvasElement::allocate_painting_surface_if_needed() [&](GC::Ref& context) { context->allocate_painting_surface_if_needed(); }, + [&](GC::Ref& context) { + context->allocate_painting_surface_if_needed(); + }, [](Empty) { // Do nothing. }); diff --git a/Libraries/LibWeb/HTML/HTMLCanvasElement.h b/Libraries/LibWeb/HTML/HTMLCanvasElement.h index d59059be942..2da8e73f71a 100644 --- a/Libraries/LibWeb/HTML/HTMLCanvasElement.h +++ b/Libraries/LibWeb/HTML/HTMLCanvasElement.h @@ -19,7 +19,7 @@ class HTMLCanvasElement final : public HTMLElement { GC_DECLARE_ALLOCATOR(HTMLCanvasElement); public: - using RenderingContext = Variant, GC::Root, Empty>; + using RenderingContext = Variant, GC::Root, GC::Root, Empty>; virtual ~HTMLCanvasElement() override; @@ -57,11 +57,12 @@ private: virtual GC::Ptr create_layout_node(CSS::StyleProperties) override; virtual void adjust_computed_style(CSS::StyleProperties&) override; + template JS::ThrowCompletionOr create_webgl_context(JS::Value options); void reset_context_to_default_state(); void notify_context_about_canvas_size_change(); - Variant, GC::Ref, Empty> m_context; + Variant, GC::Ref, GC::Ref, Empty> m_context; }; } diff --git a/Libraries/LibWeb/HTML/HTMLCanvasElement.idl b/Libraries/LibWeb/HTML/HTMLCanvasElement.idl index 4c18314788c..e77bc06c73d 100644 --- a/Libraries/LibWeb/HTML/HTMLCanvasElement.idl +++ b/Libraries/LibWeb/HTML/HTMLCanvasElement.idl @@ -2,8 +2,9 @@ #import #import #import +#import -typedef (CanvasRenderingContext2D or WebGLRenderingContext) RenderingContext; +typedef (CanvasRenderingContext2D or WebGLRenderingContext or WebGL2RenderingContext) RenderingContext; // https://html.spec.whatwg.org/multipage/semantics.html#htmlcanvaselement [Exposed=Window] diff --git a/Libraries/LibWeb/WebGL/WebGL2RenderingContext.cpp b/Libraries/LibWeb/WebGL/WebGL2RenderingContext.cpp new file mode 100644 index 00000000000..01e647aa56a --- /dev/null +++ b/Libraries/LibWeb/WebGL/WebGL2RenderingContext.cpp @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2022, Luke Wilde + * Copyright (c) 2024, Andrew Kaster + * Copyright (c) 2023, Aliaksandr Kalenik + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace Web::WebGL { + +GC_DEFINE_ALLOCATOR(WebGL2RenderingContext); + +JS::ThrowCompletionOr> WebGL2RenderingContext::create(JS::Realm& realm, HTML::HTMLCanvasElement& canvas_element, JS::Value options) +{ + // We should be coming here from getContext being called on a wrapped element. + auto context_attributes = TRY(convert_value_to_context_attributes_dictionary(canvas_element.vm(), options)); + + auto skia_backend_context = canvas_element.navigable()->traversable_navigable()->skia_backend_context(); + if (!skia_backend_context) { + fire_webgl_context_creation_error(canvas_element); + return GC::Ptr { nullptr }; + } + auto context = OpenGLContext::create(*skia_backend_context); + if (!context) { + fire_webgl_context_creation_error(canvas_element); + return GC::Ptr { nullptr }; + } + + context->set_size(canvas_element.bitmap_size_for_canvas(1, 1)); + + return realm.create(realm, canvas_element, context.release_nonnull(), context_attributes, context_attributes); +} + +WebGL2RenderingContext::WebGL2RenderingContext(JS::Realm& realm, HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters) + : PlatformObject(realm) + , WebGL2RenderingContextImpl(realm, move(context)) + , m_canvas_element(canvas_element) + , m_context_creation_parameters(context_creation_parameters) + , m_actual_context_parameters(actual_context_parameters) +{ +} + +WebGL2RenderingContext::~WebGL2RenderingContext() = default; + +void WebGL2RenderingContext::initialize(JS::Realm& realm) +{ + Base::initialize(realm); + WEB_SET_PROTOTYPE_FOR_INTERFACE(WebGL2RenderingContext); +} + +void WebGL2RenderingContext::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_canvas_element); +} + +void WebGL2RenderingContext::present() +{ + if (!m_should_present) + return; + + m_should_present = false; + + // "Before the drawing buffer is presented for compositing the implementation shall ensure that all rendering operations have been flushed to the drawing buffer." + glFlush(); + + // "By default, after compositing the contents of the drawing buffer shall be cleared to their default values, as shown in the table above. + // This default behavior can be changed by setting the preserveDrawingBuffer attribute of the WebGLContextAttributes object. + // If this flag is true, the contents of the drawing buffer shall be preserved until the author either clears or overwrites them." + if (!m_context_creation_parameters.preserve_drawing_buffer) { + context().clear_buffer_to_default_values(); + } +} + +GC::Ref WebGL2RenderingContext::canvas_for_binding() const +{ + return *m_canvas_element; +} + +void WebGL2RenderingContext::needs_to_present() +{ + m_should_present = true; + + if (!m_canvas_element->paintable()) + return; + m_canvas_element->paintable()->set_needs_display(); +} + +void WebGL2RenderingContext::set_error(GLenum error) +{ + auto context_error = glGetError(); + if (context_error != GL_NO_ERROR) + m_error = context_error; + else + m_error = error; +} + +bool WebGL2RenderingContext::is_context_lost() const +{ + dbgln_if(WEBGL_CONTEXT_DEBUG, "WebGLRenderingContext::is_context_lost()"); + return m_context_lost; +} + +Optional WebGL2RenderingContext::get_context_attributes() +{ + if (is_context_lost()) + return {}; + return m_actual_context_parameters; +} + +void WebGL2RenderingContext::set_size(Gfx::IntSize const& size) +{ + context().set_size(size); +} + +void WebGL2RenderingContext::reset_to_default_state() +{ +} + +RefPtr WebGL2RenderingContext::surface() +{ + return context().surface(); +} + +void WebGL2RenderingContext::allocate_painting_surface_if_needed() +{ + context().allocate_painting_surface_if_needed(); +} + +Optional> WebGL2RenderingContext::get_supported_extensions() const +{ + return {}; +} + +JS::Object* WebGL2RenderingContext::get_extension(String const&) +{ + return nullptr; +} + +} diff --git a/Libraries/LibWeb/WebGL/WebGL2RenderingContext.h b/Libraries/LibWeb/WebGL/WebGL2RenderingContext.h new file mode 100644 index 00000000000..ccff8b9b04c --- /dev/null +++ b/Libraries/LibWeb/WebGL/WebGL2RenderingContext.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2022, Luke Wilde + * Copyright (c) 2024, Andrew Kaster + * Copyright (c) 2024, Aliaksandr Kalenik + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace Web::WebGL { + +class WebGL2RenderingContext : public Bindings::PlatformObject + , public WebGL2RenderingContextImpl { + WEB_PLATFORM_OBJECT(WebGL2RenderingContext, Bindings::PlatformObject); + GC_DECLARE_ALLOCATOR(WebGL2RenderingContext); + +public: + static JS::ThrowCompletionOr> create(JS::Realm&, HTML::HTMLCanvasElement& canvas_element, JS::Value options); + + virtual ~WebGL2RenderingContext() override; + + void present() override; + void needs_to_present() override; + + GC::Ref canvas_for_binding() const; + + bool is_context_lost() const; + Optional get_context_attributes(); + + RefPtr surface(); + void allocate_painting_surface_if_needed(); + + void set_size(Gfx::IntSize const&); + void reset_to_default_state(); + + Optional> get_supported_extensions() const; + JS::Object* get_extension(String const& name); + +private: + virtual void initialize(JS::Realm&) override; + + WebGL2RenderingContext(JS::Realm&, HTML::HTMLCanvasElement&, NonnullOwnPtr context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters); + + virtual void visit_edges(Cell::Visitor&) override; + + GC::Ref m_canvas_element; + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#context-creation-parameters + // Each WebGLRenderingContext has context creation parameters, set upon creation, in a WebGLContextAttributes object. + WebGLContextAttributes m_context_creation_parameters {}; + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#actual-context-parameters + // Each WebGLRenderingContext has actual context parameters, set each time the drawing buffer is created, in a WebGLContextAttributes object. + WebGLContextAttributes m_actual_context_parameters {}; + + // https://www.khronos.org/registry/webgl/specs/latest/1.0/#webgl-context-lost-flag + // Each WebGLRenderingContext has a webgl context lost flag, which is initially unset. + bool m_context_lost { false }; + + // WebGL presents its drawing buffer to the HTML page compositor immediately before a compositing operation, but only if at least one of the following has occurred since the previous compositing operation: + // - Context creation + // - Canvas resize + // - clear, drawArrays, or drawElements has been called while the drawing buffer is the currently bound framebuffer + bool m_should_present { true }; + + GLenum m_error { 0 }; + + void set_error(GLenum error); +}; + +} diff --git a/Libraries/LibWeb/WebGL/WebGL2RenderingContext.idl b/Libraries/LibWeb/WebGL/WebGL2RenderingContext.idl new file mode 100644 index 00000000000..50c4242ef52 --- /dev/null +++ b/Libraries/LibWeb/WebGL/WebGL2RenderingContext.idl @@ -0,0 +1,13 @@ +#import +#import +#import +#import + +// https://registry.khronos.org/webgl/specs/latest/2.0/#3.7 +[Exposed=(Window,Worker)] +interface WebGL2RenderingContext { +}; + +WebGL2RenderingContext includes WebGLRenderingContextBase; +WebGL2RenderingContext includes WebGL2RenderingContextBase; +WebGL2RenderingContext includes WebGL2RenderingContextOverloads; diff --git a/Libraries/LibWeb/WebGL/WebGL2RenderingContextBase.idl b/Libraries/LibWeb/WebGL/WebGL2RenderingContextBase.idl new file mode 100644 index 00000000000..db151c24ec9 --- /dev/null +++ b/Libraries/LibWeb/WebGL/WebGL2RenderingContextBase.idl @@ -0,0 +1,433 @@ +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +// FIXME: BufferSource should be a Uint32Array +typedef (BufferSource or sequence) Uint32List; + +// https://registry.khronos.org/webgl/specs/latest/2.0/#3.7 +interface mixin WebGL2RenderingContextBase { + // Same note as WebGLRenderingContextBase: + // Functions that have the [WebGLHandlesContextLoss] extended attribute in the spec do not have them here. + + const GLenum READ_BUFFER = 0x0C02; + const GLenum UNPACK_ROW_LENGTH = 0x0CF2; + const GLenum UNPACK_SKIP_ROWS = 0x0CF3; + const GLenum UNPACK_SKIP_PIXELS = 0x0CF4; + const GLenum PACK_ROW_LENGTH = 0x0D02; + const GLenum PACK_SKIP_ROWS = 0x0D03; + const GLenum PACK_SKIP_PIXELS = 0x0D04; + const GLenum COLOR = 0x1800; + const GLenum DEPTH = 0x1801; + const GLenum STENCIL = 0x1802; + const GLenum RED = 0x1903; + const GLenum RGB8 = 0x8051; + const GLenum RGB10_A2 = 0x8059; + const GLenum TEXTURE_BINDING_3D = 0x806A; + const GLenum UNPACK_SKIP_IMAGES = 0x806D; + const GLenum UNPACK_IMAGE_HEIGHT = 0x806E; + const GLenum TEXTURE_3D = 0x806F; + const GLenum TEXTURE_WRAP_R = 0x8072; + const GLenum MAX_3D_TEXTURE_SIZE = 0x8073; + const GLenum UNSIGNED_INT_2_10_10_10_REV = 0x8368; + const GLenum MAX_ELEMENTS_VERTICES = 0x80E8; + const GLenum MAX_ELEMENTS_INDICES = 0x80E9; + const GLenum TEXTURE_MIN_LOD = 0x813A; + const GLenum TEXTURE_MAX_LOD = 0x813B; + const GLenum TEXTURE_BASE_LEVEL = 0x813C; + const GLenum TEXTURE_MAX_LEVEL = 0x813D; + const GLenum MIN = 0x8007; + const GLenum MAX = 0x8008; + const GLenum DEPTH_COMPONENT24 = 0x81A6; + const GLenum MAX_TEXTURE_LOD_BIAS = 0x84FD; + const GLenum TEXTURE_COMPARE_MODE = 0x884C; + const GLenum TEXTURE_COMPARE_FUNC = 0x884D; + const GLenum CURRENT_QUERY = 0x8865; + const GLenum QUERY_RESULT = 0x8866; + const GLenum QUERY_RESULT_AVAILABLE = 0x8867; + const GLenum STREAM_READ = 0x88E1; + const GLenum STREAM_COPY = 0x88E2; + const GLenum STATIC_READ = 0x88E5; + const GLenum STATIC_COPY = 0x88E6; + const GLenum DYNAMIC_READ = 0x88E9; + const GLenum DYNAMIC_COPY = 0x88EA; + const GLenum MAX_DRAW_BUFFERS = 0x8824; + const GLenum DRAW_BUFFER0 = 0x8825; + const GLenum DRAW_BUFFER1 = 0x8826; + const GLenum DRAW_BUFFER2 = 0x8827; + const GLenum DRAW_BUFFER3 = 0x8828; + const GLenum DRAW_BUFFER4 = 0x8829; + const GLenum DRAW_BUFFER5 = 0x882A; + const GLenum DRAW_BUFFER6 = 0x882B; + const GLenum DRAW_BUFFER7 = 0x882C; + const GLenum DRAW_BUFFER8 = 0x882D; + const GLenum DRAW_BUFFER9 = 0x882E; + const GLenum DRAW_BUFFER10 = 0x882F; + const GLenum DRAW_BUFFER11 = 0x8830; + const GLenum DRAW_BUFFER12 = 0x8831; + const GLenum DRAW_BUFFER13 = 0x8832; + const GLenum DRAW_BUFFER14 = 0x8833; + const GLenum DRAW_BUFFER15 = 0x8834; + const GLenum MAX_FRAGMENT_UNIFORM_COMPONENTS = 0x8B49; + const GLenum MAX_VERTEX_UNIFORM_COMPONENTS = 0x8B4A; + const GLenum SAMPLER_3D = 0x8B5F; + const GLenum SAMPLER_2D_SHADOW = 0x8B62; + const GLenum FRAGMENT_SHADER_DERIVATIVE_HINT = 0x8B8B; + const GLenum PIXEL_PACK_BUFFER = 0x88EB; + const GLenum PIXEL_UNPACK_BUFFER = 0x88EC; + const GLenum PIXEL_PACK_BUFFER_BINDING = 0x88ED; + const GLenum PIXEL_UNPACK_BUFFER_BINDING = 0x88EF; + const GLenum FLOAT_MAT2x3 = 0x8B65; + const GLenum FLOAT_MAT2x4 = 0x8B66; + const GLenum FLOAT_MAT3x2 = 0x8B67; + const GLenum FLOAT_MAT3x4 = 0x8B68; + const GLenum FLOAT_MAT4x2 = 0x8B69; + const GLenum FLOAT_MAT4x3 = 0x8B6A; + const GLenum SRGB = 0x8C40; + const GLenum SRGB8 = 0x8C41; + const GLenum SRGB8_ALPHA8 = 0x8C43; + const GLenum COMPARE_REF_TO_TEXTURE = 0x884E; + const GLenum RGBA32F = 0x8814; + const GLenum RGB32F = 0x8815; + const GLenum RGBA16F = 0x881A; + const GLenum RGB16F = 0x881B; + const GLenum VERTEX_ATTRIB_ARRAY_INTEGER = 0x88FD; + const GLenum MAX_ARRAY_TEXTURE_LAYERS = 0x88FF; + const GLenum MIN_PROGRAM_TEXEL_OFFSET = 0x8904; + const GLenum MAX_PROGRAM_TEXEL_OFFSET = 0x8905; + const GLenum MAX_VARYING_COMPONENTS = 0x8B4B; + const GLenum TEXTURE_2D_ARRAY = 0x8C1A; + const GLenum TEXTURE_BINDING_2D_ARRAY = 0x8C1D; + const GLenum R11F_G11F_B10F = 0x8C3A; + const GLenum UNSIGNED_INT_10F_11F_11F_REV = 0x8C3B; + const GLenum RGB9_E5 = 0x8C3D; + const GLenum UNSIGNED_INT_5_9_9_9_REV = 0x8C3E; + const GLenum TRANSFORM_FEEDBACK_BUFFER_MODE = 0x8C7F; + const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS = 0x8C80; + const GLenum TRANSFORM_FEEDBACK_VARYINGS = 0x8C83; + const GLenum TRANSFORM_FEEDBACK_BUFFER_START = 0x8C84; + const GLenum TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85; + const GLenum TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN = 0x8C88; + const GLenum RASTERIZER_DISCARD = 0x8C89; + const GLenum MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS = 0x8C8A; + const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B; + const GLenum INTERLEAVED_ATTRIBS = 0x8C8C; + const GLenum SEPARATE_ATTRIBS = 0x8C8D; + const GLenum TRANSFORM_FEEDBACK_BUFFER = 0x8C8E; + const GLenum TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8C8F; + const GLenum RGBA32UI = 0x8D70; + const GLenum RGB32UI = 0x8D71; + const GLenum RGBA16UI = 0x8D76; + const GLenum RGB16UI = 0x8D77; + const GLenum RGBA8UI = 0x8D7C; + const GLenum RGB8UI = 0x8D7D; + const GLenum RGBA32I = 0x8D82; + const GLenum RGB32I = 0x8D83; + const GLenum RGBA16I = 0x8D88; + const GLenum RGB16I = 0x8D89; + const GLenum RGBA8I = 0x8D8E; + const GLenum RGB8I = 0x8D8F; + const GLenum RED_INTEGER = 0x8D94; + const GLenum RGB_INTEGER = 0x8D98; + const GLenum RGBA_INTEGER = 0x8D99; + const GLenum SAMPLER_2D_ARRAY = 0x8DC1; + const GLenum SAMPLER_2D_ARRAY_SHADOW = 0x8DC4; + const GLenum SAMPLER_CUBE_SHADOW = 0x8DC5; + const GLenum UNSIGNED_INT_VEC2 = 0x8DC6; + const GLenum UNSIGNED_INT_VEC3 = 0x8DC7; + const GLenum UNSIGNED_INT_VEC4 = 0x8DC8; + const GLenum INT_SAMPLER_2D = 0x8DCA; + const GLenum INT_SAMPLER_3D = 0x8DCB; + const GLenum INT_SAMPLER_CUBE = 0x8DCC; + const GLenum INT_SAMPLER_2D_ARRAY = 0x8DCF; + const GLenum UNSIGNED_INT_SAMPLER_2D = 0x8DD2; + const GLenum UNSIGNED_INT_SAMPLER_3D = 0x8DD3; + const GLenum UNSIGNED_INT_SAMPLER_CUBE = 0x8DD4; + const GLenum UNSIGNED_INT_SAMPLER_2D_ARRAY = 0x8DD7; + const GLenum DEPTH_COMPONENT32F = 0x8CAC; + const GLenum DEPTH32F_STENCIL8 = 0x8CAD; + const GLenum FLOAT_32_UNSIGNED_INT_24_8_REV = 0x8DAD; + const GLenum FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING = 0x8210; + const GLenum FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE = 0x8211; + const GLenum FRAMEBUFFER_ATTACHMENT_RED_SIZE = 0x8212; + const GLenum FRAMEBUFFER_ATTACHMENT_GREEN_SIZE = 0x8213; + const GLenum FRAMEBUFFER_ATTACHMENT_BLUE_SIZE = 0x8214; + const GLenum FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE = 0x8215; + const GLenum FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE = 0x8216; + const GLenum FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE = 0x8217; + const GLenum FRAMEBUFFER_DEFAULT = 0x8218; + const GLenum UNSIGNED_INT_24_8 = 0x84FA; + const GLenum DEPTH24_STENCIL8 = 0x88F0; + const GLenum UNSIGNED_NORMALIZED = 0x8C17; + const GLenum DRAW_FRAMEBUFFER_BINDING = 0x8CA6; // Same as FRAMEBUFFER_BINDING + const GLenum READ_FRAMEBUFFER = 0x8CA8; + const GLenum DRAW_FRAMEBUFFER = 0x8CA9; + const GLenum READ_FRAMEBUFFER_BINDING = 0x8CAA; + const GLenum RENDERBUFFER_SAMPLES = 0x8CAB; + const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER = 0x8CD4; + const GLenum MAX_COLOR_ATTACHMENTS = 0x8CDF; + const GLenum COLOR_ATTACHMENT1 = 0x8CE1; + const GLenum COLOR_ATTACHMENT2 = 0x8CE2; + const GLenum COLOR_ATTACHMENT3 = 0x8CE3; + const GLenum COLOR_ATTACHMENT4 = 0x8CE4; + const GLenum COLOR_ATTACHMENT5 = 0x8CE5; + const GLenum COLOR_ATTACHMENT6 = 0x8CE6; + const GLenum COLOR_ATTACHMENT7 = 0x8CE7; + const GLenum COLOR_ATTACHMENT8 = 0x8CE8; + const GLenum COLOR_ATTACHMENT9 = 0x8CE9; + const GLenum COLOR_ATTACHMENT10 = 0x8CEA; + const GLenum COLOR_ATTACHMENT11 = 0x8CEB; + const GLenum COLOR_ATTACHMENT12 = 0x8CEC; + const GLenum COLOR_ATTACHMENT13 = 0x8CED; + const GLenum COLOR_ATTACHMENT14 = 0x8CEE; + const GLenum COLOR_ATTACHMENT15 = 0x8CEF; + const GLenum FRAMEBUFFER_INCOMPLETE_MULTISAMPLE = 0x8D56; + const GLenum MAX_SAMPLES = 0x8D57; + const GLenum HALF_FLOAT = 0x140B; + const GLenum RG = 0x8227; + const GLenum RG_INTEGER = 0x8228; + const GLenum R8 = 0x8229; + const GLenum RG8 = 0x822B; + const GLenum R16F = 0x822D; + const GLenum R32F = 0x822E; + const GLenum RG16F = 0x822F; + const GLenum RG32F = 0x8230; + const GLenum R8I = 0x8231; + const GLenum R8UI = 0x8232; + const GLenum R16I = 0x8233; + const GLenum R16UI = 0x8234; + const GLenum R32I = 0x8235; + const GLenum R32UI = 0x8236; + const GLenum RG8I = 0x8237; + const GLenum RG8UI = 0x8238; + const GLenum RG16I = 0x8239; + const GLenum RG16UI = 0x823A; + const GLenum RG32I = 0x823B; + const GLenum RG32UI = 0x823C; + const GLenum VERTEX_ARRAY_BINDING = 0x85B5; + const GLenum R8_SNORM = 0x8F94; + const GLenum RG8_SNORM = 0x8F95; + const GLenum RGB8_SNORM = 0x8F96; + const GLenum RGBA8_SNORM = 0x8F97; + const GLenum SIGNED_NORMALIZED = 0x8F9C; + const GLenum COPY_READ_BUFFER = 0x8F36; + const GLenum COPY_WRITE_BUFFER = 0x8F37; + const GLenum COPY_READ_BUFFER_BINDING = 0x8F36; // Same as COPY_READ_BUFFER + const GLenum COPY_WRITE_BUFFER_BINDING = 0x8F37; // Same as COPY_WRITE_BUFFER + const GLenum UNIFORM_BUFFER = 0x8A11; + const GLenum UNIFORM_BUFFER_BINDING = 0x8A28; + const GLenum UNIFORM_BUFFER_START = 0x8A29; + const GLenum UNIFORM_BUFFER_SIZE = 0x8A2A; + const GLenum MAX_VERTEX_UNIFORM_BLOCKS = 0x8A2B; + const GLenum MAX_FRAGMENT_UNIFORM_BLOCKS = 0x8A2D; + const GLenum MAX_COMBINED_UNIFORM_BLOCKS = 0x8A2E; + const GLenum MAX_UNIFORM_BUFFER_BINDINGS = 0x8A2F; + const GLenum MAX_UNIFORM_BLOCK_SIZE = 0x8A30; + const GLenum MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = 0x8A31; + const GLenum MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = 0x8A33; + const GLenum UNIFORM_BUFFER_OFFSET_ALIGNMENT = 0x8A34; + const GLenum ACTIVE_UNIFORM_BLOCKS = 0x8A36; + const GLenum UNIFORM_TYPE = 0x8A37; + const GLenum UNIFORM_SIZE = 0x8A38; + const GLenum UNIFORM_BLOCK_INDEX = 0x8A3A; + const GLenum UNIFORM_OFFSET = 0x8A3B; + const GLenum UNIFORM_ARRAY_STRIDE = 0x8A3C; + const GLenum UNIFORM_MATRIX_STRIDE = 0x8A3D; + const GLenum UNIFORM_IS_ROW_MAJOR = 0x8A3E; + const GLenum UNIFORM_BLOCK_BINDING = 0x8A3F; + const GLenum UNIFORM_BLOCK_DATA_SIZE = 0x8A40; + const GLenum UNIFORM_BLOCK_ACTIVE_UNIFORMS = 0x8A42; + const GLenum UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES = 0x8A43; + const GLenum UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER = 0x8A44; + const GLenum UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER = 0x8A46; + const GLenum INVALID_INDEX = 0xFFFFFFFF; + const GLenum MAX_VERTEX_OUTPUT_COMPONENTS = 0x9122; + const GLenum MAX_FRAGMENT_INPUT_COMPONENTS = 0x9125; + const GLenum MAX_SERVER_WAIT_TIMEOUT = 0x9111; + const GLenum OBJECT_TYPE = 0x9112; + const GLenum SYNC_CONDITION = 0x9113; + const GLenum SYNC_STATUS = 0x9114; + const GLenum SYNC_FLAGS = 0x9115; + const GLenum SYNC_FENCE = 0x9116; + const GLenum SYNC_GPU_COMMANDS_COMPLETE = 0x9117; + const GLenum UNSIGNALED = 0x9118; + const GLenum SIGNALED = 0x9119; + const GLenum ALREADY_SIGNALED = 0x911A; + const GLenum TIMEOUT_EXPIRED = 0x911B; + const GLenum CONDITION_SATISFIED = 0x911C; + const GLenum WAIT_FAILED = 0x911D; + const GLenum SYNC_FLUSH_COMMANDS_BIT = 0x00000001; + const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE; + const GLenum ANY_SAMPLES_PASSED = 0x8C2F; + const GLenum ANY_SAMPLES_PASSED_CONSERVATIVE = 0x8D6A; + const GLenum SAMPLER_BINDING = 0x8919; + const GLenum RGB10_A2UI = 0x906F; + const GLenum INT_2_10_10_10_REV = 0x8D9F; + const GLenum TRANSFORM_FEEDBACK = 0x8E22; + const GLenum TRANSFORM_FEEDBACK_PAUSED = 0x8E23; + const GLenum TRANSFORM_FEEDBACK_ACTIVE = 0x8E24; + const GLenum TRANSFORM_FEEDBACK_BINDING = 0x8E25; + const GLenum TEXTURE_IMMUTABLE_FORMAT = 0x912F; + const GLenum MAX_ELEMENT_INDEX = 0x8D6B; + const GLenum TEXTURE_IMMUTABLE_LEVELS = 0x82DF; + + const GLint64 TIMEOUT_IGNORED = -1; + + // WebGL-specific enums + const GLenum MAX_CLIENT_WAIT_TIMEOUT_WEBGL = 0x9247; + + // Buffer objects + [FIXME] undefined copyBufferSubData(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + // MapBufferRange, in particular its read-only and write-only modes, + // can not be exposed safely to JavaScript. GetBufferSubData + // replaces it for the purpose of fetching data back from the GPU. + [FIXME] undefined getBufferSubData(GLenum target, GLintptr srcByteOffset, [AllowShared] ArrayBufferView dstBuffer, optional unsigned long long dstOffset = 0, optional GLuint length = 0); + + // Framebuffer objects + [FIXME] undefined blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + [FIXME] undefined framebufferTextureLayer(GLenum target, GLenum attachment, WebGLTexture? texture, GLint level, GLint layer); + [FIXME] undefined invalidateFramebuffer(GLenum target, sequence attachments); + [FIXME] undefined invalidateSubFramebuffer(GLenum target, sequence attachments, GLint x, GLint y, GLsizei width, GLsizei height); + [FIXME] undefined readBuffer(GLenum src); + + // Renderbuffer objects + [FIXME] any getInternalformatParameter(GLenum target, GLenum internalformat, GLenum pname); + [FIXME] undefined renderbufferStorageMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + + // Texture objects + [FIXME] undefined texStorage2D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + [FIXME] undefined texStorage3D(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + + [FIXME] undefined texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, GLintptr pboOffset); + + // May throw DOMException + [FIXME] undefined texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, TexImageSource source); + + [FIXME] undefined texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView? srcData); + [FIXME] undefined texImage3D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, unsigned long long srcOffset); + + [FIXME] undefined texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLintptr pboOffset); + + // May throw DOMException + [FIXME] undefined texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, TexImageSource source); + + [FIXME] undefined texSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, [AllowShared] ArrayBufferView? srcData, optional unsigned long long srcOffset = 0); + + [FIXME] undefined copyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + + [FIXME] undefined compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, GLintptr offset); + [FIXME] undefined compressedTexImage3D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, [AllowShared] ArrayBufferView srcData, optional unsigned long long srcOffset = 0, optional GLuint srcLengthOverride = 0); + + [FIXME] undefined compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, GLintptr offset); + [FIXME] undefined compressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, [AllowShared] ArrayBufferView srcData, optional unsigned long long srcOffset = 0, optional GLuint srcLengthOverride = 0); + + // Programs and shaders + [FIXME] GLint getFragDataLocation(WebGLProgram program, DOMString name); // [WebGLHandlesContextLoss] + + // Uniforms + [FIXME] undefined uniform1ui(WebGLUniformLocation? location, GLuint v0); + [FIXME] undefined uniform2ui(WebGLUniformLocation? location, GLuint v0, GLuint v1); + [FIXME] undefined uniform3ui(WebGLUniformLocation? location, GLuint v0, GLuint v1, GLuint v2); + [FIXME] undefined uniform4ui(WebGLUniformLocation? location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + + [FIXME] undefined uniform1uiv(WebGLUniformLocation? location, Uint32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniform2uiv(WebGLUniformLocation? location, Uint32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniform3uiv(WebGLUniformLocation? location, Uint32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniform4uiv(WebGLUniformLocation? location, Uint32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniformMatrix3x2fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniformMatrix4x2fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + + [FIXME] undefined uniformMatrix2x3fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniformMatrix4x3fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + + [FIXME] undefined uniformMatrix2x4fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniformMatrix3x4fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + + // Vertex attributes + [FIXME] undefined vertexAttribI4i(GLuint index, GLint x, GLint y, GLint z, GLint w); + [FIXME] undefined vertexAttribI4iv(GLuint index, Int32List values); + [FIXME] undefined vertexAttribI4ui(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + [FIXME] undefined vertexAttribI4uiv(GLuint index, Uint32List values); + [FIXME] undefined vertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset); + + // Writing to the drawing buffer + [FIXME] undefined vertexAttribDivisor(GLuint index, GLuint divisor); + [FIXME] undefined drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount); + [FIXME] undefined drawElementsInstanced(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei instanceCount); + [FIXME] undefined drawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, GLintptr offset); + + // Multiple Render Targets + [FIXME] undefined drawBuffers(sequence buffers); + + [FIXME] undefined clearBufferfv(GLenum buffer, GLint drawbuffer, Float32List values, optional unsigned long long srcOffset = 0); + [FIXME] undefined clearBufferiv(GLenum buffer, GLint drawbuffer, Int32List values, optional unsigned long long srcOffset = 0); + [FIXME] undefined clearBufferuiv(GLenum buffer, GLint drawbuffer, Uint32List values, optional unsigned long long srcOffset = 0); + + [FIXME] undefined clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + + // Query Objects + [FIXME] WebGLQuery createQuery(); + [FIXME] undefined deleteQuery(WebGLQuery? query); + [FIXME] GLboolean isQuery(WebGLQuery? query); // [WebGLHandlesContextLoss] + [FIXME] undefined beginQuery(GLenum target, WebGLQuery query); + [FIXME] undefined endQuery(GLenum target); + [FIXME] WebGLQuery? getQuery(GLenum target, GLenum pname); + [FIXME] any getQueryParameter(WebGLQuery query, GLenum pname); + + // Sampler Objects + [FIXME] WebGLSampler createSampler(); + [FIXME] undefined deleteSampler(WebGLSampler? sampler); + [FIXME] GLboolean isSampler(WebGLSampler? sampler); // [WebGLHandlesContextLoss] + [FIXME] undefined bindSampler(GLuint unit, WebGLSampler? sampler); + [FIXME] undefined samplerParameteri(WebGLSampler sampler, GLenum pname, GLint param); + [FIXME] undefined samplerParameterf(WebGLSampler sampler, GLenum pname, GLfloat param); + [FIXME] any getSamplerParameter(WebGLSampler sampler, GLenum pname); + + // Sync objects + [FIXME] WebGLSync? fenceSync(GLenum condition, GLbitfield flags); + [FIXME] GLboolean isSync(WebGLSync? sync); // [WebGLHandlesContextLoss] + [FIXME] undefined deleteSync(WebGLSync? sync); + [FIXME] GLenum clientWaitSync(WebGLSync sync, GLbitfield flags, GLuint64 timeout); + [FIXME] undefined waitSync(WebGLSync sync, GLbitfield flags, GLint64 timeout); + [FIXME] any getSyncParameter(WebGLSync sync, GLenum pname); + + // Transform Feedback + [FIXME] WebGLTransformFeedback createTransformFeedback(); + [FIXME] undefined deleteTransformFeedback(WebGLTransformFeedback? tf); + [FIXME] GLboolean isTransformFeedback(WebGLTransformFeedback? tf); // [WebGLHandlesContextLoss] + [FIXME] undefined bindTransformFeedback (GLenum target, WebGLTransformFeedback? tf); + [FIXME] undefined beginTransformFeedback(GLenum primitiveMode); + [FIXME] undefined endTransformFeedback(); + [FIXME] undefined transformFeedbackVaryings(WebGLProgram program, sequence varyings, GLenum bufferMode); + [FIXME] WebGLActiveInfo? getTransformFeedbackVarying(WebGLProgram program, GLuint index); + [FIXME] undefined pauseTransformFeedback(); + [FIXME] undefined resumeTransformFeedback(); + + // Uniform Buffer Objects and Transform Feedback Buffers + [FIXME] undefined bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer); + [FIXME] undefined bindBufferRange(GLenum target, GLuint index, WebGLBuffer? buffer, GLintptr offset, GLsizeiptr size); + [FIXME] any getIndexedParameter(GLenum target, GLuint index); + [FIXME] sequence? getUniformIndices(WebGLProgram program, sequence uniformNames); + [FIXME] any getActiveUniforms(WebGLProgram program, sequence uniformIndices, GLenum pname); + [FIXME] GLuint getUniformBlockIndex(WebGLProgram program, DOMString uniformBlockName); + [FIXME] any getActiveUniformBlockParameter(WebGLProgram program, GLuint uniformBlockIndex, GLenum pname); + [FIXME] DOMString? getActiveUniformBlockName(WebGLProgram program, GLuint uniformBlockIndex); + [FIXME] undefined uniformBlockBinding(WebGLProgram program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + + // Vertex Array Objects + [FIXME] WebGLVertexArrayObject createVertexArray(); + [FIXME] undefined deleteVertexArray(WebGLVertexArrayObject? vertexArray); + [FIXME] GLboolean isVertexArray(WebGLVertexArrayObject? vertexArray); // [WebGLHandlesContextLoss] + [FIXME] undefined bindVertexArray(WebGLVertexArrayObject? array); +}; diff --git a/Libraries/LibWeb/WebGL/WebGL2RenderingContextOverloads.idl b/Libraries/LibWeb/WebGL/WebGL2RenderingContextOverloads.idl new file mode 100644 index 00000000000..502cb54a02f --- /dev/null +++ b/Libraries/LibWeb/WebGL/WebGL2RenderingContextOverloads.idl @@ -0,0 +1,66 @@ +#import +#import +#import + +// https://registry.khronos.org/webgl/specs/latest/2.0/#3.7 +interface mixin WebGL2RenderingContextOverloads { + // WebGL1: + [FIXME] undefined bufferData(GLenum target, GLsizeiptr size, GLenum usage); + [FIXME] undefined bufferData(GLenum target, AllowSharedBufferSource? srcData, GLenum usage); + [FIXME] undefined bufferSubData(GLenum target, GLintptr dstByteOffset, AllowSharedBufferSource srcData); + // WebGL2: + [FIXME] undefined bufferData(GLenum target, [AllowShared] ArrayBufferView srcData, GLenum usage, unsigned long long srcOffset, optional GLuint length = 0); + [FIXME] undefined bufferSubData(GLenum target, GLintptr dstByteOffset, [AllowShared] ArrayBufferView srcData, unsigned long long srcOffset, optional GLuint length = 0); + + // WebGL1 legacy entrypoints: + [FIXME] undefined texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels); + + // May throw DOMException + [FIXME] undefined texImage2D(GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type, TexImageSource source); + + [FIXME] undefined texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels); + + // May throw DOMException + [FIXME] undefined texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, TexImageSource source); + + // WebGL2 entrypoints: + [FIXME] undefined texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLintptr pboOffset); + + // May throw DOMException + [FIXME] undefined texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, TexImageSource source); + + [FIXME] undefined texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, unsigned long long srcOffset); + + [FIXME] undefined texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLintptr pboOffset); + + // May throw DOMException + [FIXME] undefined texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, TexImageSource source); + [FIXME] undefined texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView srcData, unsigned long long srcOffset); + + [FIXME] undefined compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, GLintptr offset); + [FIXME] undefined compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, [AllowShared] ArrayBufferView srcData, optional unsigned long long srcOffset = 0, optional GLuint srcLengthOverride = 0); + + [FIXME] undefined compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, GLintptr offset); + [FIXME] undefined compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,GLsizei width, GLsizei height, GLenum format, [AllowShared] ArrayBufferView srcData, optional unsigned long long srcOffset = 0, optional GLuint srcLengthOverride = 0); + + [FIXME] undefined uniform1fv(WebGLUniformLocation? location, Float32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniform2fv(WebGLUniformLocation? location, Float32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniform3fv(WebGLUniformLocation? location, Float32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniform4fv(WebGLUniformLocation? location, Float32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + + [FIXME] undefined uniform1iv(WebGLUniformLocation? location, Int32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniform2iv(WebGLUniformLocation? location, Int32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniform3iv(WebGLUniformLocation? location, Int32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniform4iv(WebGLUniformLocation? location, Int32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + + [FIXME] undefined uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + [FIXME] undefined uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32List data, optional unsigned long long srcOffset = 0, optional GLuint srcLength = 0); + + // Reading back pixels + // WebGL1: + [FIXME] undefined readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView? dstData); + // WebGL2: + [FIXME] undefined readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLintptr offset); + [FIXME] undefined readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView dstData, unsigned long long dstOffset); +}; diff --git a/Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp b/Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp index daad2d6200e..82a2c2636d4 100644 --- a/Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp +++ b/Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp @@ -27,7 +27,7 @@ namespace Web::WebGL { GC_DEFINE_ALLOCATOR(WebGLRenderingContext); // https://www.khronos.org/registry/webgl/specs/latest/1.0/#fire-a-webgl-context-event -static void fire_webgl_context_event(HTML::HTMLCanvasElement& canvas_element, FlyString const& type) +void fire_webgl_context_event(HTML::HTMLCanvasElement& canvas_element, FlyString const& type) { // To fire a WebGL context event named e means that an event using the WebGLContextEvent interface, with its type attribute [DOM4] initialized to e, its cancelable attribute initialized to true, and its isTrusted attribute [DOM4] initialized to true, is to be dispatched at the given object. // FIXME: Consider setting a status message. @@ -38,7 +38,7 @@ static void fire_webgl_context_event(HTML::HTMLCanvasElement& canvas_element, Fl } // https://www.khronos.org/registry/webgl/specs/latest/1.0/#fire-a-webgl-context-creation-error -static void fire_webgl_context_creation_error(HTML::HTMLCanvasElement& canvas_element) +void fire_webgl_context_creation_error(HTML::HTMLCanvasElement& canvas_element) { // 1. Fire a WebGL context event named "webglcontextcreationerror" at canvas, optionally with its statusMessage attribute set to a platform dependent string about the nature of the failure. fire_webgl_context_event(canvas_element, EventNames::webglcontextcreationerror); diff --git a/Libraries/LibWeb/WebGL/WebGLRenderingContext.h b/Libraries/LibWeb/WebGL/WebGLRenderingContext.h index 5f02b10fdfc..da20dadde61 100644 --- a/Libraries/LibWeb/WebGL/WebGLRenderingContext.h +++ b/Libraries/LibWeb/WebGL/WebGLRenderingContext.h @@ -75,4 +75,7 @@ private: void set_error(GLenum error); }; +void fire_webgl_context_event(HTML::HTMLCanvasElement& canvas_element, FlyString const& type); +void fire_webgl_context_creation_error(HTML::HTMLCanvasElement& canvas_element); + } diff --git a/Libraries/LibWeb/WebGL/WebGLRenderingContext.idl b/Libraries/LibWeb/WebGL/WebGLRenderingContext.idl index a233cec6c52..b91d4bdd0fd 100644 --- a/Libraries/LibWeb/WebGL/WebGLRenderingContext.idl +++ b/Libraries/LibWeb/WebGL/WebGLRenderingContext.idl @@ -1,3 +1,4 @@ +#import #import #import diff --git a/Libraries/LibWeb/idl_files.cmake b/Libraries/LibWeb/idl_files.cmake index 999aa8a0671..b85359fbd6d 100644 --- a/Libraries/LibWeb/idl_files.cmake +++ b/Libraries/LibWeb/idl_files.cmake @@ -369,6 +369,7 @@ libweb_js_bindings(WebAudio/ChannelMergerNode) libweb_js_bindings(WebAudio/OfflineAudioContext) libweb_js_bindings(WebAudio/OscillatorNode) libweb_js_bindings(WebAudio/PeriodicWave) +libweb_js_bindings(WebGL/WebGL2RenderingContext) libweb_js_bindings(WebGL/WebGLActiveInfo) libweb_js_bindings(WebGL/WebGLBuffer) libweb_js_bindings(WebGL/WebGLContextEvent) diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp index 7cf528ad8b3..036b241f779 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/BindingsGenerator/IDLGenerators.cpp @@ -105,6 +105,7 @@ static bool is_platform_object(Type const& type) "VTTRegion"sv, "VideoTrack"sv, "VideoTrackList"sv, + "WebGL2RenderingContext"sv, "WebGLActiveInfo"sv, "WebGLBuffer"sv, "WebGLFramebuffer"sv, diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWebGLRenderingContext.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWebGLRenderingContext.cpp index e791f3b6802..4bf8e02a3ed 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWebGLRenderingContext.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWebGLRenderingContext.cpp @@ -6,6 +6,8 @@ */ #include "BindingsGenerator/IDLGenerators.h" + +#include #include #include #include @@ -275,7 +277,7 @@ ErrorOr serenity_main(Main::Arguments arguments) StringView webgl_context_idl_path; Core::ArgsParser args_parser; - args_parser.add_option(webgl_context_idl_path, "Path to the WebGLRenderingContext.idl file", "webgl-idl-path", 'i', "webgl-idl-path"); + args_parser.add_option(webgl_context_idl_path, "Path to the WebGLRenderingContext idl file", "webgl-idl-path", 'i', "webgl-idl-path"); args_parser.add_option(Core::ArgsParser::Option { .argument_mode = Core::ArgsParser::OptionArgumentMode::Required, .help_string = "Path to root of IDL file tree(s)", @@ -287,8 +289,8 @@ ErrorOr serenity_main(Main::Arguments arguments) return true; }, }); - args_parser.add_option(generated_header_path, "Path to the Enums header file to generate", "generated-header-path", 'h', "generated-header-path"); - args_parser.add_option(generated_implementation_path, "Path to the Enums implementation file to generate", "generated-implementation-path", 'c', "generated-implementation-path"); + args_parser.add_option(generated_header_path, "Path to the header file to generate", "generated-header-path", 'h', "generated-header-path"); + args_parser.add_option(generated_implementation_path, "Path to the implementation file to generate", "generated-implementation-path", 'c', "generated-implementation-path"); args_parser.parse(arguments); auto generated_header_file = TRY(Core::File::open(generated_header_path, Core::File::OpenMode::Write)); @@ -306,11 +308,20 @@ ErrorOr serenity_main(Main::Arguments arguments) IDL::Parser parser(webgl_context_idl_path, StringView(webgl_context_idl_file_content), import_base_paths); auto const& interface = parser.parse(); + auto path = LexicalPath(generated_header_path); + auto title = path.title(); + auto first_dot = title.find('.'); + ByteString class_name = title; + if (first_dot.has_value()) + class_name = title.substring_view(0, *first_dot); + StringBuilder header_file_string_builder; SourceGenerator header_file_generator { header_file_string_builder }; + header_file_generator.set("class_name", class_name); StringBuilder implementation_file_string_builder; SourceGenerator implementation_file_generator { implementation_file_string_builder }; + implementation_file_generator.set("class_name", class_name); implementation_file_generator.append(R"~~~( #include @@ -327,7 +338,7 @@ ErrorOr serenity_main(Main::Arguments arguments) #include #include #include -#include +#include #include #include #include @@ -348,7 +359,7 @@ static Vector null_terminated_string(StringView string) return result; } -WebGLRenderingContextImpl::WebGLRenderingContextImpl(JS::Realm& realm, NonnullOwnPtr context) +@class_name@::@class_name@(JS::Realm& realm, NonnullOwnPtr context) : m_realm(realm) , m_context(move(context)) { @@ -370,9 +381,9 @@ namespace Web::WebGL { using namespace Web::HTML; -class WebGLRenderingContextImpl { +class @class_name@ { public: - WebGLRenderingContextImpl(JS::Realm&, NonnullOwnPtr); + @class_name@(JS::Realm&, NonnullOwnPtr); OpenGLContext& context() { return *m_context; } @@ -418,6 +429,7 @@ public: StringBuilder function_impl; SourceGenerator function_impl_generator { function_impl }; + function_impl_generator.set("class_name", class_name); ScopeGuard function_guard { [&] { function_impl_generator.append("}\n"sv); @@ -428,7 +440,7 @@ public: function_impl_generator.set("function_parameters", function_parameters.string_view()); function_impl_generator.set("function_return_type", to_cpp_type(*function.return_type, interface)); function_impl_generator.append(R"~~~( -@function_return_type@ WebGLRenderingContextImpl::@function_name@(@function_parameters@) +@function_return_type@ @class_name@::@function_name@(@function_parameters@) { m_context->make_current(); )~~~"); diff --git a/Tests/LibWeb/Text/expected/all-window-properties.txt b/Tests/LibWeb/Text/expected/all-window-properties.txt index 29d660164ff..4eab6f474f7 100644 --- a/Tests/LibWeb/Text/expected/all-window-properties.txt +++ b/Tests/LibWeb/Text/expected/all-window-properties.txt @@ -398,6 +398,7 @@ VisualViewport WeakMap WeakRef WeakSet +WebGL2RenderingContext WebGLActiveInfo WebGLBuffer WebGLContextEvent diff --git a/Tests/LibWeb/Text/expected/canvas/webgl-create-canvas.txt b/Tests/LibWeb/Text/expected/canvas/webgl-create-canvas.txt new file mode 100644 index 00000000000..a1c4d99d2b3 --- /dev/null +++ b/Tests/LibWeb/Text/expected/canvas/webgl-create-canvas.txt @@ -0,0 +1,5 @@ +FIXME: This test relies on having a GPU backend enabled, which it is not in run-tests mode :( +context instanceof WebGLRenderingContext: false +context is null: true +context2 instanceof WebGL2RenderingContext: false +context2 is null: true diff --git a/Tests/LibWeb/Text/input/canvas/webgl-create-canvas.html b/Tests/LibWeb/Text/input/canvas/webgl-create-canvas.html new file mode 100644 index 00000000000..fb48e10568e --- /dev/null +++ b/Tests/LibWeb/Text/input/canvas/webgl-create-canvas.html @@ -0,0 +1,17 @@ + + +