Files
ladybird/Libraries/LibWeb/WebGL/WebGL2RenderingContext.h
Aliaksandr Kalenik 004e5f851e LibWeb: Use ExternalContentSource for canvas painting
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.
2026-02-20 18:41:33 +01:00

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;
};
}