LibWeb: Deduplicate WebGL1 implementations from WebGL2

This makes the WebGL2 implementation file inherit from the WebGL1
implementation file. This is actually closer to what the IDL files
describe and allows us to not have to maintain two copies of the same
functions.
This commit is contained in:
Undefine 2025-11-03 18:12:45 +01:00 committed by Alexander Kalenik
parent 7a1668fe22
commit 5b88b76b84
Notes: github-actions[bot] 2025-11-05 01:20:37 +00:00
4 changed files with 384 additions and 2304 deletions

File diff suppressed because it is too large Load diff

View file

@ -13,22 +13,17 @@
#include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/Forward.h>
#include <LibWeb/WebGL/Types.h>
#include <LibWeb/WebGL/WebGLRenderingContextBase.h>
#include <LibWeb/WebGL/WebGLRenderingContextImpl.h>
#include <LibWeb/WebIDL/Types.h>
namespace Web::WebGL {
using namespace Web::HTML;
class WebGL2RenderingContextImpl : public WebGLRenderingContextBase {
class WebGL2RenderingContextImpl : public WebGLRenderingContextImpl {
public:
WebGL2RenderingContextImpl(JS::Realm&, NonnullOwnPtr<OpenGLContext>);
virtual OpenGLContext& context() override { return *m_context; }
virtual void present() = 0;
virtual void needs_to_present() = 0;
virtual void set_error(GLenum) = 0;
void copy_buffer_sub_data(WebIDL::UnsignedLong read_target, WebIDL::UnsignedLong write_target, WebIDL::LongLong read_offset, WebIDL::LongLong write_offset, WebIDL::LongLong size);
void get_buffer_sub_data(WebIDL::UnsignedLong target, WebIDL::LongLong src_byte_offset, GC::Root<WebIDL::ArrayBufferView> dst_buffer, WebIDL::UnsignedLongLong dst_offset, WebIDL::UnsignedLong length);
void blit_framebuffer(WebIDL::Long src_x0, WebIDL::Long src_y0, WebIDL::Long src_x1, WebIDL::Long src_y1, WebIDL::Long dst_x0, WebIDL::Long dst_y0, WebIDL::Long dst_x1, WebIDL::Long dst_y1, WebIDL::UnsignedLong mask, WebIDL::UnsignedLong filter);
@ -107,141 +102,6 @@ public:
void bind_vertex_array(GC::Root<WebGLVertexArrayObject> array);
void compressed_tex_image3d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::UnsignedLong internalformat, WebIDL::Long width, WebIDL::Long height, WebIDL::Long depth, WebIDL::Long border, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length_override);
void compressed_tex_sub_image3d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::Long zoffset, WebIDL::Long width, WebIDL::Long height, WebIDL::Long depth, WebIDL::UnsignedLong format, GC::Root<WebIDL::ArrayBufferView> src_data, WebIDL::UnsignedLongLong src_offset, WebIDL::UnsignedLong src_length_override);
void active_texture(WebIDL::UnsignedLong texture);
void attach_shader(GC::Root<WebGLProgram> program, GC::Root<WebGLShader> shader);
void bind_attrib_location(GC::Root<WebGLProgram> program, WebIDL::UnsignedLong index, String name);
void bind_buffer(WebIDL::UnsignedLong target, GC::Root<WebGLBuffer> buffer);
void bind_framebuffer(WebIDL::UnsignedLong target, GC::Root<WebGLFramebuffer> framebuffer);
void bind_renderbuffer(WebIDL::UnsignedLong target, GC::Root<WebGLRenderbuffer> renderbuffer);
void bind_texture(WebIDL::UnsignedLong target, GC::Root<WebGLTexture> texture);
void blend_color(float red, float green, float blue, float alpha);
void blend_equation(WebIDL::UnsignedLong mode);
void blend_equation_separate(WebIDL::UnsignedLong mode_rgb, WebIDL::UnsignedLong mode_alpha);
void blend_func(WebIDL::UnsignedLong sfactor, WebIDL::UnsignedLong dfactor);
void blend_func_separate(WebIDL::UnsignedLong src_rgb, WebIDL::UnsignedLong dst_rgb, WebIDL::UnsignedLong src_alpha, WebIDL::UnsignedLong dst_alpha);
WebIDL::UnsignedLong check_framebuffer_status(WebIDL::UnsignedLong target);
void clear(WebIDL::UnsignedLong mask);
void clear_color(float red, float green, float blue, float alpha);
void clear_depth(float depth);
void clear_stencil(WebIDL::Long s);
void color_mask(bool red, bool green, bool blue, bool alpha);
void compile_shader(GC::Root<WebGLShader> shader);
void copy_tex_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::UnsignedLong internalformat, WebIDL::Long x, WebIDL::Long y, WebIDL::Long width, WebIDL::Long height, WebIDL::Long border);
void copy_tex_sub_image2d(WebIDL::UnsignedLong target, WebIDL::Long level, WebIDL::Long xoffset, WebIDL::Long yoffset, WebIDL::Long x, WebIDL::Long y, WebIDL::Long width, WebIDL::Long height);
GC::Root<WebGLBuffer> create_buffer();
GC::Root<WebGLFramebuffer> create_framebuffer();
GC::Root<WebGLProgram> create_program();
GC::Root<WebGLRenderbuffer> create_renderbuffer();
GC::Root<WebGLShader> create_shader(WebIDL::UnsignedLong type);
GC::Root<WebGLTexture> create_texture();
void cull_face(WebIDL::UnsignedLong mode);
void delete_buffer(GC::Root<WebGLBuffer> buffer);
void delete_framebuffer(GC::Root<WebGLFramebuffer> framebuffer);
void delete_program(GC::Root<WebGLProgram> program);
void delete_renderbuffer(GC::Root<WebGLRenderbuffer> renderbuffer);
void delete_shader(GC::Root<WebGLShader> shader);
void delete_texture(GC::Root<WebGLTexture> texture);
void depth_func(WebIDL::UnsignedLong func);
void depth_mask(bool flag);
void depth_range(float z_near, float z_far);
void detach_shader(GC::Root<WebGLProgram> program, GC::Root<WebGLShader> shader);
void disable(WebIDL::UnsignedLong cap);
void disable_vertex_attrib_array(WebIDL::UnsignedLong index);
void draw_arrays(WebIDL::UnsignedLong mode, WebIDL::Long first, WebIDL::Long count);
void draw_elements(WebIDL::UnsignedLong mode, WebIDL::Long count, WebIDL::UnsignedLong type, WebIDL::LongLong offset);
void enable(WebIDL::UnsignedLong cap);
void enable_vertex_attrib_array(WebIDL::UnsignedLong index);
void finish();
void flush();
void framebuffer_renderbuffer(WebIDL::UnsignedLong target, WebIDL::UnsignedLong attachment, WebIDL::UnsignedLong renderbuffertarget, GC::Root<WebGLRenderbuffer> renderbuffer);
void framebuffer_texture2d(WebIDL::UnsignedLong target, WebIDL::UnsignedLong attachment, WebIDL::UnsignedLong textarget, GC::Root<WebGLTexture> texture, WebIDL::Long level);
void front_face(WebIDL::UnsignedLong mode);
void generate_mipmap(WebIDL::UnsignedLong target);
GC::Root<WebGLActiveInfo> get_active_attrib(GC::Root<WebGLProgram> program, WebIDL::UnsignedLong index);
GC::Root<WebGLActiveInfo> get_active_uniform(GC::Root<WebGLProgram> program, WebIDL::UnsignedLong index);
Optional<Vector<GC::Root<WebGLShader>>> get_attached_shaders(GC::Root<WebGLProgram> program);
WebIDL::Long get_attrib_location(GC::Root<WebGLProgram> program, String name);
JS::Value get_buffer_parameter(WebIDL::UnsignedLong target, WebIDL::UnsignedLong pname);
JS::Value get_parameter(WebIDL::UnsignedLong pname);
WebIDL::UnsignedLong get_error();
JS::Value get_program_parameter(GC::Root<WebGLProgram> program, WebIDL::UnsignedLong pname);
Optional<String> get_program_info_log(GC::Root<WebGLProgram> program);
JS::Value get_shader_parameter(GC::Root<WebGLShader> shader, WebIDL::UnsignedLong pname);
GC::Root<WebGLShaderPrecisionFormat> get_shader_precision_format(WebIDL::UnsignedLong shadertype, WebIDL::UnsignedLong precisiontype);
Optional<String> get_shader_info_log(GC::Root<WebGLShader> shader);
Optional<String> get_shader_source(GC::Root<WebGLShader> shader);
JS::Value get_uniform(GC::Root<WebGLProgram> program, GC::Root<WebGLUniformLocation> location);
GC::Root<WebGLUniformLocation> get_uniform_location(GC::Root<WebGLProgram> program, String name);
JS::Value get_vertex_attrib(WebIDL::UnsignedLong index, WebIDL::UnsignedLong pname);
WebIDL::LongLong get_vertex_attrib_offset(WebIDL::UnsignedLong index, WebIDL::UnsignedLong pname);
void hint(WebIDL::UnsignedLong target, WebIDL::UnsignedLong mode);
bool is_buffer(GC::Root<WebGLBuffer> buffer);
bool is_enabled(WebIDL::UnsignedLong cap);
bool is_framebuffer(GC::Root<WebGLFramebuffer> framebuffer);
bool is_program(GC::Root<WebGLProgram> program);
bool is_renderbuffer(GC::Root<WebGLRenderbuffer> renderbuffer);
bool is_shader(GC::Root<WebGLShader> shader);
bool is_texture(GC::Root<WebGLTexture> texture);
void line_width(float width);
void link_program(GC::Root<WebGLProgram> program);
void pixel_storei(WebIDL::UnsignedLong pname, WebIDL::Long param);
void polygon_offset(float factor, float units);
void renderbuffer_storage(WebIDL::UnsignedLong target, WebIDL::UnsignedLong internalformat, WebIDL::Long width, WebIDL::Long height);
void sample_coverage(float value, bool invert);
void scissor(WebIDL::Long x, WebIDL::Long y, WebIDL::Long width, WebIDL::Long height);
void shader_source(GC::Root<WebGLShader> shader, String source);
void stencil_func(WebIDL::UnsignedLong func, WebIDL::Long ref, WebIDL::UnsignedLong mask);
void stencil_func_separate(WebIDL::UnsignedLong face, WebIDL::UnsignedLong func, WebIDL::Long ref, WebIDL::UnsignedLong mask);
void stencil_mask(WebIDL::UnsignedLong mask);
void stencil_mask_separate(WebIDL::UnsignedLong face, WebIDL::UnsignedLong mask);
void stencil_op(WebIDL::UnsignedLong fail, WebIDL::UnsignedLong zfail, WebIDL::UnsignedLong zpass);
void stencil_op_separate(WebIDL::UnsignedLong face, WebIDL::UnsignedLong fail, WebIDL::UnsignedLong zfail, WebIDL::UnsignedLong zpass);
void tex_parameterf(WebIDL::UnsignedLong target, WebIDL::UnsignedLong pname, float param);
void tex_parameteri(WebIDL::UnsignedLong target, WebIDL::UnsignedLong pname, WebIDL::Long param);
void uniform1f(GC::Root<WebGLUniformLocation> location, float x);
void uniform2f(GC::Root<WebGLUniformLocation> location, float x, float y);
void uniform3f(GC::Root<WebGLUniformLocation> location, float x, float y, float z);
void uniform4f(GC::Root<WebGLUniformLocation> location, float x, float y, float z, float w);
void uniform1i(GC::Root<WebGLUniformLocation> location, WebIDL::Long x);
void uniform2i(GC::Root<WebGLUniformLocation> location, WebIDL::Long x, WebIDL::Long y);
void uniform3i(GC::Root<WebGLUniformLocation> location, WebIDL::Long x, WebIDL::Long y, WebIDL::Long z);
void uniform4i(GC::Root<WebGLUniformLocation> location, WebIDL::Long x, WebIDL::Long y, WebIDL::Long z, WebIDL::Long w);
void use_program(GC::Root<WebGLProgram> program);
void validate_program(GC::Root<WebGLProgram> program);
void vertex_attrib1f(WebIDL::UnsignedLong index, float x);
void vertex_attrib2f(WebIDL::UnsignedLong index, float x, float y);
void vertex_attrib3f(WebIDL::UnsignedLong index, float x, float y, float z);
void vertex_attrib4f(WebIDL::UnsignedLong index, float x, float y, float z, float w);
void vertex_attrib1fv(WebIDL::UnsignedLong index, Float32List values);
void vertex_attrib2fv(WebIDL::UnsignedLong index, Float32List values);
void vertex_attrib3fv(WebIDL::UnsignedLong index, Float32List values);
void vertex_attrib4fv(WebIDL::UnsignedLong index, Float32List values);
void vertex_attrib_pointer(WebIDL::UnsignedLong index, WebIDL::Long size, WebIDL::UnsignedLong type, bool normalized, WebIDL::Long stride, WebIDL::LongLong offset);
void viewport(WebIDL::Long x, WebIDL::Long y, WebIDL::Long width, WebIDL::Long height);
protected:
virtual void visit_edges(JS::Cell::Visitor&) override;
GC::Ref<JS::Realm> m_realm;
GC::Ptr<WebGLBuffer> m_array_buffer_binding;
GC::Ptr<WebGLBuffer> m_element_array_buffer_binding;
GC::Ptr<WebGLProgram> m_current_program;
GC::Ptr<WebGLFramebuffer> m_framebuffer_binding;
GC::Ptr<WebGLRenderbuffer> m_renderbuffer_binding;
GC::Ptr<WebGLTexture> m_texture_binding_2d;
GC::Ptr<WebGLTexture> m_texture_binding_cube_map;
GC::Ptr<WebGLBuffer> m_uniform_buffer_binding;
GC::Ptr<WebGLBuffer> m_copy_read_buffer_binding;
GC::Ptr<WebGLBuffer> m_copy_write_buffer_binding;
GC::Ptr<WebGLBuffer> m_transform_feedback_buffer_binding;
GC::Ptr<WebGLBuffer> m_pixel_pack_buffer_binding;
GC::Ptr<WebGLBuffer> m_pixel_unpack_buffer_binding;
GC::Ptr<WebGLTexture> m_texture_binding_2d_array;
GC::Ptr<WebGLTexture> m_texture_binding_3d;
GC::Ptr<WebGLTransformFeedback> m_transform_feedback_binding;
NonnullOwnPtr<OpenGLContext> m_context;
};
}

