LibWeb+Compositor+WebContent: Simplify nested context composition
Nested navigables were represented through compositor surface ids owned by the parent context. That forced CompositorState and ContextState to maintain bidirectional attach/detach bookkeeping, publish child snapshots into a surface map, and keep presentation mode variants just to distinguish UI presentation from parent composition. Record the child compositor context id directly in the display list and let the compositor resolve it against the painting parent at playback time. Child contexts now keep their parent context id and latest rendered surface, while parents no longer track child maps or compositor surface ids. UI presentation is represented separately from parent composition, so closing a page only stops client presentation and nested contexts keep using set_parent_context.
This commit is contained in:
parent
1b5bdb2b41
commit
d96dc6535f
29 changed files with 224 additions and 319 deletions
|
|
@ -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<CompositorContextId> 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<Painting::DisplayList> display_list, Painting::AccumulatedVisualContextTree visual_context_tree, Painting::DisplayListResourceTransaction&& resource_transaction, Painting::ScrollStateSnapshot&& scroll_state_snapshot)
|
||||
|
|
|
|||
|
|
@ -32,7 +32,8 @@ public:
|
|||
~CompositorContextHandle();
|
||||
|
||||
CompositorContextId id() const { return m_context_id; }
|
||||
void set_presentation_mode(PresentationMode);
|
||||
void set_parent_context(Optional<CompositorContextId>);
|
||||
void stop_presenting_to_client();
|
||||
|
||||
void update_display_list(NonnullRefPtr<Painting::DisplayList>, Painting::AccumulatedVisualContextTree, Painting::DisplayListResourceTransaction&&, Painting::ScrollStateSnapshot&&);
|
||||
void update_visual_context_tree(Painting::AccumulatedVisualContextTree);
|
||||
|
|
@ -70,7 +71,8 @@ public:
|
|||
virtual RefPtr<HTML::RemoteCanvas2DTransport> 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<CompositorContextId>) = 0;
|
||||
virtual void stop_presenting_to_client(CompositorContextId) = 0;
|
||||
|
||||
virtual void update_display_list(CompositorContextId, NonnullRefPtr<Painting::DisplayList>, Painting::AccumulatedVisualContextTree, Painting::DisplayListResourceTransaction&&, Painting::ScrollStateSnapshot&&) = 0;
|
||||
virtual void update_visual_context_tree(CompositorContextId, Painting::AccumulatedVisualContextTree) = 0;
|
||||
|
|
|
|||
|
|
@ -82,33 +82,4 @@ ErrorOr<Web::Compositor::AsyncScrollEnqueueResult> decode(Decoder& decoder)
|
|||
};
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<void> encode(Encoder& encoder, Web::Compositor::PublishToCompositorSurface const& mode)
|
||||
{
|
||||
TRY(encoder.encode(mode.target_context_id));
|
||||
TRY(encoder.encode(mode.surface_id));
|
||||
return {};
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<Web::Compositor::PublishToCompositorSurface> decode(Decoder& decoder)
|
||||
{
|
||||
return Web::Compositor::PublishToCompositorSurface {
|
||||
.target_context_id = TRY(decoder.decode<Web::Compositor::CompositorContextId>()),
|
||||
.surface_id = TRY(decoder.decode<Web::Painting::CompositorSurfaceId>()),
|
||||
};
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<void> encode(Encoder&, Web::Compositor::PresentToClient const&)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
template<>
|
||||
ErrorOr<Web::Compositor::PresentToClient> decode(Decoder&)
|
||||
{
|
||||
return Web::Compositor::PresentToClient {};
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,12 +10,10 @@
|
|||
#include <AK/DistinctNumeric.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/Types.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibIPC/Forward.h>
|
||||
#include <LibWeb/Compositor/AsyncScrollingState.h>
|
||||
#include <LibWeb/Export.h>
|
||||
#include <LibWeb/Painting/DisplayListResourceIds.h>
|
||||
|
||||
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<Empty, PresentToClient, PublishToCompositorSurface>;
|
||||
|
||||
}
|
||||
|
||||
namespace IPC {
|
||||
|
|
@ -87,14 +75,4 @@ WEB_API ErrorOr<void> encode(Encoder&, Web::Compositor::AsyncScrollEnqueueResult
|
|||
template<>
|
||||
WEB_API ErrorOr<Web::Compositor::AsyncScrollEnqueueResult> decode(Decoder&);
|
||||
|
||||
template<>
|
||||
WEB_API ErrorOr<void> encode(Encoder&, Web::Compositor::PublishToCompositorSurface const&);
|
||||
template<>
|
||||
WEB_API ErrorOr<Web::Compositor::PublishToCompositorSurface> decode(Decoder&);
|
||||
|
||||
template<>
|
||||
WEB_API ErrorOr<void> encode(Encoder&, Web::Compositor::PresentToClient const&);
|
||||
template<>
|
||||
WEB_API ErrorOr<Web::Compositor::PresentToClient> decode(Decoder&);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -513,11 +513,7 @@ void Navigable::initialize_navigable(NonnullRefPtr<DocumentState> 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<int>(),
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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<Compositor::CompositorContextHandle> m_compositor_context;
|
||||
Optional<Painting::CompositorSurfaceId> m_compositor_surface_id;
|
||||
RefPtr<Core::Timer> m_async_scroll_hover_update_timer;
|
||||
|
||||
struct PendingAsyncScrollOperation {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/ScalingMode.h>
|
||||
#include <LibGfx/Size.h>
|
||||
#include <LibWeb/Compositor/Types.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/Painting/AccumulatedVisualContext.h>
|
||||
#include <LibWeb/Painting/DisplayListResourceIds.h>
|
||||
|
|
@ -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; }
|
||||
|
|
|
|||
|
|
@ -65,9 +65,9 @@ void DisplayListPlayerSkia::execute(
|
|||
ScrollStateSnapshot const& scroll_state_snapshot,
|
||||
RefPtr<Gfx::PaintingSurface> 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<sk_sp<SkImage>>();
|
||||
auto image = composited_context_surface->sk_image_snapshot<sk_sp<SkImage>>();
|
||||
if (!image)
|
||||
return;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <LibGfx/Forward.h>
|
||||
|
|
@ -22,7 +21,7 @@ namespace Web::Painting {
|
|||
|
||||
class WEB_API DisplayListPlayerSkia final : public DisplayListPlayer {
|
||||
public:
|
||||
using CompositorSurfaceMap = HashMap<CompositorSurfaceId, NonnullRefPtr<Gfx::PaintingSurface>>;
|
||||
using CompositedContextResolver = Function<RefPtr<Gfx::PaintingSurface>(Web::Compositor::CompositorContextId)>;
|
||||
|
||||
DisplayListPlayerSkia();
|
||||
explicit DisplayListPlayerSkia(RefPtr<Gfx::SkiaBackendContext>);
|
||||
|
|
@ -36,7 +35,7 @@ public:
|
|||
ScrollStateSnapshot const&,
|
||||
RefPtr<Gfx::PaintingSurface>,
|
||||
CanvasSurfaceRegistry const*,
|
||||
CompositorSurfaceMap const*);
|
||||
CompositedContextResolver const*);
|
||||
|
||||
void flush(Gfx::PaintingSurface&) override;
|
||||
void flush_async(Gfx::PaintingSurface&, Function<void()>&&);
|
||||
|
|
@ -60,7 +59,7 @@ private:
|
|||
ReadonlySpan<float> gradient_positions(DisplayListGradientColorStops) const;
|
||||
|
||||
RefPtr<Gfx::SkiaBackendContext> m_skia_backend_context;
|
||||
CompositorSurfaceMap const* m_compositor_surfaces { nullptr };
|
||||
CompositedContextResolver const* m_composited_context_resolver { nullptr };
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<Media::VideoFrame const>, Gfx::ScalingMode scaling_mode = Gfx::ScalingMode::NearestNeighbor);
|
||||
|
||||
|
|
|
|||
|
|
@ -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<u64> s_next_id { 1 };
|
||||
return CompositorSurfaceId { s_next_id.fetch_add(1, AK::MemoryOrder::memory_order_relaxed) };
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<int>());
|
||||
context.display_list_recorder().draw_compositor_surface(
|
||||
context.display_list_recorder().draw_composited_context(
|
||||
context.enclosing_device_rect(absolute_rect).to_type<int>(),
|
||||
content_navigable->compositor_surface_id(),
|
||||
content_navigable->compositor_context().id(),
|
||||
Gfx::ScalingMode::NearestNeighbor);
|
||||
context.display_list_recorder().restore();
|
||||
|
||||
|
|
|
|||
|
|
@ -164,6 +164,11 @@ bool BackingStoreManager::is_valid() const
|
|||
return m_backing_stores.is_valid();
|
||||
}
|
||||
|
||||
RefPtr<Gfx::PaintingSurface> BackingStoreManager::front_store_if_present() const
|
||||
{
|
||||
return m_backing_stores.front_store;
|
||||
}
|
||||
|
||||
Gfx::PaintingSurface& BackingStoreManager::front_store()
|
||||
{
|
||||
VERIFY(m_backing_stores.front_store);
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ public:
|
|||
Optional<Publication> allocate_backing_stores(Allocation const&, RefPtr<Gfx::SkiaBackendContext> const&, bool should_publish);
|
||||
|
||||
bool is_valid() const;
|
||||
RefPtr<Gfx::PaintingSurface> front_store_if_present() const;
|
||||
Gfx::PaintingSurface& front_store();
|
||||
Gfx::PaintingSurface& back_store();
|
||||
i32 back_bitmap_id() const;
|
||||
|
|
|
|||
|
|
@ -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<Web::Compositor::CompositorContextId> 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<Web::Painting::DisplayList> 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<Gfx::PaintingSurface> 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,
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ public:
|
|||
void create_context(Web::Compositor::CompositorContextId, Optional<u64> 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<Web::Compositor::CompositorContextId> parent_context_id);
|
||||
void stop_presenting_to_client(Web::Compositor::CompositorContextId);
|
||||
void update_display_list(Web::Compositor::CompositorContextId, NonnullRefPtr<Web::Painting::DisplayList>, 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<Gfx::PaintingSurface> 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<u64> 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);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <LibCore/AnonymousBuffer.h>
|
||||
#include <LibGfx/CanvasCommandList.h>
|
||||
#include <LibGfx/DecodedImageFrame.h>
|
||||
|
|
@ -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<Web::Compositor::CompositorContextId> 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<Web::Painting::DisplayList> display_list, Web::Painting::AccumulatedVisualContextTree visual_context_tree, Web::Painting::DisplayListResourceTransaction resource_transaction, Web::Painting::ScrollStateSnapshot scroll_state_snapshot) =|
|
||||
|
|
|
|||
|
|
@ -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<Web::Compositor::CompositorContextId> 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)
|
||||
|
|
|
|||
|
|
@ -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<Web::Compositor::CompositorContextId>) 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::DisplayList>, Web::Painting::AccumulatedVisualContextTree, Web::Painting::DisplayListResourceTransaction, Web::Painting::ScrollStateSnapshot) override;
|
||||
virtual void update_visual_context_tree(Web::Compositor::CompositorContextId, Web::Painting::AccumulatedVisualContextTree) override;
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
#include <LibGfx/Color.h>
|
||||
#include <LibGfx/PainterSkia.h>
|
||||
#include <LibGfx/PaintingSurface.h>
|
||||
#include <LibGfx/SharedImageBuffer.h>
|
||||
#include <LibWeb/Page/InputEvent.h>
|
||||
#include <LibWeb/Painting/DisplayListPlayerSkia.h>
|
||||
|
||||
|
|
@ -88,7 +87,7 @@ ContextState::ContextState(Optional<u64> 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<Web::Compositor::PresentToClient>();
|
||||
}
|
||||
|
||||
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<Web::Compositor::CompositorContextId> parent_context_id)
|
||||
{
|
||||
m_published_surface = published_surface;
|
||||
}
|
||||
|
||||
Optional<ContextState::PublishedSurface> 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<Web::Compositor::CompositorContextId> ContextState::take_child_context_for_surface(Web::Painting::CompositorSurfaceId surface_id)
|
||||
{
|
||||
return m_child_contexts_by_surface_id.take(surface_id);
|
||||
}
|
||||
|
||||
Vector<ContextState::ChildSurface> ContextState::child_contexts() const
|
||||
{
|
||||
Vector<ChildSurface> 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<Gfx::IntRect> ContextState::current_frame_rect_to_present() const
|
|||
return m_presented_frame;
|
||||
}
|
||||
|
||||
Optional<ContextState::PreparedFrame> ContextState::prepare_frame(Web::Painting::DisplayListPlayerSkia& display_list_player, Gfx::IntRect viewport_rect)
|
||||
Optional<ContextState::PreparedFrame> 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::PreparedFrame> 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<Gfx::PaintingSurface> { back_store } };
|
||||
painter.clear_rect(back_store.rect().to_type<float>(), Gfx::Color::Transparent);
|
||||
});
|
||||
paint_current_display_list(display_list_player, back_store);
|
||||
if (!presents_to_client()) {
|
||||
Gfx::PainterSkia painter { NonnullRefPtr<Gfx::PaintingSurface> { back_store } };
|
||||
painter.clear_rect(back_store.rect().to_type<float>(), 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<Web::Compositor::PublishToCompositorSurface> 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<Web::Compositor::PublishToCompositorSurface>();
|
||||
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<Gfx::PaintingSurface> { back_store } };
|
||||
painter.clear_rect(back_store.rect().to_type<float>(), 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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <AK/Function.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/Noncopyable.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/Optional.h>
|
||||
|
|
@ -20,7 +19,6 @@
|
|||
#include <LibGfx/Point.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/ShareableBitmap.h>
|
||||
#include <LibGfx/SharedImage.h>
|
||||
#include <LibGfx/Size.h>
|
||||
#include <LibWeb/Compositor/AsyncScrollTree.h>
|
||||
#include <LibWeb/Compositor/AsyncScrollingState.h>
|
||||
|
|
@ -53,22 +51,13 @@ class DisplayListPlayerSkia;
|
|||
namespace Compositor {
|
||||
|
||||
class CompositorStateWebContentClient;
|
||||
using CompositedContextResolver = Function<RefPtr<Gfx::PaintingSurface>(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<Gfx::IntRect> frame_to_present;
|
||||
|
|
@ -88,24 +77,17 @@ public:
|
|||
ContextState(Optional<u64> 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::PublishToCompositorSurface>(); }
|
||||
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<PublishedSurface> 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<Web::Compositor::CompositorContextId> take_child_context_for_surface(Web::Painting::CompositorSurfaceId);
|
||||
Vector<ChildSurface> child_contexts() const;
|
||||
void set_parent_context(Optional<Web::Compositor::CompositorContextId>);
|
||||
Optional<Web::Compositor::CompositorContextId> parent_context_id() const { return m_parent_context_id; }
|
||||
RefPtr<Gfx::PaintingSurface> 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<Media::VideoFrame const>);
|
||||
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<Gfx::IntRect> take_pending_present_frame_if_unblocked();
|
||||
bool needs_synchronous_present_for_screenshot() const;
|
||||
Optional<Gfx::IntRect> current_frame_rect_to_present() const;
|
||||
Optional<PreparedFrame> prepare_frame(Web::Painting::DisplayListPlayerSkia&, Gfx::IntRect);
|
||||
Optional<PreparedFrame> prepare_frame(Web::Painting::DisplayListPlayerSkia&, Gfx::IntRect, CompositedContextResolver const*);
|
||||
void did_submit_prepared_frame(Gfx::IntRect);
|
||||
Optional<Web::Compositor::PublishToCompositorSurface> 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<u64> m_page_id;
|
||||
bool const m_async_scrolling_enabled { true };
|
||||
|
||||
Web::Compositor::PresentationMode m_presentation_mode { Empty {} };
|
||||
Optional<PublishedSurface> m_published_surface;
|
||||
HashMap<Web::Painting::CompositorSurfaceId, Web::Compositor::CompositorContextId> m_child_contexts_by_surface_id;
|
||||
bool m_presents_to_client { false };
|
||||
Optional<Web::Compositor::CompositorContextId> m_parent_context_id;
|
||||
|
||||
RefPtr<Web::Painting::DisplayList const> m_display_list;
|
||||
Optional<Web::Painting::AccumulatedVisualContextTree> m_visual_context_tree;
|
||||
mutable Optional<Web::Painting::AccumulatedVisualContextTree> m_visual_context_tree_for_compositing;
|
||||
Web::Painting::DisplayListResourceStorage m_display_list_resource_storage;
|
||||
HashMap<Web::Painting::CompositorSurfaceId, NonnullRefPtr<Gfx::PaintingSurface>> m_compositor_surfaces;
|
||||
Web::Painting::ScrollStateSnapshot m_scroll_state_snapshot;
|
||||
BackingStoreManager m_backing_store_manager;
|
||||
RefPtr<Gfx::PaintingSurface> m_latest_rendered_surface;
|
||||
|
||||
Web::Compositor::AsyncScrollTree m_async_scroll_tree;
|
||||
ViewportScrollbarController m_viewport_scrollbar_controller;
|
||||
|
|
|
|||
|
|
@ -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<Web::Compositor::CompositorContextId> 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)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,8 @@ class CompositorConnection final
|
|||
public:
|
||||
explicit CompositorConnection(NonnullOwnPtr<IPC::Transport>);
|
||||
|
||||
void set_presentation_mode(Web::Compositor::CompositorContextId, Web::Compositor::PresentationMode const&);
|
||||
void set_parent_context(Web::Compositor::CompositorContextId, Optional<Web::Compositor::CompositorContextId>);
|
||||
void stop_presenting_to_client(Web::Compositor::CompositorContextId);
|
||||
void destroy_context(Web::Compositor::CompositorContextId);
|
||||
void update_display_list(Web::Compositor::CompositorContextId, NonnullRefPtr<Web::Painting::DisplayList> 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&);
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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<Web::Compositor::CompositorContextId> 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<Web::Painting::DisplayList> display_list, Web::Painting::AccumulatedVisualContextTree visual_context_tree, Web::Painting::DisplayListResourceTransaction&& resource_transaction, Web::Painting::ScrollStateSnapshot&& scroll_state_snapshot) override
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue