From b6732b023423ec94c9b47e4fe2c8c24d36e0a73b Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Fri, 27 Oct 2023 17:28:18 +0200 Subject: [PATCH] Ladybird+WebContent: Add option to use GPU painter Adds `--enable-gpu-painting` param to enable painting command executor that uses LibAccelGfx. --- Ladybird/AppKit/UI/LadybirdWebViewBridge.cpp | 2 +- Ladybird/HelperProcess.cpp | 5 ++++- Ladybird/HelperProcess.h | 3 ++- Ladybird/Qt/BrowserWindow.cpp | 5 +++-- Ladybird/Qt/BrowserWindow.h | 3 ++- Ladybird/Qt/ConsoleWidget.cpp | 2 +- Ladybird/Qt/Tab.cpp | 4 ++-- Ladybird/Qt/Tab.h | 2 +- Ladybird/Qt/WebContentView.cpp | 5 +++-- Ladybird/Qt/WebContentView.h | 3 ++- Ladybird/Qt/main.cpp | 4 +++- Ladybird/WebContent/CMakeLists.txt | 4 ++++ Ladybird/WebContent/main.cpp | 7 ++++++ .../Libraries/LibWebView/ViewImplementation.h | 5 +++++ Userland/Services/WebContent/PageHost.cpp | 22 +++++++++++++++++-- Userland/Services/WebContent/PageHost.h | 2 ++ Userland/Utilities/headless-browser.cpp | 2 +- 17 files changed, 63 insertions(+), 17 deletions(-) diff --git a/Ladybird/AppKit/UI/LadybirdWebViewBridge.cpp b/Ladybird/AppKit/UI/LadybirdWebViewBridge.cpp index a22e530a094..8765f29be46 100644 --- a/Ladybird/AppKit/UI/LadybirdWebViewBridge.cpp +++ b/Ladybird/AppKit/UI/LadybirdWebViewBridge.cpp @@ -184,7 +184,7 @@ void WebViewBridge::create_client(WebView::EnableCallgrindProfiling enable_callg m_client_state = {}; auto candidate_web_content_paths = MUST(get_paths_for_helper_process("WebContent"sv)); - auto new_client = MUST(launch_web_content_process(*this, candidate_web_content_paths, enable_callgrind_profiling, WebView::IsLayoutTestMode::No, Ladybird::UseLagomNetworking::Yes)); + auto new_client = MUST(launch_web_content_process(*this, candidate_web_content_paths, enable_callgrind_profiling, WebView::IsLayoutTestMode::No, Ladybird::UseLagomNetworking::Yes, WebView::EnableGPUPainting::No)); m_client_state.client = new_client; m_client_state.client->on_web_content_process_crash = [this] { diff --git a/Ladybird/HelperProcess.cpp b/Ladybird/HelperProcess.cpp index b0b4990ff92..922ccd183c9 100644 --- a/Ladybird/HelperProcess.cpp +++ b/Ladybird/HelperProcess.cpp @@ -10,7 +10,8 @@ ErrorOr> launch_web_content_process(Web ReadonlySpan candidate_web_content_paths, WebView::EnableCallgrindProfiling enable_callgrind_profiling, WebView::IsLayoutTestMode is_layout_test_mode, - Ladybird::UseLagomNetworking use_lagom_networking) + Ladybird::UseLagomNetworking use_lagom_networking, + WebView::EnableGPUPainting enable_gpu_painting) { int socket_fds[2] {}; TRY(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds)); @@ -54,6 +55,8 @@ ErrorOr> launch_web_content_process(Web arguments.append("--layout-test-mode"sv); if (use_lagom_networking == Ladybird::UseLagomNetworking::Yes) arguments.append("--use-lagom-networking"sv); + if (enable_gpu_painting == WebView::EnableGPUPainting::Yes) + arguments.append("--use-gpu-painting"sv); result = Core::System::exec(arguments[0], arguments.span(), Core::System::SearchInPath::Yes); if (!result.is_error()) diff --git a/Ladybird/HelperProcess.h b/Ladybird/HelperProcess.h index 1f9e0925c66..d3da1bb7735 100644 --- a/Ladybird/HelperProcess.h +++ b/Ladybird/HelperProcess.h @@ -20,7 +20,8 @@ ErrorOr> launch_web_content_process(Web ReadonlySpan candidate_web_content_paths, WebView::EnableCallgrindProfiling, WebView::IsLayoutTestMode, - Ladybird::UseLagomNetworking); + Ladybird::UseLagomNetworking, + WebView::EnableGPUPainting); ErrorOr> launch_image_decoder_process(ReadonlySpan candidate_image_decoder_paths); ErrorOr> launch_request_server_process(ReadonlySpan candidate_request_server_paths, StringView serenity_resource_root); diff --git a/Ladybird/Qt/BrowserWindow.cpp b/Ladybird/Qt/BrowserWindow.cpp index 345b4df3cdc..2131424db92 100644 --- a/Ladybird/Qt/BrowserWindow.cpp +++ b/Ladybird/Qt/BrowserWindow.cpp @@ -41,11 +41,12 @@ static QIcon const& app_icon() return icon; } -BrowserWindow::BrowserWindow(Vector const& initial_urls, WebView::CookieJar& cookie_jar, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling, UseLagomNetworking use_lagom_networking) +BrowserWindow::BrowserWindow(Vector const& initial_urls, WebView::CookieJar& cookie_jar, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling, UseLagomNetworking use_lagom_networking, WebView::EnableGPUPainting use_gpu_painting) : m_cookie_jar(cookie_jar) , m_webdriver_content_ipc_path(webdriver_content_ipc_path) , m_enable_callgrind_profiling(enable_callgrind_profiling) , m_use_lagom_networking(use_lagom_networking) + , m_use_gpu_painting(use_gpu_painting) { setWindowIcon(app_icon()); m_tabs_container = new QTabWidget(this); @@ -462,7 +463,7 @@ Tab& BrowserWindow::new_tab(StringView html, Web::HTML::ActivateTab activate_tab Tab& BrowserWindow::create_new_tab(Web::HTML::ActivateTab activate_tab) { - auto tab = make(this, m_webdriver_content_ipc_path, m_enable_callgrind_profiling, m_use_lagom_networking); + auto tab = make(this, m_webdriver_content_ipc_path, m_enable_callgrind_profiling, m_use_lagom_networking, m_use_gpu_painting); auto tab_ptr = tab.ptr(); m_tabs.append(std::move(tab)); diff --git a/Ladybird/Qt/BrowserWindow.h b/Ladybird/Qt/BrowserWindow.h index 1a72efd7f93..e10f9ba6933 100644 --- a/Ladybird/Qt/BrowserWindow.h +++ b/Ladybird/Qt/BrowserWindow.h @@ -25,7 +25,7 @@ class WebContentView; class BrowserWindow : public QMainWindow { Q_OBJECT public: - explicit BrowserWindow(Vector const& initial_urls, WebView::CookieJar&, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling, UseLagomNetworking); + explicit BrowserWindow(Vector const& initial_urls, WebView::CookieJar&, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling, UseLagomNetworking, WebView::EnableGPUPainting); WebContentView& view() const { return m_current_tab->view(); } @@ -121,6 +121,7 @@ private: StringView m_webdriver_content_ipc_path; WebView::EnableCallgrindProfiling m_enable_callgrind_profiling; UseLagomNetworking m_use_lagom_networking; + WebView::EnableGPUPainting m_use_gpu_painting; }; } diff --git a/Ladybird/Qt/ConsoleWidget.cpp b/Ladybird/Qt/ConsoleWidget.cpp index baaed6370db..ac7cbe73347 100644 --- a/Ladybird/Qt/ConsoleWidget.cpp +++ b/Ladybird/Qt/ConsoleWidget.cpp @@ -25,7 +25,7 @@ ConsoleWidget::ConsoleWidget(WebContentView& content_view) { setLayout(new QVBoxLayout); - m_output_view = new WebContentView({}, WebView::EnableCallgrindProfiling::No, UseLagomNetworking::No); + m_output_view = new WebContentView({}, WebView::EnableCallgrindProfiling::No, UseLagomNetworking::No, WebView::EnableGPUPainting::No); if (is_using_dark_system_theme(*this)) m_output_view->update_palette(WebContentView::PaletteMode::Dark); diff --git a/Ladybird/Qt/Tab.cpp b/Ladybird/Qt/Tab.cpp index ef6cd34a17c..36bf5ba257b 100644 --- a/Ladybird/Qt/Tab.cpp +++ b/Ladybird/Qt/Tab.cpp @@ -51,7 +51,7 @@ static QIcon create_tvg_icon_with_theme_colors(QString name, QPalette const& pal return QIcon(icon_engine); } -Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling, UseLagomNetworking use_lagom_networking) +Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling, UseLagomNetworking use_lagom_networking, WebView::EnableGPUPainting enable_gpu_painting) : QWidget(window) , m_window(window) { @@ -59,7 +59,7 @@ Tab::Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView:: m_layout->setSpacing(0); m_layout->setContentsMargins(0, 0, 0, 0); - m_view = new WebContentView(webdriver_content_ipc_path, enable_callgrind_profiling, use_lagom_networking); + m_view = new WebContentView(webdriver_content_ipc_path, enable_callgrind_profiling, use_lagom_networking, enable_gpu_painting); m_toolbar = new QToolBar(this); m_location_edit = new LocationEdit(this); diff --git a/Ladybird/Qt/Tab.h b/Ladybird/Qt/Tab.h index 63733e08e28..128e103fcdc 100644 --- a/Ladybird/Qt/Tab.h +++ b/Ladybird/Qt/Tab.h @@ -28,7 +28,7 @@ class InspectorWidget; class Tab final : public QWidget { Q_OBJECT public: - Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling, UseLagomNetworking); + Tab(BrowserWindow* window, StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling, UseLagomNetworking, WebView::EnableGPUPainting); virtual ~Tab() override; WebContentView& view() { return *m_view; } diff --git a/Ladybird/Qt/WebContentView.cpp b/Ladybird/Qt/WebContentView.cpp index 9cb98ba8ca0..d1dad8ba494 100644 --- a/Ladybird/Qt/WebContentView.cpp +++ b/Ladybird/Qt/WebContentView.cpp @@ -52,8 +52,9 @@ namespace Ladybird { bool is_using_dark_system_theme(QWidget&); -WebContentView::WebContentView(StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling, UseLagomNetworking use_lagom_networking) +WebContentView::WebContentView(StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling enable_callgrind_profiling, UseLagomNetworking use_lagom_networking, WebView::EnableGPUPainting enable_gpu_painting) : m_use_lagom_networking(use_lagom_networking) + , m_use_gpu_painting(enable_gpu_painting) , m_webdriver_content_ipc_path(webdriver_content_ipc_path) { setMouseTracking(true); @@ -601,7 +602,7 @@ void WebContentView::create_client(WebView::EnableCallgrindProfiling enable_call m_client_state = {}; auto candidate_web_content_paths = get_paths_for_helper_process("WebContent"sv).release_value_but_fixme_should_propagate_errors(); - auto new_client = launch_web_content_process(*this, candidate_web_content_paths, enable_callgrind_profiling, WebView::IsLayoutTestMode::No, m_use_lagom_networking).release_value_but_fixme_should_propagate_errors(); + auto new_client = launch_web_content_process(*this, candidate_web_content_paths, enable_callgrind_profiling, WebView::IsLayoutTestMode::No, m_use_lagom_networking, m_use_gpu_painting).release_value_but_fixme_should_propagate_errors(); m_client_state.client = new_client; m_client_state.client->on_web_content_process_crash = [this] { diff --git a/Ladybird/Qt/WebContentView.h b/Ladybird/Qt/WebContentView.h index b35ce04ad10..01a778fedde 100644 --- a/Ladybird/Qt/WebContentView.h +++ b/Ladybird/Qt/WebContentView.h @@ -42,7 +42,7 @@ class WebContentView final , public WebView::ViewImplementation { Q_OBJECT public: - explicit WebContentView(StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling, UseLagomNetworking); + explicit WebContentView(StringView webdriver_content_ipc_path, WebView::EnableCallgrindProfiling, UseLagomNetworking, WebView::EnableGPUPainting); virtual ~WebContentView() override; Function on_tab_open_request; @@ -93,6 +93,7 @@ private: qreal m_inverse_pixel_scaling_ratio { 1.0 }; bool m_should_show_line_box_borders { false }; UseLagomNetworking m_use_lagom_networking {}; + WebView::EnableGPUPainting m_use_gpu_painting {}; Gfx::IntRect m_viewport_rect; diff --git a/Ladybird/Qt/main.cpp b/Ladybird/Qt/main.cpp index 2b81cbc2f83..861d4768923 100644 --- a/Ladybird/Qt/main.cpp +++ b/Ladybird/Qt/main.cpp @@ -75,6 +75,7 @@ ErrorOr serenity_main(Main::Arguments arguments) bool enable_callgrind_profiling = false; bool enable_sql_database = false; bool use_lagom_networking = false; + bool use_gpu_painting = false; Core::ArgsParser args_parser; args_parser.set_general_help("The Ladybird web browser :^)"); @@ -83,6 +84,7 @@ ErrorOr serenity_main(Main::Arguments arguments) args_parser.add_option(enable_callgrind_profiling, "Enable Callgrind profiling", "enable-callgrind-profiling", 'P'); args_parser.add_option(enable_sql_database, "Enable SQL database", "enable-sql-database", 0); args_parser.add_option(use_lagom_networking, "Enable Lagom servers for networking", "enable-lagom-networking", 0); + args_parser.add_option(use_gpu_painting, "Enable GPU painting", "enable-gpu-painting", 0); args_parser.parse(arguments); RefPtr database; @@ -106,7 +108,7 @@ ErrorOr serenity_main(Main::Arguments arguments) initial_urls.append(MUST(ak_string_from_qstring(new_tab_page))); } - Ladybird::BrowserWindow window(initial_urls, cookie_jar, webdriver_content_ipc_path, enable_callgrind_profiling ? WebView::EnableCallgrindProfiling::Yes : WebView::EnableCallgrindProfiling::No, use_lagom_networking ? Ladybird::UseLagomNetworking::Yes : Ladybird::UseLagomNetworking::No); + Ladybird::BrowserWindow window(initial_urls, cookie_jar, webdriver_content_ipc_path, enable_callgrind_profiling ? WebView::EnableCallgrindProfiling::Yes : WebView::EnableCallgrindProfiling::No, use_lagom_networking ? Ladybird::UseLagomNetworking::Yes : Ladybird::UseLagomNetworking::No, use_gpu_painting ? WebView::EnableGPUPainting::Yes : WebView::EnableGPUPainting::No); window.setWindowTitle("Ladybird"); if (Ladybird::Settings::the()->is_maximized()) { diff --git a/Ladybird/WebContent/CMakeLists.txt b/Ladybird/WebContent/CMakeLists.txt index 7ef55238dbb..a400238108b 100644 --- a/Ladybird/WebContent/CMakeLists.txt +++ b/Ladybird/WebContent/CMakeLists.txt @@ -76,3 +76,7 @@ if (HAVE_PULSEAUDIO) target_compile_definitions(webcontent PRIVATE HAVE_PULSEAUDIO=1) endif() endif() + +if (LINUX) + target_link_libraries(WebContent PRIVATE LibAccelGfx) +endif() diff --git a/Ladybird/WebContent/main.cpp b/Ladybird/WebContent/main.cpp index e6633e9d53b..ddbef5b05c7 100644 --- a/Ladybird/WebContent/main.cpp +++ b/Ladybird/WebContent/main.cpp @@ -73,13 +73,20 @@ ErrorOr serenity_main(Main::Arguments arguments) int webcontent_fd_passing_socket { -1 }; bool is_layout_test_mode = false; bool use_lagom_networking = false; + bool use_gpu_painting = false; Core::ArgsParser args_parser; args_parser.add_option(webcontent_fd_passing_socket, "File descriptor of the passing socket for the WebContent connection", "webcontent-fd-passing-socket", 'c', "webcontent_fd_passing_socket"); args_parser.add_option(is_layout_test_mode, "Is layout test mode", "layout-test-mode", 0); args_parser.add_option(use_lagom_networking, "Enable Lagom servers for networking", "use-lagom-networking", 0); + args_parser.add_option(use_gpu_painting, "Enable GPU painting", "use-gpu-painting", 0); + args_parser.parse(arguments); + if (use_gpu_painting) { + WebContent::PageHost::set_use_gpu_painter(); + } + #if defined(HAVE_QT) if (!use_lagom_networking) { Web::ResourceLoader::initialize(Ladybird::RequestManagerQt::create()); diff --git a/Userland/Libraries/LibWebView/ViewImplementation.h b/Userland/Libraries/LibWebView/ViewImplementation.h index 9567a472bc6..7729d710867 100644 --- a/Userland/Libraries/LibWebView/ViewImplementation.h +++ b/Userland/Libraries/LibWebView/ViewImplementation.h @@ -25,6 +25,11 @@ enum class EnableCallgrindProfiling { Yes }; +enum class EnableGPUPainting { + No, + Yes +}; + enum class IsLayoutTestMode { No, Yes diff --git a/Userland/Services/WebContent/PageHost.cpp b/Userland/Services/WebContent/PageHost.cpp index 52c39e9d18b..b33b3cf6848 100644 --- a/Userland/Services/WebContent/PageHost.cpp +++ b/Userland/Services/WebContent/PageHost.cpp @@ -21,6 +21,10 @@ #include #include +#ifdef AK_OS_LINUX +# include +#endif + namespace WebContent { PageHost::PageHost(ConnectionFromClient& client) @@ -36,6 +40,13 @@ PageHost::PageHost(ConnectionFromClient& client) PageHost::~PageHost() = default; +static bool s_use_gpu_painter = false; + +void PageHost::set_use_gpu_painter() +{ + s_use_gpu_painter = true; +} + void PageHost::set_has_focus(bool has_focus) { m_has_focus = has_focus; @@ -145,8 +156,15 @@ void PageHost::paint(Web::DevicePixelRect const& content_rect, Gfx::Bitmap& targ context.set_has_focus(m_has_focus); document->paintable()->paint_all_phases(context); - Web::Painting::PaintingCommandExecutorCPU painting_command_executor(target); - recording_painter.execute(painting_command_executor); + if (s_use_gpu_painter) { +#ifdef AK_OS_LINUX + Web::Painting::PaintingCommandExecutorGPU painting_command_executor(target); + recording_painter.execute(painting_command_executor); +#endif + } else { + Web::Painting::PaintingCommandExecutorCPU painting_command_executor(target); + recording_painter.execute(painting_command_executor); + } } void PageHost::set_viewport_rect(Web::DevicePixelRect const& rect) diff --git a/Userland/Services/WebContent/PageHost.h b/Userland/Services/WebContent/PageHost.h index 0042baa9906..407d7320da1 100644 --- a/Userland/Services/WebContent/PageHost.h +++ b/Userland/Services/WebContent/PageHost.h @@ -24,6 +24,8 @@ public: static NonnullOwnPtr create(ConnectionFromClient& client) { return adopt_own(*new PageHost(client)); } virtual ~PageHost(); + static void set_use_gpu_painter(); + virtual Web::Page& page() override { return *m_page; } virtual Web::Page const& page() const override { return *m_page; } diff --git a/Userland/Utilities/headless-browser.cpp b/Userland/Utilities/headless-browser.cpp index 0887921247c..4b15836978e 100644 --- a/Userland/Utilities/headless-browser.cpp +++ b/Userland/Utilities/headless-browser.cpp @@ -60,7 +60,7 @@ public: (void)is_layout_test_mode; #else auto candidate_web_content_paths = TRY(get_paths_for_helper_process("WebContent"sv)); - view->m_client_state.client = TRY(launch_web_content_process(*view, candidate_web_content_paths, WebView::EnableCallgrindProfiling::No, is_layout_test_mode, Ladybird::UseLagomNetworking::No)); + view->m_client_state.client = TRY(launch_web_content_process(*view, candidate_web_content_paths, WebView::EnableCallgrindProfiling::No, is_layout_test_mode, Ladybird::UseLagomNetworking::No, WebView::EnableGPUPainting::No)); #endif view->client().async_update_system_theme(move(theme));