LibWeb: Unify WebGL handling code in WebGLRenderingContextBase

This commit is contained in:
Undefine
2026-03-04 22:42:58 +01:00
committed by Jelle Raaijmakers
parent 5a029b4533
commit 3101565f05
Notes: github-actions[bot] 2026-03-11 19:21:46 +00:00
6 changed files with 222 additions and 327 deletions

View File

@@ -19,6 +19,18 @@ extern "C" {
#include <LibWeb/HTML/HTMLVideoElement.h>
#include <LibWeb/HTML/ImageBitmap.h>
#include <LibWeb/HTML/ImageData.h>
#include <LibWeb/WebGL/Extensions/ANGLEInstancedArrays.h>
#include <LibWeb/WebGL/Extensions/EXTBlendMinMax.h>
#include <LibWeb/WebGL/Extensions/EXTColorBufferFloat.h>
#include <LibWeb/WebGL/Extensions/EXTRenderSnorm.h>
#include <LibWeb/WebGL/Extensions/EXTTextureFilterAnisotropic.h>
#include <LibWeb/WebGL/Extensions/EXTTextureNorm16.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>
#include <LibWeb/WebGL/Extensions/WebGLCompressedTextureS3tcSrgb.h>
#include <LibWeb/WebGL/Extensions/WebGLDrawBuffers.h>
#include <LibWeb/WebGL/OpenGLContext.h>
#include <LibWeb/WebGL/WebGLRenderingContextBase.h>
@@ -87,6 +99,188 @@ WebGLRenderingContextBase::WebGLRenderingContextBase(JS::Realm& realm)
{
}
Optional<Vector<String>> WebGLRenderingContextBase::get_supported_extensions()
{
return context().get_supported_extensions();
}
JS::Object* WebGLRenderingContextBase::get_extension(String const& name)
{
// Returns an object if, and only if, name is an ASCII case-insensitive match [HTML] for one of the names returned
// from getSupportedExtensions; otherwise, returns null. The object returned from getExtension contains any constants
// or functions provided by the extension. A returned object may have no constants or functions if the extension does
// not define any, but a unique object must still be returned. That object is used to indicate that the extension has
// been enabled.
auto supported_extensions = get_supported_extensions();
auto supported_extension_iterator = supported_extensions->find_if([&name](String const& supported_extension) {
return supported_extension.equals_ignoring_ascii_case(name);
});
if (supported_extension_iterator == supported_extensions->end())
return nullptr;
if (name.equals_ignoring_ascii_case("ANGLE_instanced_arrays"sv) && context().webgl_version() == OpenGLContext::WebGLVersion::WebGL1) {
if (!m_angle_instanced_arrays_extension) {
m_angle_instanced_arrays_extension = MUST(Extensions::ANGLEInstancedArrays::create(realm(), *this));
}
VERIFY(m_angle_instanced_arrays_extension);
return m_angle_instanced_arrays_extension;
}
if (name.equals_ignoring_ascii_case("EXT_blend_minmax"sv) && context().webgl_version() == OpenGLContext::WebGLVersion::WebGL1) {
if (!m_ext_blend_min_max_extension) {
m_ext_blend_min_max_extension = MUST(Extensions::EXTBlendMinMax::create(realm(), *this));
}
VERIFY(m_ext_blend_min_max_extension);
return m_ext_blend_min_max_extension;
}
if (name.equals_ignoring_ascii_case("EXT_color_buffer_float"sv) && context().webgl_version() == OpenGLContext::WebGLVersion::WebGL2) {
if (!m_ext_color_buffer_float_extension) {
m_ext_color_buffer_float_extension = MUST(Extensions::EXTColorBufferFloat::create(realm(), *this));
}
VERIFY(m_ext_color_buffer_float_extension);
return m_ext_color_buffer_float_extension;
}
if (name.equals_ignoring_ascii_case("EXT_render_snorm"sv) && context().webgl_version() == OpenGLContext::WebGLVersion::WebGL2) {
if (!m_ext_render_snorm) {
m_ext_render_snorm = MUST(Extensions::EXTRenderSnorm::create(realm(), *this));
}
VERIFY(m_ext_render_snorm);
return m_ext_render_snorm;
}
if (name.equals_ignoring_ascii_case("EXT_texture_filter_anisotropic"sv)) {
if (!m_ext_texture_filter_anisotropic) {
m_ext_texture_filter_anisotropic = MUST(Extensions::EXTTextureFilterAnisotropic::create(realm(), *this));
}
VERIFY(m_ext_texture_filter_anisotropic);
return m_ext_texture_filter_anisotropic;
}
if (name.equals_ignoring_ascii_case("EXT_texture_norm16"sv) && context().webgl_version() == OpenGLContext::WebGLVersion::WebGL2) {
if (!m_ext_texture_norm16) {
m_ext_texture_norm16 = MUST(Extensions::EXTTextureNorm16::create(realm(), *this));
}
VERIFY(m_ext_texture_norm16);
return m_ext_texture_norm16;
}
if (name.equals_ignoring_ascii_case("OES_element_index_uint"sv) && context().webgl_version() == OpenGLContext::WebGLVersion::WebGL1) {
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) && context().webgl_version() == OpenGLContext::WebGLVersion::WebGL1) {
if (!m_oes_standard_derivatives_object_extension) {
m_oes_standard_derivatives_object_extension = MUST(Extensions::OESStandardDerivatives::create(realm(), *this));
}
VERIFY(m_oes_standard_derivatives_object_extension);
return m_oes_standard_derivatives_object_extension;
}
if (name.equals_ignoring_ascii_case("OES_vertex_array_object"sv) && context().webgl_version() == OpenGLContext::WebGLVersion::WebGL1) {
if (!m_oes_vertex_array_object_extension) {
m_oes_vertex_array_object_extension = MUST(Extensions::OESVertexArrayObject::create(realm(), *this));
}
VERIFY(m_oes_vertex_array_object_extension);
return m_oes_vertex_array_object_extension;
}
if (name.equals_ignoring_ascii_case("WEBGL_compressed_texture_s3tc"sv)) {
if (!m_webgl_compressed_texture_s3tc_extension) {
m_webgl_compressed_texture_s3tc_extension = MUST(Extensions::WebGLCompressedTextureS3tc::create(realm(), *this));
m_enabled_compressed_texture_formats.append(GL_COMPRESSED_RGB_S3TC_DXT1_EXT);
m_enabled_compressed_texture_formats.append(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT);
m_enabled_compressed_texture_formats.append(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT);
m_enabled_compressed_texture_formats.append(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT);
}
VERIFY(m_webgl_compressed_texture_s3tc_extension);
return m_webgl_compressed_texture_s3tc_extension;
}
if (name.equals_ignoring_ascii_case("WEBGL_compressed_texture_s3tc_srgb"sv)) {
if (!m_webgl_compressed_texture_s3tc_srgb_extension) {
m_webgl_compressed_texture_s3tc_srgb_extension = MUST(Extensions::WebGLCompressedTextureS3tcSrgb::create(realm(), *this));
m_enabled_compressed_texture_formats.append(GL_COMPRESSED_SRGB_S3TC_DXT1_EXT);
m_enabled_compressed_texture_formats.append(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT);
m_enabled_compressed_texture_formats.append(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT);
m_enabled_compressed_texture_formats.append(GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT);
}
VERIFY(m_webgl_compressed_texture_s3tc_srgb_extension);
return m_webgl_compressed_texture_s3tc_srgb_extension;
}
if (name.equals_ignoring_ascii_case("WEBGL_draw_buffers"sv) && context().webgl_version() == OpenGLContext::WebGLVersion::WebGL1) {
if (!m_webgl_draw_buffers_extension) {
m_webgl_draw_buffers_extension = MUST(Extensions::WebGLDrawBuffers::create(realm(), *this));
}
VERIFY(m_webgl_draw_buffers_extension);
return m_webgl_draw_buffers_extension;
}
return nullptr;
}
void WebGLRenderingContextBase::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_angle_instanced_arrays_extension);
visitor.visit(m_ext_blend_min_max_extension);
visitor.visit(m_ext_color_buffer_float_extension);
visitor.visit(m_ext_render_snorm);
visitor.visit(m_ext_texture_filter_anisotropic);
visitor.visit(m_ext_texture_norm16);
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);
visitor.visit(m_webgl_compressed_texture_s3tc_srgb_extension);
visitor.visit(m_webgl_draw_buffers_extension);
}
bool WebGLRenderingContextBase::ext_texture_filter_anisotropic_extension_enabled() const
{
return !!m_ext_texture_filter_anisotropic;
}
bool WebGLRenderingContextBase::angle_instanced_arrays_extension_enabled() const
{
return !!m_angle_instanced_arrays_extension;
}
bool WebGLRenderingContextBase::oes_standard_derivatives_extension_enabled() const
{
return !!m_oes_standard_derivatives_object_extension;
}
bool WebGLRenderingContextBase::webgl_draw_buffers_extension_enabled() const
{
return !!m_webgl_draw_buffers_extension;
}
ReadonlySpan<WebIDL::UnsignedLong> WebGLRenderingContextBase::enabled_compressed_texture_formats() const
{
return m_enabled_compressed_texture_formats;
}
Optional<Gfx::BitmapExportResult> WebGLRenderingContextBase::read_and_pixel_convert_texture_image_source(TexImageSource const& source, WebIDL::UnsignedLong format, WebIDL::UnsignedLong type, Optional<int> destination_width, Optional<int> destination_height)
{
// FIXME: If this function is called with an ImageData whose data attribute has been neutered,