mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-01-22 09:12:13 -05:00
LibWeb/WebGL: Track the shaders attached to a program
This is required to return original references to the shaders attached to a program from getAttachedShaders. This is required for Figma (and likely all other Emscripten compiled applications that use WebGL) to get it's own generated shader IDs from the shaders returned from getAttachedShaders.
This commit is contained in:
parent
3ab93667f5
commit
aa99853a5c
Notes:
github-actions[bot]
2025-01-21 20:38:32 +00:00
Author: https://github.com/Lubrsi Commit: https://github.com/LadybirdBrowser/ladybird/commit/aa99853a5c1 Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3239 Reviewed-by: https://github.com/awesomekling Reviewed-by: https://github.com/kalenikaliaksandr
5 changed files with 86 additions and 9 deletions
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Jelle Raaijmakers <jelle@ladybird.org>
|
||||
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2024, Luke Wilde <luke@ladybird.org>
|
||||
* Copyright (c) 2024-2025, Luke Wilde <luke@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -10,6 +10,7 @@
|
|||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/WebGLProgramPrototype.h>
|
||||
#include <LibWeb/WebGL/WebGLProgram.h>
|
||||
#include <LibWeb/WebGL/WebGLShader.h>
|
||||
|
||||
namespace Web::WebGL {
|
||||
|
||||
|
@ -33,4 +34,11 @@ void WebGLProgram::initialize(JS::Realm& realm)
|
|||
WEB_SET_PROTOTYPE_FOR_INTERFACE(WebGLProgram);
|
||||
}
|
||||
|
||||
void WebGLProgram::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_attached_vertex_shader);
|
||||
visitor.visit(m_attached_fragment_shader);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Jelle Raaijmakers <jelle@ladybird.org>
|
||||
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2024, Luke Wilde <luke@ladybird.org>
|
||||
* Copyright (c) 2024-2025, Luke Wilde <luke@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -22,10 +22,21 @@ public:
|
|||
|
||||
virtual ~WebGLProgram();
|
||||
|
||||
GC::Ptr<WebGLShader> attached_vertex_shader() const { return m_attached_fragment_shader; }
|
||||
void set_attached_vertex_shader(GC::Ptr<WebGLShader> shader) { m_attached_vertex_shader = shader; }
|
||||
|
||||
GC::Ptr<WebGLShader> attached_fragment_shader() const { return m_attached_fragment_shader; }
|
||||
void set_attached_fragment_shader(GC::Ptr<WebGLShader> shader) { m_attached_fragment_shader = shader; }
|
||||
|
||||
protected:
|
||||
explicit WebGLProgram(JS::Realm&, WebGLRenderingContextBase&, GLuint handle);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(JS::Cell::Visitor&) override;
|
||||
|
||||
private:
|
||||
GC::Ptr<WebGLShader> m_attached_vertex_shader;
|
||||
GC::Ptr<WebGLShader> m_attached_fragment_shader;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Jelle Raaijmakers <jelle@ladybird.org>
|
||||
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2024, Luke Wilde <luke@ladybird.org>
|
||||
* Copyright (c) 2024-2025, Luke Wilde <luke@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -15,13 +15,14 @@ namespace Web::WebGL {
|
|||
|
||||
GC_DEFINE_ALLOCATOR(WebGLShader);
|
||||
|
||||
GC::Ref<WebGLShader> WebGLShader::create(JS::Realm& realm, WebGLRenderingContextBase& context, GLuint handle)
|
||||
GC::Ref<WebGLShader> WebGLShader::create(JS::Realm& realm, WebGLRenderingContextBase& context, GLuint handle, GLenum type)
|
||||
{
|
||||
return realm.create<WebGLShader>(realm, context, handle);
|
||||
return realm.create<WebGLShader>(realm, context, handle, type);
|
||||
}
|
||||
|
||||
WebGLShader::WebGLShader(JS::Realm& realm, WebGLRenderingContextBase& context, GLuint handle)
|
||||
WebGLShader::WebGLShader(JS::Realm& realm, WebGLRenderingContextBase& context, GLuint handle, GLenum type)
|
||||
: WebGLObject(realm, context, handle)
|
||||
, m_type(type)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -18,14 +18,19 @@ class WebGLShader final : public WebGLObject {
|
|||
GC_DECLARE_ALLOCATOR(WebGLShader);
|
||||
|
||||
public:
|
||||
static GC::Ref<WebGLShader> create(JS::Realm& realm, WebGLRenderingContextBase&, GLuint handle);
|
||||
static GC::Ref<WebGLShader> create(JS::Realm& realm, WebGLRenderingContextBase&, GLuint handle, GLenum type);
|
||||
|
||||
virtual ~WebGLShader();
|
||||
|
||||
GLenum type() const { return m_type; }
|
||||
|
||||
protected:
|
||||
explicit WebGLShader(JS::Realm&, WebGLRenderingContextBase&, GLuint handle);
|
||||
explicit WebGLShader(JS::Realm&, WebGLRenderingContextBase&, GLuint handle, GLenum type);
|
||||
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
private:
|
||||
GLenum m_type { 0 };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
||||
* Copyright (c) 2024, Luke Wilde <luke@ladybird.org>
|
||||
* Copyright (c) 2024-2025, Luke Wilde <luke@ladybird.org>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
@ -605,6 +605,44 @@ public:
|
|||
function_impl_generator.append(" m_context->notify_content_will_change();\n"sv);
|
||||
}
|
||||
|
||||
if (function.name == "attachShader"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "program"sv, ""sv);
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "shader"sv, ""sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
if (program->attached_vertex_shader() == shader || program->attached_fragment_shader() == shader) {
|
||||
dbgln("WebGL: Shader is already attached to program");
|
||||
set_error(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shader->type() == GL_VERTEX_SHADER && program->attached_vertex_shader()) {
|
||||
dbgln("WebGL: Not attaching vertex shader to program as it already has a vertex shader attached");
|
||||
set_error(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
|
||||
if (shader->type() == GL_FRAGMENT_SHADER && program->attached_fragment_shader()) {
|
||||
dbgln("WebGL: Not attaching fragment shader to program as it already has a fragment shader attached");
|
||||
set_error(GL_INVALID_OPERATION);
|
||||
return;
|
||||
}
|
||||
|
||||
glAttachShader(program_handle, shader_handle);
|
||||
|
||||
switch (shader->type()) {
|
||||
case GL_VERTEX_SHADER:
|
||||
program->set_attached_vertex_shader(shader.ptr());
|
||||
break;
|
||||
case GL_FRAGMENT_SHADER:
|
||||
program->set_attached_fragment_shader(shader.ptr());
|
||||
break;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "getUniformLocation"sv) {
|
||||
generate_webgl_object_handle_unwrap(function_impl_generator, "program"sv, "{}"sv);
|
||||
function_impl_generator.append(R"~~~(
|
||||
|
@ -623,6 +661,20 @@ public:
|
|||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "createShader"sv) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
if (type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) {
|
||||
dbgln("Unknown WebGL shader type: 0x{:04x}", type);
|
||||
set_error(GL_INVALID_ENUM);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GLuint handle = glCreateShader(type);
|
||||
return WebGLShader::create(m_realm, *this, handle, type);
|
||||
)~~~");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (function.name == "createTexture"sv) {
|
||||
function_impl_generator.append(R"~~~(
|
||||
GLuint handle = 0;
|
||||
|
|
Loading…
Reference in a new issue