LibWeb: Present frames through Compositor IPC
Introduce a dedicated Compositor IPC channel between the UI process and WebContent. Use it for backing-store setup, presented bitmap delivery, and bitmap-specific ready_to_paint acknowledgements. This makes CompositorThread the single owner of frame presentation bookkeeping before async scrolling starts producing frames without the main thread. Remove old paint and backing-store messages from WebContentClient and PageClient so the UI process no longer observes two presentation protocols.
This commit is contained in:
parent
584b2748ee
commit
1b810a5e15
20 changed files with 414 additions and 100 deletions
|
|
@ -15,6 +15,10 @@
|
|||
#include <LibWeb/Painting/DisplayListPlayerSkia.h>
|
||||
#include <LibWeb/Painting/ExternalContentSource.h>
|
||||
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/NeverDestroyed.h>
|
||||
#include <AK/Queue.h>
|
||||
|
||||
#ifdef USE_VULKAN_DMABUF_IMAGES
|
||||
# include <AK/Array.h>
|
||||
# include <LibGfx/VulkanImage.h>
|
||||
|
|
@ -56,7 +60,6 @@ struct UpdateBackingStoresCommand {
|
|||
Gfx::IntSize size;
|
||||
i32 front_bitmap_id;
|
||||
i32 back_bitmap_id;
|
||||
Function<void(i32, Gfx::SharedImage, i32, Gfx::SharedImage)> allocation_callback;
|
||||
};
|
||||
|
||||
struct ScreenshotCommand {
|
||||
|
|
@ -139,14 +142,23 @@ static ErrorOr<DMABufBackingStorePair> create_linear_dmabuf_backing_stores(Gfx::
|
|||
|
||||
class CompositorThread::ThreadData final : public AtomicRefCounted<ThreadData> {
|
||||
public:
|
||||
ThreadData(NonnullRefPtr<Core::WeakEventLoopReference>&& main_thread_event_loop, CompositorThread::PresentationCallback presentation_callback)
|
||||
: m_main_thread_event_loop(move(main_thread_event_loop))
|
||||
, m_presentation_callback(move(presentation_callback))
|
||||
ThreadData(u64 page_id, NonnullRefPtr<Core::WeakEventLoopReference>&& main_thread_event_loop, CompositorThread::PagePresentationRegistration page_presentation_registration)
|
||||
: m_page_id(page_id)
|
||||
, m_main_thread_event_loop(move(main_thread_event_loop))
|
||||
, m_presents_to_client(page_presentation_registration == CompositorThread::PagePresentationRegistration::Yes)
|
||||
{
|
||||
}
|
||||
|
||||
~ThreadData() = default;
|
||||
|
||||
u64 page_id() const { return m_page_id; }
|
||||
bool presents_to_client() const { return m_presents_to_client; }
|
||||
void stop_presenting_to_client()
|
||||
{
|
||||
Sync::MutexLocker const locker { m_mutex };
|
||||
m_presents_to_client = false;
|
||||
}
|
||||
|
||||
void set_presentation_mode(CompositorThread::PresentationMode mode)
|
||||
{
|
||||
Sync::MutexLocker const locker { m_mutex };
|
||||
|
|
@ -267,10 +279,10 @@ public:
|
|||
}
|
||||
|
||||
if (should_present) {
|
||||
// Block if we already have a frame queued (back pressure)
|
||||
// Block if we already have a frame queued (back pressure).
|
||||
{
|
||||
Sync::MutexLocker const locker { m_mutex };
|
||||
while (m_queued_rasterization_tasks > 1 && !m_exit) {
|
||||
while (m_queued_rasterization_tasks > 0 && !m_exit) {
|
||||
m_ready_to_paint.wait();
|
||||
}
|
||||
if (m_exit)
|
||||
|
|
@ -297,10 +309,10 @@ public:
|
|||
|
||||
presentation_mode.visit(
|
||||
[this, viewport_rect, rendered_bitmap_id](CompositorThread::PresentToUI) {
|
||||
m_queued_rasterization_tasks++;
|
||||
invoke_on_main_thread([this, viewport_rect, rendered_bitmap_id]() {
|
||||
m_presentation_callback(viewport_rect, rendered_bitmap_id);
|
||||
});
|
||||
if (m_presents_to_client) {
|
||||
finish_rasterizing(rendered_bitmap_id);
|
||||
VERIFY(CompositorThread::present_frame_to_client(m_page_id, viewport_rect, rendered_bitmap_id));
|
||||
}
|
||||
},
|
||||
[this](CompositorThread::PublishToExternalContent const& mode) {
|
||||
auto snapshot = Gfx::DecodedImageFrame { *m_backing_stores.front_store->snapshot_bitmap() };
|
||||
|
|
@ -327,17 +339,16 @@ private:
|
|||
|
||||
void publish_backing_store_pair(UpdateBackingStoresCommand& cmd, Gfx::SharedImage front_shared_image, Gfx::SharedImage back_shared_image)
|
||||
{
|
||||
if (!cmd.allocation_callback)
|
||||
if (!m_presents_to_client)
|
||||
return;
|
||||
invoke_on_main_thread([callback = move(cmd.allocation_callback), front_bitmap_id = cmd.front_bitmap_id, front_shared_image = move(front_shared_image), back_bitmap_id = cmd.back_bitmap_id, back_shared_image = move(back_shared_image)]() mutable {
|
||||
callback(front_bitmap_id, move(front_shared_image), back_bitmap_id, move(back_shared_image));
|
||||
});
|
||||
|
||||
VERIFY(CompositorThread::present_backing_stores_to_client(m_page_id, cmd.front_bitmap_id, move(front_shared_image), cmd.back_bitmap_id, move(back_shared_image)));
|
||||
}
|
||||
|
||||
void allocate_backing_stores(UpdateBackingStoresCommand& cmd)
|
||||
{
|
||||
#ifdef USE_VULKAN_DMABUF_IMAGES
|
||||
if (m_skia_backend_context && cmd.allocation_callback) {
|
||||
if (m_skia_backend_context && m_presents_to_client) {
|
||||
auto backing_stores = create_linear_dmabuf_backing_stores(cmd.size, *m_skia_backend_context);
|
||||
if (!backing_stores.is_error()) {
|
||||
auto backing_store_pair = backing_stores.release_value();
|
||||
|
|
@ -372,8 +383,9 @@ private:
|
|||
});
|
||||
}
|
||||
|
||||
u64 m_page_id { 0 };
|
||||
NonnullRefPtr<Core::WeakEventLoopReference> m_main_thread_event_loop;
|
||||
CompositorThread::PresentationCallback m_presentation_callback;
|
||||
bool m_presents_to_client { false };
|
||||
|
||||
mutable Sync::Mutex m_mutex;
|
||||
mutable Sync::ConditionVariable m_command_ready { m_mutex };
|
||||
|
|
@ -389,6 +401,7 @@ private:
|
|||
CompositorThread::PresentationMode m_presentation_mode { CompositorThread::PresentToUI {} };
|
||||
|
||||
Atomic<i32> m_queued_rasterization_tasks { 0 };
|
||||
Optional<i32> m_presented_bitmap_id_awaiting_ack;
|
||||
mutable Sync::ConditionVariable m_ready_to_paint { m_mutex };
|
||||
|
||||
bool m_needs_present { false };
|
||||
|
|
@ -399,25 +412,180 @@ private:
|
|||
mutable Sync::ConditionVariable m_frame_completed { m_mutex };
|
||||
|
||||
public:
|
||||
void decrement_queued_tasks()
|
||||
void finish_rasterizing(i32 bitmap_id)
|
||||
{
|
||||
Sync::MutexLocker const locker { m_mutex };
|
||||
VERIFY(m_queued_rasterization_tasks >= 1 && m_queued_rasterization_tasks <= 2);
|
||||
VERIFY(!m_presented_bitmap_id_awaiting_ack.has_value());
|
||||
m_presented_bitmap_id_awaiting_ack = bitmap_id;
|
||||
m_queued_rasterization_tasks++;
|
||||
VERIFY(m_queued_rasterization_tasks == 1);
|
||||
}
|
||||
|
||||
void decrement_queued_tasks(i32 bitmap_id)
|
||||
{
|
||||
Sync::MutexLocker const locker { m_mutex };
|
||||
if (m_presented_bitmap_id_awaiting_ack != bitmap_id)
|
||||
return;
|
||||
|
||||
VERIFY(m_queued_rasterization_tasks == 1);
|
||||
m_presented_bitmap_id_awaiting_ack.clear();
|
||||
m_queued_rasterization_tasks--;
|
||||
m_ready_to_paint.signal();
|
||||
m_command_ready.signal();
|
||||
}
|
||||
};
|
||||
|
||||
CompositorThread::CompositorThread(PresentationCallback presentation_callback)
|
||||
: m_thread_data(adopt_ref(*new ThreadData(Core::EventLoop::current_weak(), move(presentation_callback))))
|
||||
struct FramePresentationState {
|
||||
RefPtr<Core::WeakEventLoopReference> event_loop;
|
||||
CompositorThread::BackingStorePresentationCallback backing_store_callback;
|
||||
CompositorThread::FramePresentationCallback frame_callback;
|
||||
};
|
||||
|
||||
static Sync::Mutex& compositor_presentation_state_mutex()
|
||||
{
|
||||
static NeverDestroyed<Sync::Mutex> mutex;
|
||||
return *mutex;
|
||||
}
|
||||
|
||||
static HashMap<u64, NonnullRefPtr<CompositorThread::ThreadData>>& page_compositors()
|
||||
{
|
||||
static NeverDestroyed<HashMap<u64, NonnullRefPtr<CompositorThread::ThreadData>>> compositors;
|
||||
return *compositors;
|
||||
}
|
||||
|
||||
static FramePresentationState& frame_presentation_state()
|
||||
{
|
||||
static NeverDestroyed<FramePresentationState> state;
|
||||
return *state;
|
||||
}
|
||||
|
||||
CompositorThread::CompositorThread(u64 page_id, PagePresentationRegistration page_presentation_registration)
|
||||
: m_thread_data(adopt_ref(*new ThreadData(page_id, Core::EventLoop::current_weak(), page_presentation_registration)))
|
||||
{
|
||||
if (page_presentation_registration == PagePresentationRegistration::Yes)
|
||||
register_page_compositor(page_id, m_thread_data);
|
||||
}
|
||||
|
||||
CompositorThread::~CompositorThread()
|
||||
{
|
||||
unregister_page_compositor(m_thread_data->page_id(), *m_thread_data);
|
||||
m_thread_data->exit();
|
||||
}
|
||||
|
||||
void CompositorThread::register_page_compositor(u64 page_id, NonnullRefPtr<ThreadData> thread_data)
|
||||
{
|
||||
Sync::MutexLocker const locker { compositor_presentation_state_mutex() };
|
||||
page_compositors().set(page_id, move(thread_data));
|
||||
}
|
||||
|
||||
void CompositorThread::unregister_page_compositor(u64 page_id, ThreadData& thread_data)
|
||||
{
|
||||
Sync::MutexLocker const locker { compositor_presentation_state_mutex() };
|
||||
auto compositor = page_compositors().find(page_id);
|
||||
if (compositor == page_compositors().end())
|
||||
return;
|
||||
if (compositor->value.ptr() != &thread_data)
|
||||
return;
|
||||
page_compositors().remove(compositor);
|
||||
}
|
||||
|
||||
void CompositorThread::set_frame_presentation_callbacks(NonnullRefPtr<Core::WeakEventLoopReference> event_loop, BackingStorePresentationCallback backing_store_callback, FramePresentationCallback frame_callback)
|
||||
{
|
||||
Sync::MutexLocker const locker { compositor_presentation_state_mutex() };
|
||||
auto& state = frame_presentation_state();
|
||||
state.event_loop = move(event_loop);
|
||||
state.backing_store_callback = move(backing_store_callback);
|
||||
state.frame_callback = move(frame_callback);
|
||||
}
|
||||
|
||||
void CompositorThread::clear_frame_presentation_callbacks()
|
||||
{
|
||||
Sync::MutexLocker const locker { compositor_presentation_state_mutex() };
|
||||
auto& state = frame_presentation_state();
|
||||
state.event_loop = nullptr;
|
||||
state.backing_store_callback = {};
|
||||
state.frame_callback = {};
|
||||
}
|
||||
|
||||
bool CompositorThread::present_backing_stores_to_client(u64 page_id, i32 front_bitmap_id, Gfx::SharedImage&& front_shared_image, i32 back_bitmap_id, Gfx::SharedImage&& back_shared_image)
|
||||
{
|
||||
RefPtr<Core::WeakEventLoopReference> event_loop_reference;
|
||||
{
|
||||
Sync::MutexLocker const locker { compositor_presentation_state_mutex() };
|
||||
if (!page_compositors().contains(page_id))
|
||||
return false;
|
||||
auto& state = frame_presentation_state();
|
||||
if (!state.backing_store_callback)
|
||||
return false;
|
||||
event_loop_reference = state.event_loop;
|
||||
}
|
||||
|
||||
if (!event_loop_reference)
|
||||
return false;
|
||||
auto event_loop = event_loop_reference->take();
|
||||
if (!event_loop)
|
||||
return false;
|
||||
|
||||
event_loop->deferred_invoke([page_id, front_bitmap_id, front_shared_image = move(front_shared_image), back_bitmap_id, back_shared_image = move(back_shared_image)]() mutable {
|
||||
Sync::MutexLocker const locker { compositor_presentation_state_mutex() };
|
||||
if (!page_compositors().contains(page_id)) {
|
||||
dbgln_if(COMPOSITOR_DEBUG, "[Compositor] Dropping queued UI backing stores for page {} front={} back={}: page unregistered",
|
||||
page_id, front_bitmap_id, back_bitmap_id);
|
||||
return;
|
||||
}
|
||||
auto& state = frame_presentation_state();
|
||||
if (state.backing_store_callback)
|
||||
state.backing_store_callback(page_id, front_bitmap_id, move(front_shared_image), back_bitmap_id, move(back_shared_image));
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CompositorThread::present_frame_to_client(u64 page_id, Gfx::IntRect const& viewport_rect, i32 bitmap_id)
|
||||
{
|
||||
RefPtr<Core::WeakEventLoopReference> event_loop_reference;
|
||||
{
|
||||
Sync::MutexLocker const locker { compositor_presentation_state_mutex() };
|
||||
if (!page_compositors().contains(page_id))
|
||||
return false;
|
||||
auto& state = frame_presentation_state();
|
||||
if (!state.frame_callback)
|
||||
return false;
|
||||
event_loop_reference = state.event_loop;
|
||||
}
|
||||
|
||||
if (!event_loop_reference)
|
||||
return false;
|
||||
auto event_loop = event_loop_reference->take();
|
||||
if (!event_loop)
|
||||
return false;
|
||||
|
||||
event_loop->deferred_invoke([page_id, viewport_rect, bitmap_id] {
|
||||
Sync::MutexLocker const locker { compositor_presentation_state_mutex() };
|
||||
if (!page_compositors().contains(page_id)) {
|
||||
dbgln_if(COMPOSITOR_DEBUG, "[Compositor] Dropping queued UI present for page {} bitmap {}: page unregistered",
|
||||
page_id, bitmap_id);
|
||||
return;
|
||||
}
|
||||
auto& state = frame_presentation_state();
|
||||
if (state.frame_callback)
|
||||
state.frame_callback(page_id, viewport_rect, bitmap_id);
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
void CompositorThread::presented_bitmap_ready_to_paint(u64 page_id, i32 bitmap_id)
|
||||
{
|
||||
RefPtr<ThreadData> thread_data;
|
||||
{
|
||||
Sync::MutexLocker const locker { compositor_presentation_state_mutex() };
|
||||
auto compositor = page_compositors().find(page_id);
|
||||
if (compositor == page_compositors().end())
|
||||
return;
|
||||
thread_data = compositor->value;
|
||||
}
|
||||
thread_data->decrement_queued_tasks(bitmap_id);
|
||||
}
|
||||
|
||||
void CompositorThread::start(DisplayListPlayerType display_list_player_type)
|
||||
{
|
||||
m_thread = Threading::Thread::construct("Compositor"sv, [thread_data = m_thread_data, display_list_player_type] {
|
||||
|
|
@ -433,6 +601,12 @@ void CompositorThread::set_presentation_mode(PresentationMode mode)
|
|||
m_thread_data->set_presentation_mode(move(mode));
|
||||
}
|
||||
|
||||
void CompositorThread::stop_presenting_to_client()
|
||||
{
|
||||
m_thread_data->stop_presenting_to_client();
|
||||
unregister_page_compositor(m_thread_data->page_id(), *m_thread_data);
|
||||
}
|
||||
|
||||
void CompositorThread::update_display_list(NonnullRefPtr<Painting::DisplayList> display_list, Painting::ScrollStateSnapshot&& scroll_state_snapshot)
|
||||
{
|
||||
m_thread_data->enqueue_command(UpdateDisplayListCommand { move(display_list), move(scroll_state_snapshot) });
|
||||
|
|
@ -443,9 +617,9 @@ void CompositorThread::update_scroll_state(Painting::ScrollStateSnapshot&& scrol
|
|||
m_thread_data->enqueue_command(UpdateScrollStateCommand { move(scroll_state_snapshot) });
|
||||
}
|
||||
|
||||
void CompositorThread::update_backing_stores(Gfx::IntSize size, i32 front_id, i32 back_id, Function<void(i32, Gfx::SharedImage, i32, Gfx::SharedImage)>&& allocation_callback)
|
||||
void CompositorThread::update_backing_stores(Gfx::IntSize size, i32 front_id, i32 back_id)
|
||||
{
|
||||
m_thread_data->enqueue_command(UpdateBackingStoresCommand { size, front_id, back_id, move(allocation_callback) });
|
||||
m_thread_data->enqueue_command(UpdateBackingStoresCommand { size, front_id, back_id });
|
||||
}
|
||||
|
||||
u64 CompositorThread::present_frame(Gfx::IntRect viewport_rect)
|
||||
|
|
@ -463,9 +637,4 @@ void CompositorThread::request_screenshot(NonnullRefPtr<Gfx::PaintingSurface> ta
|
|||
m_thread_data->enqueue_command(ScreenshotCommand { move(target_surface), move(callback) });
|
||||
}
|
||||
|
||||
void CompositorThread::ready_to_paint()
|
||||
{
|
||||
m_thread_data->decrement_queued_tasks();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,24 +8,32 @@
|
|||
|
||||
#include <AK/Noncopyable.h>
|
||||
#include <AK/NonnullRefPtr.h>
|
||||
#include <AK/Queue.h>
|
||||
#include <AK/Variant.h>
|
||||
#include <LibCore/Forward.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/SharedImage.h>
|
||||
#include <LibSync/ConditionVariable.h>
|
||||
#include <LibThreading/Forward.h>
|
||||
#include <LibWeb/Export.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/Page/Page.h>
|
||||
|
||||
namespace Web::Compositor {
|
||||
|
||||
class CompositorThread {
|
||||
class WEB_API CompositorThread {
|
||||
AK_MAKE_NONCOPYABLE(CompositorThread);
|
||||
AK_MAKE_NONMOVABLE(CompositorThread);
|
||||
|
||||
public:
|
||||
class ThreadData;
|
||||
|
||||
public:
|
||||
using PresentationCallback = Function<void(Gfx::IntRect const&, i32)>;
|
||||
enum class PagePresentationRegistration {
|
||||
No,
|
||||
Yes,
|
||||
};
|
||||
|
||||
using BackingStorePresentationCallback = Function<void(u64 page_id, i32 front_bitmap_id, Gfx::SharedImage, i32 back_bitmap_id, Gfx::SharedImage)>;
|
||||
using FramePresentationCallback = Function<void(u64 page_id, Gfx::IntRect const&, i32 bitmap_id)>;
|
||||
struct PresentToUI {
|
||||
};
|
||||
struct PublishToExternalContent {
|
||||
|
|
@ -33,24 +41,32 @@ public:
|
|||
};
|
||||
using PresentationMode = Variant<PresentToUI, PublishToExternalContent>;
|
||||
|
||||
explicit CompositorThread(PresentationCallback);
|
||||
CompositorThread(u64 page_id, PagePresentationRegistration);
|
||||
~CompositorThread();
|
||||
|
||||
static void set_frame_presentation_callbacks(NonnullRefPtr<Core::WeakEventLoopReference>, BackingStorePresentationCallback, FramePresentationCallback);
|
||||
static void clear_frame_presentation_callbacks();
|
||||
static void presented_bitmap_ready_to_paint(u64 page_id, i32 bitmap_id);
|
||||
|
||||
void start(DisplayListPlayerType);
|
||||
void stop_presenting_to_client();
|
||||
void set_presentation_mode(PresentationMode);
|
||||
|
||||
void update_display_list(NonnullRefPtr<Painting::DisplayList>, Painting::ScrollStateSnapshot&&);
|
||||
void update_scroll_state(Painting::ScrollStateSnapshot&&);
|
||||
void update_backing_stores(Gfx::IntSize, i32 front_id, i32 back_id, Function<void(i32, Gfx::SharedImage, i32, Gfx::SharedImage)>&& = {});
|
||||
void update_backing_stores(Gfx::IntSize, i32 front_id, i32 back_id);
|
||||
u64 present_frame(Gfx::IntRect);
|
||||
void wait_for_frame(u64 frame_id);
|
||||
void request_screenshot(NonnullRefPtr<Gfx::PaintingSurface>, Function<void()>&& callback);
|
||||
|
||||
void ready_to_paint();
|
||||
|
||||
private:
|
||||
NonnullRefPtr<ThreadData> m_thread_data;
|
||||
RefPtr<Threading::Thread> m_thread;
|
||||
|
||||
static void register_page_compositor(u64 page_id, NonnullRefPtr<ThreadData>);
|
||||
static void unregister_page_compositor(u64 page_id, ThreadData&);
|
||||
static bool present_backing_stores_to_client(u64 page_id, i32 front_bitmap_id, Gfx::SharedImage&&, i32 back_bitmap_id, Gfx::SharedImage&&);
|
||||
static bool present_frame_to_client(u64 page_id, Gfx::IntRect const&, i32 bitmap_id);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,15 +273,17 @@ bool Navigable::is_ancestor_of(GC::Ref<Navigable> other) const
|
|||
return false;
|
||||
}
|
||||
|
||||
Navigable::Navigable(GC::Ref<Page> page, bool is_svg_page)
|
||||
Navigable::Navigable(
|
||||
GC::Ref<Page> page,
|
||||
bool is_svg_page,
|
||||
Compositor::CompositorThread::PagePresentationRegistration page_presentation_registration)
|
||||
: m_page(page)
|
||||
, m_event_handler({}, *this)
|
||||
, m_is_svg_page(is_svg_page)
|
||||
, m_backing_store_manager(heap().allocate<Painting::BackingStoreManager>(*this))
|
||||
, m_rendering_thread([page_client = &page->client()](Gfx::IntRect const& viewport_rect, i32 bitmap_id) {
|
||||
if (page_client)
|
||||
page_client->page_did_paint(viewport_rect, bitmap_id);
|
||||
})
|
||||
, m_rendering_thread(
|
||||
is_svg_page ? 0 : page->client().id(),
|
||||
is_svg_page ? Compositor::CompositorThread::PagePresentationRegistration::No : page_presentation_registration)
|
||||
{
|
||||
all_navigables().set(*this);
|
||||
|
||||
|
|
@ -3106,11 +3108,6 @@ void Navigable::set_has_session_history_entry_and_ready_for_navigation()
|
|||
}
|
||||
}
|
||||
|
||||
void Navigable::ready_to_paint()
|
||||
{
|
||||
m_rendering_thread.ready_to_paint();
|
||||
}
|
||||
|
||||
NonnullRefPtr<Painting::ExternalContentSource> Navigable::external_content_source() const
|
||||
{
|
||||
VERIFY(m_external_content_source);
|
||||
|
|
|
|||
|
|
@ -229,7 +229,6 @@ public:
|
|||
bool has_pending_navigations() const { return !m_pending_navigations.is_empty(); }
|
||||
void clear_pending_navigations() { m_pending_navigations.clear(); }
|
||||
|
||||
void ready_to_paint();
|
||||
void record_display_list_and_scroll_state(PaintConfig);
|
||||
void paint_next_frame();
|
||||
void render_screenshot(Gfx::PaintingSurface&, PaintConfig, Function<void()>&& callback);
|
||||
|
|
@ -259,7 +258,10 @@ public:
|
|||
void reset_zoom();
|
||||
|
||||
protected:
|
||||
explicit Navigable(GC::Ref<Page>, bool is_svg_page);
|
||||
explicit Navigable(
|
||||
GC::Ref<Page>,
|
||||
bool is_svg_page,
|
||||
Compositor::CompositorThread::PagePresentationRegistration = Compositor::CompositorThread::PagePresentationRegistration::No);
|
||||
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
virtual void finalize() override;
|
||||
|
|
|
|||
|
|
@ -35,7 +35,10 @@ namespace Web::HTML {
|
|||
GC_DEFINE_ALLOCATOR(TraversableNavigable);
|
||||
|
||||
TraversableNavigable::TraversableNavigable(GC::Ref<Page> page)
|
||||
: Navigable(page, page->client().is_svg_page_client())
|
||||
: Navigable(
|
||||
page,
|
||||
page->client().is_svg_page_client(),
|
||||
Compositor::CompositorThread::PagePresentationRegistration::Yes)
|
||||
, m_storage_shed(StorageAPI::StorageShed::create(page->heap()))
|
||||
, m_session_history_traversal_queue(vm().heap().allocate<SessionHistoryTraversalQueue>())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@
|
|||
#include <LibGfx/Point.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/ShareableBitmap.h>
|
||||
#include <LibGfx/SharedImage.h>
|
||||
#include <LibGfx/Size.h>
|
||||
#include <LibHTTP/Cookie/Cookie.h>
|
||||
#include <LibHTTP/Forward.h>
|
||||
|
|
@ -450,7 +449,6 @@ public:
|
|||
virtual void page_did_request_activate_tab() { }
|
||||
virtual void page_did_close_top_level_traversable() { }
|
||||
virtual void page_did_update_navigation_buttons_state([[maybe_unused]] bool back_enabled, [[maybe_unused]] bool forward_enabled) { }
|
||||
virtual void page_did_allocate_backing_stores([[maybe_unused]] i32 front_bitmap_id, [[maybe_unused]] Gfx::SharedImage front_backing_store, [[maybe_unused]] i32 back_bitmap_id, [[maybe_unused]] Gfx::SharedImage back_backing_store) { }
|
||||
|
||||
virtual void request_file(FileRequest) = 0;
|
||||
|
||||
|
|
@ -490,7 +488,6 @@ public:
|
|||
|
||||
virtual void page_did_mutate_dom([[maybe_unused]] FlyString const& type, [[maybe_unused]] DOM::Node const& target, [[maybe_unused]] DOM::NodeList& added_nodes, [[maybe_unused]] DOM::NodeList& removed_nodes, [[maybe_unused]] GC::Ptr<DOM::Node> previous_sibling, [[maybe_unused]] GC::Ptr<DOM::Node> next_sibling, [[maybe_unused]] Optional<String> const& attribute_name) { }
|
||||
|
||||
virtual void page_did_paint([[maybe_unused]] Gfx::IntRect const& content_rect, [[maybe_unused]] i32 bitmap_id) { }
|
||||
virtual void page_did_take_screenshot(Gfx::ShareableBitmap const&) { }
|
||||
|
||||
virtual void received_message_from_web_ui([[maybe_unused]] String const& name, [[maybe_unused]] JS::Value data) { }
|
||||
|
|
|
|||
|
|
@ -26,6 +26,14 @@ void BackingStoreManager::visit_edges(Cell::Visitor& visitor)
|
|||
visitor.visit(m_navigable);
|
||||
}
|
||||
|
||||
void BackingStoreManager::finalize()
|
||||
{
|
||||
Base::finalize();
|
||||
m_backing_store_shrink_timer->on_timeout = {};
|
||||
m_backing_store_shrink_timer->stop();
|
||||
m_backing_store_shrink_timer.clear();
|
||||
}
|
||||
|
||||
void BackingStoreManager::restart_resize_timer()
|
||||
{
|
||||
m_backing_store_shrink_timer->restart();
|
||||
|
|
@ -37,15 +45,7 @@ void BackingStoreManager::reallocate_backing_stores(Gfx::IntSize size)
|
|||
m_back_bitmap_id = m_next_bitmap_id++;
|
||||
m_allocated_size = size;
|
||||
|
||||
Function<void(i32, Gfx::SharedImage, i32, Gfx::SharedImage)> allocation_callback;
|
||||
if (m_navigable->is_top_level_traversable()) {
|
||||
auto* page_client = &m_navigable->top_level_traversable()->page().client();
|
||||
allocation_callback = [page_client](i32 front_bitmap_id, Gfx::SharedImage front_backing_store, i32 back_bitmap_id, Gfx::SharedImage back_backing_store) mutable {
|
||||
page_client->page_did_allocate_backing_stores(front_bitmap_id, move(front_backing_store), back_bitmap_id, move(back_backing_store));
|
||||
};
|
||||
}
|
||||
|
||||
m_navigable->rendering_thread().update_backing_stores(size, m_front_bitmap_id, m_back_bitmap_id, move(allocation_callback));
|
||||
m_navigable->rendering_thread().update_backing_stores(size, m_front_bitmap_id, m_back_bitmap_id);
|
||||
}
|
||||
|
||||
void BackingStoreManager::resize_backing_stores_if_needed(WindowResizingInProgress window_resize_in_progress)
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ class WEB_API BackingStoreManager : public JS::Cell {
|
|||
GC_DECLARE_ALLOCATOR(BackingStoreManager);
|
||||
|
||||
public:
|
||||
static constexpr bool OVERRIDES_FINALIZE = true;
|
||||
|
||||
enum class WindowResizingInProgress {
|
||||
No,
|
||||
Yes
|
||||
|
|
@ -23,6 +25,7 @@ public:
|
|||
void reallocate_backing_stores(Gfx::IntSize);
|
||||
void restart_resize_timer();
|
||||
|
||||
virtual void finalize() override;
|
||||
virtual void visit_edges(Cell::Visitor& visitor) override;
|
||||
|
||||
BackingStoreManager(HTML::Navigable&);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ set(GENERATED_SOURCES
|
|||
${GENERATED_SOURCES}
|
||||
../../Services/RequestServer/RequestClientEndpoint.h
|
||||
../../Services/RequestServer/RequestServerEndpoint.h
|
||||
../../Services/WebContent/CompositorClientEndpoint.h
|
||||
../../Services/WebContent/CompositorServerEndpoint.h
|
||||
../../Services/WebContent/WebContentClientEndpoint.h
|
||||
../../Services/WebContent/WebContentServerEndpoint.h
|
||||
../../Services/WebContent/WebDriverClientEndpoint.h
|
||||
|
|
@ -67,8 +69,10 @@ set(GENERATED_SOURCES
|
|||
UIProcessServerEndpoint.h
|
||||
)
|
||||
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/WebContent/WebContentServer.ipc ${CMAKE_BINARY_DIR}/Services/WebContent/WebContentServerEndpoint.h)
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/WebContent/CompositorClient.ipc ${CMAKE_BINARY_DIR}/Services/WebContent/CompositorClientEndpoint.h)
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/WebContent/CompositorServer.ipc ${CMAKE_BINARY_DIR}/Services/WebContent/CompositorServerEndpoint.h)
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/WebContent/WebContentClient.ipc ${CMAKE_BINARY_DIR}/Services/WebContent/WebContentClientEndpoint.h)
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/WebContent/WebContentServer.ipc ${CMAKE_BINARY_DIR}/Services/WebContent/WebContentServerEndpoint.h)
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/WebContent/WebDriverClient.ipc ${CMAKE_BINARY_DIR}/Services/WebContent/WebDriverClientEndpoint.h)
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/WebContent/WebDriverServer.ipc ${CMAKE_BINARY_DIR}/Services/WebContent/WebDriverServerEndpoint.h)
|
||||
compile_ipc(${LADYBIRD_SOURCE_DIR}/Services/WebContent/WebUIClient.ipc ${CMAKE_BINARY_DIR}/Services/WebContent/WebUIClientEndpoint.h)
|
||||
|
|
|
|||
|
|
@ -147,16 +147,19 @@ void ViewImplementation::create_new_process_for_cross_site_navigation(URL::URL c
|
|||
|
||||
void ViewImplementation::server_did_paint(Badge<WebContentClient>, i32 bitmap_id, Gfx::IntSize size)
|
||||
{
|
||||
bool did_swap_bitmap = false;
|
||||
if (m_client_state.back_bitmap.id == bitmap_id) {
|
||||
m_client_state.has_usable_bitmap = true;
|
||||
m_client_state.back_bitmap.last_painted_size = size.to_type<Web::DevicePixels>();
|
||||
swap(m_client_state.back_bitmap, m_client_state.front_bitmap);
|
||||
m_backup_shared_image_buffer = nullptr;
|
||||
if (on_ready_to_paint)
|
||||
on_ready_to_paint();
|
||||
did_swap_bitmap = true;
|
||||
}
|
||||
|
||||
client().async_ready_to_paint(page_id());
|
||||
client().notify_presented_bitmap_ready_to_paint(page_id(), bitmap_id);
|
||||
|
||||
if (did_swap_bitmap && on_ready_to_paint)
|
||||
on_ready_to_paint();
|
||||
}
|
||||
|
||||
void ViewImplementation::set_window_position(Gfx::IntPoint position)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@
|
|||
*/
|
||||
|
||||
#include <AK/Debug.h>
|
||||
#include <AK/NeverDestroyed.h>
|
||||
#include <LibHTTP/Cookie/ParsedCookie.h>
|
||||
#include <LibIPC/Transport.h>
|
||||
#include <LibIPC/TransportHandle.h>
|
||||
#include <LibWebView/Application.h>
|
||||
#include <LibWebView/CookieJar.h>
|
||||
|
|
@ -15,11 +17,60 @@
|
|||
#include <LibWebView/ViewImplementation.h>
|
||||
#include <LibWebView/WebContentClient.h>
|
||||
#include <LibWebView/WebUI.h>
|
||||
#include <WebContent/CompositorClientEndpoint.h>
|
||||
#include <WebContent/CompositorServerEndpoint.h>
|
||||
|
||||
namespace WebView {
|
||||
|
||||
HashTable<WebContentClient*> WebContentClient::s_clients;
|
||||
|
||||
class CompositorConnectionToServer final
|
||||
: public IPC::ConnectionToServer<CompositorClientEndpoint, CompositorServerEndpoint>
|
||||
, public CompositorClientEndpoint {
|
||||
C_OBJECT(CompositorConnectionToServer)
|
||||
|
||||
public:
|
||||
CompositorConnectionToServer(WebContentClient& web_content_client, NonnullOwnPtr<IPC::Transport> transport)
|
||||
: IPC::ConnectionToServer<CompositorClientEndpoint, CompositorServerEndpoint>(*this, move(transport))
|
||||
, m_web_content_client(web_content_client)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
virtual void die() override { }
|
||||
|
||||
virtual void did_allocate_backing_stores(u64 page_id, i32 front_bitmap_id, Gfx::SharedImage front_backing_store, i32 back_bitmap_id, Gfx::SharedImage back_backing_store) override
|
||||
{
|
||||
m_web_content_client.did_present_backing_stores(page_id, front_bitmap_id, move(front_backing_store), back_bitmap_id, move(back_backing_store));
|
||||
}
|
||||
|
||||
virtual void did_paint(u64 page_id, Gfx::IntRect content_rect, i32 bitmap_id) override
|
||||
{
|
||||
m_web_content_client.did_present_bitmap(page_id, content_rect, bitmap_id);
|
||||
}
|
||||
|
||||
WebContentClient& m_web_content_client;
|
||||
};
|
||||
|
||||
static HashMap<WebContentClient*, NonnullRefPtr<CompositorConnectionToServer>>& compositor_connections()
|
||||
{
|
||||
static NeverDestroyed<HashMap<WebContentClient*, NonnullRefPtr<CompositorConnectionToServer>>> connections;
|
||||
return *connections;
|
||||
}
|
||||
|
||||
static void initialize_compositor_connection(WebContentClient& web_content_client)
|
||||
{
|
||||
auto paired_transport = IPC::Transport::create_paired();
|
||||
if (paired_transport.is_error()) {
|
||||
dbgln("Failed to create compositor IPC transport: {}", paired_transport.error());
|
||||
return;
|
||||
}
|
||||
|
||||
auto connection = CompositorConnectionToServer::construct(web_content_client, move(paired_transport.value().local));
|
||||
compositor_connections().set(&web_content_client, connection);
|
||||
web_content_client.async_connect_to_compositor(move(paired_transport.value().remote_handle));
|
||||
}
|
||||
|
||||
static Optional<String> history_title(Utf16String const& title, URL::URL const& url)
|
||||
{
|
||||
if (title.is_empty())
|
||||
|
|
@ -37,16 +88,19 @@ WebContentClient::WebContentClient(NonnullOwnPtr<IPC::Transport> transport, View
|
|||
{
|
||||
s_clients.set(this);
|
||||
m_views.set(0, view);
|
||||
initialize_compositor_connection(*this);
|
||||
}
|
||||
|
||||
WebContentClient::WebContentClient(NonnullOwnPtr<IPC::Transport> transport)
|
||||
: IPC::ConnectionToServer<WebContentClientEndpoint, WebContentServerEndpoint>(*this, move(transport))
|
||||
{
|
||||
s_clients.set(this);
|
||||
initialize_compositor_connection(*this);
|
||||
}
|
||||
|
||||
WebContentClient::~WebContentClient()
|
||||
{
|
||||
compositor_connections().remove(this);
|
||||
s_clients.remove(this);
|
||||
}
|
||||
|
||||
|
|
@ -103,10 +157,26 @@ void WebContentClient::notify_all_views_of_crash()
|
|||
}
|
||||
}
|
||||
|
||||
void WebContentClient::did_paint(u64 page_id, Gfx::IntRect rect, i32 bitmap_id)
|
||||
void WebContentClient::notify_presented_bitmap_ready_to_paint(u64 page_id, i32 bitmap_id)
|
||||
{
|
||||
auto connection = compositor_connections().get(this);
|
||||
if (!connection.has_value() || !connection.value()->is_open()) {
|
||||
dbgln_if(COMPOSITOR_DEBUG, "[Compositor] UI compositor IPC unavailable for ready_to_paint page {} bitmap {} (connection={}, open={})",
|
||||
page_id, bitmap_id, connection.has_value(), connection.has_value() && connection.value()->is_open());
|
||||
return;
|
||||
}
|
||||
connection.value()->async_ready_to_paint(page_id, bitmap_id);
|
||||
}
|
||||
|
||||
void WebContentClient::did_present_bitmap(u64 page_id, Gfx::IntRect rect, i32 bitmap_id)
|
||||
{
|
||||
if (auto view = view_for_page_id(page_id); view.has_value())
|
||||
view->server_did_paint({}, bitmap_id, rect.size());
|
||||
} else {
|
||||
dbgln_if(COMPOSITOR_DEBUG, "[Compositor] UI dropping did_paint for page {} bitmap {}: no view",
|
||||
page_id, bitmap_id);
|
||||
notify_presented_bitmap_ready_to_paint(page_id, bitmap_id);
|
||||
}
|
||||
}
|
||||
|
||||
void WebContentClient::did_request_new_process_for_navigation(u64 page_id, URL::URL url)
|
||||
|
|
@ -846,7 +916,7 @@ void WebContentClient::did_update_navigation_buttons_state(u64 page_id, bool bac
|
|||
view->did_update_navigation_buttons_state({}, back_enabled, forward_enabled);
|
||||
}
|
||||
|
||||
void WebContentClient::did_allocate_backing_stores(u64 page_id, i32 front_bitmap_id, Gfx::SharedImage front_backing_store, i32 back_bitmap_id, Gfx::SharedImage back_backing_store)
|
||||
void WebContentClient::did_present_backing_stores(u64 page_id, i32 front_bitmap_id, Gfx::SharedImage front_backing_store, i32 back_bitmap_id, Gfx::SharedImage back_backing_store)
|
||||
{
|
||||
if (auto view = view_for_page_id(page_id); view.has_value())
|
||||
view->did_allocate_backing_stores({}, front_bitmap_id, move(front_backing_store), back_bitmap_id, move(back_backing_store));
|
||||
|
|
|
|||
|
|
@ -58,6 +58,9 @@ public:
|
|||
void web_ui_disconnected(Badge<WebUI>);
|
||||
|
||||
void notify_all_views_of_crash();
|
||||
void notify_presented_bitmap_ready_to_paint(u64 page_id, i32 bitmap_id);
|
||||
void did_present_backing_stores(u64 page_id, i32 front_bitmap_id, Gfx::SharedImage front_backing_store, i32 back_bitmap_id, Gfx::SharedImage back_backing_store);
|
||||
void did_present_bitmap(u64 page_id, Gfx::IntRect, i32 bitmap_id);
|
||||
|
||||
pid_t pid() const { return m_process_handle.pid; }
|
||||
void set_pid(pid_t pid) { m_process_handle.pid = pid; }
|
||||
|
|
@ -67,7 +70,6 @@ private:
|
|||
|
||||
virtual void die() override;
|
||||
|
||||
virtual void did_paint(u64 page_id, Gfx::IntRect, i32) override;
|
||||
virtual void did_request_new_process_for_navigation(u64 page_id, URL::URL url) override;
|
||||
virtual void did_finish_loading(u64 page_id, URL::URL) override;
|
||||
virtual void did_request_refresh(u64 page_id) override;
|
||||
|
|
@ -153,7 +155,6 @@ private:
|
|||
virtual void did_request_clipboard_entries(u64 page_id, u64 request_id) override;
|
||||
virtual void did_change_audio_play_state(u64 page_id, Web::HTML::AudioPlayState) override;
|
||||
virtual void did_update_navigation_buttons_state(u64 page_id, bool back_enabled, bool forward_enabled) override;
|
||||
virtual void did_allocate_backing_stores(u64 page_id, i32 front_bitmap_id, Gfx::SharedImage front_backing_store, i32 back_bitmap_id, Gfx::SharedImage back_backing_store) override;
|
||||
virtual Messages::WebContentClient::RequestWorkerAgentResponse request_worker_agent(u64 page_id, Web::Bindings::AgentType worker_type) override;
|
||||
|
||||
Optional<ViewImplementation&> view_for_page_id(u64, SourceLocation = SourceLocation::current());
|
||||
|
|
|
|||
8
Services/WebContent/CompositorClient.ipc
Normal file
8
Services/WebContent/CompositorClient.ipc
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/SharedImage.h>
|
||||
|
||||
endpoint CompositorClient
|
||||
{
|
||||
did_allocate_backing_stores(u64 page_id, i32 front_bitmap_id, Gfx::SharedImage front_backing_store, i32 back_bitmap_id, Gfx::SharedImage back_backing_store) =|
|
||||
did_paint(u64 page_id, Gfx::IntRect content_rect, i32 bitmap_id) =|
|
||||
}
|
||||
4
Services/WebContent/CompositorServer.ipc
Normal file
4
Services/WebContent/CompositorServer.ipc
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
endpoint CompositorServer
|
||||
{
|
||||
ready_to_paint(u64 page_id, i32 bitmap_id) =|
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@
|
|||
*/
|
||||
|
||||
#include <AK/JsonObject.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/QuickSort.h>
|
||||
#include <LibCore/EventLoop.h>
|
||||
#include <LibCore/System.h>
|
||||
|
|
@ -19,6 +20,8 @@
|
|||
#include <LibGfx/SystemTheme.h>
|
||||
#include <LibJS/Runtime/ConsoleObject.h>
|
||||
#include <LibJS/Runtime/Date.h>
|
||||
#include <LibSync/ConditionVariable.h>
|
||||
#include <LibThreading/Thread.h>
|
||||
#include <LibUnicode/TimeZone.h>
|
||||
#include <LibWeb/ARIA/RoleType.h>
|
||||
#include <LibWeb/Bindings/MainThreadVM.h>
|
||||
|
|
@ -27,6 +30,7 @@
|
|||
#include <LibWeb/CSS/Parser/ErrorReporter.h>
|
||||
#include <LibWeb/CSS/StyleComputer.h>
|
||||
#include <LibWeb/CSS/StyleSheetList.h>
|
||||
#include <LibWeb/Compositor/CompositorThread.h>
|
||||
#include <LibWeb/CookieStore/CookieStore.h>
|
||||
#include <LibWeb/DOM/Attr.h>
|
||||
#include <LibWeb/DOM/CharacterData.h>
|
||||
|
|
@ -59,6 +63,8 @@
|
|||
#include <LibWeb/Worker/WebWorkerClient.h>
|
||||
#include <LibWebView/Attribute.h>
|
||||
#include <LibWebView/ViewImplementation.h>
|
||||
#include <WebContent/CompositorClientEndpoint.h>
|
||||
#include <WebContent/CompositorServerEndpoint.h>
|
||||
#include <WebContent/ConnectionFromClient.h>
|
||||
#include <WebContent/PageClient.h>
|
||||
#include <WebContent/PageHost.h>
|
||||
|
|
@ -66,6 +72,31 @@
|
|||
|
||||
namespace WebContent {
|
||||
|
||||
class CompositorConnectionFromClient final
|
||||
: public IPC::ConnectionFromClient<CompositorClientEndpoint, CompositorServerEndpoint> {
|
||||
C_OBJECT(CompositorConnectionFromClient)
|
||||
|
||||
public:
|
||||
virtual void die() override { }
|
||||
|
||||
private:
|
||||
explicit CompositorConnectionFromClient(NonnullOwnPtr<IPC::Transport> transport)
|
||||
: IPC::ConnectionFromClient<CompositorClientEndpoint, CompositorServerEndpoint>(*this, move(transport), 1)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void ready_to_paint(u64 page_id, i32 bitmap_id) override
|
||||
{
|
||||
Web::Compositor::CompositorThread::presented_bitmap_ready_to_paint(page_id, bitmap_id);
|
||||
}
|
||||
};
|
||||
|
||||
struct CompositorIPCStartupState {
|
||||
Sync::Mutex mutex;
|
||||
Sync::ConditionVariable ready { mutex };
|
||||
bool did_install_presentation_callbacks { false };
|
||||
};
|
||||
|
||||
ConnectionFromClient::ConnectionFromClient(NonnullOwnPtr<IPC::Transport> transport)
|
||||
: IPC::ConnectionFromClient<WebContentClientEndpoint, WebContentServerEndpoint>(*this, move(transport), 1)
|
||||
, m_page_host(PageHost::create(*this))
|
||||
|
|
@ -148,6 +179,40 @@ void ConnectionFromClient::connect_to_image_decoder(IPC::TransportHandle handle)
|
|||
on_image_decoder_connection(handle);
|
||||
}
|
||||
|
||||
void ConnectionFromClient::connect_to_compositor(IPC::TransportHandle handle)
|
||||
{
|
||||
auto startup_state = make<CompositorIPCStartupState>();
|
||||
|
||||
auto thread = Threading::Thread::construct("CompositorIPC"sv, [handle = move(handle), startup_state = startup_state.ptr()]() mutable {
|
||||
Core::EventLoop event_loop;
|
||||
auto transport = MUST(handle.create_transport());
|
||||
auto connection = CompositorConnectionFromClient::construct(move(transport));
|
||||
Web::Compositor::CompositorThread::set_frame_presentation_callbacks(
|
||||
Core::EventLoop::current_weak(),
|
||||
[connection = connection.ptr()](u64 page_id, i32 front_bitmap_id, Gfx::SharedImage front_backing_store, i32 back_bitmap_id, Gfx::SharedImage back_backing_store) {
|
||||
connection->async_did_allocate_backing_stores(page_id, front_bitmap_id, move(front_backing_store), back_bitmap_id, move(back_backing_store));
|
||||
},
|
||||
[connection = connection.ptr()](u64 page_id, Gfx::IntRect const& viewport_rect, i32 bitmap_id) {
|
||||
connection->async_did_paint(page_id, viewport_rect, bitmap_id);
|
||||
});
|
||||
{
|
||||
Sync::MutexLocker const locker { startup_state->mutex };
|
||||
startup_state->did_install_presentation_callbacks = true;
|
||||
startup_state->ready.signal();
|
||||
}
|
||||
auto result = event_loop.exec();
|
||||
Web::Compositor::CompositorThread::clear_frame_presentation_callbacks();
|
||||
return result;
|
||||
});
|
||||
thread->start();
|
||||
{
|
||||
Sync::MutexLocker const locker { startup_state->mutex };
|
||||
while (!startup_state->did_install_presentation_callbacks)
|
||||
startup_state->ready.wait();
|
||||
}
|
||||
thread->detach();
|
||||
}
|
||||
|
||||
void ConnectionFromClient::connect_to_request_server(IPC::TransportHandle handle)
|
||||
{
|
||||
if (on_request_server_connection)
|
||||
|
|
@ -206,12 +271,6 @@ void ConnectionFromClient::set_viewport(u64 page_id, Web::DevicePixelSize size,
|
|||
}
|
||||
}
|
||||
|
||||
void ConnectionFromClient::ready_to_paint(u64 page_id)
|
||||
{
|
||||
if (auto page = this->page(page_id); page.has_value())
|
||||
page->ready_to_paint();
|
||||
}
|
||||
|
||||
void ConnectionFromClient::key_event(u64 page_id, Web::KeyEvent event)
|
||||
{
|
||||
enqueue_input_event({ page_id, move(event), 0 });
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ private:
|
|||
virtual void connect_to_web_ui(u64 page_id, IPC::TransportHandle handle) override;
|
||||
virtual void connect_to_request_server(IPC::TransportHandle handle) override;
|
||||
virtual void connect_to_image_decoder(IPC::TransportHandle handle) override;
|
||||
virtual void connect_to_compositor(IPC::TransportHandle handle) override;
|
||||
virtual void update_system_theme(u64 page_id, Core::AnonymousBuffer) override;
|
||||
virtual void update_screen_rects(u64 page_id, Vector<Web::DevicePixelRect>, u32) override;
|
||||
virtual void load_url(u64 page_id, URL::URL) override;
|
||||
|
|
@ -77,7 +78,6 @@ private:
|
|||
virtual void mouse_event(u64 page_id, Web::MouseEvent) override;
|
||||
virtual void drag_event(u64 page_id, Web::DragEvent) override;
|
||||
virtual void pinch_event(u64 page_id, Web::PinchEvent) override;
|
||||
virtual void ready_to_paint(u64 page_id) override;
|
||||
virtual void debug_request(u64 page_id, ByteString, ByteString) override;
|
||||
virtual void get_source(u64 page_id) override;
|
||||
virtual void inspect_dom_tree(u64 page_id) override;
|
||||
|
|
|
|||
|
|
@ -188,11 +188,6 @@ void PageClient::set_window_size(Web::DevicePixelSize size)
|
|||
page().set_window_size(size);
|
||||
}
|
||||
|
||||
void PageClient::ready_to_paint()
|
||||
{
|
||||
page().top_level_traversable()->ready_to_paint();
|
||||
}
|
||||
|
||||
Queue<Web::QueuedInputEvent>& PageClient::input_event_queue()
|
||||
{
|
||||
return client().input_event_queue();
|
||||
|
|
@ -681,6 +676,8 @@ void PageClient::page_did_request_activate_tab()
|
|||
|
||||
void PageClient::page_did_close_top_level_traversable()
|
||||
{
|
||||
page().top_level_traversable()->rendering_thread().stop_presenting_to_client();
|
||||
|
||||
// FIXME: Rename this IPC call
|
||||
client().async_did_close_browsing_context(m_id);
|
||||
|
||||
|
|
@ -734,11 +731,6 @@ void PageClient::page_did_change_audio_play_state(Web::HTML::AudioPlayState play
|
|||
client().async_did_change_audio_play_state(m_id, play_state);
|
||||
}
|
||||
|
||||
void PageClient::page_did_allocate_backing_stores(i32 front_bitmap_id, Gfx::SharedImage front_backing_store, i32 back_bitmap_id, Gfx::SharedImage back_backing_store)
|
||||
{
|
||||
client().async_did_allocate_backing_stores(m_id, front_bitmap_id, move(front_backing_store), back_bitmap_id, move(back_backing_store));
|
||||
}
|
||||
|
||||
Web::PageClient::WorkerAgentResponse PageClient::request_worker_agent(Web::Bindings::AgentType type)
|
||||
{
|
||||
auto response = client().send_sync_but_allow_failure<Messages::WebContentClient::RequestWorkerAgent>(m_id, type);
|
||||
|
|
@ -788,11 +780,6 @@ void PageClient::page_did_mutate_dom(FlyString const& type, Web::DOM::Node const
|
|||
client().async_did_mutate_dom(m_id, { type.to_string(), target.unique_id(), move(serialized_target), mutation.release_value() });
|
||||
}
|
||||
|
||||
void PageClient::page_did_paint(Gfx::IntRect const& content_rect, i32 bitmap_id)
|
||||
{
|
||||
client().async_did_paint(m_id, content_rect, bitmap_id);
|
||||
}
|
||||
|
||||
void PageClient::page_did_take_screenshot(Gfx::ShareableBitmap const& screenshot)
|
||||
{
|
||||
client().async_did_take_screenshot(m_id, screenshot);
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/SharedImage.h>
|
||||
#include <LibWeb/CSS/StyleSheetIdentifier.h>
|
||||
#include <LibWeb/HTML/AudioPlayState.h>
|
||||
#include <LibWeb/HTML/FileFilter.h>
|
||||
|
|
@ -85,8 +84,6 @@ public:
|
|||
void did_disconnect_devtools_client();
|
||||
bool has_devtools_client() const { return m_devtools_client_count > 0; }
|
||||
|
||||
void ready_to_paint();
|
||||
|
||||
void initialize_js_console(Web::DOM::Document& document);
|
||||
void js_console_input(StringView js_source);
|
||||
void did_execute_js_console_input(JsonValue const&);
|
||||
|
|
@ -189,10 +186,8 @@ private:
|
|||
virtual void page_did_insert_clipboard_entry(Web::Clipboard::SystemClipboardRepresentation const&, StringView presentation_style) override;
|
||||
virtual void page_did_request_clipboard_entries(u64 request_id) override;
|
||||
virtual void page_did_change_audio_play_state(Web::HTML::AudioPlayState) override;
|
||||
virtual void page_did_allocate_backing_stores(i32 front_bitmap_id, Gfx::SharedImage front_backing_store, i32 back_bitmap_id, Gfx::SharedImage back_backing_store) override;
|
||||
virtual WorkerAgentResponse request_worker_agent(Web::Bindings::AgentType) override;
|
||||
virtual void page_did_mutate_dom(FlyString const& type, Web::DOM::Node const& target, Web::DOM::NodeList& added_nodes, Web::DOM::NodeList& removed_nodes, GC::Ptr<Web::DOM::Node> previous_sibling, GC::Ptr<Web::DOM::Node> next_sibling, Optional<String> const& attribute_name) override;
|
||||
virtual void page_did_paint(Gfx::IntRect const& content_rect, i32 bitmap_id) override;
|
||||
virtual void page_did_take_screenshot(Gfx::ShareableBitmap const& screenshot) override;
|
||||
virtual void received_message_from_web_ui(String const& name, JS::Value data) override;
|
||||
virtual void page_did_start_network_request(u64 request_id, URL::URL const&, ByteString const&, Vector<HTTP::Header> const&, ReadonlyBytes, Optional<String>) override;
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
#include <LibGfx/Color.h>
|
||||
#include <LibIPC/TransportHandle.h>
|
||||
#include <LibGfx/Cursor.h>
|
||||
#include <LibGfx/SharedImage.h>
|
||||
#include <LibGfx/ShareableBitmap.h>
|
||||
#include <LibHTTP/Cookie/Cookie.h>
|
||||
#include <LibHTTP/Cookie/ParsedCookie.h>
|
||||
|
|
@ -38,7 +37,6 @@ endpoint WebContentClient
|
|||
did_start_loading(u64 page_id, URL::URL url, bool is_redirect) =|
|
||||
did_finish_loading(u64 page_id, URL::URL url) =|
|
||||
did_request_refresh(u64 page_id) =|
|
||||
did_paint(u64 page_id, Gfx::IntRect content_rect, i32 bitmap_id) =|
|
||||
did_request_cursor_change(u64 page_id, Gfx::Cursor cursor) =|
|
||||
did_change_title(u64 page_id, Utf16String title) =|
|
||||
did_change_url(u64 page_id, URL::URL url) =|
|
||||
|
|
@ -117,7 +115,6 @@ endpoint WebContentClient
|
|||
did_request_clipboard_entries(u64 page_id, u64 request_id) =|
|
||||
|
||||
did_update_navigation_buttons_state(u64 page_id, bool back_enabled, bool forward_enabled) =|
|
||||
did_allocate_backing_stores(u64 page_id, i32 front_bitmap_id, Gfx::SharedImage front_backing_store, i32 back_bitmap_id, Gfx::SharedImage back_backing_store) =|
|
||||
|
||||
did_change_audio_play_state(u64 page_id, Web::HTML::AudioPlayState play_state) =|
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ endpoint WebContentServer
|
|||
connect_to_web_ui(u64 page_id, IPC::TransportHandle handle) =|
|
||||
connect_to_request_server(IPC::TransportHandle handle) =|
|
||||
connect_to_image_decoder(IPC::TransportHandle handle) =|
|
||||
connect_to_compositor(IPC::TransportHandle handle) =|
|
||||
|
||||
update_system_theme(u64 page_id, Core::AnonymousBuffer theme_buffer) =|
|
||||
update_screen_rects(u64 page_id, Vector<Web::DevicePixelRect> rects, u32 main_screen_index) =|
|
||||
|
|
@ -43,8 +44,6 @@ endpoint WebContentServer
|
|||
reload(u64 page_id) =|
|
||||
traverse_the_history_by_delta(u64 page_id, i32 delta) =|
|
||||
|
||||
ready_to_paint(u64 page_id) =|
|
||||
|
||||
set_viewport(u64 page_id, Web::DevicePixelSize size, double device_pixel_ratio, Web::ViewportIsFullscreen is_fullscreen) =|
|
||||
|
||||
key_event(u64 page_id, Web::KeyEvent event) =|
|
||||
|
|
|
|||
Loading…
Reference in a new issue