From c92f8ab1ea26da068f1a08d9b7b2f0e9e924b2d7 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Thu, 20 Jun 2024 21:34:51 +0300 Subject: [PATCH] Everywhere: Use IOSurface as backing store on macOS Using mmap-allocated memory for backing stores does not allow us to benefit from using GPU-accelerated painting, because all the performance increase we get is mostly negated by reading the GPU-allocated texture back into RAM, so it can be shared with the browser process. With IOSurface, we get a framebuffer that is both shareable between processes and can be used as underlying memory for an OpenGL/Metal texture. This change does not yet benefit from using IOSurface and merely wraps them into Gfx::Bitmap to be used by the CPU painter. --- Ladybird/AppKit/main.mm | 6 ++ Ladybird/MachPortServer.cpp | 41 ++++--- Ladybird/MachPortServer.h | 9 ++ Ladybird/Qt/main.cpp | 4 + Ladybird/WebContent/main.cpp | 3 +- Userland/Libraries/LibCore/Forward.h | 4 + .../LibCore/Platform/MachMessageTypes.h | 65 +++++++++++ .../Platform/ProcessStatisticsMach.cpp | 11 +- .../LibCore/Platform/ProcessStatisticsMach.h | 17 +-- .../LibWebView/ViewImplementation.cpp | 31 ++++++ .../Libraries/LibWebView/ViewImplementation.h | 4 + .../Libraries/LibWebView/WebContentClient.cpp | 17 +++ .../Libraries/LibWebView/WebContentClient.h | 3 + .../WebContent/BackingStoreManager.cpp | 101 ++++++++++++++---- .../Services/WebContent/BackingStoreManager.h | 6 ++ 15 files changed, 266 insertions(+), 56 deletions(-) create mode 100644 Userland/Libraries/LibCore/Platform/MachMessageTypes.h diff --git a/Ladybird/AppKit/main.mm b/Ladybird/AppKit/main.mm index 9315beb62b9..e98d3028c5b 100644 --- a/Ladybird/AppKit/main.mm +++ b/Ladybird/AppKit/main.mm @@ -18,6 +18,8 @@ #include #include #include +#include +#include #import #import @@ -123,6 +125,10 @@ ErrorOr serenity_main(Main::Arguments arguments) mach_port_server->on_receive_child_mach_port = [](auto pid, auto port) { WebView::ProcessManager::the().add_process(pid, move(port)); }; + mach_port_server->on_receive_backing_stores = [](Ladybird::MachPortServer::BackingStoresMessage message) { + auto view = WebView::WebContentClient::view_for_pid_and_page_id(message.pid, message.page_id); + view->did_allocate_iosurface_backing_stores(message.front_backing_store_id, move(message.front_backing_store_port), message.back_backing_store_id, move(message.back_backing_store_port)); + }; auto database = TRY(WebView::Database::create()); auto cookie_jar = TRY(WebView::CookieJar::create(*database)); diff --git a/Ladybird/MachPortServer.cpp b/Ladybird/MachPortServer.cpp index dfe8fb65c3b..7bc87324608 100644 --- a/Ladybird/MachPortServer.cpp +++ b/Ladybird/MachPortServer.cpp @@ -6,6 +6,7 @@ #include "MachPortServer.h" #include +#include #include namespace Ladybird { @@ -55,8 +56,7 @@ ErrorOr MachPortServer::allocate_server_port() void MachPortServer::thread_loop() { while (!m_should_stop.load(MemoryOrder::memory_order_acquire)) { - - Core::Platform::ParentPortMessage message {}; + Core::Platform::ReceivedMachMessage message {}; // Get the pid of the child from the audit trailer so we can associate the port w/it mach_msg_options_t const options = MACH_RCV_MSG | MACH_RCV_TRAILER_TYPE(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT); @@ -68,23 +68,38 @@ void MachPortServer::thread_loop() break; } - if (message.header.msgh_id != Core::Platform::SELF_TASK_PORT_MESSAGE_ID) { - dbgln("Received message with id {}, ignoring", message.header.msgh_id); + if (message.header.msgh_id == Core::Platform::BACKING_STORE_IOSURFACES_MESSAGE_ID) { + auto pid = static_cast(message.body.parent_iosurface.trailer.msgh_audit.val[5]); + auto const& backing_stores_message = message.body.parent_iosurface; + auto front_child_port = Core::MachPort::adopt_right(backing_stores_message.front_descriptor.name, Core::MachPort::PortRight::Send); + auto back_child_port = Core::MachPort::adopt_right(backing_stores_message.back_descriptor.name, Core::MachPort::PortRight::Send); + auto const& metadata = backing_stores_message.metadata; + if (on_receive_backing_stores) + on_receive_backing_stores({ .pid = pid, + .page_id = metadata.page_id, + .front_backing_store_id = metadata.front_backing_store_id, + .back_backing_store_id = metadata.back_backing_store_id, + .front_backing_store_port = move(front_child_port), + .back_backing_store_port = move(back_child_port) }); continue; } - if (MACH_MSGH_BITS_LOCAL(message.header.msgh_bits) != MACH_MSG_TYPE_MOVE_SEND) { - dbgln("Received message with invalid local port rights {}, ignoring", MACH_MSGH_BITS_LOCAL(message.header.msgh_bits)); + if (message.header.msgh_id == Core::Platform::SELF_TASK_PORT_MESSAGE_ID) { + if (MACH_MSGH_BITS_LOCAL(message.header.msgh_bits) != MACH_MSG_TYPE_MOVE_SEND) { + dbgln("Received message with invalid local port rights {}, ignoring", MACH_MSGH_BITS_LOCAL(message.header.msgh_bits)); + continue; + } + + auto const& task_port_message = message.body.parent; + auto pid = static_cast(task_port_message.trailer.msgh_audit.val[5]); + auto child_port = Core::MachPort::adopt_right(task_port_message.port_descriptor.name, Core::MachPort::PortRight::Send); + dbgln_if(MACH_PORT_DEBUG, "Received child port {:x} from pid {}", child_port.port(), pid); + if (on_receive_child_mach_port) + on_receive_child_mach_port(pid, move(child_port)); continue; } - auto pid = static_cast(message.trailer.msgh_audit.val[5]); - auto child_port = Core::MachPort::adopt_right(message.port_descriptor.name, Core::MachPort::PortRight::Send); - dbgln_if(MACH_PORT_DEBUG, "Received child port {:x} from pid {}", child_port.port(), pid); - - if (on_receive_child_mach_port) - on_receive_child_mach_port(pid, move(child_port)); + dbgln("Received message with id {}, ignoring", message.header.msgh_id); } } - } diff --git a/Ladybird/MachPortServer.h b/Ladybird/MachPortServer.h index 71a7559d9bb..a3eb048e22d 100644 --- a/Ladybird/MachPortServer.h +++ b/Ladybird/MachPortServer.h @@ -31,6 +31,15 @@ public: bool is_initialized(); Function on_receive_child_mach_port; + struct BackingStoresMessage { + pid_t pid { -1 }; + u64 page_id { 0 }; + i32 front_backing_store_id { 0 }; + i32 back_backing_store_id { 0 }; + Core::MachPort front_backing_store_port; + Core::MachPort back_backing_store_port; + }; + Function on_receive_backing_stores; ByteString const& server_port_name() const { return m_server_port_name; } diff --git a/Ladybird/Qt/main.cpp b/Ladybird/Qt/main.cpp index 481ab5a46bb..93321b0e56d 100644 --- a/Ladybird/Qt/main.cpp +++ b/Ladybird/Qt/main.cpp @@ -150,6 +150,10 @@ ErrorOr serenity_main(Main::Arguments arguments) mach_port_server->on_receive_child_mach_port = [](auto pid, auto port) { WebView::ProcessManager::the().add_process(pid, move(port)); }; + mach_port_server->on_receive_backing_stores = [](Ladybird::MachPortServer::BackingStoresMessage message) { + auto view = WebView::WebContentClient::view_for_pid_and_page_id(message.pid, message.page_id); + view->did_allocate_iosurface_backing_stores(message.front_backing_store_id, move(message.front_backing_store_port), message.back_backing_store_id, move(message.back_backing_store_port)); + }; #endif RefPtr database; diff --git a/Ladybird/WebContent/main.cpp b/Ladybird/WebContent/main.cpp index 1c91929c8bc..a9715bf6aa3 100644 --- a/Ladybird/WebContent/main.cpp +++ b/Ladybird/WebContent/main.cpp @@ -148,7 +148,8 @@ ErrorOr serenity_main(Main::Arguments arguments) #if defined(AK_OS_MACOS) if (!mach_server_name.is_empty()) { - Core::Platform::register_with_mach_server(mach_server_name); + auto server_port = Core::Platform::register_with_mach_server(mach_server_name); + WebContent::BackingStoreManager::set_browser_mach_port(move(server_port)); } #endif diff --git a/Userland/Libraries/LibCore/Forward.h b/Userland/Libraries/LibCore/Forward.h index a36dfad0494..6805d60ba6d 100644 --- a/Userland/Libraries/LibCore/Forward.h +++ b/Userland/Libraries/LibCore/Forward.h @@ -49,4 +49,8 @@ class UDPSocket; enum class TimerShouldFireWhenNotVisible; +#ifdef AK_OS_MACH +class MachPort; +#endif + } diff --git a/Userland/Libraries/LibCore/Platform/MachMessageTypes.h b/Userland/Libraries/LibCore/Platform/MachMessageTypes.h new file mode 100644 index 00000000000..54abf77321c --- /dev/null +++ b/Userland/Libraries/LibCore/Platform/MachMessageTypes.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2024, Andrew Kaster + * Copyright (c) 2024, Aliaksandr Kalenik + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include + +#if !defined(AK_OS_MACH) +# error "This file is only available on Mach platforms" +#endif + +#include + +namespace Core::Platform { + +struct MessageBodyWithSelfTaskPort { + mach_msg_body_t body; + mach_msg_port_descriptor_t port_descriptor; + mach_msg_audit_trailer_t trailer; +}; + +struct MessageWithSelfTaskPort { + mach_msg_header_t header; + mach_msg_body_t body; + mach_msg_port_descriptor_t port_descriptor; +}; + +struct BackingStoreMetadata { + u64 page_id { 0 }; + i32 back_backing_store_id { 0 }; + i32 front_backing_store_id { 0 }; +}; + +struct MessageBodyWithBackingStores { + mach_msg_body_t body; + mach_msg_port_descriptor_t front_descriptor; + mach_msg_port_descriptor_t back_descriptor; + BackingStoreMetadata metadata; + mach_msg_audit_trailer_t trailer; +}; + +struct MessageWithBackingStores { + mach_msg_header_t header; + mach_msg_body_t body; + mach_msg_port_descriptor_t front_descriptor; + mach_msg_port_descriptor_t back_descriptor; + BackingStoreMetadata metadata; +}; + +struct ReceivedMachMessage { + mach_msg_header_t header; + union { + MessageBodyWithSelfTaskPort parent; + MessageBodyWithBackingStores parent_iosurface; + } body; +}; + +static constexpr mach_msg_id_t SELF_TASK_PORT_MESSAGE_ID = 0x1234CAFE; +static constexpr mach_msg_id_t BACKING_STORE_IOSURFACES_MESSAGE_ID = 0x1234CAFF; + +} diff --git a/Userland/Libraries/LibCore/Platform/ProcessStatisticsMach.cpp b/Userland/Libraries/LibCore/Platform/ProcessStatisticsMach.cpp index a09d1acba59..5d1d36e1db3 100644 --- a/Userland/Libraries/LibCore/Platform/ProcessStatisticsMach.cpp +++ b/Userland/Libraries/LibCore/Platform/ProcessStatisticsMach.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include namespace Core::Platform { @@ -75,17 +76,17 @@ ErrorOr update_process_statistics(ProcessStatistics& statistics) return {}; } -void register_with_mach_server(ByteString const& server_name) +MachPort register_with_mach_server(ByteString const& server_name) { auto server_port_or_error = Core::MachPort::look_up_from_bootstrap_server(server_name); if (server_port_or_error.is_error()) { dbgln("Failed to lookup server port: {}", server_port_or_error.error()); - return; + VERIFY_NOT_REACHED(); } auto server_port = server_port_or_error.release_value(); // Send our own task port to the server so they can query statistics about us - ChildPortMessage message {}; + MessageWithSelfTaskPort message {}; message.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSGH_BITS_ZERO) | MACH_MSGH_BITS_COMPLEX; message.header.msgh_size = sizeof(message); message.header.msgh_remote_port = server_port.port(); @@ -101,8 +102,10 @@ void register_with_mach_server(ByteString const& server_name) auto const send_result = mach_msg(&message.header, MACH_SEND_MSG | MACH_SEND_TIMEOUT, message.header.msgh_size, 0, MACH_PORT_NULL, timeout, MACH_PORT_NULL); if (send_result != KERN_SUCCESS) { dbgln("Failed to send message to server: {}", mach_error_string(send_result)); - return; + VERIFY_NOT_REACHED(); } + + return server_port; } } diff --git a/Userland/Libraries/LibCore/Platform/ProcessStatisticsMach.h b/Userland/Libraries/LibCore/Platform/ProcessStatisticsMach.h index c8ad3ea788e..666a71ebfcf 100644 --- a/Userland/Libraries/LibCore/Platform/ProcessStatisticsMach.h +++ b/Userland/Libraries/LibCore/Platform/ProcessStatisticsMach.h @@ -17,21 +17,6 @@ namespace Core::Platform { -struct ChildPortMessage { - mach_msg_header_t header; - mach_msg_body_t body; - mach_msg_port_descriptor_t port_descriptor; -}; - -struct ParentPortMessage { - mach_msg_header_t header; - mach_msg_body_t body; - mach_msg_port_descriptor_t port_descriptor; - mach_msg_audit_trailer_t trailer; // for the child's pid -}; - -static constexpr mach_msg_id_t SELF_TASK_PORT_MESSAGE_ID = 0x1234CAFE; - -void register_with_mach_server(ByteString const& server_name); +MachPort register_with_mach_server(ByteString const& server_name); } diff --git a/Userland/Libraries/LibWebView/ViewImplementation.cpp b/Userland/Libraries/LibWebView/ViewImplementation.cpp index 2b50476d6d5..db3fa86f9e6 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.cpp +++ b/Userland/Libraries/LibWebView/ViewImplementation.cpp @@ -12,6 +12,11 @@ #include #include +#ifdef AK_OS_MACOS +# include +# include +#endif + namespace WebView { ViewImplementation::ViewImplementation() @@ -397,6 +402,32 @@ void ViewImplementation::did_allocate_backing_stores(Badge, i3 m_client_state.back_bitmap.id = back_bitmap_id; } +#ifdef AK_OS_MACOS +void ViewImplementation::did_allocate_iosurface_backing_stores(i32 front_id, Core::MachPort&& front_port, i32 back_id, Core::MachPort&& back_port) +{ + if (m_client_state.has_usable_bitmap) { + // NOTE: We keep the outgoing front bitmap as a backup so we have something to paint until we get a new one. + m_backup_bitmap = m_client_state.front_bitmap.bitmap; + m_backup_bitmap_size = m_client_state.front_bitmap.last_painted_size; + } + m_client_state.has_usable_bitmap = false; + + auto front_iosurface = Core::IOSurfaceHandle::from_mach_port(move(front_port)); + auto back_iosurface = Core::IOSurfaceHandle::from_mach_port(move(back_port)); + + auto front_size = Gfx::IntSize { front_iosurface.width(), front_iosurface.height() }; + auto back_size = Gfx::IntSize { back_iosurface.width(), back_iosurface.height() }; + + auto front_bitmap = Gfx::Bitmap::create_wrapper(Gfx::BitmapFormat::BGRA8888, front_size, front_size.width() * front_iosurface.bytes_per_element(), front_iosurface.data(), [handle = move(front_iosurface)] {}); + auto back_bitmap = Gfx::Bitmap::create_wrapper(Gfx::BitmapFormat::BGRA8888, back_size, back_size.width() * back_iosurface.bytes_per_element(), back_iosurface.data(), [handle = move(back_iosurface)] {}); + + m_client_state.front_bitmap.bitmap = front_bitmap.release_value_but_fixme_should_propagate_errors(); + m_client_state.front_bitmap.id = front_id; + m_client_state.back_bitmap.bitmap = back_bitmap.release_value_but_fixme_should_propagate_errors(); + m_client_state.back_bitmap.id = back_id; +} +#endif + void ViewImplementation::handle_resize() { client().async_set_viewport_size(page_id(), this->viewport_size()); diff --git a/Userland/Libraries/LibWebView/ViewImplementation.h b/Userland/Libraries/LibWebView/ViewImplementation.h index bd3bdf67cd8..aa1fe6367bf 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.h +++ b/Userland/Libraries/LibWebView/ViewImplementation.h @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -118,6 +119,9 @@ public: void did_update_navigation_buttons_state(Badge, bool back_enabled, bool forward_enabled) const; void did_allocate_backing_stores(Badge, i32 front_bitmap_id, Gfx::ShareableBitmap const&, i32 back_bitmap_id, Gfx::ShareableBitmap const&); +#ifdef AK_OS_MACOS + void did_allocate_iosurface_backing_stores(i32 front_bitmap_id, Core::MachPort&&, i32 back_bitmap_id, Core::MachPort&&); +#endif enum class ScreenshotType { Visible, diff --git a/Userland/Libraries/LibWebView/WebContentClient.cpp b/Userland/Libraries/LibWebView/WebContentClient.cpp index 10b6dafab0f..edb4612257e 100644 --- a/Userland/Libraries/LibWebView/WebContentClient.cpp +++ b/Userland/Libraries/LibWebView/WebContentClient.cpp @@ -11,12 +11,29 @@ namespace WebView { +static HashTable s_clients; + +Optional WebContentClient::view_for_pid_and_page_id(pid_t pid, u64 page_id) +{ + for (auto* client : s_clients) { + if (client->m_process_handle.pid == pid) + return client->view_for_page_id(page_id); + } + return {}; +} + WebContentClient::WebContentClient(NonnullOwnPtr socket, ViewImplementation& view) : IPC::ConnectionToServer(*this, move(socket)) { + s_clients.set(this); m_views.set(0, &view); } +WebContentClient::~WebContentClient() +{ + s_clients.remove(this); +} + void WebContentClient::die() { VERIFY(on_web_content_process_crash); diff --git a/Userland/Libraries/LibWebView/WebContentClient.h b/Userland/Libraries/LibWebView/WebContentClient.h index 1c59667e124..6e2df157d06 100644 --- a/Userland/Libraries/LibWebView/WebContentClient.h +++ b/Userland/Libraries/LibWebView/WebContentClient.h @@ -26,7 +26,10 @@ class WebContentClient final IPC_CLIENT_CONNECTION(WebContentClient, "/tmp/session/%sid/portal/webcontent"sv); public: + static Optional view_for_pid_and_page_id(pid_t pid, u64 page_id); + WebContentClient(NonnullOwnPtr, ViewImplementation&); + ~WebContentClient(); void register_view(u64 page_id, ViewImplementation&); void unregister_view(u64 page_id); diff --git a/Userland/Services/WebContent/BackingStoreManager.cpp b/Userland/Services/WebContent/BackingStoreManager.cpp index 71ec7ea0b2e..a354e527921 100644 --- a/Userland/Services/WebContent/BackingStoreManager.cpp +++ b/Userland/Services/WebContent/BackingStoreManager.cpp @@ -9,8 +9,22 @@ #include #include +#ifdef AK_OS_MACOS +# include +# include +# include +#endif + namespace WebContent { +#ifdef AK_OS_MACOS +static Optional s_browser_mach_port; +void BackingStoreManager::set_browser_mach_port(Core::MachPort&& port) +{ + s_browser_mach_port = move(port); +} +#endif + BackingStoreManager::BackingStoreManager(PageClient& page_client) : m_page_client(page_client) { @@ -24,10 +38,71 @@ void BackingStoreManager::restart_resize_timer() m_backing_store_shrink_timer->restart(); } +void BackingStoreManager::reallocate_backing_stores(Gfx::IntSize size) +{ +#ifdef AK_OS_MACOS + if (s_browser_mach_port.has_value()) { + auto back_iosurface = Core::IOSurfaceHandle::create(size.width(), size.height()); + auto back_iosurface_port = back_iosurface.create_mach_port(); + + auto front_iosurface = Core::IOSurfaceHandle::create(size.width(), size.height()); + auto front_iosurface_port = front_iosurface.create_mach_port(); + + m_front_bitmap_id = m_next_bitmap_id++; + m_back_bitmap_id = m_next_bitmap_id++; + + m_front_bitmap = Gfx::Bitmap::create_wrapper(Gfx::BitmapFormat::BGRA8888, size, size.width() * front_iosurface.bytes_per_element(), front_iosurface.data(), [handle = move(front_iosurface)] {}).release_value(); + m_back_bitmap = Gfx::Bitmap::create_wrapper(Gfx::BitmapFormat::BGRA8888, size, size.width() * back_iosurface.bytes_per_element(), back_iosurface.data(), [handle = move(back_iosurface)] {}).release_value(); + + Core::Platform::BackingStoreMetadata metadata; + metadata.page_id = m_page_client.m_id; + metadata.front_backing_store_id = m_front_bitmap_id; + metadata.back_backing_store_id = m_back_bitmap_id; + + Core::Platform::MessageWithBackingStores message; + + message.header.msgh_remote_port = s_browser_mach_port->port(); + message.header.msgh_local_port = MACH_PORT_NULL; + message.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, 0) | MACH_MSGH_BITS_COMPLEX; + message.header.msgh_size = sizeof(message); + message.header.msgh_id = Core::Platform::BACKING_STORE_IOSURFACES_MESSAGE_ID; + + message.body.msgh_descriptor_count = 2; + + message.front_descriptor.name = front_iosurface_port.release(); + message.front_descriptor.disposition = MACH_MSG_TYPE_MOVE_SEND; + message.front_descriptor.type = MACH_MSG_PORT_DESCRIPTOR; + + message.back_descriptor.name = back_iosurface_port.release(); + message.back_descriptor.disposition = MACH_MSG_TYPE_MOVE_SEND; + message.back_descriptor.type = MACH_MSG_PORT_DESCRIPTOR; + + message.metadata = metadata; + + mach_msg_timeout_t const timeout = 100; // milliseconds + auto const send_result = mach_msg(&message.header, MACH_SEND_MSG | MACH_SEND_TIMEOUT, message.header.msgh_size, 0, MACH_PORT_NULL, timeout, MACH_PORT_NULL); + if (send_result != KERN_SUCCESS) { + dbgln("Failed to send message to server: {}", mach_error_string(send_result)); + VERIFY_NOT_REACHED(); + } + + return; + } +#endif + + m_front_bitmap_id = m_next_bitmap_id++; + m_back_bitmap_id = m_next_bitmap_id++; + + m_front_bitmap = Gfx::Bitmap::create_shareable(Gfx::BitmapFormat::BGRA8888, size).release_value(); + m_back_bitmap = Gfx::Bitmap::create_shareable(Gfx::BitmapFormat::BGRA8888, size).release_value(); + + m_page_client.page_did_allocate_backing_stores(m_front_bitmap_id, m_front_bitmap->to_shareable_bitmap(), m_back_bitmap_id, m_back_bitmap->to_shareable_bitmap()); +} + void BackingStoreManager::resize_backing_stores_if_needed(WindowResizingInProgress window_resize_in_progress) { - auto css_pixels_viewport_rect = m_page_client.page().top_level_traversable()->viewport_rect(); - auto viewport_size = m_page_client.page().css_to_device_rect(css_pixels_viewport_rect).size(); + auto css_pixels_viewpor_rect = m_page_client.page().top_level_traversable()->viewport_rect(); + auto viewport_size = m_page_client.page().css_to_device_rect(css_pixels_viewpor_rect).size(); if (viewport_size.is_empty()) return; @@ -43,26 +118,8 @@ void BackingStoreManager::resize_backing_stores_if_needed(WindowResizingInProgre m_back_bitmap.clear(); } - auto old_front_bitmap_id = m_front_bitmap_id; - auto old_back_bitmap_id = m_back_bitmap_id; - - auto reallocate_backing_store_if_needed = [&](RefPtr& bitmap, int& id) { - if (!bitmap || !bitmap->size().contains(minimum_needed_size.to_type())) { - if (auto new_bitmap_or_error = Gfx::Bitmap::create_shareable(Gfx::BitmapFormat::BGRA8888, minimum_needed_size.to_type()); !new_bitmap_or_error.is_error()) { - bitmap = new_bitmap_or_error.release_value(); - id = m_next_bitmap_id++; - } - } - }; - - reallocate_backing_store_if_needed(m_front_bitmap, m_front_bitmap_id); - reallocate_backing_store_if_needed(m_back_bitmap, m_back_bitmap_id); - - auto& front_bitmap = m_front_bitmap; - auto& back_bitmap = m_back_bitmap; - - if (m_front_bitmap_id != old_front_bitmap_id || m_back_bitmap_id != old_back_bitmap_id) { - m_page_client.page_did_allocate_backing_stores(m_front_bitmap_id, front_bitmap->to_shareable_bitmap(), m_back_bitmap_id, back_bitmap->to_shareable_bitmap()); + if (!m_front_bitmap || !m_back_bitmap || !m_front_bitmap->size().contains(minimum_needed_size.to_type())) { + reallocate_backing_stores(minimum_needed_size.to_type()); } } diff --git a/Userland/Services/WebContent/BackingStoreManager.h b/Userland/Services/WebContent/BackingStoreManager.h index ffc2fecc873..4cb4db19788 100644 --- a/Userland/Services/WebContent/BackingStoreManager.h +++ b/Userland/Services/WebContent/BackingStoreManager.h @@ -6,6 +6,7 @@ #pragma once +#include #include #include @@ -13,11 +14,16 @@ namespace WebContent { class BackingStoreManager { public: +#ifdef AK_OS_MACOS + static void set_browser_mach_port(Core::MachPort&&); +#endif + enum class WindowResizingInProgress { No, Yes }; void resize_backing_stores_if_needed(WindowResizingInProgress window_resize_in_progress); + void reallocate_backing_stores(Gfx::IntSize); void restart_resize_timer(); RefPtr back_bitmap() { return m_back_bitmap; }