diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index e1ae31aa534..811736f30a2 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -804,6 +804,7 @@ set(SOURCES WebDriver/Response.cpp WebDriver/Screenshot.cpp WebDriver/TimeoutsConfiguration.cpp + WebGL/ANGLEInstancedArrays.cpp WebGL/EventNames.cpp WebGL/OpenGLContext.cpp WebGL/WebGL2RenderingContext.cpp diff --git a/Libraries/LibWeb/WebGL/ANGLEInstancedArrays.cpp b/Libraries/LibWeb/WebGL/ANGLEInstancedArrays.cpp new file mode 100644 index 00000000000..01c1e672070 --- /dev/null +++ b/Libraries/LibWeb/WebGL/ANGLEInstancedArrays.cpp @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2024, Aliaksandr Kalenik + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include + +#define GL_GLEXT_PROTOTYPES 1 +#include +#include + +namespace Web::WebGL { + +GC_DEFINE_ALLOCATOR(ANGLEInstancedArrays); + +JS::ThrowCompletionOr> ANGLEInstancedArrays::create(JS::Realm& realm) +{ + return realm.create(realm); +} + +ANGLEInstancedArrays::ANGLEInstancedArrays(JS::Realm& realm) + : PlatformObject(realm) +{ +} + +void ANGLEInstancedArrays::vertex_attrib_divisor_angle(GLuint index, GLuint divisor) +{ + glVertexAttribDivisorANGLE(index, divisor); +} + +void ANGLEInstancedArrays::draw_arrays_instanced_angle(GLenum mode, GLint first, GLsizei count, GLsizei primcount) +{ + glDrawArraysInstancedANGLE(mode, first, count, primcount); +} + +void ANGLEInstancedArrays::draw_elements_instanced_angle(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei primcount) +{ + glDrawElementsInstancedANGLE(mode, count, type, reinterpret_cast(offset), primcount); +} + +void ANGLEInstancedArrays::initialize(JS::Realm& realm) +{ + Base::initialize(realm); + WEB_SET_PROTOTYPE_FOR_INTERFACE(ANGLEInstancedArrays); +} + +} diff --git a/Libraries/LibWeb/WebGL/ANGLEInstancedArrays.h b/Libraries/LibWeb/WebGL/ANGLEInstancedArrays.h new file mode 100644 index 00000000000..54d40ae5e46 --- /dev/null +++ b/Libraries/LibWeb/WebGL/ANGLEInstancedArrays.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024, Aliaksandr Kalenik + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include + +namespace Web::WebGL { + +class ANGLEInstancedArrays : public Bindings::PlatformObject { + WEB_PLATFORM_OBJECT(ANGLEInstancedArrays, Bindings::PlatformObject); + GC_DECLARE_ALLOCATOR(ANGLEInstancedArrays); + +public: + static JS::ThrowCompletionOr> create(JS::Realm&); + + void draw_arrays_instanced_angle(GLenum mode, GLint first, GLsizei count, GLsizei primcount); + void draw_elements_instanced_angle(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei primcount); + void vertex_attrib_divisor_angle(GLuint index, GLuint divisor); + +protected: + void initialize(JS::Realm&) override; + +private: + ANGLEInstancedArrays(JS::Realm&); +}; + +} diff --git a/Libraries/LibWeb/WebGL/ANGLEInstancedArrays.idl b/Libraries/LibWeb/WebGL/ANGLEInstancedArrays.idl new file mode 100644 index 00000000000..121ee2885a8 --- /dev/null +++ b/Libraries/LibWeb/WebGL/ANGLEInstancedArrays.idl @@ -0,0 +1,15 @@ +#import + +// https://registry.khronos.org/webgl/extensions/ANGLE_instanced_arrays/ +// NOTE: Original ANGLE_instanced_arrays 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 ANGLEInstancedArrays { + const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE = 0x88FE; + undefined drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount); + undefined drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei primcount); + undefined vertexAttribDivisorANGLE(GLuint index, GLuint divisor); +}; diff --git a/Libraries/LibWeb/WebGL/Types.h b/Libraries/LibWeb/WebGL/Types.h index 9d5c6d7a2a5..f8848e6528a 100644 --- a/Libraries/LibWeb/WebGL/Types.h +++ b/Libraries/LibWeb/WebGL/Types.h @@ -14,6 +14,8 @@ namespace Web::WebGL { using GLenum = unsigned int; using GLuint = unsigned int; using GLint = int; +using GLsizei = int; +using GLintptr = int; // FIXME: This should really be "struct __GLsync*", but the linker doesn't recognise it. // Since this conflicts with the original definition of GLsync, the suffix "Internal" has been added. diff --git a/Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp b/Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp index 42245ddf0ed..7a0c8937867 100644 --- a/Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp +++ b/Libraries/LibWeb/WebGL/WebGLRenderingContext.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -166,8 +167,11 @@ Optional> WebGLRenderingContext::get_supported_extensions() return context().get_supported_extensions(); } -JS::Object* WebGLRenderingContext::get_extension(String const&) +JS::Object* WebGLRenderingContext::get_extension(String const& name) { + if (name == "ANGLE_instanced_arrays"sv) { + return MUST(ANGLEInstancedArrays::create(realm())); + } return nullptr; } diff --git a/Libraries/LibWeb/idl_files.cmake b/Libraries/LibWeb/idl_files.cmake index 83d0aad42ea..34dc23a850d 100644 --- a/Libraries/LibWeb/idl_files.cmake +++ b/Libraries/LibWeb/idl_files.cmake @@ -370,6 +370,7 @@ libweb_js_bindings(WebAudio/OfflineAudioContext) libweb_js_bindings(WebAudio/OscillatorNode) libweb_js_bindings(WebAudio/PannerNode) libweb_js_bindings(WebAudio/PeriodicWave) +libweb_js_bindings(WebGL/ANGLEInstancedArrays) libweb_js_bindings(WebGL/WebGL2RenderingContext) libweb_js_bindings(WebGL/WebGLActiveInfo) libweb_js_bindings(WebGL/WebGLBuffer)