View file

@ -1,6 +1,7 @@
/*
* Copyright (c) 2024-2025, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
* Copyright (c) 2024-2025, Luke Wilde <luke@ladybird.org>
* Copyright (c) 2025, Undefine <undefine@undefine.pl>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
@ -28,6 +29,7 @@ extern "C" {
#include <LibWeb/WebGL/WebGLShaderPrecisionFormat.h>
#include <LibWeb/WebGL/WebGLSync.h>
#include <LibWeb/WebGL/WebGLTexture.h>
#include <LibWeb/WebGL/WebGLTransformFeedback.h>
#include <LibWeb/WebGL/WebGLUniformLocation.h>
#include <LibWeb/WebGL/WebGLVertexArrayObject.h>
#include <LibWeb/WebIDL/Buffers.h>
@ -134,18 +136,50 @@ void WebGLRenderingContextImpl::bind_buffer(WebIDL::UnsignedLong target, GC::Roo
buffer_handle = handle_or_error.release_value();
}
switch (target) {
case GL_ELEMENT_ARRAY_BUFFER:
m_element_array_buffer_binding = buffer;
break;
case GL_ARRAY_BUFFER:
m_array_buffer_binding = buffer;
break;
default:
dbgln("Unknown WebGL buffer object binding target for storing current binding: 0x{:04x}", target);
set_error(GL_INVALID_ENUM);
return;
if (m_context->webgl_version() == OpenGLContext::WebGLVersion::WebGL2) {
switch (target) {
case GL_ARRAY_BUFFER:
m_array_buffer_binding = buffer;
break;
case GL_COPY_READ_BUFFER:
m_copy_read_buffer_binding = buffer;
break;
case GL_COPY_WRITE_BUFFER:
m_copy_write_buffer_binding = buffer;
break;
case GL_ELEMENT_ARRAY_BUFFER:
m_element_array_buffer_binding = buffer;
break;
case GL_PIXEL_PACK_BUFFER:
m_pixel_pack_buffer_binding = buffer;
break;
case GL_PIXEL_UNPACK_BUFFER:
m_pixel_unpack_buffer_binding = buffer;
break;
case GL_TRANSFORM_FEEDBACK_BUFFER:
m_transform_feedback_buffer_binding = buffer;
break;
case GL_UNIFORM_BUFFER:
m_uniform_buffer_binding = buffer;
break;
default:
dbgln("Unknown WebGL buffer object binding target for storing current binding: 0x{:04x}", target);
set_error(GL_INVALID_ENUM);
return;
}
} else {
switch (target) {
case GL_ELEMENT_ARRAY_BUFFER:
m_element_array_buffer_binding = buffer;
break;
case GL_ARRAY_BUFFER:
m_array_buffer_binding = buffer;
break;
default:
dbgln("Unknown WebGL buffer object binding target for storing current binding: 0x{:04x}", target);
set_error(GL_INVALID_ENUM);
return;
}
}
glBindBuffer(target, buffer_handle);
@ -209,6 +243,23 @@ void WebGLRenderingContextImpl::bind_texture(WebIDL::UnsignedLong target, GC::Ro
m_texture_binding_cube_map = texture;
break;
case GL_TEXTURE_2D_ARRAY:
if (m_context->webgl_version() == OpenGLContext::WebGLVersion::WebGL2) {
m_texture_binding_2d_array = texture;
break;
}
set_error(GL_INVALID_ENUM);
return;
case GL_TEXTURE_3D:
if (m_context->webgl_version() == OpenGLContext::WebGLVersion::WebGL2) {
m_texture_binding_3d = texture;
break;
}
set_error(GL_INVALID_ENUM);
return;
default:
dbgln("Unknown WebGL texture target for storing current binding: 0x{:04x}", target);
set_error(GL_INVALID_ENUM);
@ -1184,6 +1235,37 @@ JS::Value WebGLRenderingContextImpl::get_parameter(WebIDL::UnsignedLong pname)
auto array_buffer = JS::ArrayBuffer::create(m_realm, move(byte_buffer));
return JS::Int32Array::create(m_realm, 4, array_buffer);
}
case GL_FRAGMENT_SHADER_DERIVATIVE_HINT: {
if (m_context->webgl_version() == OpenGLContext::WebGLVersion::WebGL2) { // FIXME: Allow this code path for GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES
GLint result { 0 };
glGetIntegervRobustANGLE(GL_FRAGMENT_SHADER_DERIVATIVE_HINT, 1, nullptr, &result);
return JS::Value(result);
}
set_error(GL_INVALID_ENUM);
return JS::js_null();
}
case GL_MAX_COLOR_ATTACHMENTS: {
if (m_context->webgl_version() == OpenGLContext::WebGLVersion::WebGL2) { // FIXME: Allow this code path for MAX_COLOR_ATTACHMENTS_WEBGL
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_COLOR_ATTACHMENTS, 1, nullptr, &result);
return JS::Value(result);
}
set_error(GL_INVALID_ENUM);
return JS::js_null();
}
case GL_MAX_DRAW_BUFFERS: {
if (m_context->webgl_version() == OpenGLContext::WebGLVersion::WebGL2) { // FIXME: Allow this code path for MAX_DRAW_BUFFERS_WEBGL
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_DRAW_BUFFERS, 1, nullptr, &result);
return JS::Value(result);
}
set_error(GL_INVALID_ENUM);
return JS::js_null();
}
case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: {
if (ext_texture_filter_anisotropic_extension_enabled()) {
GLfloat result { 0.0f };
@ -1194,6 +1276,7 @@ JS::Value WebGLRenderingContextImpl::get_parameter(WebIDL::UnsignedLong pname)
set_error(GL_INVALID_ENUM);
return JS::js_null();
}
case COMPRESSED_TEXTURE_FORMATS: {
auto formats = enabled_compressed_texture_formats();
auto byte_buffer = MUST(ByteBuffer::copy(formats.data(), formats.reinterpret<u8 const>().size()));
@ -1204,11 +1287,249 @@ JS::Value WebGLRenderingContextImpl::get_parameter(WebIDL::UnsignedLong pname)
return JS::Value(m_unpack_flip_y);
case UNPACK_PREMULTIPLY_ALPHA_WEBGL:
return JS::Value(m_unpack_premultiply_alpha);
default:
dbgln("Unknown WebGL parameter name: {:x}", pname);
set_error(GL_INVALID_ENUM);
return JS::js_null();
}
if (m_context->webgl_version() == OpenGLContext::WebGLVersion::WebGL2) {
switch (pname) {
case GL_COPY_READ_BUFFER_BINDING: {
if (!m_copy_read_buffer_binding)
return JS::js_null();
return JS::Value(m_copy_read_buffer_binding);
}
case GL_COPY_WRITE_BUFFER_BINDING: {
if (!m_copy_write_buffer_binding)
return JS::js_null();
return JS::Value(m_copy_write_buffer_binding);
}
case GL_MAX_SAMPLES: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_SAMPLES, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_3D_TEXTURE_SIZE: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_3D_TEXTURE_SIZE, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_ARRAY_TEXTURE_LAYERS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_ARRAY_TEXTURE_LAYERS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_VERTEX_UNIFORM_COMPONENTS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_VERTEX_UNIFORM_COMPONENTS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_UNIFORM_BLOCK_SIZE: {
GLint64 result { 0 };
glGetInteger64vRobustANGLE(GL_MAX_UNIFORM_BLOCK_SIZE, 1, nullptr, &result);
return JS::Value(static_cast<double>(result));
}
case GL_MAX_UNIFORM_BUFFER_BINDINGS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_UNIFORM_BUFFER_BINDINGS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_VERTEX_UNIFORM_BLOCKS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_VERTEX_UNIFORM_BLOCKS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_FRAGMENT_INPUT_COMPONENTS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_FRAGMENT_INPUT_COMPONENTS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_FRAGMENT_UNIFORM_COMPONENTS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_COMBINED_UNIFORM_BLOCKS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_COMBINED_UNIFORM_BLOCKS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS: {
GLint64 result { 0 };
glGetInteger64vRobustANGLE(GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS, 1, nullptr, &result);
return JS::Value(static_cast<double>(result));
}
case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS: {
GLint64 result { 0 };
glGetInteger64vRobustANGLE(GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS, 1, nullptr, &result);
return JS::Value(static_cast<double>(result));
}
case GL_MAX_ELEMENT_INDEX: {
GLint64 result { 0 };
glGetInteger64vRobustANGLE(GL_MAX_ELEMENT_INDEX, 1, nullptr, &result);
return JS::Value(static_cast<double>(result));
}
case GL_MAX_FRAGMENT_UNIFORM_BLOCKS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_FRAGMENT_UNIFORM_BLOCKS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_VARYING_COMPONENTS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_VARYING_COMPONENTS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_ELEMENTS_INDICES: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_ELEMENTS_INDICES, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_ELEMENTS_VERTICES: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_ELEMENTS_VERTICES, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_TEXTURE_LOD_BIAS: {
GLfloat result { 0.0f };
glGetFloatvRobustANGLE(GL_MAX_TEXTURE_LOD_BIAS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MIN_PROGRAM_TEXEL_OFFSET: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MIN_PROGRAM_TEXEL_OFFSET, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_PROGRAM_TEXEL_OFFSET: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_PROGRAM_TEXEL_OFFSET, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_VERTEX_OUTPUT_COMPONENTS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_MAX_VERTEX_OUTPUT_COMPONENTS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_MAX_SERVER_WAIT_TIMEOUT: {
GLint64 result { 0 };
glGetInteger64vRobustANGLE(GL_MAX_SERVER_WAIT_TIMEOUT, 1, nullptr, &result);
return JS::Value(static_cast<double>(result));
}
case GL_PACK_ROW_LENGTH: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_PACK_ROW_LENGTH, 1, nullptr, &result);
return JS::Value(result);
}
case GL_PACK_SKIP_ROWS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_PACK_SKIP_ROWS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_PACK_SKIP_PIXELS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_PACK_SKIP_PIXELS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_PIXEL_PACK_BUFFER_BINDING: {
if (!m_pixel_pack_buffer_binding)
return JS::js_null();
return JS::Value(m_pixel_pack_buffer_binding);
}
case GL_PIXEL_UNPACK_BUFFER_BINDING: {
if (!m_pixel_unpack_buffer_binding)
return JS::js_null();
return JS::Value(m_pixel_unpack_buffer_binding);
}
case GL_TEXTURE_BINDING_2D_ARRAY: {
if (!m_texture_binding_2d_array)
return JS::js_null();
return JS::Value(m_texture_binding_2d_array);
}
case GL_TRANSFORM_FEEDBACK_ACTIVE: {
GLboolean result { GL_FALSE };
glGetBooleanvRobustANGLE(GL_TRANSFORM_FEEDBACK_ACTIVE, 1, nullptr, &result);
return JS::Value(result == GL_TRUE);
}
case GL_TRANSFORM_FEEDBACK_BINDING: {
if (!m_transform_feedback_binding)
return JS::js_null();
return JS::Value(m_transform_feedback_binding);
}
case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: {
if (!m_transform_feedback_buffer_binding)
return JS::js_null();
return JS::Value(m_transform_feedback_buffer_binding);
}
case GL_TRANSFORM_FEEDBACK_PAUSED: {
GLboolean result { GL_FALSE };
glGetBooleanvRobustANGLE(GL_TRANSFORM_FEEDBACK_PAUSED, 1, nullptr, &result);
return JS::Value(result == GL_TRUE);
}
case GL_RASTERIZER_DISCARD: {
GLboolean result { GL_FALSE };
glGetBooleanvRobustANGLE(GL_RASTERIZER_DISCARD, 1, nullptr, &result);
return JS::Value(result == GL_TRUE);
}
case GL_SAMPLER_BINDING: {
GLint handle { 0 };
glGetIntegervRobustANGLE(GL_SAMPLER_BINDING, 1, nullptr, &handle);
return WebGLSampler::create(m_realm, *this, handle);
}
case GL_UNIFORM_BUFFER_BINDING: {
if (!m_uniform_buffer_binding)
return JS::js_null();
return JS::Value(m_uniform_buffer_binding);
}
case GL_UNPACK_IMAGE_HEIGHT: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_UNPACK_IMAGE_HEIGHT, 1, nullptr, &result);
return JS::Value(result);
}
case GL_UNPACK_ROW_LENGTH: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_UNPACK_ROW_LENGTH, 1, nullptr, &result);
return JS::Value(result);
}
case GL_UNPACK_SKIP_IMAGES: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_UNPACK_SKIP_IMAGES, 1, nullptr, &result);
return JS::Value(result);
}
case GL_UNPACK_SKIP_PIXELS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_UNPACK_SKIP_PIXELS, 1, nullptr, &result);
return JS::Value(result);
}
case GL_UNPACK_SKIP_ROWS: {
GLint result { 0 };
glGetIntegervRobustANGLE(GL_UNPACK_SKIP_ROWS, 1, nullptr, &result);
return JS::Value(result);
}
case MAX_CLIENT_WAIT_TIMEOUT_WEBGL:
// FIXME: Make this an actual limit
return JS::js_infinity();
}
}
dbgln("Unknown WebGL parameter name: {:x}", pname);
set_error(GL_INVALID_ENUM);
return JS::js_null();
}
WebIDL::UnsignedLong WebGLRenderingContextImpl::get_error()
@ -1237,8 +1558,17 @@ JS::Value WebGLRenderingContextImpl::get_program_parameter(GC::Root<WebGLProgram
case GL_ATTACHED_SHADERS:
case GL_ACTIVE_ATTRIBUTES:
case GL_ACTIVE_UNIFORMS:
return JS::Value(result);
case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
case GL_TRANSFORM_FEEDBACK_VARYINGS:
case GL_ACTIVE_UNIFORM_BLOCKS:
if (m_context->webgl_version() == OpenGLContext::WebGLVersion::WebGL2)
return JS::Value(result);
set_error(GL_INVALID_ENUM);
return JS::js_null();
case GL_DELETE_STATUS:
case GL_LINK_STATUS:
case GL_VALIDATE_STATUS:
@ -1410,10 +1740,10 @@ JS::Value WebGLRenderingContextImpl::get_vertex_attrib(WebIDL::UnsignedLong inde
glGetVertexAttribivRobustANGLE(index, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, 1, nullptr, &handle);
return WebGLBuffer::create(m_realm, *this, handle);
}
case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE: {
if (angle_instanced_arrays_extension_enabled()) {
case GL_VERTEX_ATTRIB_ARRAY_DIVISOR: { // NOTE: This has the same value as GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE
if (angle_instanced_arrays_extension_enabled() || m_context->webgl_version() == OpenGLContext::WebGLVersion::WebGL2) {
GLint result { 0 };
glGetVertexAttribivRobustANGLE(index, GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE, 1, nullptr, &result);
glGetVertexAttribivRobustANGLE(index, GL_VERTEX_ATTRIB_ARRAY_DIVISOR, 1, nullptr, &result);
return JS::Value(result);
}
@ -1425,6 +1755,16 @@ JS::Value WebGLRenderingContextImpl::get_vertex_attrib(WebIDL::UnsignedLong inde
glGetVertexAttribivRobustANGLE(index, GL_VERTEX_ATTRIB_ARRAY_ENABLED, 1, nullptr, &result);
return JS::Value(result == GL_TRUE);
}
case GL_VERTEX_ATTRIB_ARRAY_INTEGER: {
if (m_context->webgl_version() == OpenGLContext::WebGLVersion::WebGL2) {
GLint result { 0 };
glGetVertexAttribivRobustANGLE(index, GL_VERTEX_ATTRIB_ARRAY_INTEGER, 1, nullptr, &result);
return JS::Value(result == GL_TRUE);
}
set_error(GL_INVALID_ENUM);
return JS::js_null();
}
case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED: {
GLint result { 0 };
glGetVertexAttribivRobustANGLE(index, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, 1, nullptr, &result);
@ -1620,15 +1960,9 @@ void WebGLRenderingContextImpl::renderbuffer_storage(WebIDL::UnsignedLong target
{
m_context->make_current();
#define GL_DEPTH_STENCIL 0x84F9
#define GL_DEPTH24_STENCIL8 0x88F0
if (internalformat == GL_DEPTH_STENCIL)
internalformat = GL_DEPTH24_STENCIL8;
#undef GL_DEPTH_STENCIL
#undef GL_DEPTH24_STENCIL8
glRenderbufferStorage(target, internalformat, width, height);
}
@ -1891,6 +2225,16 @@ void WebGLRenderingContextImpl::visit_edges(JS::Cell::Visitor& visitor)
visitor.visit(m_renderbuffer_binding);
visitor.visit(m_texture_binding_2d);
visitor.visit(m_texture_binding_cube_map);
visitor.visit(m_uniform_buffer_binding);
visitor.visit(m_copy_read_buffer_binding);
visitor.visit(m_copy_write_buffer_binding);
visitor.visit(m_transform_feedback_buffer_binding);
visitor.visit(m_texture_binding_2d_array);
visitor.visit(m_texture_binding_3d);
visitor.visit(m_transform_feedback_binding);
visitor.visit(m_pixel_pack_buffer_binding);
visitor.visit(m_pixel_unpack_buffer_binding);
}
}

View file

@ -153,6 +153,17 @@ protected:
GC::Ptr<WebGLTexture> m_texture_binding_2d;
GC::Ptr<WebGLTexture> m_texture_binding_cube_map;
// FIXME: Those are WebGL2 only but those need to be accessible from shared methods
GC::Ptr<WebGLBuffer> m_uniform_buffer_binding;
GC::Ptr<WebGLBuffer> m_copy_read_buffer_binding;
GC::Ptr<WebGLBuffer> m_copy_write_buffer_binding;
GC::Ptr<WebGLBuffer> m_transform_feedback_buffer_binding;
GC::Ptr<WebGLBuffer> m_pixel_pack_buffer_binding;
GC::Ptr<WebGLBuffer> m_pixel_unpack_buffer_binding;
GC::Ptr<WebGLTexture> m_texture_binding_2d_array;
GC::Ptr<WebGLTexture> m_texture_binding_3d;
GC::Ptr<WebGLTransformFeedback> m_transform_feedback_binding;
NonnullOwnPtr<OpenGLContext> m_context;
};