Merge 3fca836e15
into 3eefa464ee
This commit is contained in:
commit
18c6840c0f
11 changed files with 558 additions and 46 deletions
|
@ -69,6 +69,7 @@ void WebGL2RenderingContext::initialize(JS::Realm& realm)
|
|||
void WebGL2RenderingContext::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
WebGL2RenderingContextImpl::visit_edges(visitor);
|
||||
visitor.visit(m_canvas_element);
|
||||
}
|
||||
|
||||
|
@ -128,7 +129,10 @@ Optional<WebGLContextAttributes> WebGL2RenderingContext::get_context_attributes(
|
|||
|
||||
void WebGL2RenderingContext::set_size(Gfx::IntSize const& size)
|
||||
{
|
||||
context().set_size(size);
|
||||
Gfx::IntSize final_size;
|
||||
final_size.set_width(max(size.width(), 1));
|
||||
final_size.set_height(max(size.height(), 1));
|
||||
context().set_size(final_size);
|
||||
}
|
||||
|
||||
void WebGL2RenderingContext::reset_to_default_state()
|
||||
|
|
|
@ -298,7 +298,7 @@ interface mixin WebGL2RenderingContextBase {
|
|||
// Framebuffer objects
|
||||
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<GLenum> attachments);
|
||||
undefined invalidateFramebuffer(GLenum target, sequence<GLenum> attachments);
|
||||
[FIXME] undefined invalidateSubFramebuffer(GLenum target, sequence<GLenum> attachments, GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
undefined readBuffer(GLenum src);
|
||||
|
||||
|
@ -360,22 +360,22 @@ interface mixin WebGL2RenderingContextBase {
|
|||
[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);
|
||||
undefined vertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, GLintptr offset);
|
||||
|
||||
// Writing to the drawing buffer
|
||||
[FIXME] undefined vertexAttribDivisor(GLuint index, GLuint divisor);
|
||||
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);
|
||||
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
|
||||
undefined drawBuffers(sequence<GLenum> 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);
|
||||
undefined clearBufferfv(GLenum buffer, GLint drawbuffer, Float32List values, optional unsigned long long srcOffset = 0);
|
||||
undefined clearBufferiv(GLenum buffer, GLint drawbuffer, Int32List values, optional unsigned long long srcOffset = 0);
|
||||
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);
|
||||
undefined clearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil);
|
||||
|
||||
// Query Objects
|
||||
[FIXME] WebGLQuery createQuery();
|
||||
|
@ -388,11 +388,11 @@ interface mixin WebGL2RenderingContextBase {
|
|||
|
||||
// Sampler Objects
|
||||
WebGLSampler createSampler();
|
||||
[FIXME] undefined deleteSampler(WebGLSampler? sampler);
|
||||
undefined deleteSampler(WebGLSampler? sampler);
|
||||
[FIXME] GLboolean isSampler(WebGLSampler? sampler); // [WebGLHandlesContextLoss]
|
||||
undefined bindSampler(GLuint unit, WebGLSampler? sampler);
|
||||
[FIXME] undefined samplerParameteri(WebGLSampler sampler, GLenum pname, GLint param);
|
||||
[FIXME] undefined samplerParameterf(WebGLSampler sampler, GLenum pname, GLfloat param);
|
||||
undefined samplerParameteri(WebGLSampler sampler, GLenum pname, GLint param);
|
||||
undefined samplerParameterf(WebGLSampler sampler, GLenum pname, GLfloat param);
|
||||
[FIXME] any getSamplerParameter(WebGLSampler sampler, GLenum pname);
|
||||
|
||||
// Sync objects
|
||||
|
@ -421,10 +421,10 @@ interface mixin WebGL2RenderingContextBase {
|
|||
[FIXME] any getIndexedParameter(GLenum target, GLuint index);
|
||||
[FIXME] sequence<GLuint>? getUniformIndices(WebGLProgram program, sequence<DOMString> uniformNames);
|
||||
[FIXME] any getActiveUniforms(WebGLProgram program, sequence<GLuint> 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);
|
||||
GLuint getUniformBlockIndex(WebGLProgram program, DOMString uniformBlockName);
|
||||
any getActiveUniformBlockParameter(WebGLProgram program, GLuint uniformBlockIndex, GLenum pname);
|
||||
DOMString? getActiveUniformBlockName(WebGLProgram program, GLuint uniformBlockIndex);
|
||||
undefined uniformBlockBinding(WebGLProgram program, GLuint uniformBlockIndex, GLuint uniformBlockBinding);
|
||||
|
||||
// Vertex Array Objects
|
||||
WebGLVertexArrayObject createVertexArray();
|
||||
|
|
|
@ -10,8 +10,8 @@ interface mixin WebGL2RenderingContextOverloads {
|
|||
undefined bufferData(GLenum target, BufferSource? srcData, GLenum usage);
|
||||
undefined bufferSubData(GLenum target, GLintptr dstByteOffset, BufferSource 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);
|
||||
undefined bufferData(GLenum target, [AllowShared] ArrayBufferView srcData, GLenum usage, unsigned long long srcOffset, optional GLuint length = 0);
|
||||
undefined bufferSubData(GLenum target, GLintptr dstByteOffset, [AllowShared] ArrayBufferView srcData, unsigned long long srcOffset, optional GLuint length = 0);
|
||||
|
||||
// WebGL1 legacy entrypoints:
|
||||
undefined texImage2D(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, [AllowShared] ArrayBufferView? pixels);
|
||||
|
@ -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);
|
||||
|
|
|
@ -86,6 +86,7 @@ void WebGLRenderingContext::initialize(JS::Realm& realm)
|
|||
void WebGLRenderingContext::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
WebGLRenderingContextImpl::visit_edges(visitor);
|
||||
visitor.visit(m_canvas_element);
|
||||
}
|
||||
|
||||
|
@ -145,7 +146,10 @@ Optional<WebGLContextAttributes> WebGLRenderingContext::get_context_attributes()
|
|||
|
||||
void WebGLRenderingContext::set_size(Gfx::IntSize const& size)
|
||||
{
|
||||
context().set_size(size);
|
||||
Gfx::IntSize final_size;
|
||||
final_size.set_width(max(size.width(), 1));
|
||||
final_size.set_height(max(size.height(), 1));
|
||||
context().set_size(final_size);
|
||||
}
|
||||
|
||||
void WebGLRenderingContext::reset_to_default_state()
|
||||
|
|
|
@ -13,6 +13,7 @@ namespace Web::WebGL {
|
|||
class WebGLRenderingContextBase {
|
||||
public:
|
||||
virtual GC::Cell const* gc_cell() const = 0;
|
||||
virtual void visit_edges(JS::Cell::Visitor&) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ interface mixin WebGLRenderingContextBase {
|
|||
undefined deleteBuffer(WebGLBuffer? buffer);
|
||||
undefined deleteFramebuffer(WebGLFramebuffer? framebuffer);
|
||||
undefined deleteProgram(WebGLProgram? program);
|
||||
[FIXME] undefined deleteRenderbuffer(WebGLRenderbuffer? renderbuffer);
|
||||
undefined deleteRenderbuffer(WebGLRenderbuffer? renderbuffer);
|
||||
undefined deleteShader(WebGLShader? shader);
|
||||
undefined deleteTexture(WebGLTexture? texture);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -29,6 +29,21 @@ u32 BufferableObjectBase::byte_length() const
|
|||
[](GC::Ref<JS::ArrayBuffer> array_buffer) { return static_cast<u32>(array_buffer->byte_length()); });
|
||||
}
|
||||
|
||||
u32 BufferableObjectBase::element_size() const
|
||||
{
|
||||
return m_bufferable_object.visit(
|
||||
[](GC::Ref<JS::TypedArrayBase> typed_array) -> u32 {
|
||||
auto typed_array_record = JS::make_typed_array_with_buffer_witness_record(typed_array, JS::ArrayBuffer::Order::SeqCst);
|
||||
return typed_array_record.object->element_size();
|
||||
},
|
||||
[](GC::Ref<JS::DataView>) -> u32 {
|
||||
return 1;
|
||||
},
|
||||
[](GC::Ref<JS::ArrayBuffer>) -> u32 {
|
||||
return 1;
|
||||
});
|
||||
}
|
||||
|
||||
GC::Ref<JS::Object> BufferableObjectBase::raw_object()
|
||||
{
|
||||
return m_bufferable_object.visit([](auto const& obj) -> GC::Ref<JS::Object> { return obj; });
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
virtual ~BufferableObjectBase() override = default;
|
||||
|
||||
u32 byte_length() const;
|
||||
u32 element_size() const;
|
||||
|
||||
GC::Ref<JS::Object> raw_object();
|
||||
GC::Ref<JS::Object const> raw_object() const { return const_cast<BufferableObjectBase&>(*this).raw_object(); }
|
||||
|
|
|
@ -210,7 +210,7 @@ JS::ThrowCompletionOr<ResolvedOverload> resolve_overload(JS::VM& vm, IDL::Effect
|
|||
// then remove from S all other entries.
|
||||
else if (value.is_object() && is<JS::DataView>(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<ResolvedOverload> 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<JS::TypedArrayBase const&>(value.as_object()).element_name() || type.name() == "BufferSource"))
|
||||
if (type.is_plain() && (type.name() == static_cast<JS::TypedArrayBase const&>(value.as_object()).element_name() || type.name() == "BufferSource" || type.name() == "ArrayBufferView"))
|
||||
return true;
|
||||
if (type.is_object())
|
||||
return true;
|
||||
|
|
|
@ -29,7 +29,16 @@ static bool is_webgl_object_type(StringView type_name)
|
|||
|
||||
static bool gl_function_modifies_framebuffer(StringView function_name)
|
||||
{
|
||||
return function_name == "clearColor"sv || function_name == "drawArrays"sv || function_name == "drawElements"sv;
|
||||
return function_name == "clear"sv
|
||||
|| function_name == "clearBufferfv"sv
|
||||
|| function_name == "clearBufferiv"sv
|
||||
|| function_name == "clearBufferuiv"sv
|
||||
|| function_name == "clearBufferfi"sv
|
||||
|| function_name == "drawArrays"sv
|
||||
|| function_name == "drawElements"sv
|
||||
|| function_name == "drawElementsInstanced"sv
|
||||
|| function_name == "blitFramebuffer"sv
|
||||
|| function_name == "invalidateFramebuffer"sv;
|
||||
}
|
||||
|
||||
static ByteString to_cpp_type(const IDL::Type& type, const IDL::Interface& interface)
|
||||
|
@ -180,6 +189,13 @@ static void generate_get_parameter(SourceGenerator& generator, int webgl_version
|
|||
{ "MAX_VERTEX_UNIFORM_BLOCKS"sv, { "GLint"sv }, 2 },
|
||||
{ "MAX_FRAGMENT_INPUT_COMPONENTS"sv, { "GLint"sv }, 2 },
|
||||
{ "MAX_COMBINED_UNIFORM_BLOCKS"sv, { "GLint"sv }, 2 },
|
||||
{ "UNIFORM_BUFFER_BINDING"sv, { "WebGLBuffer"sv }, 2 },
|
||||
{ "TEXTURE_BINDING_2D_ARRAY"sv, { "WebGLTexture"sv }, 2 },
|
||||
{ "COPY_READ_BUFFER_BINDING"sv, { "WebGLBuffer"sv }, 2 },
|
||||
{ "COPY_WRITE_BUFFER_BINDING"sv, { "WebGLBuffer"sv }, 2 },
|
||||
{ "MAX_ELEMENT_INDEX"sv, { "GLint64"sv }, 2 },
|
||||
{ "MAX_FRAGMENT_UNIFORM_BLOCKS"sv, { "GLint"sv }, 2 },
|
||||
{ "MAX_VARYING_COMPONENTS"sv, { "GLint"sv }, 2 },
|
||||
};
|
||||
|
||||
auto is_primitive_type = [](StringView type) {
|
||||
|
@ -236,12 +252,11 @@ static void generate_get_parameter(SourceGenerator& generator, int webgl_version
|
|||
return JS::@type_name@::create(m_realm, @element_count@, array_buffer);
|
||||
)~~~");
|
||||
} else if (type_name == "WebGLProgram"sv || type_name == "WebGLBuffer"sv || type_name == "WebGLTexture"sv || type_name == "WebGLFramebuffer"sv || type_name == "WebGLRenderbuffer"sv) {
|
||||
impl_generator.set("stored_name", name_and_type.name.to_lowercase_string());
|
||||
impl_generator.append(R"~~~(
|
||||
GLint result;
|
||||
glGetIntegerv(GL_@parameter_name@, &result);
|
||||
if (!result)
|
||||
if (!m_@stored_name@)
|
||||
return JS::js_null();
|
||||
return @type_name@::create(m_realm, *this, result);
|
||||
return JS::Value(m_@stored_name@);
|
||||
)~~~");
|
||||
} else {
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -337,6 +352,40 @@ static void generate_webgl_object_handle_unwrap(SourceGenerator& generator, Stri
|
|||
generator.append(unwrap_generator.as_string_view());
|
||||
}
|
||||
|
||||
static void generate_get_active_uniform_block_parameter(SourceGenerator& generator)
|
||||
{
|
||||
generate_webgl_object_handle_unwrap(generator, "program"sv, "JS::js_null()"sv);
|
||||
generator.append(R"~~~(
|
||||
switch (pname) {
|
||||
case GL_UNIFORM_BLOCK_BINDING:
|
||||
case GL_UNIFORM_BLOCK_DATA_SIZE:
|
||||
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS: {
|
||||
GLint result = 0;
|
||||
glGetActiveUniformBlockiv(program_handle, uniform_block_index, pname, &result);
|
||||
return JS::Value(result);
|
||||
}
|
||||
case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES: {
|
||||
GLint num_active_uniforms = 0;
|
||||
glGetActiveUniformBlockiv(program_handle, uniform_block_index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS, &num_active_uniforms);
|
||||
auto active_uniform_indices_buffer = MUST(ByteBuffer::create_zeroed(num_active_uniforms * sizeof(GLint)));
|
||||
glGetActiveUniformBlockiv(program_handle, uniform_block_index, GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES, reinterpret_cast<GLint*>(active_uniform_indices_buffer.data()));
|
||||
auto array_buffer = JS::ArrayBuffer::create(m_realm, move(active_uniform_indices_buffer));
|
||||
return JS::Uint32Array::create(m_realm, num_active_uniforms, array_buffer);
|
||||
}
|
||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
|
||||
case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER: {
|
||||
GLint result = 0;
|
||||
glGetActiveUniformBlockiv(program_handle, uniform_block_index, pname, &result);
|
||||
return JS::Value(result == GL_TRUE);
|
||||
}
|
||||
default:
|
||||
dbgln("Unknown WebGL active uniform block parameter name: {:x}", pname);
|
||||
set_error(GL_INVALID_ENUM);
|
||||
return JS::js_null();
|
||||
}
|
||||
)~~~");
|
||||
}
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
StringView generated_header_path;
|
||||
|
@ -576,6 +625,14 @@ public:
|
|||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "invalidateFramebuffer"sv) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
glInvalidateFramebuffer(target, attachments.size(), attachments.data());
|
||||
needs_to_present();
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "createVertexArray"sv) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
GLuint handle = 0;
|
||||
|
@ -680,7 +737,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
|
||||
|
@ -716,14 +773,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) {
|
||||
|
@ -749,7 +815,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<HTMLImageElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> {
|
||||
return source->immutable_bitmap();
|
||||
},
|
||||
[](GC::Root<HTMLCanvasElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> {
|
||||
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<HTMLVideoElement> const& source) -> RefPtr<Gfx::ImmutableBitmap> {
|
||||
return Gfx::ImmutableBitmap::create(*source->bitmap());
|
||||
},
|
||||
[](GC::Root<ImageBitmap> const& source) -> RefPtr<Gfx::ImmutableBitmap> {
|
||||
return Gfx::ImmutableBitmap::create(*source->bitmap());
|
||||
},
|
||||
[](GC::Root<ImageData> const& source) -> RefPtr<Gfx::ImmutableBitmap> {
|
||||
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) {
|
||||
|
@ -795,6 +912,11 @@ public:
|
|||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "getActiveUniformBlockParameter"sv) {
|
||||
generate_get_active_uniform_block_parameter(function_impl_generator);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "bufferData"sv && function.overload_index == 0) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
glBufferData(target, size, 0, usage);
|
||||
|
@ -802,6 +924,62 @@ public:
|
|||
continue;
|
||||
}
|
||||
|
||||
if (webgl_version == 2 && function.name == "bufferData"sv && function.overload_index == 2) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
VERIFY(src_data);
|
||||
auto const& viewed_array_buffer = src_data->viewed_array_buffer();
|
||||
auto const& byte_buffer = viewed_array_buffer->buffer();
|
||||
auto src_data_length = src_data->byte_length();
|
||||
auto src_data_element_size = src_data->element_size();
|
||||
u8 const* buffer_ptr = byte_buffer.data();
|
||||
|
||||
u64 copy_length = length == 0 ? src_data_length - src_offset : length;
|
||||
copy_length *= src_data_element_size;
|
||||
|
||||
if (src_offset > src_data_length) {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (src_offset + copy_length > src_data_length) {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
buffer_ptr += src_offset * src_data_element_size;
|
||||
glBufferData(target, copy_length, buffer_ptr, usage);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (webgl_version == 2 && function.name == "bufferSubData"sv && function.overload_index == 1) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
VERIFY(src_data);
|
||||
auto const& viewed_array_buffer = src_data->viewed_array_buffer();
|
||||
auto const& byte_buffer = viewed_array_buffer->buffer();
|
||||
auto src_data_length = src_data->byte_length();
|
||||
auto src_data_element_size = src_data->element_size();
|
||||
u8 const* buffer_ptr = byte_buffer.data();
|
||||
|
||||
u64 copy_length = length == 0 ? src_data_length - src_offset : length;
|
||||
copy_length *= src_data_element_size;
|
||||
|
||||
if (src_offset > src_data_length) {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
if (src_offset + copy_length > src_data_length) {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
buffer_ptr += src_offset * src_data_element_size;
|
||||
glBufferSubData(target, dst_byte_offset, copy_length, buffer_ptr);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "readPixels"sv) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
if (!pixels) {
|
||||
|
@ -832,6 +1010,14 @@ public:
|
|||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "drawElementsInstanced"sv) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
glDrawElementsInstanced(mode, count, type, reinterpret_cast<void*>(offset), instance_count);
|
||||
needs_to_present();
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "drawBuffers"sv) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
glDrawBuffers(buffers.size(), buffers.data());
|
||||
|
@ -867,14 +1053,16 @@ public:
|
|||
|
||||
if (webgl_version == 2) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
if (src_offset + src_length > (count * matrix_size)) {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
raw_data += src_offset;
|
||||
if (src_length == 0) {
|
||||
count -= src_offset;
|
||||
}
|
||||
|
||||
if (src_offset + src_length <= count) {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
} else {
|
||||
count = src_length;
|
||||
}
|
||||
)~~~");
|
||||
}
|
||||
|
@ -919,14 +1107,16 @@ public:
|
|||
|
||||
if (webgl_version == 2) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
if (src_offset + src_length > count) {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
|
||||
data += src_offset;
|
||||
if (src_length == 0) {
|
||||
count -= src_offset;
|
||||
}
|
||||
|
||||
if (src_offset + src_length <= count) {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
} else {
|
||||
count = src_length;
|
||||
}
|
||||
)~~~");
|
||||
}
|
||||
|
@ -955,6 +1145,13 @@ public:
|
|||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "vertexAttribIPointer"sv) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
glVertexAttribIPointer(index, size, type, stride, reinterpret_cast<void*>(offset));
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "getParameter"sv) {
|
||||
generate_get_parameter(function_impl_generator, webgl_version);
|
||||
continue;
|
||||
|
@ -1040,6 +1237,21 @@ public:
|
|||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "getActiveUniformBlockName"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "program"sv, "OptionalNone {}"sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
GLint uniform_block_name_length = 0;
|
||||
glGetActiveUniformBlockiv(program_handle, uniform_block_index, GL_UNIFORM_BLOCK_NAME_LENGTH, &uniform_block_name_length);
|
||||
Vector<GLchar> uniform_block_name;
|
||||
uniform_block_name.resize(uniform_block_name_length);
|
||||
if (!uniform_block_name_length)
|
||||
return String {};
|
||||
glGetActiveUniformBlockName(program_handle, uniform_block_index, uniform_block_name_length, nullptr, uniform_block_name.data());
|
||||
return String::from_utf8_without_validation(ReadonlyBytes { uniform_block_name.data(), static_cast<size_t>(uniform_block_name_length - 1) });
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "deleteBuffer"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "buffer"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
|
@ -1056,6 +1268,14 @@ public:
|
|||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "deleteRenderbuffer"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "renderbuffer"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
glDeleteRenderbuffers(1, &renderbuffer_handle);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "deleteTexture"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "texture"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
|
@ -1072,6 +1292,225 @@ public:
|
|||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "deleteSampler"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "sampler"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
glDeleteSamplers(1, &sampler_handle);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "bindBuffer"sv) {
|
||||
// FIXME: Implement Buffer Object Binding restrictions.
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "buffer"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
switch (target) {
|
||||
case GL_ELEMENT_ARRAY_BUFFER:
|
||||
m_element_array_buffer_binding = buffer;
|
||||
break;
|
||||
case GL_ARRAY_BUFFER:
|
||||
m_array_buffer_binding = buffer;
|
||||
break;
|
||||
)~~~");
|
||||
|
||||
if (webgl_version == 2) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
case GL_UNIFORM_BUFFER:
|
||||
m_uniform_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;
|
||||
)~~~");
|
||||
}
|
||||
|
||||
function_impl_generator.append(R"~~~(
|
||||
default:
|
||||
dbgln("Unknown WebGL buffer object binding target for storing current binding: 0x{:04x}", target);
|
||||
break;
|
||||
}
|
||||
|
||||
glBindBuffer(target, buffer_handle);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "useProgram"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "program"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
glUseProgram(program_handle);
|
||||
m_current_program = program;
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "bindFramebuffer"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "framebuffer"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
glBindFramebuffer(target, framebuffer_handle);
|
||||
m_framebuffer_binding = framebuffer;
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "bindRenderbuffer"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "renderbuffer"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
glBindRenderbuffer(target, renderbuffer_handle);
|
||||
m_renderbuffer_binding = renderbuffer;
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "bindTexture"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "texture"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
switch (target) {
|
||||
case GL_TEXTURE_2D:
|
||||
m_texture_binding_2d = texture;
|
||||
break;
|
||||
case GL_TEXTURE_CUBE_MAP:
|
||||
m_texture_binding_cube_map = texture;
|
||||
break;
|
||||
)~~~");
|
||||
|
||||
if (webgl_version == 2) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
case GL_TEXTURE_2D_ARRAY:
|
||||
m_texture_binding_2d_array = texture;
|
||||
break;
|
||||
case GL_TEXTURE_3D:
|
||||
m_texture_binding_3d = texture;
|
||||
break;
|
||||
)~~~");
|
||||
}
|
||||
|
||||
function_impl_generator.append(R"~~~(
|
||||
default:
|
||||
dbgln("Unknown WebGL texture target for storing current binding: 0x{:04x}", target);
|
||||
break;
|
||||
}
|
||||
glBindTexture(target, texture_handle);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "renderbufferStorage"sv) {
|
||||
// To be backward compatible with WebGL 1, also accepts internal format DEPTH_STENCIL, which should be
|
||||
// mapped to DEPTH24_STENCIL8 by implementations.
|
||||
if (webgl_version == 2) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
if (internalformat == GL_DEPTH_STENCIL)
|
||||
internalformat = GL_DEPTH24_STENCIL8;
|
||||
)~~~");
|
||||
}
|
||||
|
||||
function_impl_generator.append(R"~~~(
|
||||
glRenderbufferStorage(target, internalformat, width, height);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name.starts_with("samplerParameter"sv)) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "sampler"sv, ""sv);
|
||||
function_impl_generator.set("param_type", function.name.substring_view(16, 1));
|
||||
// pname is given in the following table:
|
||||
// - TEXTURE_COMPARE_FUNC
|
||||
// - TEXTURE_COMPARE_MODE
|
||||
// - TEXTURE_MAG_FILTER
|
||||
// - TEXTURE_MAX_LOD
|
||||
// - TEXTURE_MIN_FILTER
|
||||
// - TEXTURE_MIN_LOD
|
||||
// - TEXTURE_WRAP_R
|
||||
// - TEXTURE_WRAP_S
|
||||
// - TEXTURE_WRAP_T
|
||||
// If pname is not in the table above, generates an INVALID_ENUM error.
|
||||
// NOTE: We have to do this ourselves, as OpenGL does not.
|
||||
function_impl_generator.append(R"~~~(
|
||||
switch (pname) {
|
||||
case GL_TEXTURE_COMPARE_FUNC:
|
||||
case GL_TEXTURE_COMPARE_MODE:
|
||||
case GL_TEXTURE_MAG_FILTER:
|
||||
case GL_TEXTURE_MAX_LOD:
|
||||
case GL_TEXTURE_MIN_FILTER:
|
||||
case GL_TEXTURE_MIN_LOD:
|
||||
case GL_TEXTURE_WRAP_R:
|
||||
case GL_TEXTURE_WRAP_S:
|
||||
case GL_TEXTURE_WRAP_T:
|
||||
break;
|
||||
default:
|
||||
dbgln("Unknown WebGL sampler parameter name: 0x{:04x}", pname);
|
||||
set_error(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
glSamplerParameter@param_type@(sampler_handle, pname, param);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name.starts_with("clearBuffer"sv) && function.name.ends_with('v')) {
|
||||
auto element_type = function.name.substring_view(11, 2);
|
||||
if (element_type == "fv"sv) {
|
||||
function_impl_generator.set("cpp_element_type", "float"sv);
|
||||
function_impl_generator.set("typed_array_type", "Float32Array"sv);
|
||||
function_impl_generator.set("gl_postfix", "f"sv);
|
||||
} else if (element_type == "iv"sv) {
|
||||
function_impl_generator.set("cpp_element_type", "int"sv);
|
||||
function_impl_generator.set("typed_array_type", "Int32Array"sv);
|
||||
function_impl_generator.set("gl_postfix", "i"sv);
|
||||
} else if (element_type == "ui"sv) {
|
||||
function_impl_generator.set("cpp_element_type", "u32"sv);
|
||||
function_impl_generator.set("typed_array_type", "Uint32Array"sv);
|
||||
function_impl_generator.set("gl_postfix", "ui"sv);
|
||||
} else {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
function_impl_generator.append(R"~~~(
|
||||
@cpp_element_type@ const* data = nullptr;
|
||||
size_t count = 0;
|
||||
if (values.has<Vector<@cpp_element_type@>>()) {
|
||||
auto& vector = values.get<Vector<@cpp_element_type@>>();
|
||||
data = vector.data();
|
||||
count = vector.size();
|
||||
} else if (values.has<GC::Root<WebIDL::BufferSource>>()) {
|
||||
auto& typed_array_base = static_cast<JS::TypedArrayBase&>(*values.get<GC::Root<WebIDL::BufferSource>>()->raw_object());
|
||||
auto& typed_array = verify_cast<JS::@typed_array_type@>(typed_array_base);
|
||||
data = typed_array.data().data();
|
||||
count = typed_array.array_length().length();
|
||||
} else {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
|
||||
switch (buffer) {
|
||||
case GL_COLOR:
|
||||
if (src_offset + 4 > count) {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case GL_DEPTH:
|
||||
case GL_STENCIL:
|
||||
if (src_offset + 1 > count) {
|
||||
set_error(GL_INVALID_VALUE);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dbgln("Unknown WebGL buffer target for buffer clearing: 0x{:04x}", buffer);
|
||||
set_error(GL_INVALID_ENUM);
|
||||
return;
|
||||
}
|
||||
|
||||
data += src_offset;
|
||||
glClearBuffer@gl_postfix@v(buffer, drawbuffer, data);
|
||||
needs_to_present();
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector<ByteString> gl_call_arguments;
|
||||
for (size_t i = 0; i < function.parameters.size(); ++i) {
|
||||
auto const& parameter = function.parameters[i];
|
||||
|
@ -1129,8 +1568,8 @@ public:
|
|||
size_t byte_size = 0;
|
||||
if (@buffer_source_name@->is_typed_array_base()) {
|
||||
auto& typed_array_base = static_cast<JS::TypedArrayBase&>(*@buffer_source_name@->raw_object());
|
||||
ptr = typed_array_base.viewed_array_buffer()->buffer().data();
|
||||
byte_size = typed_array_base.viewed_array_buffer()->byte_length();
|
||||
ptr = typed_array_base.viewed_array_buffer()->buffer().data() + typed_array_base.byte_offset();
|
||||
byte_size = @buffer_source_name@->byte_length();
|
||||
} else if (@buffer_source_name@->is_data_view()) {
|
||||
auto& data_view = static_cast<JS::DataView&>(*@buffer_source_name@->raw_object());
|
||||
ptr = data_view.viewed_array_buffer()->buffer().data();
|
||||
|
@ -1175,8 +1614,31 @@ public:
|
|||
}
|
||||
|
||||
header_file_generator.append(R"~~~(
|
||||
protected:
|
||||
virtual void visit_edges(JS::Cell::Visitor&) override;
|
||||
|
||||
private:
|
||||
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;
|
||||
)~~~");
|
||||
|
||||
if (webgl_version == 2) {
|
||||
header_file_generator.append(R"~~~(
|
||||
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<WebGLTexture> m_texture_binding_2d_array;
|
||||
GC::Ptr<WebGLTexture> m_texture_binding_3d;
|
||||
)~~~");
|
||||
}
|
||||
|
||||
header_file_generator.append(R"~~~(
|
||||
NonnullOwnPtr<OpenGLContext> m_context;
|
||||
};
|
||||
|
||||
|
@ -1184,6 +1646,31 @@ private:
|
|||
)~~~");
|
||||
|
||||
implementation_file_generator.append(R"~~~(
|
||||
void @class_name@::visit_edges(JS::Cell::Visitor& visitor)
|
||||
{
|
||||
visitor.visit(m_realm);
|
||||
visitor.visit(m_array_buffer_binding);
|
||||
visitor.visit(m_element_array_buffer_binding);
|
||||
visitor.visit(m_current_program);
|
||||
visitor.visit(m_framebuffer_binding);
|
||||
visitor.visit(m_renderbuffer_binding);
|
||||
visitor.visit(m_texture_binding_2d);
|
||||
visitor.visit(m_texture_binding_cube_map);
|
||||
)~~~");
|
||||
|
||||
if (webgl_version == 2) {
|
||||
implementation_file_generator.append(R"~~~(
|
||||
visitor.visit(m_uniform_buffer_binding);
|
||||
visitor.visit(m_copy_read_buffer_binding);
|
||||
visitor.visit(m_copy_write_buffer_binding);
|
||||
visitor.visit(m_texture_binding_2d_array);
|
||||
visitor.visit(m_texture_binding_3d);
|
||||
)~~~");
|
||||
}
|
||||
|
||||
implementation_file_generator.append(R"~~~(
|
||||
}
|
||||
|
||||
}
|
||||
)~~~");
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue