diff --git a/Ladybird/WebContent/main.cpp b/Ladybird/WebContent/main.cpp index cca477a5621..4fcbe169e9d 100644 --- a/Ladybird/WebContent/main.cpp +++ b/Ladybird/WebContent/main.cpp @@ -135,7 +135,8 @@ ErrorOr serenity_main(Main::Arguments arguments) Web::set_chrome_process_executable_path(executable_path); if (use_skia_painter) { - WebContent::PageClient::set_use_skia_painter(); + // Always use the CPU backend for layout tests, as the GPU backend is not deterministic + WebContent::PageClient::set_use_skia_painter(is_layout_test_mode ? WebContent::PageClient::UseSkiaPainter::CPUBackend : WebContent::PageClient::UseSkiaPainter::GPUBackendIfAvailable); } if (enable_http_cache) { diff --git a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp index d5dd24cd514..37e76b57ee1 100644 --- a/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp +++ b/Userland/Libraries/LibWeb/HTML/TraversableNavigable.cpp @@ -30,7 +30,7 @@ TraversableNavigable::TraversableNavigable(JS::NonnullGCPtr page) { #ifdef AK_OS_MACOS auto display_list_player_type = page->client().display_list_player_type(); - if (display_list_player_type == DisplayListPlayerType::Skia) { + if (display_list_player_type == DisplayListPlayerType::SkiaGPUIfAvailable) { m_metal_context = Core::get_metal_context(); m_skia_backend_context = Painting::DisplayListPlayerSkia::create_metal_context(*m_metal_context); } @@ -38,7 +38,7 @@ TraversableNavigable::TraversableNavigable(JS::NonnullGCPtr page) #ifdef USE_VULKAN auto display_list_player_type = page->client().display_list_player_type(); - if (display_list_player_type == DisplayListPlayerType::Skia) { + if (display_list_player_type == DisplayListPlayerType::SkiaGPUIfAvailable) { auto maybe_vulkan_context = Core::create_vulkan_context(); if (!maybe_vulkan_context.is_error()) { auto vulkan_context = maybe_vulkan_context.release_value(); @@ -1203,8 +1203,8 @@ void TraversableNavigable::paint(DevicePixelRect const& content_rect, Painting:: paint_config.has_focus = paint_options.has_focus; record_display_list(display_list_recorder, paint_config); - auto display_list_player_type = page().client().display_list_player_type(); - if (display_list_player_type == DisplayListPlayerType::Skia) { + switch (page().client().display_list_player_type()) { + case DisplayListPlayerType::SkiaGPUIfAvailable: { #ifdef AK_OS_MACOS if (m_metal_context && m_skia_backend_context && is(target)) { auto& iosurface_backing_store = static_cast(target); @@ -1223,11 +1223,23 @@ void TraversableNavigable::paint(DevicePixelRect const& content_rect, Painting:: } #endif + // Fallback to CPU backend if GPU is not available Painting::DisplayListPlayerSkia player(target.bitmap()); display_list.execute(player); - } else { + break; + } + case DisplayListPlayerType::SkiaCPU: { + Painting::DisplayListPlayerSkia player(target.bitmap()); + display_list.execute(player); + break; + } + case DisplayListPlayerType::CPU: { Painting::DisplayListPlayerCPU player(target.bitmap()); display_list.execute(player); + break; + } + default: + VERIFY_NOT_REACHED(); } } diff --git a/Userland/Libraries/LibWeb/Page/Page.h b/Userland/Libraries/LibWeb/Page/Page.h index 458e925123b..70bcd2a66c6 100644 --- a/Userland/Libraries/LibWeb/Page/Page.h +++ b/Userland/Libraries/LibWeb/Page/Page.h @@ -278,7 +278,8 @@ struct PaintOptions { enum class DisplayListPlayerType { CPU, - Skia + SkiaGPUIfAvailable, + SkiaCPU, }; class PageClient : public JS::Cell { diff --git a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp index 40c2dc7e3eb..9353c03b1b4 100644 --- a/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp +++ b/Userland/Libraries/LibWeb/SVG/SVGDecodedImageData.cpp @@ -105,7 +105,8 @@ RefPtr SVGDecodedImageData::render(Gfx::IntSize size) const display_list.execute(executor); break; } - case DisplayListPlayerType::Skia: { + case DisplayListPlayerType::SkiaGPUIfAvailable: + case DisplayListPlayerType::SkiaCPU: { Painting::DisplayListPlayerSkia executor { *bitmap }; display_list.execute(executor); break; diff --git a/Userland/Services/WebContent/PageClient.cpp b/Userland/Services/WebContent/PageClient.cpp index 762207046f3..2a813604dfa 100644 --- a/Userland/Services/WebContent/PageClient.cpp +++ b/Userland/Services/WebContent/PageClient.cpp @@ -27,13 +27,13 @@ namespace WebContent { -static bool s_use_skia_painter = false; +static PageClient::UseSkiaPainter s_use_skia_painter = PageClient::UseSkiaPainter::No; JS_DEFINE_ALLOCATOR(PageClient); -void PageClient::set_use_skia_painter() +void PageClient::set_use_skia_painter(UseSkiaPainter use_skia_painter) { - s_use_skia_painter = true; + s_use_skia_painter = use_skia_painter; } JS::NonnullGCPtr PageClient::create(JS::VM& vm, PageHost& page_host, u64 id) @@ -732,9 +732,16 @@ void PageClient::did_get_js_console_messages(i32 start_index, Vector Web::DisplayListPlayerType PageClient::display_list_player_type() const { - if (s_use_skia_painter) - return Web::DisplayListPlayerType::Skia; - return Web::DisplayListPlayerType::CPU; + switch (s_use_skia_painter) { + case UseSkiaPainter::No: + return Web::DisplayListPlayerType::CPU; + case UseSkiaPainter::GPUBackendIfAvailable: + return Web::DisplayListPlayerType::SkiaGPUIfAvailable; + case UseSkiaPainter::CPUBackend: + return Web::DisplayListPlayerType::SkiaCPU; + default: + VERIFY_NOT_REACHED(); + } } void PageClient::queue_screenshot_task(Optional node_id) diff --git a/Userland/Services/WebContent/PageClient.h b/Userland/Services/WebContent/PageClient.h index af380221c5b..60549b1cff4 100644 --- a/Userland/Services/WebContent/PageClient.h +++ b/Userland/Services/WebContent/PageClient.h @@ -27,7 +27,12 @@ public: virtual ~PageClient() override; - static void set_use_skia_painter(); + enum class UseSkiaPainter { + No, + CPUBackend, + GPUBackendIfAvailable, + }; + static void set_use_skia_painter(UseSkiaPainter); virtual void schedule_repaint() override; virtual bool is_ready_to_paint() const override;