mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 23:47:45 +00:00
LibWeb: Make 2D and 3D canvas rendering contexts GC-allocated
This commit is contained in:
parent
b8d485e6f0
commit
4452b5ca09
11 changed files with 107 additions and 61 deletions
|
@ -4,9 +4,11 @@
|
|||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibWeb/Bindings/WebGLRenderingContextPrototype.h>
|
||||
#include <LibWeb/Bindings/Wrapper.h>
|
||||
#include <LibWeb/DOM/Document.h>
|
||||
#include <LibWeb/HTML/HTMLCanvasElement.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/WebGL/WebGLContextEvent.h>
|
||||
#include <LibWeb/WebGL/WebGLRenderingContext.h>
|
||||
|
||||
|
@ -30,7 +32,7 @@ static void fire_webgl_context_creation_error(HTML::HTMLCanvasElement& canvas_el
|
|||
fire_webgl_context_event(canvas_element, "webglcontextcreationerror"sv);
|
||||
}
|
||||
|
||||
JS::ThrowCompletionOr<RefPtr<WebGLRenderingContext>> WebGLRenderingContext::create(HTML::HTMLCanvasElement& canvas_element, JS::Value options)
|
||||
JS::ThrowCompletionOr<JS::GCPtr<WebGLRenderingContext>> WebGLRenderingContext::create(HTML::Window& window, HTML::HTMLCanvasElement& canvas_element, JS::Value options)
|
||||
{
|
||||
// We should be coming here from getContext being called on a wrapped <canvas> element.
|
||||
auto context_attributes = TRY(convert_value_to_context_attributes_dictionary(canvas_element.vm(), options));
|
||||
|
@ -38,20 +40,29 @@ JS::ThrowCompletionOr<RefPtr<WebGLRenderingContext>> WebGLRenderingContext::crea
|
|||
bool created_bitmap = canvas_element.create_bitmap(/* minimum_width= */ 1, /* minimum_height= */ 1);
|
||||
if (!created_bitmap) {
|
||||
fire_webgl_context_creation_error(canvas_element);
|
||||
return RefPtr<WebGLRenderingContext> { nullptr };
|
||||
return JS::GCPtr<WebGLRenderingContext> { nullptr };
|
||||
}
|
||||
|
||||
#ifndef __serenity__
|
||||
// FIXME: Make WebGL work on other platforms.
|
||||
(void)window;
|
||||
(void)context_attributes;
|
||||
dbgln("FIXME: WebGL not supported on the current platform");
|
||||
fire_webgl_context_creation_error(canvas_element);
|
||||
return RefPtr<WebGLRenderingContext> { nullptr };
|
||||
return JS::GCPtr<WebGLRenderingContext> { nullptr };
|
||||
#else
|
||||
// FIXME: LibGL currently doesn't propagate context creation errors.
|
||||
auto context = GL::create_context(*canvas_element.bitmap());
|
||||
return adopt_ref(*new WebGLRenderingContext(canvas_element, move(context), context_attributes, context_attributes));
|
||||
return window.heap().allocate<WebGLRenderingContext>(window.realm(), window, canvas_element, move(context), context_attributes, context_attributes);
|
||||
#endif
|
||||
}
|
||||
|
||||
WebGLRenderingContext::WebGLRenderingContext(HTML::Window& window, HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr<GL::GLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters)
|
||||
: WebGLRenderingContextBase(window, canvas_element, move(context), move(context_creation_parameters), move(actual_context_parameters))
|
||||
{
|
||||
set_prototype(&window.ensure_web_prototype<Bindings::WebGLRenderingContextPrototype>("WebGLRenderingContext"));
|
||||
}
|
||||
|
||||
WebGLRenderingContext::~WebGLRenderingContext() = default;
|
||||
|
||||
}
|
||||
|
|
|
@ -6,26 +6,22 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/Wrappable.h>
|
||||
#include <LibWeb/WebGL/WebGLRenderingContextBase.h>
|
||||
|
||||
namespace Web::WebGL {
|
||||
|
||||
class WebGLRenderingContext
|
||||
: public WebGLRenderingContextBase
|
||||
, public Bindings::Wrappable {
|
||||
class WebGLRenderingContext final : public WebGLRenderingContextBase {
|
||||
WEB_PLATFORM_OBJECT(WebGLRenderingContext, WebGLRenderingContextBase);
|
||||
|
||||
public:
|
||||
using WrapperType = Bindings::WebGLRenderingContextWrapper;
|
||||
static JS::ThrowCompletionOr<JS::GCPtr<WebGLRenderingContext>> create(HTML::Window&, HTML::HTMLCanvasElement& canvas_element, JS::Value options);
|
||||
|
||||
static JS::ThrowCompletionOr<RefPtr<WebGLRenderingContext>> create(HTML::HTMLCanvasElement& canvas_element, JS::Value options);
|
||||
|
||||
virtual ~WebGLRenderingContext() override = default;
|
||||
virtual ~WebGLRenderingContext() override;
|
||||
|
||||
private:
|
||||
WebGLRenderingContext(HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr<GL::GLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters)
|
||||
: WebGLRenderingContextBase(canvas_element, move(context), move(context_creation_parameters), move(actual_context_parameters))
|
||||
{
|
||||
}
|
||||
WebGLRenderingContext(HTML::Window&, HTML::HTMLCanvasElement&, NonnullOwnPtr<GL::GLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
WRAPPER_HACK(WebGLRenderingContext, Web::WebGL)
|
||||
|
|
|
@ -7,12 +7,14 @@
|
|||
#include <AK/Debug.h>
|
||||
#include <LibGL/GLContext.h>
|
||||
#include <LibWeb/HTML/HTMLCanvasElement.h>
|
||||
#include <LibWeb/HTML/Window.h>
|
||||
#include <LibWeb/WebGL/WebGLRenderingContextBase.h>
|
||||
|
||||
namespace Web::WebGL {
|
||||
|
||||
WebGLRenderingContextBase::WebGLRenderingContextBase(HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr<GL::GLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters)
|
||||
: m_canvas_element(canvas_element)
|
||||
WebGLRenderingContextBase::WebGLRenderingContextBase(HTML::Window& window, HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr<GL::GLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters)
|
||||
: PlatformObject(window.realm())
|
||||
, m_canvas_element(canvas_element)
|
||||
, m_context(move(context))
|
||||
, m_context_creation_parameters(move(context_creation_parameters))
|
||||
, m_actual_context_parameters(move(actual_context_parameters))
|
||||
|
@ -21,6 +23,12 @@ WebGLRenderingContextBase::WebGLRenderingContextBase(HTML::HTMLCanvasElement& ca
|
|||
|
||||
WebGLRenderingContextBase::~WebGLRenderingContextBase() = default;
|
||||
|
||||
void WebGLRenderingContextBase::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_canvas_element.ptr());
|
||||
}
|
||||
|
||||
#define RETURN_WITH_WEBGL_ERROR_IF(condition, error) \
|
||||
if (condition) { \
|
||||
dbgln_if(WEBGL_CONTEXT_DEBUG, "{}(): error {:#x}", __func__, error); \
|
||||
|
|
|
@ -15,9 +15,9 @@
|
|||
|
||||
namespace Web::WebGL {
|
||||
|
||||
class WebGLRenderingContextBase
|
||||
: public RefCounted<WebGLRenderingContextBase>
|
||||
, public Weakable<WebGLRenderingContextBase> {
|
||||
class WebGLRenderingContextBase : public Bindings::PlatformObject {
|
||||
WEB_PLATFORM_OBJECT(WebGLRenderingContextBase, Bindings::PlatformObject);
|
||||
|
||||
public:
|
||||
virtual ~WebGLRenderingContextBase();
|
||||
|
||||
|
@ -62,10 +62,12 @@ public:
|
|||
void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
|
||||
protected:
|
||||
WebGLRenderingContextBase(HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr<GL::GLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters);
|
||||
WebGLRenderingContextBase(HTML::Window&, HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr<GL::GLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters);
|
||||
|
||||
private:
|
||||
JS::Handle<HTML::HTMLCanvasElement> m_canvas_element;
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
JS::NonnullGCPtr<HTML::HTMLCanvasElement> m_canvas_element;
|
||||
|
||||
NonnullOwnPtr<GL::GLContext> m_context;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue