diff --git a/Userland/Libraries/LibWeb/OutOfProcessWebView.cpp b/Userland/Libraries/LibWeb/OutOfProcessWebView.cpp index 003571e2e8..ae3bfb7ecb 100644 --- a/Userland/Libraries/LibWeb/OutOfProcessWebView.cpp +++ b/Userland/Libraries/LibWeb/OutOfProcessWebView.cpp @@ -97,21 +97,33 @@ void OutOfProcessWebView::resize_event(GUI::ResizeEvent& event) client().post_message(Messages::WebContentServer::SetViewportRect(Gfx::IntRect({ horizontal_scrollbar().value(), vertical_scrollbar().value() }, available_size()))); - m_front_bitmap = nullptr; - m_back_bitmap = nullptr; + if (m_front_bitmap) { + m_front_bitmap = nullptr; + client().post_message(Messages::WebContentServer::RemoveBackingStore(m_front_bitmap_id)); + } + + if (m_back_bitmap) { + m_back_bitmap = nullptr; + client().post_message(Messages::WebContentServer::RemoveBackingStore(m_back_bitmap_id)); + } + + m_front_bitmap_id = -1; + m_back_bitmap_id = -1; m_has_usable_bitmap = false; if (available_size().is_empty()) return; if (auto new_bitmap = Gfx::Bitmap::create_shareable(Gfx::BitmapFormat::RGB32, available_size())) { - new_bitmap->shared_buffer()->share_with(client().server_pid()); m_front_bitmap = move(new_bitmap); + m_front_bitmap_id = m_next_bitmap_id++; + client().post_message(Messages::WebContentServer::AddBackingStore(m_front_bitmap_id, m_front_bitmap->to_shareable_bitmap())); } if (auto new_bitmap = Gfx::Bitmap::create_shareable(Gfx::BitmapFormat::RGB32, available_size())) { - new_bitmap->shared_buffer()->share_with(client().server_pid()); m_back_bitmap = move(new_bitmap); + m_back_bitmap_id = m_next_bitmap_id++; + client().post_message(Messages::WebContentServer::AddBackingStore(m_back_bitmap_id, m_back_bitmap->to_shareable_bitmap())); } request_repaint(); @@ -144,11 +156,12 @@ void OutOfProcessWebView::theme_change_event(GUI::ThemeChangeEvent& event) request_repaint(); } -void OutOfProcessWebView::notify_server_did_paint(Badge, i32 shbuf_id) +void OutOfProcessWebView::notify_server_did_paint(Badge, i32 bitmap_id) { - if (m_back_bitmap->shbuf_id() == shbuf_id) { + if (m_back_bitmap_id == bitmap_id) { m_has_usable_bitmap = true; swap(m_back_bitmap, m_front_bitmap); + swap(m_back_bitmap_id, m_front_bitmap_id); update(); } } @@ -246,7 +259,7 @@ void OutOfProcessWebView::request_repaint() // it won't have a back bitmap yet, so we can just skip repaint requests. if (!m_back_bitmap) return; - client().post_message(Messages::WebContentServer::Paint(m_back_bitmap->rect().translated(horizontal_scrollbar().value(), vertical_scrollbar().value()), m_back_bitmap->shbuf_id())); + client().post_message(Messages::WebContentServer::Paint(m_back_bitmap->rect().translated(horizontal_scrollbar().value(), vertical_scrollbar().value()), m_back_bitmap_id)); } WebContentClient& OutOfProcessWebView::client() diff --git a/Userland/Libraries/LibWeb/OutOfProcessWebView.h b/Userland/Libraries/LibWeb/OutOfProcessWebView.h index a742a01af8..3a9167a06c 100644 --- a/Userland/Libraries/LibWeb/OutOfProcessWebView.h +++ b/Userland/Libraries/LibWeb/OutOfProcessWebView.h @@ -50,7 +50,7 @@ public: void load_empty_document(); void notify_server_did_layout(Badge, const Gfx::IntSize& content_size); - void notify_server_did_paint(Badge, i32 shbuf_id); + void notify_server_did_paint(Badge, i32 bitmap_id); void notify_server_did_invalidate_content_rect(Badge, const Gfx::IntRect&); void notify_server_did_change_selection(Badge); void notify_server_did_change_title(Badge, const String&); @@ -89,7 +89,9 @@ private: RefPtr m_client; RefPtr m_front_bitmap; RefPtr m_back_bitmap; - + i32 m_front_bitmap_id { -1 }; + i32 m_back_bitmap_id { -1 }; + i32 m_next_bitmap_id { 0 }; bool m_has_usable_bitmap { false }; }; diff --git a/Userland/Libraries/LibWeb/WebContentClient.cpp b/Userland/Libraries/LibWeb/WebContentClient.cpp index c31420a56b..7032924600 100644 --- a/Userland/Libraries/LibWeb/WebContentClient.cpp +++ b/Userland/Libraries/LibWeb/WebContentClient.cpp @@ -45,10 +45,7 @@ void WebContentClient::handshake() void WebContentClient::handle(const Messages::WebContentClient::DidPaint& message) { -#ifdef DEBUG_SPAM - dbg() << "handle: WebContentClient::DidPaint! content_rect=" << message.content_rect() << ", shbuf_id=" << message.shbuf_id(); -#endif - m_view.notify_server_did_paint({}, message.shbuf_id()); + m_view.notify_server_did_paint({}, message.bitmap_id()); } void WebContentClient::handle([[maybe_unused]] const Messages::WebContentClient::DidFinishLoading& message) diff --git a/Userland/Services/WebContent/ClientConnection.cpp b/Userland/Services/WebContent/ClientConnection.cpp index 2f5b44f95a..43fabf1c6c 100644 --- a/Userland/Services/WebContent/ClientConnection.cpp +++ b/Userland/Services/WebContent/ClientConnection.cpp @@ -102,33 +102,33 @@ void ClientConnection::handle(const Messages::WebContentServer::SetViewportRect& m_page_host->set_viewport_rect(message.rect()); } +void ClientConnection::handle(const Messages::WebContentServer::AddBackingStore& message) +{ + m_backing_stores.set(message.backing_store_id(), *message.bitmap().bitmap()); +} + +void ClientConnection::handle(const Messages::WebContentServer::RemoveBackingStore& message) +{ + m_backing_stores.remove(message.backing_store_id()); +} + void ClientConnection::handle(const Messages::WebContentServer::Paint& message) { -#ifdef DEBUG_SPAM - dbg() << "handle: WebContentServer::Paint: content_rect=" << message.content_rect() << ", shbuf_id=" << message.shbuf_id(); -#endif - for (auto& pending_paint : m_pending_paint_requests) { - if (pending_paint.bitmap->shbuf_id() == message.shbuf_id()) { + if (pending_paint.bitmap_id == message.backing_store_id()) { pending_paint.content_rect = message.content_rect(); return; } } - auto shared_buffer = SharedBuffer::create_from_shbuf_id(message.shbuf_id()); - if (!shared_buffer) { -#ifdef DEBUG_SPAM - dbgln("WebContentServer::Paint: SharedBuffer already gone! Ignoring :^)"); -#endif - return; - } - auto shared_bitmap = Gfx::Bitmap::create_with_shared_buffer(Gfx::BitmapFormat::RGB32, shared_buffer.release_nonnull(), message.content_rect().size()); - if (!shared_bitmap) { - did_misbehave("WebContentServer::Paint: Cannot create Gfx::Bitmap wrapper around SharedBuffer"); + auto it = m_backing_stores.find(message.backing_store_id()); + if (it == m_backing_stores.end()) { + did_misbehave("Client requested paint with backing store ID"); return; } - m_pending_paint_requests.append({ message.content_rect(), shared_bitmap.release_nonnull() }); + auto& bitmap = *it->value; + m_pending_paint_requests.append({ message.content_rect(), bitmap, message.backing_store_id() }); m_paint_flush_timer->start(); } @@ -136,7 +136,7 @@ void ClientConnection::flush_pending_paint_requests() { for (auto& pending_paint : m_pending_paint_requests) { m_page_host->paint(pending_paint.content_rect, *pending_paint.bitmap); - post_message(Messages::WebContentClient::DidPaint(pending_paint.content_rect, pending_paint.bitmap->shbuf_id())); + post_message(Messages::WebContentClient::DidPaint(pending_paint.content_rect, pending_paint.bitmap_id)); } m_pending_paint_requests.clear(); } diff --git a/Userland/Services/WebContent/ClientConnection.h b/Userland/Services/WebContent/ClientConnection.h index 42e2ab8313..34a13713f3 100644 --- a/Userland/Services/WebContent/ClientConnection.h +++ b/Userland/Services/WebContent/ClientConnection.h @@ -60,6 +60,8 @@ private: virtual void handle(const Messages::WebContentServer::MouseMove&) override; virtual void handle(const Messages::WebContentServer::MouseUp&) override; virtual void handle(const Messages::WebContentServer::KeyDown&) override; + virtual void handle(const Messages::WebContentServer::AddBackingStore&) override; + virtual void handle(const Messages::WebContentServer::RemoveBackingStore&) override; void flush_pending_paint_requests(); @@ -68,9 +70,12 @@ private: struct PaintRequest { Gfx::IntRect content_rect; NonnullRefPtr bitmap; + i32 bitmap_id { -1 }; }; Vector m_pending_paint_requests; RefPtr m_paint_flush_timer; + + HashMap> m_backing_stores; }; } diff --git a/Userland/Services/WebContent/WebContentClient.ipc b/Userland/Services/WebContent/WebContentClient.ipc index 10008a765c..2e2f63d831 100644 --- a/Userland/Services/WebContent/WebContentClient.ipc +++ b/Userland/Services/WebContent/WebContentClient.ipc @@ -2,7 +2,7 @@ endpoint WebContentClient = 90 { DidStartLoading(URL url) =| DidFinishLoading(URL url) =| - DidPaint(Gfx::IntRect content_rect, i32 shbuf_id) =| + DidPaint(Gfx::IntRect content_rect, i32 bitmap_id) =| DidInvalidateContentRect(Gfx::IntRect content_rect) =| DidChangeSelection() =| DidLayout(Gfx::IntSize content_size) =| diff --git a/Userland/Services/WebContent/WebContentServer.ipc b/Userland/Services/WebContent/WebContentServer.ipc index cb2ff26b85..e025e0b0cd 100644 --- a/Userland/Services/WebContent/WebContentServer.ipc +++ b/Userland/Services/WebContent/WebContentServer.ipc @@ -7,7 +7,10 @@ endpoint WebContentServer = 89 LoadURL(URL url) =| LoadHTML(String html, URL url) =| - Paint(Gfx::IntRect content_rect, i32 shbuf_id) =| + AddBackingStore(i32 backing_store_id, Gfx::ShareableBitmap bitmap) =| + RemoveBackingStore(i32 backing_store_id) =| + + Paint(Gfx::IntRect content_rect, i32 backing_store_id) =| SetViewportRect(Gfx::IntRect rect) =| MouseDown(Gfx::IntPoint position, unsigned button, unsigned buttons, unsigned modifiers) =|