mirror of
https://github.com/LadybirdBrowser/ladybird
synced 2026-04-26 01:35:08 +02:00
present() now snapshots the PaintingSurface into an ImmutableBitmap and publishes it to the ExternalContentSource, so the rendering thread never touches the live GPU surface — eliminating the data race described in the ExternalContentSource commit (problem 1). Canvas elements are registered with Page and presented once per frame from the event loop, rather than on every individual draw call in CRC2D::did_draw(). A dirty flag on HTMLCanvasElement ensures the snapshot is only taken when content has actually changed, and makes the present() call in CanvasPaintable::paint() a no-op when the surface has already been snapshotted for the current frame.
89 lines
3.8 KiB
C++
89 lines
3.8 KiB
C++
/*
|
|
* Copyright (c) 2022, Luke Wilde <lukew@serenityos.org>
|
|
* Copyright (c) 2024, Andrew Kaster <andrew@ladybird.org>
|
|
* Copyright (c) 2024, Aliaksandr Kalenik <kalenik.aliaksandr@gmail.com>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <LibGC/Ptr.h>
|
|
#include <LibWeb/Bindings/PlatformObject.h>
|
|
#include <LibWeb/Forward.h>
|
|
#include <LibWeb/WebGL/Types.h>
|
|
#include <LibWeb/WebGL/WebGL2RenderingContextOverloads.h>
|
|
#include <LibWeb/WebGL/WebGLContextAttributes.h>
|
|
|
|
namespace Web::WebGL {
|
|
|
|
class WebGL2RenderingContext final : public WebGL2RenderingContextOverloads {
|
|
WEB_PLATFORM_OBJECT(WebGL2RenderingContext, WebGL2RenderingContextOverloads);
|
|
GC_DECLARE_ALLOCATOR(WebGL2RenderingContext);
|
|
|
|
public:
|
|
static JS::ThrowCompletionOr<GC::Ptr<WebGL2RenderingContext>> create(JS::Realm&, HTML::HTMLCanvasElement& canvas_element, JS::Value options);
|
|
|
|
virtual ~WebGL2RenderingContext() override;
|
|
|
|
void present() override;
|
|
void needs_to_present() override;
|
|
|
|
GC::Ref<HTML::HTMLCanvasElement> canvas_for_binding() const;
|
|
|
|
bool is_context_lost() const;
|
|
Optional<WebGLContextAttributes> get_context_attributes();
|
|
|
|
RefPtr<Gfx::PaintingSurface> surface();
|
|
void allocate_painting_surface_if_needed();
|
|
|
|
void set_size(Gfx::IntSize const&);
|
|
void reset_to_default_state();
|
|
|
|
Optional<Vector<String>> get_supported_extensions();
|
|
JS::Object* get_extension(String const& name);
|
|
|
|
WebIDL::Long drawing_buffer_width() const;
|
|
WebIDL::Long drawing_buffer_height() const;
|
|
|
|
private:
|
|
virtual void initialize(JS::Realm&) override;
|
|
|
|
WebGL2RenderingContext(JS::Realm&, HTML::HTMLCanvasElement&, NonnullOwnPtr<OpenGLContext> context, WebGLContextAttributes context_creation_parameters, WebGLContextAttributes actual_context_parameters);
|
|
|
|
virtual void visit_edges(Cell::Visitor&) override;
|
|
|
|
virtual bool ext_texture_filter_anisotropic_extension_enabled() const override;
|
|
virtual bool angle_instanced_arrays_extension_enabled() const override;
|
|
virtual bool oes_standard_derivatives_extension_enabled() const override;
|
|
virtual bool webgl_draw_buffers_extension_enabled() const override;
|
|
virtual ReadonlySpan<WebIDL::UnsignedLong> enabled_compressed_texture_formats() const override;
|
|
|
|
GC::Ref<HTML::HTMLCanvasElement> m_canvas_element;
|
|
|
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#context-creation-parameters
|
|
// Each WebGLRenderingContext has context creation parameters, set upon creation, in a WebGLContextAttributes object.
|
|
WebGLContextAttributes m_context_creation_parameters {};
|
|
|
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#actual-context-parameters
|
|
// Each WebGLRenderingContext has actual context parameters, set each time the drawing buffer is created, in a WebGLContextAttributes object.
|
|
WebGLContextAttributes m_actual_context_parameters {};
|
|
|
|
// https://www.khronos.org/registry/webgl/specs/latest/1.0/#webgl-context-lost-flag
|
|
// Each WebGLRenderingContext has a webgl context lost flag, which is initially unset.
|
|
bool m_context_lost { false };
|
|
|
|
Vector<WebIDL::UnsignedLong> m_enabled_compressed_texture_formats;
|
|
|
|
// Extensions
|
|
// "Multiple calls to getExtension with the same extension string, taking into account case-insensitive comparison, must return the same object as long as the extension is enabled."
|
|
GC::Ptr<Extensions::EXTColorBufferFloat> m_ext_color_buffer_float_extension;
|
|
GC::Ptr<Extensions::EXTRenderSnorm> m_ext_render_snorm;
|
|
GC::Ptr<Extensions::EXTTextureFilterAnisotropic> m_ext_texture_filter_anisotropic;
|
|
GC::Ptr<Extensions::EXTTextureNorm16> m_ext_texture_norm16;
|
|
GC::Ptr<Extensions::WebGLCompressedTextureS3tc> m_webgl_compressed_texture_s3tc_extension;
|
|
GC::Ptr<Extensions::WebGLCompressedTextureS3tcSrgb> m_webgl_compressed_texture_s3tc_srgb_extension;
|
|
};
|
|
|
|
}
|