mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-04-21 03:55:24 +00:00
LibWeb/WebGL: Set INVALID_OPERATION if object does not belong to context
This commit is contained in:
parent
fbae24f7a9
commit
07635d4554
Notes:
github-actions[bot]
2024-12-19 12:39:36 +00:00
Author: https://github.com/kalenikaliaksandr Commit: https://github.com/LadybirdBrowser/ladybird/commit/07635d45540 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2965
3 changed files with 79 additions and 20 deletions
|
@ -10,6 +10,8 @@
|
|||
#include <LibWeb/Bindings/WebGLObjectPrototype.h>
|
||||
#include <LibWeb/WebGL/WebGLObject.h>
|
||||
|
||||
#include <GLES2/gl2.h>
|
||||
|
||||
namespace Web::WebGL {
|
||||
|
||||
WebGLObject::WebGLObject(JS::Realm& realm, WebGLRenderingContextBase& context, GLuint handle)
|
||||
|
@ -33,4 +35,11 @@ void WebGLObject::visit_edges(Visitor& visitor)
|
|||
visitor.visit(m_context->gc_cell());
|
||||
}
|
||||
|
||||
ErrorOr<GLuint> WebGLObject::handle(WebGLRenderingContextBase const* context) const
|
||||
{
|
||||
if (context == m_context)
|
||||
return m_handle;
|
||||
return Error::from_errno(GL_INVALID_OPERATION);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
String label() const { return m_label; }
|
||||
void set_label(String const& label) { m_label = label; }
|
||||
|
||||
GLuint handle() const { return m_handle; }
|
||||
ErrorOr<GLuint> handle(WebGLRenderingContextBase const* context) const;
|
||||
|
||||
protected:
|
||||
explicit WebGLObject(JS::Realm&, WebGLRenderingContextBase&, GLuint handle);
|
||||
|
|
|
@ -316,6 +316,27 @@ static void generate_get_internal_format_parameter(SourceGenerator& generator)
|
|||
)~~~");
|
||||
}
|
||||
|
||||
static void generate_webgl_object_handle_unwrap(SourceGenerator& generator, StringView object_name, StringView early_return_value)
|
||||
{
|
||||
StringBuilder string_builder;
|
||||
SourceGenerator unwrap_generator { string_builder };
|
||||
unwrap_generator.set("object_name", object_name);
|
||||
unwrap_generator.set("early_return_value", early_return_value);
|
||||
unwrap_generator.append(R"~~~(
|
||||
GLuint @object_name@_handle = 0;
|
||||
if (@object_name@) {
|
||||
auto handle_or_error = @object_name@->handle(this);
|
||||
if (handle_or_error.is_error()) {
|
||||
set_error(GL_INVALID_OPERATION);
|
||||
return @early_return_value@;
|
||||
}
|
||||
@object_name@_handle = handle_or_error.release_value();
|
||||
}
|
||||
)~~~");
|
||||
|
||||
generator.append(unwrap_generator.as_string_view());
|
||||
}
|
||||
|
||||
ErrorOr<int> serenity_main(Main::Arguments arguments)
|
||||
{
|
||||
StringView generated_header_path;
|
||||
|
@ -511,9 +532,10 @@ public:
|
|||
}
|
||||
|
||||
if (function.name == "getUniformLocation"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "program"sv, "{}"sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
auto name_null_terminated = null_terminated_string(name);
|
||||
return WebGLUniformLocation::create(m_realm, glGetUniformLocation(program ? program->handle() : 0, name_null_terminated.data()));
|
||||
return WebGLUniformLocation::create(m_realm, glGetUniformLocation(program_handle, name_null_terminated.data()));
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
@ -581,13 +603,14 @@ public:
|
|||
}
|
||||
|
||||
if (function.name == "shaderSource"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "shader"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
Vector<GLchar*> strings;
|
||||
auto string = null_terminated_string(source);
|
||||
strings.append(string.data());
|
||||
Vector<GLint> length;
|
||||
length.append(source.bytes().size());
|
||||
glShaderSource(shader->handle(), 1, strings.data(), length.data());
|
||||
glShaderSource(shader_handle, 1, strings.data(), length.data());
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
@ -753,18 +776,20 @@ public:
|
|||
}
|
||||
|
||||
if (function.name == "getShaderParameter"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "shader"sv, "JS::js_null()"sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
GLint result = 0;
|
||||
glGetShaderiv(shader->handle(), pname, &result);
|
||||
glGetShaderiv(shader_handle, pname, &result);
|
||||
return JS::Value(result);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "getProgramParameter"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "program"sv, "JS::js_null()"sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
GLint result = 0;
|
||||
glGetProgramiv(program->handle(), pname, &result);
|
||||
glGetProgramiv(program_handle, pname, &result);
|
||||
return JS::Value(result);
|
||||
)~~~");
|
||||
continue;
|
||||
|
@ -946,13 +971,14 @@ public:
|
|||
}
|
||||
|
||||
if (function.name == "getActiveUniform"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "program"sv, "{}"sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
GLint size = 0;
|
||||
GLenum type = 0;
|
||||
GLsizei buf_size = 256;
|
||||
GLsizei length = 0;
|
||||
GLchar name[256];
|
||||
glGetActiveUniform(program->handle(), index, buf_size, &length, &size, &type, name);
|
||||
glGetActiveUniform(program_handle, index, buf_size, &length, &size, &type, name);
|
||||
auto readonly_bytes = ReadonlyBytes { name, static_cast<size_t>(length) };
|
||||
return WebGLActiveInfo::create(m_realm, String::from_utf8_without_validation(readonly_bytes), type, size);
|
||||
)~~~");
|
||||
|
@ -960,13 +986,14 @@ public:
|
|||
}
|
||||
|
||||
if (function.name == "getActiveAttrib"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "program"sv, "{}"sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
GLint size = 0;
|
||||
GLenum type = 0;
|
||||
GLsizei buf_size = 256;
|
||||
GLsizei length = 0;
|
||||
GLchar name[256];
|
||||
glGetActiveAttrib(program->handle(), index, buf_size, &length, &size, &type, name);
|
||||
glGetActiveAttrib(program_handle, index, buf_size, &length, &size, &type, name);
|
||||
auto readonly_bytes = ReadonlyBytes { name, static_cast<size_t>(length) };
|
||||
return WebGLActiveInfo::create(m_realm, String::from_utf8_without_validation(readonly_bytes), type, size);
|
||||
)~~~");
|
||||
|
@ -974,28 +1001,30 @@ public:
|
|||
}
|
||||
|
||||
if (function.name == "getShaderInfoLog"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "shader"sv, "{}"sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
GLint info_log_length = 0;
|
||||
glGetShaderiv(shader->handle(), GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
glGetShaderiv(shader_handle, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
Vector<GLchar> info_log;
|
||||
info_log.resize(info_log_length);
|
||||
if (!info_log_length)
|
||||
return String {};
|
||||
glGetShaderInfoLog(shader->handle(), info_log_length, nullptr, info_log.data());
|
||||
glGetShaderInfoLog(shader_handle, info_log_length, nullptr, info_log.data());
|
||||
return String::from_utf8_without_validation(ReadonlyBytes { info_log.data(), static_cast<size_t>(info_log_length - 1) });
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "getProgramInfoLog"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "program"sv, "{}"sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
GLint info_log_length = 0;
|
||||
glGetProgramiv(program->handle(), GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
glGetProgramiv(program_handle, GL_INFO_LOG_LENGTH, &info_log_length);
|
||||
Vector<GLchar> info_log;
|
||||
info_log.resize(info_log_length);
|
||||
if (!info_log_length)
|
||||
return String {};
|
||||
glGetProgramInfoLog(program->handle(), info_log_length, nullptr, info_log.data());
|
||||
glGetProgramInfoLog(program_handle, info_log_length, nullptr, info_log.data());
|
||||
return String::from_utf8_without_validation(ReadonlyBytes { info_log.data(), static_cast<size_t>(info_log_length - 1) });
|
||||
)~~~");
|
||||
continue;
|
||||
|
@ -1012,33 +1041,33 @@ public:
|
|||
}
|
||||
|
||||
if (function.name == "deleteBuffer"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "buffer"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
auto handle = buffer ? buffer->handle() : 0;
|
||||
glDeleteBuffers(1, &handle);
|
||||
glDeleteBuffers(1, &buffer_handle);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "deleteFramebuffer"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "framebuffer"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
auto handle = framebuffer ? framebuffer->handle() : 0;
|
||||
glDeleteFramebuffers(1, &handle);
|
||||
glDeleteFramebuffers(1, &framebuffer_handle);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "deleteTexture"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "texture"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
auto handle = texture ? texture->handle() : 0;
|
||||
glDeleteTextures(1, &handle);
|
||||
glDeleteTextures(1, &texture_handle);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "deleteVertexArray"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "vertex_array"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
auto handle = vertex_array ? vertex_array->handle() : 0;
|
||||
glDeleteVertexArrays(1, &handle);
|
||||
glDeleteVertexArrays(1, &vertex_array_handle);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
@ -1060,7 +1089,28 @@ public:
|
|||
continue;
|
||||
}
|
||||
if (is_webgl_object_type(parameter.type->name())) {
|
||||
gl_call_arguments.append(ByteString::formatted("{} ? {}->handle() : 0", parameter_name, parameter_name));
|
||||
if (function.return_type->name() == "undefined"sv) {
|
||||
function_impl_generator.set("early_return_value", "");
|
||||
} else if (function.return_type->is_integer()) {
|
||||
function_impl_generator.set("early_return_value", "-1");
|
||||
} else if (function.return_type->is_boolean()) {
|
||||
function_impl_generator.set("early_return_value", "false");
|
||||
} else {
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
function_impl_generator.set("handle_parameter_name", parameter_name);
|
||||
function_impl_generator.append(R"~~~(
|
||||
auto @handle_parameter_name@_handle = 0;
|
||||
if (@handle_parameter_name@) {
|
||||
auto handle_or_error = @handle_parameter_name@->handle(this);
|
||||
if (handle_or_error.is_error()) {
|
||||
set_error(GL_INVALID_OPERATION);
|
||||
return @early_return_value@;
|
||||
}
|
||||
@handle_parameter_name@_handle = handle_or_error.release_value();
|
||||
}
|
||||
)~~~");
|
||||
gl_call_arguments.append(ByteString::formatted("{}_handle", parameter_name));
|
||||
continue;
|
||||
}
|
||||
if (parameter.type->name() == "WebGLUniformLocation"sv) {
|
||||
|
|
Loading…
Add table
Reference in a new issue