ladybird/Libraries/LibWeb/HTML/HTMLCanvasElement.h
Aliaksandr Kalenik 6c162d8b5d LibWeb+LibWebView+WebContent: Recover after Compositor process crashes
The browser previously treated the out-of-process Compositor as fatal.

Restart the shared Compositor from the browser process, reconnect
process-backed WebContent clients, recreate compositor contexts, restore
viewport state, and ask WebContent to repaint and republish canvas and
media resources. WebContent now marks its compositor connection lost,
returns conservative values for synchronous compositor queries while
reconnecting, and drops outgoing updates until the replacement transport
arrives.

Synchronous input queries through the compositor control connection now
use fallible IPC. If the Compositor exits after the open check or before
the sync reply arrives, scroll and mouse handling report that the
Compositor did not handle the event and let the normal WebContent
fallback run.

Mouse events queued while the Compositor is unavailable now fall back to
direct WebContent dispatch. This keeps input completion in step with the
pending-event queue.

Recovery is capped at three automatic restarts. If the restart limit is
exceeded, if restart, reconnect, or context recreation fails, or if the
replacement Compositor exits during active recovery, the browser crashes
instead of switching process-backed views to a fallback path.
2026-05-24 03:35:07 +01:00

86 lines
3.1 KiB
C++

/*
* Copyright (c) 2020, Andreas Kling <andreas@ladybird.org>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/Optional.h>
#include <LibGfx/Forward.h>
#include <LibGfx/PaintingSurface.h>
#include <LibWeb/HTML/HTMLElement.h>
#include <LibWeb/Painting/DisplayListResourceIds.h>
#include <LibWeb/WebIDL/Types.h>
namespace Web::HTML {
class HTMLCanvasElement final : public HTMLElement {
WEB_PLATFORM_OBJECT(HTMLCanvasElement, HTMLElement);
GC_DECLARE_ALLOCATOR(HTMLCanvasElement);
public:
static constexpr bool OVERRIDES_FINALIZE = true;
using RenderingContext = Variant<GC::Ref<CanvasRenderingContext2D>, GC::Ref<WebGL::WebGLRenderingContext>, GC::Ref<WebGL::WebGL2RenderingContext>, Empty>;
virtual ~HTMLCanvasElement() override;
Gfx::IntSize bitmap_size_for_canvas(size_t minimum_width = 0, size_t minimum_height = 0) const;
JS::ThrowCompletionOr<RenderingContext> get_context(String const& type, JS::Value options);
enum class HasOrCreatedContext {
No,
Yes,
};
JS::ThrowCompletionOr<HasOrCreatedContext> create_2d_context(JS::Value options);
WebIDL::UnsignedLong width() const;
WebIDL::UnsignedLong height() const;
void set_width(WebIDL::UnsignedLong);
void set_height(WebIDL::UnsignedLong);
virtual void attribute_changed(FlyString const& local_name, Optional<String> const& old_value, Optional<String> const& value, Optional<FlyString> const& namespace_) override;
String to_data_url(StringView type, Optional<JS::Value> quality);
WebIDL::ExceptionOr<void> to_blob(GC::Ref<WebIDL::CallbackType> callback, StringView type, Optional<JS::Value> quality);
RefPtr<Gfx::Bitmap> get_bitmap_from_surface();
void present();
void republish_compositor_surface();
void set_canvas_content_dirty();
RefPtr<Gfx::PaintingSurface> surface() const;
void allocate_painting_surface_if_needed();
Painting::CompositorSurfaceId ensure_compositor_surface_id();
CSS::ComputationContext canvas_font_computation_context();
private:
HTMLCanvasElement(DOM::Document&, DOM::QualifiedName);
virtual void initialize(JS::Realm&) override;
virtual void finalize() override;
virtual void visit_edges(Cell::Visitor&) override;
virtual bool is_presentational_hint(FlyString const&) const override;
virtual void apply_presentational_hints(Vector<CSS::StyleProperty>&) const override;
virtual GC::Ptr<Layout::Node> create_layout_node(GC::Ref<CSS::ComputedProperties>) override;
virtual void adjust_computed_style(CSS::ComputedProperties&) override;
template<typename ContextType>
JS::ThrowCompletionOr<HasOrCreatedContext> create_webgl_context(JS::Value options);
void reset_context_to_default_state();
void notify_context_about_canvas_size_change();
void clear_compositor_surface();
void update_compositor_surface();
Variant<GC::Ref<HTML::CanvasRenderingContext2D>, GC::Ref<WebGL::WebGLRenderingContext>, GC::Ref<WebGL::WebGL2RenderingContext>, Empty> m_context;
Optional<Painting::CompositorSurfaceId> m_compositor_surface_id;
bool m_canvas_content_dirty { false };
};
}