diff --git a/Libraries/LibWeb/WebGL/WebGL2RenderingContextOverloads.idl b/Libraries/LibWeb/WebGL/WebGL2RenderingContextOverloads.idl index 6936009f432..f08efe936e5 100644 --- a/Libraries/LibWeb/WebGL/WebGL2RenderingContextOverloads.idl +++ b/Libraries/LibWeb/WebGL/WebGL2RenderingContextOverloads.idl @@ -22,20 +22,20 @@ interface mixin WebGL2RenderingContextOverloads { 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); + 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); + undefined texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, TexImageSource source); 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); + undefined texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, TexImageSource source); 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); diff --git a/Libraries/LibWeb/WebGL/WebGLRenderingContextOverloads.idl b/Libraries/LibWeb/WebGL/WebGLRenderingContextOverloads.idl index fb07c3dc8d6..d844d42e880 100644 --- a/Libraries/LibWeb/WebGL/WebGLRenderingContextOverloads.idl +++ b/Libraries/LibWeb/WebGL/WebGLRenderingContextOverloads.idl @@ -28,7 +28,7 @@ interface mixin WebGLRenderingContextOverloads { undefined texImage2D(GLenum target, GLint level, GLint internalformat, GLenum format, GLenum type, TexImageSource source); // May throw DOMException undefined texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels); - [FIXME] undefined texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, TexImageSource source); // May throw DOMException + undefined texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, TexImageSource source); // May throw DOMException undefined uniform1fv(WebGLUniformLocation? location, Float32List v); undefined uniform2fv(WebGLUniformLocation? location, Float32List v); diff --git a/Libraries/LibWeb/WebIDL/OverloadResolution.cpp b/Libraries/LibWeb/WebIDL/OverloadResolution.cpp index 2362f3c3785..f7202713347 100644 --- a/Libraries/LibWeb/WebIDL/OverloadResolution.cpp +++ b/Libraries/LibWeb/WebIDL/OverloadResolution.cpp @@ -210,7 +210,7 @@ JS::ThrowCompletionOr resolve_overload(JS::VM& vm, IDL::Effect // then remove from S all other entries. else if (value.is_object() && is(value.as_object()) && has_overload_with_argument_type_or_subtype_matching(overloads, i, [](IDL::Type const& type) { - if (type.is_plain() && (type.name() == "DataView" || type.name() == "BufferSource")) + if (type.is_plain() && (type.name() == "DataView" || type.name() == "BufferSource" || type.name() == "ArrayBufferView")) return true; if (type.is_object()) return true; @@ -228,7 +228,7 @@ JS::ThrowCompletionOr resolve_overload(JS::VM& vm, IDL::Effect // then remove from S all other entries. else if (value.is_object() && value.as_object().is_typed_array() && has_overload_with_argument_type_or_subtype_matching(overloads, i, [&](IDL::Type const& type) { - if (type.is_plain() && (type.name() == static_cast(value.as_object()).element_name() || type.name() == "BufferSource")) + if (type.is_plain() && (type.name() == static_cast(value.as_object()).element_name() || type.name() == "BufferSource" || type.name() == "ArrayBufferView")) return true; if (type.is_object()) return true; diff --git a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWebGLRenderingContext.cpp b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWebGLRenderingContext.cpp index 1d04dfcc9cb..79951ce8d22 100644 --- a/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWebGLRenderingContext.cpp +++ b/Meta/Lagom/Tools/CodeGenerators/LibWeb/GenerateWebGLRenderingContext.cpp @@ -725,7 +725,7 @@ public: continue; } - if (function.name == "texImage2D"sv && function.overload_index == 1) { + if (function.name == "texImage2D"sv && (function.overload_index == 1 || (webgl_version == 2 && function.overload_index == 2))) { // FIXME: If this function is called with an ImageData whose data attribute has been neutered, // an INVALID_VALUE error is generated. // FIXME: If this function is called with an ImageBitmap that has been neutered, an INVALID_VALUE @@ -761,14 +761,23 @@ public: return; void const* pixels_ptr = bitmap->bitmap()->begin(); +)~~~"); + + if (webgl_version == 2 && function.overload_index == 2) { + function_impl_generator.append(R"~~~( + glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels_ptr); +)~~~"); + } else { + function_impl_generator.append(R"~~~( int width = bitmap->width(); int height = bitmap->height(); glTexImage2D(target, level, internalformat, width, height, 0, format, type, pixels_ptr); )~~~"); + } continue; } - if (webgl_version == 2 && function.name == "texImage2D"sv && function.overload_index == 2) { + if (webgl_version == 2 && function.name == "texImage2D"sv && function.overload_index == 3) { function_impl_generator.append(R"~~~( void const* pixels_ptr = nullptr; if (src_data) { @@ -794,7 +803,58 @@ public: continue; } - if (webgl_version == 2 && function.name == "texSubImage2D"sv && function.overload_index == 1) { + if (function.name == "texSubImage2D" && (function.overload_index == 1 || (webgl_version == 2 && function.overload_index == 2))) { + // FIXME: If this function is called with an ImageData whose data attribute has been neutered, + // an INVALID_VALUE error is generated. + // FIXME: If this function is called with an ImageBitmap that has been neutered, an INVALID_VALUE + // error is generated. + // FIXME: If this function is called with an HTMLImageElement or HTMLVideoElement whose origin + // differs from the origin of the containing Document, or with an HTMLCanvasElement, + // ImageBitmap or OffscreenCanvas whose bitmap's origin-clean flag is set to false, + // a SECURITY_ERR exception must be thrown. See Origin Restrictions. + // FIXME: If source is null then an INVALID_VALUE error is generated. + function_impl_generator.append(R"~~~( + auto bitmap = source.visit( + [](GC::Root const& source) -> RefPtr { + return source->immutable_bitmap(); + }, + [](GC::Root const& source) -> RefPtr { + auto surface = source->surface(); + if (!surface) + return {}; + auto bitmap = MUST(Gfx::Bitmap::create(Gfx::BitmapFormat::RGBA8888, Gfx::AlphaType::Premultiplied, surface->size())); + surface->read_into_bitmap(*bitmap); + return Gfx::ImmutableBitmap::create(*bitmap); + }, + [](GC::Root const& source) -> RefPtr { + return Gfx::ImmutableBitmap::create(*source->bitmap()); + }, + [](GC::Root const& source) -> RefPtr { + return Gfx::ImmutableBitmap::create(*source->bitmap()); + }, + [](GC::Root const& source) -> RefPtr { + return Gfx::ImmutableBitmap::create(source->bitmap()); + }); + if (!bitmap) + return; + + void const* pixels_ptr = bitmap->bitmap()->begin(); +)~~~"); + if (webgl_version == 2 && function.overload_index == 2) { + function_impl_generator.append(R"~~~( + glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels_ptr); +)~~~"); + } else { + function_impl_generator.append(R"~~~( + int width = bitmap->width(); + int height = bitmap->height(); + glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels_ptr); +)~~~"); + } + continue; + } + + if (webgl_version == 2 && function.name == "texSubImage2D"sv && function.overload_index == 3) { function_impl_generator.append(R"~~~( void const* pixels_ptr = nullptr; if (src_data) {