diff --git a/Libraries/LibWeb/Compositor/CompositorHost.cpp b/Libraries/LibWeb/Compositor/CompositorHost.cpp index 41958c8fb7..97a408bbaa 100644 --- a/Libraries/LibWeb/Compositor/CompositorHost.cpp +++ b/Libraries/LibWeb/Compositor/CompositorHost.cpp @@ -21,9 +21,14 @@ CompositorContextHandle::~CompositorContextHandle() m_host.destroy_context(m_context_id); } -void CompositorContextHandle::set_presentation_mode(PresentationMode mode) +void CompositorContextHandle::set_parent_context(Optional parent_context_id) { - m_host.set_presentation_mode(m_context_id, move(mode)); + m_host.set_parent_context(m_context_id, parent_context_id); +} + +void CompositorContextHandle::stop_presenting_to_client() +{ + m_host.stop_presenting_to_client(m_context_id); } void CompositorContextHandle::update_display_list(NonnullRefPtr display_list, Painting::AccumulatedVisualContextTree visual_context_tree, Painting::DisplayListResourceTransaction&& resource_transaction, Painting::ScrollStateSnapshot&& scroll_state_snapshot) diff --git a/Libraries/LibWeb/Compositor/CompositorHost.h b/Libraries/LibWeb/Compositor/CompositorHost.h index 1f215a1b46..726f7a68d2 100644 --- a/Libraries/LibWeb/Compositor/CompositorHost.h +++ b/Libraries/LibWeb/Compositor/CompositorHost.h @@ -32,7 +32,8 @@ public: ~CompositorContextHandle(); CompositorContextId id() const { return m_context_id; } - void set_presentation_mode(PresentationMode); + void set_parent_context(Optional); + void stop_presenting_to_client(); void update_display_list(NonnullRefPtr, Painting::AccumulatedVisualContextTree, Painting::DisplayListResourceTransaction&&, Painting::ScrollStateSnapshot&&); void update_visual_context_tree(Painting::AccumulatedVisualContextTree); @@ -70,7 +71,8 @@ public: virtual RefPtr create_canvas_2d_transport() = 0; virtual void destroy_context(CompositorContextId) = 0; - virtual void set_presentation_mode(CompositorContextId, PresentationMode) = 0; + virtual void set_parent_context(CompositorContextId, Optional) = 0; + virtual void stop_presenting_to_client(CompositorContextId) = 0; virtual void update_display_list(CompositorContextId, NonnullRefPtr, Painting::AccumulatedVisualContextTree, Painting::DisplayListResourceTransaction&&, Painting::ScrollStateSnapshot&&) = 0; virtual void update_visual_context_tree(CompositorContextId, Painting::AccumulatedVisualContextTree) = 0; diff --git a/Libraries/LibWeb/Compositor/Types.cpp b/Libraries/LibWeb/Compositor/Types.cpp index 0957575c38..27e5103445 100644 --- a/Libraries/LibWeb/Compositor/Types.cpp +++ b/Libraries/LibWeb/Compositor/Types.cpp @@ -82,33 +82,4 @@ ErrorOr decode(Decoder& decoder) }; } -template<> -ErrorOr encode(Encoder& encoder, Web::Compositor::PublishToCompositorSurface const& mode) -{ - TRY(encoder.encode(mode.target_context_id)); - TRY(encoder.encode(mode.surface_id)); - return {}; -} - -template<> -ErrorOr decode(Decoder& decoder) -{ - return Web::Compositor::PublishToCompositorSurface { - .target_context_id = TRY(decoder.decode()), - .surface_id = TRY(decoder.decode()), - }; -} - -template<> -ErrorOr encode(Encoder&, Web::Compositor::PresentToClient const&) -{ - return {}; -} - -template<> -ErrorOr decode(Decoder&) -{ - return Web::Compositor::PresentToClient {}; -} - } diff --git a/Libraries/LibWeb/Compositor/Types.h b/Libraries/LibWeb/Compositor/Types.h index f927480f21..9ce17ab6ea 100644 --- a/Libraries/LibWeb/Compositor/Types.h +++ b/Libraries/LibWeb/Compositor/Types.h @@ -10,12 +10,10 @@ #include #include #include -#include #include #include #include #include -#include namespace Web::Compositor { @@ -53,16 +51,6 @@ enum class AsyncScrollOperationTracking { Yes, }; -struct PublishToCompositorSurface { - CompositorContextId target_context_id; - Painting::CompositorSurfaceId surface_id; -}; - -struct PresentToClient { -}; - -using PresentationMode = Variant; - } namespace IPC { @@ -87,14 +75,4 @@ WEB_API ErrorOr encode(Encoder&, Web::Compositor::AsyncScrollEnqueueResult template<> WEB_API ErrorOr decode(Decoder&); -template<> -WEB_API ErrorOr encode(Encoder&, Web::Compositor::PublishToCompositorSurface const&); -template<> -WEB_API ErrorOr decode(Decoder&); - -template<> -WEB_API ErrorOr encode(Encoder&, Web::Compositor::PresentToClient const&); -template<> -WEB_API ErrorOr decode(Decoder&); - } diff --git a/Libraries/LibWeb/HTML/Navigable.cpp b/Libraries/LibWeb/HTML/Navigable.cpp index 4a640d8021..5ef119bb77 100644 --- a/Libraries/LibWeb/HTML/Navigable.cpp +++ b/Libraries/LibWeb/HTML/Navigable.cpp @@ -513,11 +513,7 @@ void Navigable::initialize_navigable(NonnullRefPtr document_state m_should_show_caret_hit_test_debug_overlay = parent->m_should_show_caret_hit_test_debug_overlay; } if (parent && !m_is_svg_page && has_compositor_context() && parent->has_compositor_context()) { - m_compositor_surface_id = Painting::allocate_compositor_surface_id(); - compositor_context().set_presentation_mode(Compositor::PublishToCompositorSurface { - .target_context_id = parent->compositor_context().id(), - .surface_id = *m_compositor_surface_id, - }); + compositor_context().set_parent_context(parent->compositor_context().id()); } // 6. Set the initial visibility state of documentState's document to navigable's traversable navigable's system visibility state. @@ -3766,24 +3762,15 @@ void Navigable::set_has_session_history_entry_and_ready_for_navigation() process_pending_navigations(); } -Painting::CompositorSurfaceId Navigable::compositor_surface_id() const +void Navigable::clear_parent_compositor_context() { - VERIFY(m_compositor_surface_id.has_value()); - return *m_compositor_surface_id; -} - -void Navigable::clear_compositor_surface() -{ - if (!m_compositor_surface_id.has_value()) - return; if (has_compositor_context()) - compositor_context().set_presentation_mode(Empty {}); - m_compositor_surface_id.clear(); + compositor_context().set_parent_context({}); } void Navigable::destroy_compositor_context() { - clear_compositor_surface(); + clear_parent_compositor_context(); m_compositor_context.clear(); } @@ -3793,11 +3780,8 @@ void Navigable::repaint_after_compositor_process_reconnect() if (has_compositor_context()) { if (auto parent = this->parent(); - parent && parent->has_compositor_context() && has_compositor_surface_id()) { - compositor_context().set_presentation_mode(Compositor::PublishToCompositorSurface { - .target_context_id = parent->compositor_context().id(), - .surface_id = *m_compositor_surface_id, - }); + parent && parent->has_compositor_context()) { + compositor_context().set_parent_context(parent->compositor_context().id()); } compositor_context().viewport_size_updated( page().css_to_device_rect(viewport_rect()).size().to_type(), @@ -3909,9 +3893,8 @@ void Navigable::paint_next_frame() if (is_top_level_traversable()) { paint_config.canvas_fill_rect = Gfx::IntRect { {}, viewport_rect.size() }; } else { - // Nested navigables publish transparent bitmaps to their preconfigured compositor surface instead of filling - // the canvas for the UI process. - if (!m_compositor_surface_id.has_value()) + // Nested navigables paint transparent bitmaps for their parent compositor context. + if (!parent() || !parent()->has_compositor_context()) return; } diff --git a/Libraries/LibWeb/HTML/Navigable.h b/Libraries/LibWeb/HTML/Navigable.h index a1ee42e9bc..f7e3ba0a05 100644 --- a/Libraries/LibWeb/HTML/Navigable.h +++ b/Libraries/LibWeb/HTML/Navigable.h @@ -271,11 +271,13 @@ public: VERIFY(m_compositor_context); return *m_compositor_context; } + Compositor::CompositorContextHandle const& compositor_context() const + { + VERIFY(m_compositor_context); + return *m_compositor_context; + } bool has_compositor_context() const { return m_compositor_context; } - Painting::CompositorSurfaceId compositor_surface_id() const; - bool has_compositor_surface_id() const { return m_compositor_surface_id.has_value(); } - void set_pending_set_browser_zoom_request(bool value) { m_pending_set_browser_zoom_request = value; } bool pending_set_browser_zoom_request() const { return m_pending_set_browser_zoom_request; } @@ -319,7 +321,7 @@ private: void reset_cursor_blink_cycle(); void scroll_offset_did_change(); - void clear_compositor_surface(); + void clear_parent_compositor_context(); void destroy_compositor_context(); void inform_the_navigation_api_about_aborting_navigation(); @@ -389,7 +391,6 @@ private: Painting::DisplayListResourceStorage m_display_list_resource_storage; Painting::DisplayListResourceSet m_compositor_display_list_resources; OwnPtr m_compositor_context; - Optional m_compositor_surface_id; RefPtr m_async_scroll_hover_update_timer; struct PendingAsyncScrollOperation { diff --git a/Libraries/LibWeb/Painting/DisplayListCommand.cpp b/Libraries/LibWeb/Painting/DisplayListCommand.cpp index b73cd8ab45..f4d74bc45d 100644 --- a/Libraries/LibWeb/Painting/DisplayListCommand.cpp +++ b/Libraries/LibWeb/Painting/DisplayListCommand.cpp @@ -40,7 +40,7 @@ void DrawRepeatedDecodedImageFrame::dump(StringBuilder& builder) const builder.appendff(" dst_rect={} clip_rect={}", dst_rect, clip_rect); } -void DrawCompositorSurface::dump(StringBuilder& builder) const +void DrawCompositedContext::dump(StringBuilder& builder) const { builder.appendff(" dst_rect={}", dst_rect); } diff --git a/Libraries/LibWeb/Painting/DisplayListCommand.h b/Libraries/LibWeb/Painting/DisplayListCommand.h index fecbfeb43b..d2483683ca 100644 --- a/Libraries/LibWeb/Painting/DisplayListCommand.h +++ b/Libraries/LibWeb/Painting/DisplayListCommand.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -38,7 +39,7 @@ class DisplayList; V(FillRect, fill_rect) \ V(DrawScaledDecodedImageFrame, draw_scaled_decoded_image_frame) \ V(DrawRepeatedDecodedImageFrame, draw_repeated_decoded_image_frame) \ - V(DrawCompositorSurface, draw_compositor_surface) \ + V(DrawCompositedContext, draw_composited_context) \ V(DrawCanvas, draw_canvas) \ V(DrawVideoFrame, draw_video_frame) \ V(Save, save) \ @@ -188,12 +189,12 @@ struct DrawRepeatedDecodedImageFrame { void dump(StringBuilder&) const; }; -struct DrawCompositorSurface { - static constexpr StringView command_name = "DrawCompositorSurface"sv; - static constexpr DisplayListCommandType command_type = DisplayListCommandType::DrawCompositorSurface; +struct DrawCompositedContext { + static constexpr StringView command_name = "DrawCompositedContext"sv; + static constexpr DisplayListCommandType command_type = DisplayListCommandType::DrawCompositedContext; Gfx::IntRect dst_rect; - CompositorSurfaceId surface_id; + Web::Compositor::CompositorContextId child_context_id; Gfx::ScalingMode scaling_mode; [[nodiscard]] Gfx::IntRect bounding_rect() const { return dst_rect; } diff --git a/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp b/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp index b85e2fa9b6..f26ef2c6a4 100644 --- a/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp +++ b/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp @@ -65,9 +65,9 @@ void DisplayListPlayerSkia::execute( ScrollStateSnapshot const& scroll_state_snapshot, RefPtr surface, CanvasSurfaceRegistry const* canvas_surface_registry, - CompositorSurfaceMap const* compositor_surfaces) + CompositedContextResolver const* composited_context_resolver) { - TemporaryChange compositor_surfaces_change { m_compositor_surfaces, compositor_surfaces }; + TemporaryChange composited_context_resolver_change { m_composited_context_resolver, composited_context_resolver }; DisplayListPlayer::execute( display_list, visual_context_tree, @@ -225,16 +225,16 @@ void DisplayListPlayerSkia::play_command(FillRect const& command) canvas.drawRect(to_skia_rect(rect), paint); } -void DisplayListPlayerSkia::play_command(DrawCompositorSurface const& command) +void DisplayListPlayerSkia::play_command(DrawCompositedContext const& command) { - if (!m_compositor_surfaces) + if (!m_composited_context_resolver) return; - auto compositor_surface = m_compositor_surfaces->get(command.surface_id); - if (!compositor_surface.has_value()) + auto composited_context_surface = (*m_composited_context_resolver)(command.child_context_id); + if (!composited_context_surface) return; - auto image = compositor_surface.value()->sk_image_snapshot>(); + auto image = composited_context_surface->sk_image_snapshot>(); if (!image) return; diff --git a/Libraries/LibWeb/Painting/DisplayListPlayerSkia.h b/Libraries/LibWeb/Painting/DisplayListPlayerSkia.h index 67a4090844..7c095c095e 100644 --- a/Libraries/LibWeb/Painting/DisplayListPlayerSkia.h +++ b/Libraries/LibWeb/Painting/DisplayListPlayerSkia.h @@ -7,7 +7,6 @@ #pragma once #include -#include #include #include #include @@ -22,7 +21,7 @@ namespace Web::Painting { class WEB_API DisplayListPlayerSkia final : public DisplayListPlayer { public: - using CompositorSurfaceMap = HashMap>; + using CompositedContextResolver = Function(Web::Compositor::CompositorContextId)>; DisplayListPlayerSkia(); explicit DisplayListPlayerSkia(RefPtr); @@ -36,7 +35,7 @@ public: ScrollStateSnapshot const&, RefPtr, CanvasSurfaceRegistry const*, - CompositorSurfaceMap const*); + CompositedContextResolver const*); void flush(Gfx::PaintingSurface&) override; void flush_async(Gfx::PaintingSurface&, Function&&); @@ -60,7 +59,7 @@ private: ReadonlySpan gradient_positions(DisplayListGradientColorStops) const; RefPtr m_skia_backend_context; - CompositorSurfaceMap const* m_compositor_surfaces { nullptr }; + CompositedContextResolver const* m_composited_context_resolver { nullptr }; }; } diff --git a/Libraries/LibWeb/Painting/DisplayListRecorder.cpp b/Libraries/LibWeb/Painting/DisplayListRecorder.cpp index 26ad449f14..63f1aa937f 100644 --- a/Libraries/LibWeb/Painting/DisplayListRecorder.cpp +++ b/Libraries/LibWeb/Painting/DisplayListRecorder.cpp @@ -512,13 +512,13 @@ void DisplayListRecorder::draw_rect(Gfx::IntRect const& rect, Color color, bool .rough = rough }); } -void DisplayListRecorder::draw_compositor_surface(Gfx::IntRect const& dst_rect, CompositorSurfaceId surface_id, Gfx::ScalingMode scaling_mode) +void DisplayListRecorder::draw_composited_context(Gfx::IntRect const& dst_rect, Web::Compositor::CompositorContextId child_context_id, Gfx::ScalingMode scaling_mode) { if (dst_rect.is_empty()) return; - append_command(DrawCompositorSurface { + append_command(DrawCompositedContext { .dst_rect = dst_rect, - .surface_id = surface_id, + .child_context_id = child_context_id, .scaling_mode = scaling_mode, }); } diff --git a/Libraries/LibWeb/Painting/DisplayListRecorder.h b/Libraries/LibWeb/Painting/DisplayListRecorder.h index 56bf75e303..6b8f6454b7 100644 --- a/Libraries/LibWeb/Painting/DisplayListRecorder.h +++ b/Libraries/LibWeb/Painting/DisplayListRecorder.h @@ -73,7 +73,7 @@ public: void draw_rect(Gfx::IntRect const& rect, Color color, bool rough = false); void draw_scaled_decoded_image_frame(Gfx::IntRect const& dst_rect, Gfx::DecodedImageFrame frame, Gfx::ScalingMode scaling_mode = Gfx::ScalingMode::NearestNeighbor); - void draw_compositor_surface(Gfx::IntRect const& dst_rect, CompositorSurfaceId, Gfx::ScalingMode scaling_mode = Gfx::ScalingMode::NearestNeighbor); + void draw_composited_context(Gfx::IntRect const& dst_rect, Web::Compositor::CompositorContextId, Gfx::ScalingMode scaling_mode = Gfx::ScalingMode::NearestNeighbor); void draw_canvas(Gfx::IntRect const& dst_rect, CanvasId, Gfx::ScalingMode scaling_mode = Gfx::ScalingMode::NearestNeighbor); void draw_video_frame(Gfx::IntRect const& dst_rect, VideoFrameResourceId, RefPtr, Gfx::ScalingMode scaling_mode = Gfx::ScalingMode::NearestNeighbor); diff --git a/Libraries/LibWeb/Painting/DisplayListResourceIds.h b/Libraries/LibWeb/Painting/DisplayListResourceIds.h index 859ea82688..a69744bb0d 100644 --- a/Libraries/LibWeb/Painting/DisplayListResourceIds.h +++ b/Libraries/LibWeb/Painting/DisplayListResourceIds.h @@ -16,7 +16,6 @@ AK_TYPEDEF_DISTINCT_ORDERED_ID(u64, FontResourceId); AK_TYPEDEF_DISTINCT_ORDERED_ID(u64, ImageFrameResourceId); AK_TYPEDEF_DISTINCT_ORDERED_ID(u64, VideoFrameResourceId); AK_TYPEDEF_DISTINCT_ORDERED_ID(u64, DisplayListResourceId); -AK_TYPEDEF_DISTINCT_ORDERED_ID(u64, CompositorSurfaceId); AK_TYPEDEF_DISTINCT_ORDERED_ID(u64, CanvasId); inline VideoFrameResourceId allocate_video_frame_resource_id() @@ -25,10 +24,4 @@ inline VideoFrameResourceId allocate_video_frame_resource_id() return VideoFrameResourceId { s_next_id.fetch_add(1, AK::MemoryOrder::memory_order_relaxed) }; } -inline CompositorSurfaceId allocate_compositor_surface_id() -{ - static Atomic s_next_id { 1 }; - return CompositorSurfaceId { s_next_id.fetch_add(1, AK::MemoryOrder::memory_order_relaxed) }; -} - } diff --git a/Libraries/LibWeb/Painting/NavigableContainerViewportPaintable.cpp b/Libraries/LibWeb/Painting/NavigableContainerViewportPaintable.cpp index 813e44d286..0e842dbd23 100644 --- a/Libraries/LibWeb/Painting/NavigableContainerViewportPaintable.cpp +++ b/Libraries/LibWeb/Painting/NavigableContainerViewportPaintable.cpp @@ -47,14 +47,14 @@ void NavigableContainerViewportPaintable::paint(DisplayListRecordingContext& con auto content_navigable = navigable_container.content_navigable(); VERIFY(content_navigable); - if (content_navigable->has_been_destroyed() || !content_navigable->has_compositor_surface_id()) + if (content_navigable->has_been_destroyed() || !content_navigable->has_compositor_context()) return; context.display_list_recorder().save(); context.display_list_recorder().add_clip_rect(clip_rect.to_type()); - context.display_list_recorder().draw_compositor_surface( + context.display_list_recorder().draw_composited_context( context.enclosing_device_rect(absolute_rect).to_type(), - content_navigable->compositor_surface_id(), + content_navigable->compositor_context().id(), Gfx::ScalingMode::NearestNeighbor); context.display_list_recorder().restore(); diff --git a/Services/Compositor/BackingStoreManager.cpp b/Services/Compositor/BackingStoreManager.cpp index b78d1d0efb..fb45c3add9 100644 --- a/Services/Compositor/BackingStoreManager.cpp +++ b/Services/Compositor/BackingStoreManager.cpp @@ -164,6 +164,11 @@ bool BackingStoreManager::is_valid() const return m_backing_stores.is_valid(); } +RefPtr BackingStoreManager::front_store_if_present() const +{ + return m_backing_stores.front_store; +} + Gfx::PaintingSurface& BackingStoreManager::front_store() { VERIFY(m_backing_stores.front_store); diff --git a/Services/Compositor/BackingStoreManager.h b/Services/Compositor/BackingStoreManager.h index 58f3f9f28d..dfae3f7182 100644 --- a/Services/Compositor/BackingStoreManager.h +++ b/Services/Compositor/BackingStoreManager.h @@ -41,6 +41,7 @@ public: Optional allocate_backing_stores(Allocation const&, RefPtr const&, bool should_publish); bool is_valid() const; + RefPtr front_store_if_present() const; Gfx::PaintingSurface& front_store(); Gfx::PaintingSurface& back_store(); i32 back_bitmap_id() const; diff --git a/Services/Compositor/CompositorState.cpp b/Services/Compositor/CompositorState.cpp index fb4ced5d22..8f6b5dfe29 100644 --- a/Services/Compositor/CompositorState.cpp +++ b/Services/Compositor/CompositorState.cpp @@ -81,39 +81,50 @@ void CompositorState::destroy_context(Web::Compositor::CompositorContextId conte VERIFY(context); cancel_pending_async_presents_for_context(context_id); - detach_from_parent_surface(context_id, *context); - for (auto& child_context_entry : context->child_contexts()) { - auto* child_context = context_if_present(child_context_entry.child_context_id); - VERIFY(child_context); - child_context->did_detach_from_parent_surface(context_id, child_context_entry.surface_id); + clear_parent_context(*context); + for (auto& context_entry : m_contexts) { + if (context_entry.key == context_id) + continue; + auto& possible_child_context = *context_entry.value; + auto parent_context_id = possible_child_context.parent_context_id(); + if (parent_context_id.has_value() && *parent_context_id == context_id) + possible_child_context.set_parent_context({}); } m_contexts.remove(context_id); } -void CompositorState::set_presentation_mode(Web::Compositor::CompositorContextId context_id, Web::Compositor::PresentationMode presentation_mode) +void CompositorState::set_parent_context(Web::Compositor::CompositorContextId context_id, Optional parent_context_id) { auto* context = context_if_present(context_id); VERIFY(context); - auto& context_state = *context; - auto was_presenting_to_client = context_state.presents_to_client(); - auto will_present_to_client = ContextState::presentation_mode_presents_to_client(presentation_mode); - detach_from_parent_surface(context_id, context_state); + if (parent_context_id.has_value()) { + VERIFY(!context->presents_to_client()); + VERIFY(*parent_context_id != context_id); + VERIFY(context_if_present(*parent_context_id)); + } - presentation_mode.visit( - [](Empty const&) {}, - [](Web::Compositor::PresentToClient const&) {}, - [&](Web::Compositor::PublishToCompositorSurface const& mode) { - auto* parent_context = context_if_present(mode.target_context_id); - VERIFY(parent_context); - parent_context->attach_child_surface(mode.surface_id, context_id); - context_state.set_published_surface({ - .parent_context_id = mode.target_context_id, - .surface_id = mode.surface_id, - }); - }); - context_state.set_presentation_mode(move(presentation_mode)); - context_state.did_stop_presenting_to_client_if_needed(was_presenting_to_client, will_present_to_client); + auto current_parent_context_id = context->parent_context_id(); + if (current_parent_context_id.has_value() == parent_context_id.has_value() + && (!current_parent_context_id.has_value() || *current_parent_context_id == *parent_context_id)) + return; + + clear_parent_context(*context); + context->set_parent_context(parent_context_id); + + if (!parent_context_id.has_value() || !context->latest_rendered_surface()) + return; + + auto* parent_context = context_if_present(*parent_context_id); + VERIFY(parent_context); + present_current_frame(*parent_context_id, *parent_context); +} + +void CompositorState::stop_presenting_to_client(Web::Compositor::CompositorContextId context_id) +{ + auto* context = context_if_present(context_id); + VERIFY(context); + context->stop_presenting_to_client(); } void CompositorState::update_display_list(Web::Compositor::CompositorContextId context_id, NonnullRefPtr display_list, Web::Painting::AccumulatedVisualContextTree visual_context_tree, Web::Painting::DisplayListResourceTransaction&& resource_transaction, Web::Painting::ScrollStateSnapshot&& scroll_state_snapshot) @@ -269,7 +280,8 @@ void CompositorState::present_frame(Web::Compositor::CompositorContextId context void CompositorState::present_frame(Web::Compositor::CompositorContextId context_id, ContextState& context, Gfx::IntRect viewport_rect) { - auto prepared_frame = context.prepare_frame(*m_display_list_player, viewport_rect); + auto composited_context_resolver = resolver_for(context_id); + auto prepared_frame = context.prepare_frame(*m_display_list_player, viewport_rect, &composited_context_resolver); if (!prepared_frame.has_value()) return; @@ -339,8 +351,11 @@ void CompositorState::flush_descendant_surfaces_for_screenshot(Web::Compositor:: // present synchronously (deepest-first) — to capture a complete frame instead of a stale/blank iframe. auto* context = context_if_present(context_id); VERIFY(context); - for (auto& child : context->child_contexts()) - present_subtree_for_screenshot(child.child_context_id); + for (auto& context_entry : m_contexts) { + auto parent_context_id = context_entry.value->parent_context_id(); + if (parent_context_id.has_value() && *parent_context_id == context_id) + present_subtree_for_screenshot(context_entry.key); + } } bool CompositorState::present_subtree_for_screenshot(Web::Compositor::CompositorContextId context_id) @@ -349,23 +364,24 @@ bool CompositorState::present_subtree_for_screenshot(Web::Compositor::Compositor VERIFY(context); bool needs_present = context->needs_synchronous_present_for_screenshot(); - for (auto& child : context->child_contexts()) { - if (present_subtree_for_screenshot(child.child_context_id)) + for (auto& context_entry : m_contexts) { + auto parent_context_id = context_entry.value->parent_context_id(); + if (parent_context_id.has_value() + && *parent_context_id == context_id + && present_subtree_for_screenshot(context_entry.key)) needs_present = true; } - if (!needs_present || !context->publishes_to_parent_surface()) + if (!needs_present) return false; - present_context_synchronously(*context); - return true; + return present_context_synchronously(context_id, *context); } -void CompositorState::present_context_synchronously(ContextState& context) +bool CompositorState::present_context_synchronously(Web::Compositor::CompositorContextId context_id, ContextState& context) { - auto publish_mode = context.present_synchronously(*m_display_list_player); - if (publish_mode.has_value()) - publish_to_parent_surface(context, *publish_mode); + auto composited_context_resolver = resolver_for(context_id); + return context.present_synchronously(*m_display_list_player, &composited_context_resolver); } bool CompositorState::request_screenshot(Web::Compositor::CompositorContextId context_id, Gfx::ShareableBitmap& target_bitmap) @@ -377,7 +393,8 @@ bool CompositorState::request_screenshot(Web::Compositor::CompositorContextId co return false; flush_descendant_surfaces_for_screenshot(context_id); - context->paint_screenshot(*m_display_list_player, target_bitmap); + auto composited_context_resolver = resolver_for(context_id); + context->paint_screenshot(*m_display_list_player, target_bitmap, &composited_context_resolver); return true; } @@ -417,15 +434,15 @@ void CompositorState::did_finish_async_present(PendingAsyncPresent& pending_pres VERIFY(context); context->did_finish_gpu_present(bitmap_id); - context->presentation_mode().visit( - [](Empty const&) {}, - [&](Web::Compositor::PresentToClient const&) { - VERIFY(m_client); - m_client->did_present_frame(context_id, viewport_rect, bitmap_id); - }, - [&](Web::Compositor::PublishToCompositorSurface const& mode) { - publish_to_parent_surface(*context, mode); - }); + if (context->presents_to_client()) { + VERIFY(m_client); + m_client->did_present_frame(context_id, viewport_rect, bitmap_id); + } + if (auto parent_context_id = context->parent_context_id(); parent_context_id.has_value()) { + auto* parent_context = context_if_present(*parent_context_id); + VERIFY(parent_context); + present_current_frame(*parent_context_id, *parent_context); + } schedule_pending_present_frame_if_unblocked(context_id, *context); } @@ -484,19 +501,35 @@ ContextState const* CompositorState::context_if_present(Web::Compositor::Composi return it->value.ptr(); } -void CompositorState::detach_from_parent_surface(Web::Compositor::CompositorContextId context_id, ContextState& context) +void CompositorState::clear_parent_context(ContextState& context) { - auto published_surface = context.take_published_surface(); - if (!published_surface.has_value()) + auto parent_context_id = context.parent_context_id(); + if (!parent_context_id.has_value()) return; - auto* parent_context = context_if_present(published_surface->parent_context_id); - VERIFY(parent_context); - auto removed_child_context_id = parent_context->take_child_context_for_surface(published_surface->surface_id); - VERIFY(removed_child_context_id.has_value()); - VERIFY(*removed_child_context_id == context_id); - parent_context->clear_compositor_surface(published_surface->surface_id); - present_current_frame(published_surface->parent_context_id, *parent_context); + context.set_parent_context({}); + auto* parent_context = context_if_present(*parent_context_id); + if (!parent_context) + return; + present_current_frame(*parent_context_id, *parent_context); +} + +CompositedContextResolver CompositorState::resolver_for(Web::Compositor::CompositorContextId parent_context_id) +{ + return [this, parent_context_id](Web::Compositor::CompositorContextId child_context_id) { + return resolve_composited_context(parent_context_id, child_context_id); + }; +} + +RefPtr CompositorState::resolve_composited_context(Web::Compositor::CompositorContextId parent_context_id, Web::Compositor::CompositorContextId child_context_id) +{ + auto* child_context = context_if_present(child_context_id); + if (!child_context) + return nullptr; + auto child_parent_context_id = child_context->parent_context_id(); + if (!child_parent_context_id.has_value() || *child_parent_context_id != parent_context_id) + return nullptr; + return child_context->latest_rendered_surface(); } void CompositorState::resize_backing_stores_if_needed(Web::Compositor::CompositorContextId context_id, ContextState& context) @@ -533,15 +566,6 @@ void CompositorState::present_current_frame(Web::Compositor::CompositorContextId schedule_present_frame(context_id, context, *frame_to_present); } -void CompositorState::publish_to_parent_surface(ContextState& context, Web::Compositor::PublishToCompositorSurface const& mode) -{ - auto* parent_context = context_if_present(mode.target_context_id); - VERIFY(parent_context); - - parent_context->update_compositor_surface(mode.surface_id, context.snapshot_front_store()); - present_current_frame(mode.target_context_id, *parent_context); -} - bool CompositorState::apply_context_update_result( Web::Compositor::CompositorContextId context_id, ContextState& context, diff --git a/Services/Compositor/CompositorState.h b/Services/Compositor/CompositorState.h index 8ceccf2d14..69b3510379 100644 --- a/Services/Compositor/CompositorState.h +++ b/Services/Compositor/CompositorState.h @@ -77,7 +77,7 @@ public: void create_context(Web::Compositor::CompositorContextId, Optional page_id, CompositorStateWebContentClient&); void destroy_context(Web::Compositor::CompositorContextId); - void set_presentation_mode(Web::Compositor::CompositorContextId, Web::Compositor::PresentationMode); + void set_parent_context(Web::Compositor::CompositorContextId, Optional parent_context_id); void stop_presenting_to_client(Web::Compositor::CompositorContextId); void update_display_list(Web::Compositor::CompositorContextId, NonnullRefPtr, Web::Painting::AccumulatedVisualContextTree, Web::Painting::DisplayListResourceTransaction&&, Web::Painting::ScrollStateSnapshot&&); void update_visual_context_tree(Web::Compositor::CompositorContextId, Web::Painting::AccumulatedVisualContextTree); @@ -117,12 +117,13 @@ private: ContextState* context_if_present(Web::Compositor::CompositorContextId); ContextState const* context_if_present(Web::Compositor::CompositorContextId) const; - void detach_from_parent_surface(Web::Compositor::CompositorContextId, ContextState&); + void clear_parent_context(ContextState&); + CompositedContextResolver resolver_for(Web::Compositor::CompositorContextId parent_context_id); + RefPtr resolve_composited_context(Web::Compositor::CompositorContextId parent_context_id, Web::Compositor::CompositorContextId child_context_id); void schedule_backing_store_shrink(Web::Compositor::CompositorContextId, ContextState&); void shrink_backing_stores_after_resize(Web::Compositor::CompositorContextId); void resize_backing_stores_if_needed(Web::Compositor::CompositorContextId, ContextState&); void present_current_frame(Web::Compositor::CompositorContextId, ContextState&); - void publish_to_parent_surface(ContextState&, Web::Compositor::PublishToCompositorSurface const&); bool apply_context_update_result( Web::Compositor::CompositorContextId, ContextState&, @@ -135,7 +136,7 @@ private: void present_pending_frames_on_vsync(Optional display_id); void flush_descendant_surfaces_for_screenshot(Web::Compositor::CompositorContextId); bool present_subtree_for_screenshot(Web::Compositor::CompositorContextId); - void present_context_synchronously(ContextState&); + bool present_context_synchronously(Web::Compositor::CompositorContextId, ContextState&); void publish_backing_stores(Web::Compositor::CompositorContextId, ContextState&, BackingStoreManager::Publication&&); void did_finish_async_present(PendingAsyncPresent&); void cancel_pending_async_presents_for_context(Web::Compositor::CompositorContextId); diff --git a/Services/Compositor/CompositorWebContentServer.ipc b/Services/Compositor/CompositorWebContentServer.ipc index 188711b45e..ddcb72a363 100644 --- a/Services/Compositor/CompositorWebContentServer.ipc +++ b/Services/Compositor/CompositorWebContentServer.ipc @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -19,7 +20,8 @@ endpoint CompositorWebContentServer { init_transport(int peer_pid) => (int compositor_pid) - set_presentation_mode(Web::Compositor::CompositorContextId context_id, Web::Compositor::PresentationMode presentation_mode) =| + set_parent_context(Web::Compositor::CompositorContextId context_id, Optional parent_context_id) =| + stop_presenting_to_client(Web::Compositor::CompositorContextId context_id) =| destroy_context(Web::Compositor::CompositorContextId context_id) =| update_display_list(Web::Compositor::CompositorContextId context_id, NonnullRefPtr display_list, Web::Painting::AccumulatedVisualContextTree visual_context_tree, Web::Painting::DisplayListResourceTransaction resource_transaction, Web::Painting::ScrollStateSnapshot scroll_state_snapshot) =| diff --git a/Services/Compositor/ConnectionFromWebContent.cpp b/Services/Compositor/ConnectionFromWebContent.cpp index 18fb4cf509..5455f504ad 100644 --- a/Services/Compositor/ConnectionFromWebContent.cpp +++ b/Services/Compositor/ConnectionFromWebContent.cpp @@ -64,10 +64,16 @@ void ConnectionFromWebContent::verify_context_is_owned_by_this_connection(Web::C VERIFY_NOT_REACHED(); } -void ConnectionFromWebContent::set_presentation_mode(Web::Compositor::CompositorContextId context_id, Web::Compositor::PresentationMode presentation_mode) +void ConnectionFromWebContent::set_parent_context(Web::Compositor::CompositorContextId context_id, Optional parent_context_id) { verify_context_is_owned_by_this_connection(context_id); - m_compositor_state->set_presentation_mode(context_id, move(presentation_mode)); + m_compositor_state->set_parent_context(context_id, parent_context_id); +} + +void ConnectionFromWebContent::stop_presenting_to_client(Web::Compositor::CompositorContextId context_id) +{ + verify_context_is_owned_by_this_connection(context_id); + m_compositor_state->stop_presenting_to_client(context_id); } void ConnectionFromWebContent::destroy_context(Web::Compositor::CompositorContextId context_id) diff --git a/Services/Compositor/ConnectionFromWebContent.h b/Services/Compositor/ConnectionFromWebContent.h index c651835a0f..6e5d2d8ca7 100644 --- a/Services/Compositor/ConnectionFromWebContent.h +++ b/Services/Compositor/ConnectionFromWebContent.h @@ -37,7 +37,8 @@ private: virtual void die() override; virtual Messages::CompositorWebContentServer::InitTransportResponse init_transport(int peer_pid) override; - virtual void set_presentation_mode(Web::Compositor::CompositorContextId, Web::Compositor::PresentationMode) override; + virtual void set_parent_context(Web::Compositor::CompositorContextId, Optional) override; + virtual void stop_presenting_to_client(Web::Compositor::CompositorContextId) override; virtual void destroy_context(Web::Compositor::CompositorContextId) override; virtual void update_display_list(Web::Compositor::CompositorContextId, NonnullRefPtr, Web::Painting::AccumulatedVisualContextTree, Web::Painting::DisplayListResourceTransaction, Web::Painting::ScrollStateSnapshot) override; virtual void update_visual_context_tree(Web::Compositor::CompositorContextId, Web::Painting::AccumulatedVisualContextTree) override; diff --git a/Services/Compositor/ContextState.cpp b/Services/Compositor/ContextState.cpp index f547870cbe..6a6039f15b 100644 --- a/Services/Compositor/ContextState.cpp +++ b/Services/Compositor/ContextState.cpp @@ -13,7 +13,6 @@ #include #include #include -#include #include #include @@ -88,7 +87,7 @@ ContextState::ContextState(Optional page_id, CompositorStateWebContentClien , m_async_scrolling_enabled(async_scrolling_enabled) { if (page_id.has_value()) - m_presentation_mode = Web::Compositor::PresentToClient {}; + m_presents_to_client = true; } ContextState::~ContextState() @@ -96,11 +95,6 @@ ContextState::~ContextState() stop_backing_store_shrink_timer(); } -bool ContextState::presentation_mode_presents_to_client(Web::Compositor::PresentationMode const& presentation_mode) -{ - return presentation_mode.has(); -} - bool ContextState::is_owned_by(CompositorStateWebContentClient const& web_content_client) const { return &m_web_content_client == &web_content_client; @@ -117,11 +111,11 @@ void ContextState::dispatch_mouse_event_to_web_content(Web::MouseEvent const& ev m_web_content_client.dispatch_mouse_event_to_web_content(*m_page_id, event); } -void ContextState::set_presentation_mode(Web::Compositor::PresentationMode presentation_mode) +void ContextState::stop_presenting_to_client() { - if (presentation_mode_presents_to_client(presentation_mode)) - VERIFY(m_page_id.has_value()); - m_presentation_mode = move(presentation_mode); + auto was_presenting_to_client = m_presents_to_client; + m_presents_to_client = false; + did_stop_presenting_to_client_if_needed(was_presenting_to_client, m_presents_to_client); } void ContextState::did_stop_presenting_to_client_if_needed(bool was_presenting_to_client, bool will_present_to_client) @@ -132,44 +126,9 @@ void ContextState::did_stop_presenting_to_client_if_needed(bool was_presenting_t m_presented_bitmap_id_awaiting_ack.clear(); } -void ContextState::set_published_surface(PublishedSurface published_surface) +void ContextState::set_parent_context(Optional parent_context_id) { - m_published_surface = published_surface; -} - -Optional ContextState::take_published_surface() -{ - if (!m_published_surface.has_value()) - return {}; - return m_published_surface.release_value(); -} - -void ContextState::did_detach_from_parent_surface(Web::Compositor::CompositorContextId parent_context_id, Web::Painting::CompositorSurfaceId surface_id) -{ - VERIFY(m_published_surface.has_value()); - VERIFY(m_published_surface->parent_context_id == parent_context_id); - VERIFY(m_published_surface->surface_id == surface_id); - m_published_surface.clear(); - m_presentation_mode = Empty {}; -} - -void ContextState::attach_child_surface(Web::Painting::CompositorSurfaceId surface_id, Web::Compositor::CompositorContextId child_context_id) -{ - m_child_contexts_by_surface_id.set(surface_id, child_context_id); -} - -Optional ContextState::take_child_context_for_surface(Web::Painting::CompositorSurfaceId surface_id) -{ - return m_child_contexts_by_surface_id.take(surface_id); -} - -Vector ContextState::child_contexts() const -{ - Vector child_contexts; - child_contexts.ensure_capacity(m_child_contexts_by_surface_id.size()); - for (auto& child_context : m_child_contexts_by_surface_id) - child_contexts.unchecked_append({ child_context.key, child_context.value }); - return child_contexts; + m_parent_context_id = parent_context_id; } void ContextState::apply_display_list_resource_transaction(Web::Painting::DisplayListResourceTransaction&& resource_transaction) @@ -259,22 +218,6 @@ void ContextState::clear_video_frame(Web::Painting::VideoFrameResourceId frame_i m_display_list_resource_storage.clear_video_frame(frame_id); } -void ContextState::update_compositor_surface(Web::Painting::CompositorSurfaceId surface_id, Gfx::SharedImage&& shared_image) -{ - auto shared_image_buffer = Gfx::SharedImageBuffer::import_from_shared_image(move(shared_image)); - m_compositor_surfaces.set(surface_id, Gfx::PaintingSurface::wrap_bitmap(*shared_image_buffer.bitmap())); -} - -void ContextState::clear_compositor_surface(Web::Painting::CompositorSurfaceId surface_id) -{ - m_compositor_surfaces.remove(surface_id); -} - -Gfx::SharedImage ContextState::snapshot_front_store() -{ - return m_backing_store_manager.front_store().snapshot_into_shared_image(); -} - void ContextState::invalidate_wheel_event_listener_state(u64 generation) { m_wheel_event_listener_state_generation = max(m_wheel_event_listener_state_generation, generation); @@ -618,7 +561,7 @@ Optional ContextState::current_frame_rect_to_present() const return m_presented_frame; } -Optional ContextState::prepare_frame(Web::Painting::DisplayListPlayerSkia& display_list_player, Gfx::IntRect viewport_rect) +Optional ContextState::prepare_frame(Web::Painting::DisplayListPlayerSkia& display_list_player, Gfx::IntRect viewport_rect, CompositedContextResolver const* composited_context_resolver) { if (is_present_blocked()) { m_pending_present_frame = viewport_rect; @@ -631,14 +574,11 @@ Optional ContextState::prepare_frame(Web::Painting: } auto& back_store = m_backing_store_manager.back_store(); - m_presentation_mode.visit( - [](Empty const&) {}, - [](Web::Compositor::PresentToClient const&) {}, - [&](Web::Compositor::PublishToCompositorSurface const&) { - Gfx::PainterSkia painter { NonnullRefPtr { back_store } }; - painter.clear_rect(back_store.rect().to_type(), Gfx::Color::Transparent); - }); - paint_current_display_list(display_list_player, back_store); + if (!presents_to_client()) { + Gfx::PainterSkia painter { NonnullRefPtr { back_store } }; + painter.clear_rect(back_store.rect().to_type(), Gfx::Color::Transparent); + } + paint_current_display_list(display_list_player, back_store, composited_context_resolver); auto rendered_bitmap_id = m_backing_store_manager.back_bitmap_id(); m_gpu_present_bitmap_id_awaiting_completion = rendered_bitmap_id; @@ -656,34 +596,33 @@ void ContextState::did_submit_prepared_frame(Gfx::IntRect viewport_rect) m_presented_frame = viewport_rect; } -Optional ContextState::present_synchronously(Web::Painting::DisplayListPlayerSkia& display_list_player) +bool ContextState::present_synchronously(Web::Painting::DisplayListPlayerSkia& display_list_player, CompositedContextResolver const* composited_context_resolver) { - auto* publish_mode = m_presentation_mode.get_pointer(); - VERIFY(publish_mode); if (!can_render_frame()) - return {}; - // Don't race an async present already in flight for this context; its own completion will publish. + return false; + // Don't race an async present already in flight for this context; its own completion will update the output. if (is_present_blocked()) - return {}; + return false; auto viewport_rect = m_pending_present_frame; if (!viewport_rect.has_value()) viewport_rect = m_presented_frame; if (!viewport_rect.has_value()) - return {}; + return false; auto& back_store = m_backing_store_manager.back_store(); - { + if (!presents_to_client()) { Gfx::PainterSkia painter { NonnullRefPtr { back_store } }; painter.clear_rect(back_store.rect().to_type(), Gfx::Color::Transparent); } - paint_current_display_list(display_list_player, back_store); + paint_current_display_list(display_list_player, back_store, composited_context_resolver); display_list_player.flush(back_store); m_backing_store_manager.swap(); + m_latest_rendered_surface = m_backing_store_manager.front_store_if_present(); m_presented_frame = viewport_rect; m_pending_present_frame.clear(); m_pending_present_frame_scheduled = false; - return *publish_mode; + return true; } bool ContextState::can_paint_screenshot(Gfx::ShareableBitmap& target_bitmap) const @@ -691,12 +630,12 @@ bool ContextState::can_paint_screenshot(Gfx::ShareableBitmap& target_bitmap) con return m_display_list && target_bitmap.is_valid() && target_bitmap.bitmap(); } -void ContextState::paint_screenshot(Web::Painting::DisplayListPlayerSkia& display_list_player, Gfx::ShareableBitmap& target_bitmap) +void ContextState::paint_screenshot(Web::Painting::DisplayListPlayerSkia& display_list_player, Gfx::ShareableBitmap& target_bitmap, CompositedContextResolver const* composited_context_resolver) { VERIFY(can_paint_screenshot(target_bitmap)); auto target_surface = Gfx::PaintingSurface::wrap_bitmap(*target_bitmap.bitmap()); - paint_current_display_list(display_list_player, *target_surface); + paint_current_display_list(display_list_player, *target_surface, composited_context_resolver); display_list_player.flush(*target_surface); } @@ -713,6 +652,7 @@ void ContextState::did_finish_gpu_present(i32 bitmap_id) { VERIFY(m_gpu_present_bitmap_id_awaiting_completion == bitmap_id); m_gpu_present_bitmap_id_awaiting_completion.clear(); + m_latest_rendered_surface = m_backing_store_manager.front_store_if_present(); } void ContextState::stop_backing_store_shrink_timer() @@ -878,7 +818,7 @@ Web::Painting::AccumulatedVisualContextTree const& ContextState::visual_context_ return *m_visual_context_tree_for_compositing; } -void ContextState::paint_current_display_list(Web::Painting::DisplayListPlayerSkia& display_list_player, Gfx::PaintingSurface& surface) +void ContextState::paint_current_display_list(Web::Painting::DisplayListPlayerSkia& display_list_player, Gfx::PaintingSurface& surface, CompositedContextResolver const* composited_context_resolver) { VERIFY(m_display_list); display_list_player.execute( @@ -888,7 +828,7 @@ void ContextState::paint_current_display_list(Web::Painting::DisplayListPlayerSk m_scroll_state_snapshot, surface, &m_canvas_surface_registry, - &m_compositor_surfaces); + composited_context_resolver); m_viewport_scrollbar_controller.paint(surface, display_list_player, m_scroll_state_snapshot); } diff --git a/Services/Compositor/ContextState.h b/Services/Compositor/ContextState.h index ae6cf880f9..1f374c1bd3 100644 --- a/Services/Compositor/ContextState.h +++ b/Services/Compositor/ContextState.h @@ -7,7 +7,6 @@ #pragma once #include -#include #include #include #include @@ -20,7 +19,6 @@ #include #include #include -#include #include #include #include @@ -53,22 +51,13 @@ class DisplayListPlayerSkia; namespace Compositor { class CompositorStateWebContentClient; +using CompositedContextResolver = Function(Web::Compositor::CompositorContextId)>; class ContextState { AK_MAKE_NONCOPYABLE(ContextState); AK_MAKE_NONMOVABLE(ContextState); public: - struct PublishedSurface { - Web::Compositor::CompositorContextId parent_context_id; - Web::Painting::CompositorSurfaceId surface_id; - }; - - struct ChildSurface { - Web::Painting::CompositorSurfaceId surface_id; - Web::Compositor::CompositorContextId child_context_id; - }; - struct AsyncScrollResult { Web::Compositor::AsyncScrollEnqueueResult enqueue_result; Optional frame_to_present; @@ -88,24 +77,17 @@ public: ContextState(Optional page_id, CompositorStateWebContentClient&, Web::Painting::CanvasSurfaceRegistry const&, bool async_scrolling_enabled); ~ContextState(); - static bool presentation_mode_presents_to_client(Web::Compositor::PresentationMode const&); - bool is_owned_by(CompositorStateWebContentClient const&) const; void request_rendering_update(); void dispatch_mouse_event_to_web_content(Web::MouseEvent const&); - bool presents_to_client() const { return presentation_mode_presents_to_client(m_presentation_mode); } - bool publishes_to_parent_surface() const { return m_presentation_mode.has(); } - Web::Compositor::PresentationMode const& presentation_mode() const { return m_presentation_mode; } - void set_presentation_mode(Web::Compositor::PresentationMode); + bool presents_to_client() const { return m_presents_to_client; } + void stop_presenting_to_client(); void did_stop_presenting_to_client_if_needed(bool was_presenting_to_client, bool will_present_to_client); - void set_published_surface(PublishedSurface); - Optional take_published_surface(); - void did_detach_from_parent_surface(Web::Compositor::CompositorContextId parent_context_id, Web::Painting::CompositorSurfaceId); - void attach_child_surface(Web::Painting::CompositorSurfaceId, Web::Compositor::CompositorContextId child_context_id); - Optional take_child_context_for_surface(Web::Painting::CompositorSurfaceId); - Vector child_contexts() const; + void set_parent_context(Optional); + Optional parent_context_id() const { return m_parent_context_id; } + RefPtr latest_rendered_surface() const { return m_latest_rendered_surface; } void apply_display_list_resource_transaction(Web::Painting::DisplayListResourceTransaction&&); void install_display_list_update( @@ -116,9 +98,6 @@ public: void update_scroll_state(Web::Painting::ScrollStateSnapshot&&); void update_video_frame(Web::Painting::VideoFrameResourceId, NonnullRefPtr); void clear_video_frame(Web::Painting::VideoFrameResourceId); - void update_compositor_surface(Web::Painting::CompositorSurfaceId, Gfx::SharedImage&&); - void clear_compositor_surface(Web::Painting::CompositorSurfaceId); - Gfx::SharedImage snapshot_front_store(); void invalidate_wheel_event_listener_state(u64 generation); ContextUpdateResult handle_mouse_event(Web::MouseEvent const&); @@ -150,11 +129,11 @@ public: Optional take_pending_present_frame_if_unblocked(); bool needs_synchronous_present_for_screenshot() const; Optional current_frame_rect_to_present() const; - Optional prepare_frame(Web::Painting::DisplayListPlayerSkia&, Gfx::IntRect); + Optional prepare_frame(Web::Painting::DisplayListPlayerSkia&, Gfx::IntRect, CompositedContextResolver const*); void did_submit_prepared_frame(Gfx::IntRect); - Optional present_synchronously(Web::Painting::DisplayListPlayerSkia&); + bool present_synchronously(Web::Painting::DisplayListPlayerSkia&, CompositedContextResolver const*); bool can_paint_screenshot(Gfx::ShareableBitmap&) const; - void paint_screenshot(Web::Painting::DisplayListPlayerSkia&, Gfx::ShareableBitmap&); + void paint_screenshot(Web::Painting::DisplayListPlayerSkia&, Gfx::ShareableBitmap&, CompositedContextResolver const*); bool acknowledge_presented_bitmap(i32 bitmap_id); void did_finish_gpu_present(i32 bitmap_id); @@ -176,24 +155,23 @@ private: bool is_present_blocked() const; bool can_render_frame() const; Web::Painting::AccumulatedVisualContextTree const& visual_context_tree_for_compositing() const; - void paint_current_display_list(Web::Painting::DisplayListPlayerSkia&, Gfx::PaintingSurface&); + void paint_current_display_list(Web::Painting::DisplayListPlayerSkia&, Gfx::PaintingSurface&, CompositedContextResolver const*); CompositorStateWebContentClient& m_web_content_client; Web::Painting::CanvasSurfaceRegistry const& m_canvas_surface_registry; Optional m_page_id; bool const m_async_scrolling_enabled { true }; - Web::Compositor::PresentationMode m_presentation_mode { Empty {} }; - Optional m_published_surface; - HashMap m_child_contexts_by_surface_id; + bool m_presents_to_client { false }; + Optional m_parent_context_id; RefPtr m_display_list; Optional m_visual_context_tree; mutable Optional m_visual_context_tree_for_compositing; Web::Painting::DisplayListResourceStorage m_display_list_resource_storage; - HashMap> m_compositor_surfaces; Web::Painting::ScrollStateSnapshot m_scroll_state_snapshot; BackingStoreManager m_backing_store_manager; + RefPtr m_latest_rendered_surface; Web::Compositor::AsyncScrollTree m_async_scroll_tree; ViewportScrollbarController m_viewport_scrollbar_controller; diff --git a/Services/WebContent/CompositorConnection.cpp b/Services/WebContent/CompositorConnection.cpp index a29605168a..a681c16549 100644 --- a/Services/WebContent/CompositorConnection.cpp +++ b/Services/WebContent/CompositorConnection.cpp @@ -24,11 +24,18 @@ void CompositorConnection::die() did_lose_compositor(); } -void CompositorConnection::set_presentation_mode(Web::Compositor::CompositorContextId context_id, Web::Compositor::PresentationMode const& presentation_mode) +void CompositorConnection::set_parent_context(Web::Compositor::CompositorContextId context_id, Optional parent_context_id) { if (!can_send_message_to_compositor()) return; - async_set_presentation_mode(context_id, presentation_mode); + async_set_parent_context(context_id, parent_context_id); +} + +void CompositorConnection::stop_presenting_to_client(Web::Compositor::CompositorContextId context_id) +{ + if (!can_send_message_to_compositor()) + return; + async_stop_presenting_to_client(context_id); } void CompositorConnection::destroy_context(Web::Compositor::CompositorContextId context_id) diff --git a/Services/WebContent/CompositorConnection.h b/Services/WebContent/CompositorConnection.h index 66a2009c4a..91eef82585 100644 --- a/Services/WebContent/CompositorConnection.h +++ b/Services/WebContent/CompositorConnection.h @@ -37,7 +37,8 @@ class CompositorConnection final public: explicit CompositorConnection(NonnullOwnPtr); - void set_presentation_mode(Web::Compositor::CompositorContextId, Web::Compositor::PresentationMode const&); + void set_parent_context(Web::Compositor::CompositorContextId, Optional); + void stop_presenting_to_client(Web::Compositor::CompositorContextId); void destroy_context(Web::Compositor::CompositorContextId); void update_display_list(Web::Compositor::CompositorContextId, NonnullRefPtr const&, Web::Painting::AccumulatedVisualContextTree const&, Web::Painting::DisplayListResourceTransaction const&, Web::Painting::ScrollStateSnapshot const&); void update_visual_context_tree(Web::Compositor::CompositorContextId, Web::Painting::AccumulatedVisualContextTree const&); diff --git a/Services/WebContent/PageClient.cpp b/Services/WebContent/PageClient.cpp index 798847c0ba..80c0bba788 100644 --- a/Services/WebContent/PageClient.cpp +++ b/Services/WebContent/PageClient.cpp @@ -818,7 +818,7 @@ void PageClient::page_did_request_activate_tab() void PageClient::page_did_close_top_level_traversable() { - page().top_level_traversable()->compositor_context().set_presentation_mode(Empty {}); + page().top_level_traversable()->compositor_context().stop_presenting_to_client(); if (m_webdriver) m_webdriver->page_did_close_window({}, page().top_level_traversable()->window_handle()); diff --git a/Services/WebContent/WebContentCompositorHost.cpp b/Services/WebContent/WebContentCompositorHost.cpp index 7d67d7ef53..a7058f4139 100644 --- a/Services/WebContent/WebContentCompositorHost.cpp +++ b/Services/WebContent/WebContentCompositorHost.cpp @@ -178,10 +178,16 @@ private: m_client.did_destroy_compositor_context(context_id); } - virtual void set_presentation_mode(Web::Compositor::CompositorContextId context_id, Web::Compositor::PresentationMode mode) override + virtual void set_parent_context(Web::Compositor::CompositorContextId context_id, Optional parent_context_id) override { if (auto* connection = compositor_connection()) - connection->set_presentation_mode(context_id, mode); + connection->set_parent_context(context_id, parent_context_id); + } + + virtual void stop_presenting_to_client(Web::Compositor::CompositorContextId context_id) override + { + if (auto* connection = compositor_connection()) + connection->stop_presenting_to_client(context_id); } virtual void update_display_list(Web::Compositor::CompositorContextId context_id, NonnullRefPtr display_list, Web::Painting::AccumulatedVisualContextTree visual_context_tree, Web::Painting::DisplayListResourceTransaction&& resource_transaction, Web::Painting::ScrollStateSnapshot&& scroll_state_snapshot) override diff --git a/Tests/LibWeb/Text/expected/async-scrolling/nested-navigable-wheel-admission.txt b/Tests/LibWeb/Text/expected/async-scrolling/nested-navigable-wheel-admission.txt index 4ced7c2a22..f53081e4cb 100644 --- a/Tests/LibWeb/Text/expected/async-scrolling/nested-navigable-wheel-admission.txt +++ b/Tests/LibWeb/Text/expected/async-scrolling/nested-navigable-wheel-admission.txt @@ -17,6 +17,6 @@ SaveLayer@0 CompositorMainThreadWheelEventRegion@1 rect=[40,40 160x120] Save@1 AddClipRect@1 rect=[40,40 160x120] - DrawCompositorSurface@1 dst_rect=[40,40 160x120] + DrawCompositedContext@1 dst_rect=[40,40 160x120] Restore@1 Restore@0 diff --git a/Tests/LibWeb/Text/expected/display_list/iframe-compositor-surface.txt b/Tests/LibWeb/Text/expected/display_list/iframe-compositor-surface.txt index 205435a3d3..edaa7c9f0b 100644 --- a/Tests/LibWeb/Text/expected/display_list/iframe-compositor-surface.txt +++ b/Tests/LibWeb/Text/expected/display_list/iframe-compositor-surface.txt @@ -12,6 +12,6 @@ SaveLayer@0 CompositorMainThreadWheelEventRegion@1 rect=[0,0 120x80] Save@1 AddClipRect@1 rect=[0,0 120x80] - DrawCompositorSurface@1 dst_rect=[0,0 120x80] + DrawCompositedContext@1 dst_rect=[0,0 120x80] Restore@1 Restore@0