1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-24 15:07:45 +00:00

LibWeb: Make 2D and 3D canvas rendering contexts GC-allocated

This commit is contained in:
Andreas Kling 2022-09-02 15:53:02 +02:00
parent b8d485e6f0
commit 4452b5ca09
11 changed files with 107 additions and 61 deletions

View file

@ -151,6 +151,10 @@ static bool impl_is_wrapper(Type const& type)
return true; return true;
if (type.name == "MutationRecord"sv) if (type.name == "MutationRecord"sv)
return true; return true;
if (type.name == "CanvasRenderingContext2D"sv)
return true;
if (type.name == "WebGLRenderingContext"sv)
return true;
return false; return false;
} }

View file

@ -450,7 +450,6 @@ class URLSearchParamsIterator;
namespace Web::Bindings { namespace Web::Bindings {
class BlobWrapper; class BlobWrapper;
class CanvasGradientWrapper; class CanvasGradientWrapper;
class CanvasRenderingContext2DWrapper;
class CryptoWrapper; class CryptoWrapper;
class DOMExceptionWrapper; class DOMExceptionWrapper;
class DOMPointWrapper; class DOMPointWrapper;
@ -478,7 +477,6 @@ class TextMetricsWrapper;
class URLSearchParamsIteratorWrapper; class URLSearchParamsIteratorWrapper;
class URLSearchParamsWrapper; class URLSearchParamsWrapper;
class URLWrapper; class URLWrapper;
class WebGLRenderingContextWrapper;
class WindowProxy; class WindowProxy;
class WorkerLocationWrapper; class WorkerLocationWrapper;
class WorkerNavigatorWrapper; class WorkerNavigatorWrapper;

View file

@ -10,7 +10,7 @@
#include <LibGfx/Painter.h> #include <LibGfx/Painter.h>
#include <LibGfx/Quad.h> #include <LibGfx/Quad.h>
#include <LibGfx/Rect.h> #include <LibGfx/Rect.h>
#include <LibWeb/Bindings/CanvasRenderingContext2DWrapper.h> #include <LibWeb/Bindings/CanvasRenderingContext2DPrototype.h>
#include <LibWeb/DOM/ExceptionOr.h> #include <LibWeb/DOM/ExceptionOr.h>
#include <LibWeb/HTML/CanvasRenderingContext2D.h> #include <LibWeb/HTML/CanvasRenderingContext2D.h>
#include <LibWeb/HTML/HTMLCanvasElement.h> #include <LibWeb/HTML/HTMLCanvasElement.h>
@ -23,13 +23,26 @@
namespace Web::HTML { namespace Web::HTML {
CanvasRenderingContext2D::CanvasRenderingContext2D(HTMLCanvasElement& element) JS::NonnullGCPtr<CanvasRenderingContext2D> CanvasRenderingContext2D::create(HTML::Window& window, HTMLCanvasElement& element)
: m_element(JS::make_handle(element))
{ {
return *window.heap().allocate<CanvasRenderingContext2D>(window.realm(), window, element);
}
CanvasRenderingContext2D::CanvasRenderingContext2D(HTML::Window& window, HTMLCanvasElement& element)
: PlatformObject(window.realm())
, m_element(element)
{
set_prototype(&window.ensure_web_prototype<Bindings::CanvasRenderingContext2DPrototype>("CanvasRenderingContext2D"));
} }
CanvasRenderingContext2D::~CanvasRenderingContext2D() = default; CanvasRenderingContext2D::~CanvasRenderingContext2D() = default;
void CanvasRenderingContext2D::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
visitor.visit(m_element.ptr());
}
HTMLCanvasElement& CanvasRenderingContext2D::canvas_element() HTMLCanvasElement& CanvasRenderingContext2D::canvas_element()
{ {
return *m_element; return *m_element;
@ -306,11 +319,7 @@ void CanvasRenderingContext2D::fill(Path2D& path, String const& fill_rule)
RefPtr<ImageData> CanvasRenderingContext2D::create_image_data(int width, int height) const RefPtr<ImageData> CanvasRenderingContext2D::create_image_data(int width, int height) const
{ {
if (!wrapper()) { return ImageData::create_with_size(vm(), width, height);
dbgln("Hmm! Attempted to create ImageData for wrapper-less CRC2D.");
return {};
}
return ImageData::create_with_size(wrapper()->vm(), width, height);
} }
// https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-getimagedata // https://html.spec.whatwg.org/multipage/canvas.html#dom-context-2d-getimagedata
@ -326,7 +335,7 @@ DOM::ExceptionOr<RefPtr<ImageData>> CanvasRenderingContext2D::get_image_data(int
// 3. Let imageData be a new ImageData object. // 3. Let imageData be a new ImageData object.
// 4. Initialize imageData given sw, sh, settings set to settings, and defaultColorSpace set to this's color space. // 4. Initialize imageData given sw, sh, settings set to settings, and defaultColorSpace set to this's color space.
auto image_data = ImageData::create_with_size(wrapper()->vm(), width, height); auto image_data = ImageData::create_with_size(vm(), width, height);
// NOTE: We don't attempt to create the underlying bitmap here; if it doesn't exist, it's like copying only transparent black pixels (which is a no-op). // NOTE: We don't attempt to create the underlying bitmap here; if it doesn't exist, it's like copying only transparent black pixels (which is a no-op).
if (!canvas_element().bitmap()) if (!canvas_element().bitmap())

View file

@ -7,14 +7,13 @@
#pragma once #pragma once
#include <AK/RefCountForwarder.h>
#include <AK/Variant.h> #include <AK/Variant.h>
#include <LibGfx/AffineTransform.h> #include <LibGfx/AffineTransform.h>
#include <LibGfx/Color.h> #include <LibGfx/Color.h>
#include <LibGfx/Forward.h> #include <LibGfx/Forward.h>
#include <LibGfx/Painter.h> #include <LibGfx/Painter.h>
#include <LibGfx/Path.h> #include <LibGfx/Path.h>
#include <LibWeb/Bindings/Wrappable.h> #include <LibWeb/Bindings/PlatformObject.h>
#include <LibWeb/DOM/ExceptionOr.h> #include <LibWeb/DOM/ExceptionOr.h>
#include <LibWeb/HTML/Canvas/CanvasDrawImage.h> #include <LibWeb/HTML/Canvas/CanvasDrawImage.h>
#include <LibWeb/HTML/Canvas/CanvasDrawPath.h> #include <LibWeb/HTML/Canvas/CanvasDrawPath.h>
@ -37,8 +36,7 @@ namespace Web::HTML {
using CanvasImageSource = Variant<JS::Handle<HTMLImageElement>, JS::Handle<HTMLCanvasElement>>; using CanvasImageSource = Variant<JS::Handle<HTMLImageElement>, JS::Handle<HTMLCanvasElement>>;
class CanvasRenderingContext2D class CanvasRenderingContext2D
: public RefCounted<CanvasRenderingContext2D> : public Bindings::PlatformObject
, public Bindings::Wrappable
, public CanvasPath , public CanvasPath
, public CanvasState , public CanvasState
, public CanvasTransform<CanvasRenderingContext2D> , public CanvasTransform<CanvasRenderingContext2D>
@ -50,14 +48,11 @@ class CanvasRenderingContext2D
, public CanvasImageData , public CanvasImageData
, public CanvasPathDrawingStyles<CanvasRenderingContext2D> { , public CanvasPathDrawingStyles<CanvasRenderingContext2D> {
AK_MAKE_NONCOPYABLE(CanvasRenderingContext2D); WEB_PLATFORM_OBJECT(CanvasRenderingContext2D, Bindings::PlatformObject);
AK_MAKE_NONMOVABLE(CanvasRenderingContext2D);
public: public:
using WrapperType = Bindings::CanvasRenderingContext2DWrapper; static JS::NonnullGCPtr<CanvasRenderingContext2D> create(HTML::Window&, HTMLCanvasElement&);
virtual ~CanvasRenderingContext2D() override;
static NonnullRefPtr<CanvasRenderingContext2D> create(HTMLCanvasElement& element) { return adopt_ref(*new CanvasRenderingContext2D(element)); }
~CanvasRenderingContext2D();
virtual void fill_rect(float x, float y, float width, float height) override; virtual void fill_rect(float x, float y, float width, float height) override;
virtual void stroke_rect(float x, float y, float width, float height) override; virtual void stroke_rect(float x, float y, float width, float height) override;
@ -88,7 +83,9 @@ public:
virtual void clip() override; virtual void clip() override;
private: private:
explicit CanvasRenderingContext2D(HTMLCanvasElement&); explicit CanvasRenderingContext2D(HTML::Window&, HTMLCanvasElement&);
virtual void visit_edges(Cell::Visitor&) override;
struct PreparedTextGlyph { struct PreparedTextGlyph {
unsigned int c; unsigned int c;
@ -112,7 +109,7 @@ private:
void stroke_internal(Gfx::Path const&); void stroke_internal(Gfx::Path const&);
void fill_internal(Gfx::Path&, String const& fill_rule); void fill_internal(Gfx::Path&, String const& fill_rule);
JS::Handle<HTMLCanvasElement> m_element; JS::NonnullGCPtr<HTMLCanvasElement> m_element;
// https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-origin-clean // https://html.spec.whatwg.org/multipage/canvas.html#concept-canvas-origin-clean
bool m_origin_clean { true }; bool m_origin_clean { true };
@ -127,3 +124,5 @@ DOM::ExceptionOr<CanvasImageSourceUsability> check_usability_of_image(CanvasImag
bool image_is_not_origin_clean(CanvasImageSource const&); bool image_is_not_origin_clean(CanvasImageSource const&);
} }
WRAPPER_HACK(CanvasRenderingContext2D, Web::HTML)

View file

@ -8,6 +8,7 @@
#include <AK/Checked.h> #include <AK/Checked.h>
#include <LibGfx/Bitmap.h> #include <LibGfx/Bitmap.h>
#include <LibGfx/PNGWriter.h> #include <LibGfx/PNGWriter.h>
#include <LibWeb/Bindings/HTMLCanvasElementPrototype.h>
#include <LibWeb/CSS/StyleComputer.h> #include <LibWeb/CSS/StyleComputer.h>
#include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/CanvasRenderingContext2D.h> #include <LibWeb/HTML/CanvasRenderingContext2D.h>
@ -21,10 +22,25 @@ static constexpr auto max_canvas_area = 16384 * 16384;
HTMLCanvasElement::HTMLCanvasElement(DOM::Document& document, DOM::QualifiedName qualified_name) HTMLCanvasElement::HTMLCanvasElement(DOM::Document& document, DOM::QualifiedName qualified_name)
: HTMLElement(document, move(qualified_name)) : HTMLElement(document, move(qualified_name))
{ {
set_prototype(&document.window().ensure_web_prototype<Bindings::HTMLCanvasElementPrototype>("HTMLCanvasElement"));
} }
HTMLCanvasElement::~HTMLCanvasElement() = default; HTMLCanvasElement::~HTMLCanvasElement() = default;
void HTMLCanvasElement::visit_edges(Cell::Visitor& visitor)
{
Base::visit_edges(visitor);
m_context.visit(
[&](JS::NonnullGCPtr<CanvasRenderingContext2D>& context) {
visitor.visit(context.ptr());
},
[&](JS::NonnullGCPtr<WebGL::WebGLRenderingContext>& context) {
visitor.visit(context.ptr());
},
[](Empty) {
});
}
unsigned HTMLCanvasElement::width() const unsigned HTMLCanvasElement::width() const
{ {
return attribute(HTML::AttributeNames::width).to_uint().value_or(300); return attribute(HTML::AttributeNames::width).to_uint().value_or(300);
@ -38,10 +54,10 @@ unsigned HTMLCanvasElement::height() const
void HTMLCanvasElement::reset_context_to_default_state() void HTMLCanvasElement::reset_context_to_default_state()
{ {
m_context.visit( m_context.visit(
[](NonnullRefPtr<CanvasRenderingContext2D>& context) { [](JS::NonnullGCPtr<CanvasRenderingContext2D>& context) {
context->reset_to_default_state(); context->reset_to_default_state();
}, },
[](NonnullRefPtr<WebGL::WebGLRenderingContext>&) { [](JS::NonnullGCPtr<WebGL::WebGLRenderingContext>&) {
TODO(); TODO();
}, },
[](Empty) { [](Empty) {
@ -71,22 +87,22 @@ RefPtr<Layout::Node> HTMLCanvasElement::create_layout_node(NonnullRefPtr<CSS::St
HTMLCanvasElement::HasOrCreatedContext HTMLCanvasElement::create_2d_context() HTMLCanvasElement::HasOrCreatedContext HTMLCanvasElement::create_2d_context()
{ {
if (!m_context.has<Empty>()) if (!m_context.has<Empty>())
return m_context.has<NonnullRefPtr<CanvasRenderingContext2D>>() ? HasOrCreatedContext::Yes : HasOrCreatedContext::No; return m_context.has<JS::NonnullGCPtr<CanvasRenderingContext2D>>() ? HasOrCreatedContext::Yes : HasOrCreatedContext::No;
m_context = CanvasRenderingContext2D::create(*this); m_context = CanvasRenderingContext2D::create(window(), *this);
return HasOrCreatedContext::Yes; return HasOrCreatedContext::Yes;
} }
JS::ThrowCompletionOr<HTMLCanvasElement::HasOrCreatedContext> HTMLCanvasElement::create_webgl_context(JS::Value options) JS::ThrowCompletionOr<HTMLCanvasElement::HasOrCreatedContext> HTMLCanvasElement::create_webgl_context(JS::Value options)
{ {
if (!m_context.has<Empty>()) if (!m_context.has<Empty>())
return m_context.has<NonnullRefPtr<WebGL::WebGLRenderingContext>>() ? HasOrCreatedContext::Yes : HasOrCreatedContext::No; return m_context.has<JS::NonnullGCPtr<WebGL::WebGLRenderingContext>>() ? HasOrCreatedContext::Yes : HasOrCreatedContext::No;
auto maybe_context = TRY(WebGL::WebGLRenderingContext::create(*this, options)); auto maybe_context = TRY(WebGL::WebGLRenderingContext::create(window(), *this, options));
if (!maybe_context) if (!maybe_context)
return HasOrCreatedContext::No; return HasOrCreatedContext::No;
m_context = maybe_context.release_nonnull(); m_context = JS::NonnullGCPtr<WebGL::WebGLRenderingContext>(*maybe_context);
return HasOrCreatedContext::Yes; return HasOrCreatedContext::Yes;
} }
@ -104,7 +120,7 @@ JS::ThrowCompletionOr<HTMLCanvasElement::RenderingContext> HTMLCanvasElement::ge
// NOTE: See the spec for the full table. // NOTE: See the spec for the full table.
if (type == "2d"sv) { if (type == "2d"sv) {
if (create_2d_context() == HasOrCreatedContext::Yes) if (create_2d_context() == HasOrCreatedContext::Yes)
return m_context; return JS::make_handle(*m_context.get<JS::NonnullGCPtr<HTML::CanvasRenderingContext2D>>());
return Empty {}; return Empty {};
} }
@ -112,7 +128,7 @@ JS::ThrowCompletionOr<HTMLCanvasElement::RenderingContext> HTMLCanvasElement::ge
// NOTE: The WebGL spec says "experimental-webgl" is also acceptable and must be equivalent to "webgl". Other engines accept this, so we do too. // NOTE: The WebGL spec says "experimental-webgl" is also acceptable and must be equivalent to "webgl". Other engines accept this, so we do too.
if (type.is_one_of("webgl"sv, "experimental-webgl"sv)) { if (type.is_one_of("webgl"sv, "experimental-webgl"sv)) {
if (TRY(create_webgl_context(options)) == HasOrCreatedContext::Yes) if (TRY(create_webgl_context(options)) == HasOrCreatedContext::Yes)
return m_context; return JS::make_handle(*m_context.get<JS::NonnullGCPtr<WebGL::WebGLRenderingContext>>());
return Empty {}; return Empty {};
} }
@ -168,10 +184,10 @@ String HTMLCanvasElement::to_data_url(String const& type, [[maybe_unused]] Optio
void HTMLCanvasElement::present() void HTMLCanvasElement::present()
{ {
m_context.visit( m_context.visit(
[](NonnullRefPtr<CanvasRenderingContext2D>&) { [](JS::NonnullGCPtr<CanvasRenderingContext2D>&) {
// Do nothing, CRC2D writes directly to the canvas bitmap. // Do nothing, CRC2D writes directly to the canvas bitmap.
}, },
[](NonnullRefPtr<WebGL::WebGLRenderingContext>& context) { [](JS::NonnullGCPtr<WebGL::WebGLRenderingContext>& context) {
context->present(); context->present();
}, },
[](Empty) { [](Empty) {

View file

@ -17,7 +17,7 @@ class HTMLCanvasElement final : public HTMLElement {
WEB_PLATFORM_OBJECT(HTMLCanvasElement, HTMLElement); WEB_PLATFORM_OBJECT(HTMLCanvasElement, HTMLElement);
public: public:
using RenderingContext = Variant<NonnullRefPtr<CanvasRenderingContext2D>, NonnullRefPtr<WebGL::WebGLRenderingContext>, Empty>; using RenderingContext = Variant<JS::Handle<CanvasRenderingContext2D>, JS::Handle<WebGL::WebGLRenderingContext>, Empty>;
virtual ~HTMLCanvasElement() override; virtual ~HTMLCanvasElement() override;
@ -40,6 +40,8 @@ public:
private: private:
HTMLCanvasElement(DOM::Document&, DOM::QualifiedName); HTMLCanvasElement(DOM::Document&, DOM::QualifiedName);
virtual void visit_edges(Cell::Visitor&) override;
virtual RefPtr<Layout::Node> create_layout_node(NonnullRefPtr<CSS::StyleProperties>) override; virtual RefPtr<Layout::Node> create_layout_node(NonnullRefPtr<CSS::StyleProperties>) override;
enum class HasOrCreatedContext { enum class HasOrCreatedContext {
@ -52,7 +54,8 @@ private:
void reset_context_to_default_state(); void reset_context_to_default_state();
RefPtr<Gfx::Bitmap> m_bitmap; RefPtr<Gfx::Bitmap> m_bitmap;
RenderingContext m_context;
Variant<JS::NonnullGCPtr<HTML::CanvasRenderingContext2D>, JS::NonnullGCPtr<WebGL::WebGLRenderingContext>, Empty> m_context;
}; };
} }

View file

@ -4,9 +4,11 @@
* SPDX-License-Identifier: BSD-2-Clause * SPDX-License-Identifier: BSD-2-Clause
*/ */
#include <LibWeb/Bindings/WebGLRenderingContextPrototype.h>
#include <LibWeb/Bindings/Wrapper.h> #include <LibWeb/Bindings/Wrapper.h>
#include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Document.h>
#include <LibWeb/HTML/HTMLCanvasElement.h> #include <LibWeb/HTML/HTMLCanvasElement.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/WebGL/WebGLContextEvent.h> #include <LibWeb/WebGL/WebGLContextEvent.h>
#include <LibWeb/WebGL/WebGLRenderingContext.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); 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. // 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)); 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); bool created_bitmap = canvas_element.create_bitmap(/* minimum_width= */ 1, /* minimum_height= */ 1);
if (!created_bitmap) { if (!created_bitmap) {
fire_webgl_context_creation_error(canvas_element); fire_webgl_context_creation_error(canvas_element);
return RefPtr<WebGLRenderingContext> { nullptr }; return JS::GCPtr<WebGLRenderingContext> { nullptr };
} }
#ifndef __serenity__ #ifndef __serenity__
// FIXME: Make WebGL work on other platforms. // FIXME: Make WebGL work on other platforms.
(void)window;
(void)context_attributes; (void)context_attributes;
dbgln("FIXME: WebGL not supported on the current platform"); dbgln("FIXME: WebGL not supported on the current platform");
fire_webgl_context_creation_error(canvas_element); fire_webgl_context_creation_error(canvas_element);
return RefPtr<WebGLRenderingContext> { nullptr }; return JS::GCPtr<WebGLRenderingContext> { nullptr };
#else #else
// FIXME: LibGL currently doesn't propagate context creation errors. // FIXME: LibGL currently doesn't propagate context creation errors.
auto context = GL::create_context(*canvas_element.bitmap()); 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 #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;
} }

View file

@ -6,26 +6,22 @@
#pragma once #pragma once
#include <LibWeb/Bindings/Wrappable.h>
#include <LibWeb/WebGL/WebGLRenderingContextBase.h> #include <LibWeb/WebGL/WebGLRenderingContextBase.h>
namespace Web::WebGL { namespace Web::WebGL {
class WebGLRenderingContext class WebGLRenderingContext final : public WebGLRenderingContextBase {
: public WebGLRenderingContextBase WEB_PLATFORM_OBJECT(WebGLRenderingContext, WebGLRenderingContextBase);
, public Bindings::Wrappable {
public: 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;
virtual ~WebGLRenderingContext() override = default;
private: private:
WebGLRenderingContext(HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr<GL::GLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters) WebGLRenderingContext(HTML::Window&, HTML::HTMLCanvasElement&, 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))
{
}
}; };
} }
WRAPPER_HACK(WebGLRenderingContext, Web::WebGL)

View file

@ -7,12 +7,14 @@
#include <AK/Debug.h> #include <AK/Debug.h>
#include <LibGL/GLContext.h> #include <LibGL/GLContext.h>
#include <LibWeb/HTML/HTMLCanvasElement.h> #include <LibWeb/HTML/HTMLCanvasElement.h>
#include <LibWeb/HTML/Window.h>
#include <LibWeb/WebGL/WebGLRenderingContextBase.h> #include <LibWeb/WebGL/WebGLRenderingContextBase.h>
namespace Web::WebGL { namespace Web::WebGL {
WebGLRenderingContextBase::WebGLRenderingContextBase(HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr<GL::GLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters) WebGLRenderingContextBase::WebGLRenderingContextBase(HTML::Window& window, HTML::HTMLCanvasElement& canvas_element, NonnullOwnPtr<GL::GLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters)
: m_canvas_element(canvas_element) : PlatformObject(window.realm())
, m_canvas_element(canvas_element)
, m_context(move(context)) , m_context(move(context))
, m_context_creation_parameters(move(context_creation_parameters)) , m_context_creation_parameters(move(context_creation_parameters))
, m_actual_context_parameters(move(actual_context_parameters)) , m_actual_context_parameters(move(actual_context_parameters))
@ -21,6 +23,12 @@ WebGLRenderingContextBase::WebGLRenderingContextBase(HTML::HTMLCanvasElement& ca
WebGLRenderingContextBase::~WebGLRenderingContextBase() = default; 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) \ #define RETURN_WITH_WEBGL_ERROR_IF(condition, error) \
if (condition) { \ if (condition) { \
dbgln_if(WEBGL_CONTEXT_DEBUG, "{}(): error {:#x}", __func__, error); \ dbgln_if(WEBGL_CONTEXT_DEBUG, "{}(): error {:#x}", __func__, error); \

View file

@ -15,9 +15,9 @@
namespace Web::WebGL { namespace Web::WebGL {
class WebGLRenderingContextBase class WebGLRenderingContextBase : public Bindings::PlatformObject {
: public RefCounted<WebGLRenderingContextBase> WEB_PLATFORM_OBJECT(WebGLRenderingContextBase, Bindings::PlatformObject);
, public Weakable<WebGLRenderingContextBase> {
public: public:
virtual ~WebGLRenderingContextBase(); virtual ~WebGLRenderingContextBase();
@ -62,10 +62,12 @@ public:
void viewport(GLint x, GLint y, GLsizei width, GLsizei height); void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
protected: 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: 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; NonnullOwnPtr<GL::GLContext> m_context;

View file

@ -62,7 +62,7 @@ libweb_js_wrapper(Geometry/DOMRect)
libweb_js_wrapper(Geometry/DOMRectList) libweb_js_wrapper(Geometry/DOMRectList)
libweb_js_wrapper(Geometry/DOMRectReadOnly) libweb_js_wrapper(Geometry/DOMRectReadOnly)
libweb_js_wrapper(HTML/CanvasGradient) libweb_js_wrapper(HTML/CanvasGradient)
libweb_js_wrapper(HTML/CanvasRenderingContext2D) libweb_js_wrapper(HTML/CanvasRenderingContext2D NO_INSTANCE)
libweb_js_wrapper(HTML/CloseEvent NO_INSTANCE) libweb_js_wrapper(HTML/CloseEvent NO_INSTANCE)
libweb_js_wrapper(HTML/DOMParser NO_INSTANCE) libweb_js_wrapper(HTML/DOMParser NO_INSTANCE)
libweb_js_wrapper(HTML/DOMStringMap NO_INSTANCE) libweb_js_wrapper(HTML/DOMStringMap NO_INSTANCE)
@ -183,7 +183,7 @@ libweb_js_wrapper(UIEvents/UIEvent NO_INSTANCE)
libweb_js_wrapper(URL/URL) libweb_js_wrapper(URL/URL)
libweb_js_wrapper(URL/URLSearchParams ITERABLE) libweb_js_wrapper(URL/URLSearchParams ITERABLE)
libweb_js_wrapper(WebGL/WebGLContextEvent NO_INSTANCE) libweb_js_wrapper(WebGL/WebGLContextEvent NO_INSTANCE)
libweb_js_wrapper(WebGL/WebGLRenderingContext) libweb_js_wrapper(WebGL/WebGLRenderingContext NO_INSTANCE)
libweb_js_wrapper(WebSockets/WebSocket NO_INSTANCE) libweb_js_wrapper(WebSockets/WebSocket NO_INSTANCE)
libweb_js_wrapper(XHR/ProgressEvent NO_INSTANCE) libweb_js_wrapper(XHR/ProgressEvent NO_INSTANCE)
libweb_js_wrapper(XHR/XMLHttpRequest NO_INSTANCE) libweb_js_wrapper(XHR/XMLHttpRequest NO_INSTANCE)