From cd7262ee5623aa7b4571ef121139002827fe9965 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 16 Sep 2022 15:01:47 +0200 Subject: [PATCH] LibWeb+LibWebView+WebContent: Add Web::Platform::ImageCodecPlugin This replaces the previous Web::ImageDecoding::Decoder interface. While we're doing this, also move the SerenityOS implementation of this interface from LibWebView to WebContent. That means we no longer have to link with LibImageDecoderClient in applications that use a web view. --- Userland/Libraries/LibWeb/CMakeLists.txt | 2 +- .../Libraries/LibWeb/HTML/HTMLLinkElement.cpp | 4 +-- Userland/Libraries/LibWeb/ImageDecoding.cpp | 32 ------------------- .../Libraries/LibWeb/Loader/FrameLoader.cpp | 6 ++-- .../Libraries/LibWeb/Loader/ImageResource.cpp | 4 +-- .../LibWeb/Platform/ImageCodecPlugin.cpp | 28 ++++++++++++++++ .../ImageCodecPlugin.h} | 17 ++++------ Userland/Libraries/LibWebView/CMakeLists.txt | 3 +- .../LibWebView/ImageDecoderClientAdapter.h | 32 ------------------- Userland/Services/WebContent/CMakeLists.txt | 3 +- .../WebContent/ImageCodecPluginSerenity.cpp} | 15 ++++----- .../WebContent/ImageCodecPluginSerenity.h | 30 +++++++++++++++++ Userland/Services/WebContent/main.cpp | 5 ++- Userland/Utilities/headless-browser.cpp | 27 ++++++---------- 14 files changed, 95 insertions(+), 113 deletions(-) delete mode 100644 Userland/Libraries/LibWeb/ImageDecoding.cpp create mode 100644 Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.cpp rename Userland/Libraries/LibWeb/{ImageDecoding.h => Platform/ImageCodecPlugin.h} (59%) delete mode 100644 Userland/Libraries/LibWebView/ImageDecoderClientAdapter.h rename Userland/{Libraries/LibWebView/ImageDecoderClientAdapter.cpp => Services/WebContent/ImageCodecPluginSerenity.cpp} (66%) create mode 100644 Userland/Services/WebContent/ImageCodecPluginSerenity.h diff --git a/Userland/Libraries/LibWeb/CMakeLists.txt b/Userland/Libraries/LibWeb/CMakeLists.txt index 2037d55dfa..26ea86867b 100644 --- a/Userland/Libraries/LibWeb/CMakeLists.txt +++ b/Userland/Libraries/LibWeb/CMakeLists.txt @@ -268,7 +268,6 @@ set(SOURCES HTML/WorkerLocation.cpp HTML/WorkerNavigator.cpp HighResolutionTime/Performance.cpp - ImageDecoding.cpp Infra/ByteSequences.cpp IntersectionObserver/IntersectionObserver.cpp Layout/BlockContainer.cpp @@ -355,6 +354,7 @@ set(SOURCES Painting/TextPaintable.cpp Platform/EventLoopPlugin.cpp Platform/FontPlugin.cpp + Platform/ImageCodecPlugin.cpp Platform/Timer.cpp RequestIdleCallback/IdleDeadline.cpp ResizeObserver/ResizeObserver.cpp diff --git a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp index 9fd5d9024c..5b4d4158df 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLLinkElement.cpp @@ -12,9 +12,9 @@ #include #include #include -#include #include #include +#include namespace Web::HTML { @@ -156,7 +156,7 @@ bool HTMLLinkElement::load_favicon_and_use_if_window_is_active() return false; RefPtr favicon_bitmap; - auto decoded_image = Web::ImageDecoding::Decoder::the().decode_image(resource()->encoded_data()); + auto decoded_image = Platform::ImageCodecPlugin::the().decode_image(resource()->encoded_data()); if (!decoded_image.has_value() || decoded_image->frames.is_empty()) { dbgln("Could not decode favicon {}", resource()->url()); return false; diff --git a/Userland/Libraries/LibWeb/ImageDecoding.cpp b/Userland/Libraries/LibWeb/ImageDecoding.cpp deleted file mode 100644 index fc2aefee4e..0000000000 --- a/Userland/Libraries/LibWeb/ImageDecoding.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2021, Andreas Kling - * Copyright (c) 2022, Dex♪ - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#include - -namespace Web::ImageDecoding { - -static RefPtr s_decoder; - -Decoder::Decoder() = default; - -Decoder::~Decoder() = default; - -void Decoder::initialize(RefPtr&& decoder) -{ - s_decoder = move(decoder); -} - -Decoder& Decoder::the() -{ - if (!s_decoder) [[unlikely]] { - dbgln("Web::ImageDecoding::Decoder was not initialized!"); - VERIFY_NOT_REACHED(); - } - return *s_decoder; -} - -} diff --git a/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp b/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp index dd16be17db..f757ddd81e 100644 --- a/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp +++ b/Userland/Libraries/LibWeb/Loader/FrameLoader.cpp @@ -19,10 +19,10 @@ #include #include #include -#include #include #include #include +#include #include namespace Web { @@ -82,7 +82,7 @@ static bool build_text_document(DOM::Document& document, ByteBuffer const& data) static bool build_image_document(DOM::Document& document, ByteBuffer const& data) { - auto image = ImageDecoding::Decoder::the().decode_image(data); + auto image = Platform::ImageCodecPlugin::the().decode_image(data); if (!image.has_value() || image->frames.is_empty()) return false; auto const& frame = image->frames[0]; @@ -215,7 +215,7 @@ bool FrameLoader::load(LoadRequest& request, Type type) if (data.is_empty()) return; RefPtr favicon_bitmap; - auto decoded_image = ImageDecoding::Decoder::the().decode_image(data); + auto decoded_image = Platform::ImageCodecPlugin::the().decode_image(data); if (!decoded_image.has_value() || decoded_image->frames.is_empty()) { dbgln("Could not decode favicon {}", favicon_url); } else { diff --git a/Userland/Libraries/LibWeb/Loader/ImageResource.cpp b/Userland/Libraries/LibWeb/Loader/ImageResource.cpp index ac2704f4c4..25a60753d5 100644 --- a/Userland/Libraries/LibWeb/Loader/ImageResource.cpp +++ b/Userland/Libraries/LibWeb/Loader/ImageResource.cpp @@ -6,8 +6,8 @@ #include #include -#include #include +#include namespace Web { @@ -47,7 +47,7 @@ void ImageResource::decode_if_needed() const if (!m_decoded_frames.is_empty()) return; - auto image = ImageDecoding::Decoder::the().decode_image(encoded_data()); + auto image = Platform::ImageCodecPlugin::the().decode_image(encoded_data()); if (image.has_value()) { m_loop_count = image.value().loop_count; diff --git a/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.cpp b/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.cpp new file mode 100644 index 0000000000..5405734961 --- /dev/null +++ b/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.cpp @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2021-2022, Andreas Kling + * Copyright (c) 2022, Dex♪ + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include + +namespace Web::Platform { + +static ImageCodecPlugin* s_the; + +ImageCodecPlugin::~ImageCodecPlugin() = default; + +ImageCodecPlugin& ImageCodecPlugin::the() +{ + VERIFY(s_the); + return *s_the; +} + +void ImageCodecPlugin::install(ImageCodecPlugin& plugin) +{ + VERIFY(!s_the); + s_the = &plugin; +} + +} diff --git a/Userland/Libraries/LibWeb/ImageDecoding.h b/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.h similarity index 59% rename from Userland/Libraries/LibWeb/ImageDecoding.h rename to Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.h index 2c462aae2c..c26f61114d 100644 --- a/Userland/Libraries/LibWeb/ImageDecoding.h +++ b/Userland/Libraries/LibWeb/Platform/ImageCodecPlugin.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020-2021, Andreas Kling + * Copyright (c) 2020-2022, Andreas Kling * Copyright (c) 2022, Dex♪ * * SPDX-License-Identifier: BSD-2-Clause @@ -9,9 +9,9 @@ #include #include -#include +#include -namespace Web::ImageDecoding { +namespace Web::Platform { struct Frame { RefPtr bitmap; @@ -24,17 +24,14 @@ struct DecodedImage { Vector frames; }; -class Decoder : public RefCounted { +class ImageCodecPlugin { public: - virtual ~Decoder(); + static ImageCodecPlugin& the(); + static void install(ImageCodecPlugin&); - static void initialize(RefPtr&&); - static Decoder& the(); + virtual ~ImageCodecPlugin(); virtual Optional decode_image(ReadonlyBytes) = 0; - -protected: - explicit Decoder(); }; } diff --git a/Userland/Libraries/LibWebView/CMakeLists.txt b/Userland/Libraries/LibWebView/CMakeLists.txt index 64aa178e56..6b2aa60744 100644 --- a/Userland/Libraries/LibWebView/CMakeLists.txt +++ b/Userland/Libraries/LibWebView/CMakeLists.txt @@ -1,6 +1,5 @@ set(SOURCES DOMTreeModel.cpp - ImageDecoderClientAdapter.cpp OutOfProcessWebView.cpp RequestServerAdapter.cpp StylePropertiesModel.cpp @@ -16,6 +15,6 @@ set(GENERATED_SOURCES ) serenity_lib(LibWebView webview) -target_link_libraries(LibWebView LibFileSystemAccessClient LibGfx LibGUI LibImageDecoderClient LibIPC LibProtocol LibWeb) +target_link_libraries(LibWebView LibFileSystemAccessClient LibGfx LibGUI LibIPC LibProtocol LibWeb) add_subdirectory(DumpLayoutTree) diff --git a/Userland/Libraries/LibWebView/ImageDecoderClientAdapter.h b/Userland/Libraries/LibWebView/ImageDecoderClientAdapter.h deleted file mode 100644 index e46b0e6974..0000000000 --- a/Userland/Libraries/LibWebView/ImageDecoderClientAdapter.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2022, Dex♪ - * - * SPDX-License-Identifier: BSD-2-Clause - */ - -#pragma once - -#include -#include - -namespace ImageDecoderClient { -class Client; -} - -namespace WebView { - -class ImageDecoderClientAdapter : public Web::ImageDecoding::Decoder { -public: - static NonnullRefPtr create(); - - virtual ~ImageDecoderClientAdapter() override = default; - - virtual Optional decode_image(ReadonlyBytes) override; - -private: - explicit ImageDecoderClientAdapter() = default; - - RefPtr m_client; -}; - -} diff --git a/Userland/Services/WebContent/CMakeLists.txt b/Userland/Services/WebContent/CMakeLists.txt index 0a46963ba8..ca7b7395a8 100644 --- a/Userland/Services/WebContent/CMakeLists.txt +++ b/Userland/Services/WebContent/CMakeLists.txt @@ -12,6 +12,7 @@ set(SOURCES ConsoleGlobalObject.cpp EventLoopPluginSerenity.cpp FontPluginSerenity.cpp + ImageCodecPluginSerenity.cpp PageHost.cpp TimerSerenity.cpp WebContentClientEndpoint.h @@ -21,5 +22,5 @@ set(SOURCES ) serenity_bin(WebContent) -target_link_libraries(WebContent LibCore LibIPC LibGfx LibWebView LibWeb LibMain) +target_link_libraries(WebContent LibCore LibIPC LibGfx LibImageDecoderClient LibWebView LibWeb LibMain) link_with_locale_data(WebContent) diff --git a/Userland/Libraries/LibWebView/ImageDecoderClientAdapter.cpp b/Userland/Services/WebContent/ImageCodecPluginSerenity.cpp similarity index 66% rename from Userland/Libraries/LibWebView/ImageDecoderClientAdapter.cpp rename to Userland/Services/WebContent/ImageCodecPluginSerenity.cpp index 47fa6e1878..426cf5fb27 100644 --- a/Userland/Libraries/LibWebView/ImageDecoderClientAdapter.cpp +++ b/Userland/Services/WebContent/ImageCodecPluginSerenity.cpp @@ -1,20 +1,19 @@ /* * Copyright (c) 2022, Dex♪ + * Copyright (c) 2022, Andreas Kling * * SPDX-License-Identifier: BSD-2-Clause */ +#include "ImageCodecPluginSerenity.h" #include -#include -namespace WebView { +namespace WebContent { -NonnullRefPtr ImageDecoderClientAdapter::create() -{ - return adopt_ref(*new ImageDecoderClientAdapter()); -} +ImageCodecPluginSerenity::ImageCodecPluginSerenity() = default; +ImageCodecPluginSerenity::~ImageCodecPluginSerenity() = default; -Optional ImageDecoderClientAdapter::decode_image(ReadonlyBytes bytes) +Optional ImageCodecPluginSerenity::decode_image(ReadonlyBytes bytes) { if (!m_client) { m_client = ImageDecoderClient::Client::try_create().release_value_but_fixme_should_propagate_errors(); @@ -28,7 +27,7 @@ Optional ImageDecoderClientAdapter::decode_ima return {}; auto result = result_or_empty.release_value(); - Web::ImageDecoding::DecodedImage decoded_image; + Web::Platform::DecodedImage decoded_image; decoded_image.is_animated = result.is_animated; decoded_image.loop_count = result.loop_count; for (auto const& frame : result.frames) { diff --git a/Userland/Services/WebContent/ImageCodecPluginSerenity.h b/Userland/Services/WebContent/ImageCodecPluginSerenity.h new file mode 100644 index 0000000000..42d967b0f1 --- /dev/null +++ b/Userland/Services/WebContent/ImageCodecPluginSerenity.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022, Dex♪ + * Copyright (c) 2022, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include + +namespace ImageDecoderClient { +class Client; +} + +namespace WebContent { + +class ImageCodecPluginSerenity final : public Web::Platform::ImageCodecPlugin { +public: + ImageCodecPluginSerenity(); + virtual ~ImageCodecPluginSerenity() override; + + virtual Optional decode_image(ReadonlyBytes) override; + +private: + RefPtr m_client; +}; + +} diff --git a/Userland/Services/WebContent/main.cpp b/Userland/Services/WebContent/main.cpp index fccdf5380a..ce7c2c5266 100644 --- a/Userland/Services/WebContent/main.cpp +++ b/Userland/Services/WebContent/main.cpp @@ -6,16 +6,15 @@ #include "EventLoopPluginSerenity.h" #include "FontPluginSerenity.h" +#include "ImageCodecPluginSerenity.h" #include #include #include #include #include -#include #include #include #include -#include #include #include #include @@ -32,9 +31,9 @@ ErrorOr serenity_main(Main::Arguments) TRY(Core::System::unveil(nullptr, nullptr)); Web::Platform::EventLoopPlugin::install(*new WebContent::EventLoopPluginSerenity); + Web::Platform::ImageCodecPlugin::install(*new WebContent::ImageCodecPluginSerenity); Web::Platform::FontPlugin::install(*new WebContent::FontPluginSerenity); - Web::ImageDecoding::Decoder::initialize(WebView::ImageDecoderClientAdapter::create()); Web::WebSockets::WebSocketClientManager::initialize(TRY(WebView::WebSocketClientManagerAdapter::try_create())); Web::ResourceLoader::initialize(TRY(WebView::RequestServerAdapter::try_create())); diff --git a/Userland/Utilities/headless-browser.cpp b/Userland/Utilities/headless-browser.cpp index db0f2c5b7f..350d69be13 100644 --- a/Userland/Utilities/headless-browser.cpp +++ b/Userland/Utilities/headless-browser.cpp @@ -36,11 +36,11 @@ #include #include #include -#include #include #include #include #include +#include #include #include #include @@ -235,26 +235,22 @@ private: Web::CSS::PreferredColorScheme m_preferred_color_scheme { Web::CSS::PreferredColorScheme::Auto }; }; -class HeadlessImageDecoderClient : public Web::ImageDecoding::Decoder { +class ImageCodecPluginHeadless : public Web::Platform::ImageCodecPlugin { public: - static NonnullRefPtr create() - { - return adopt_ref(*new HeadlessImageDecoderClient()); - } + ImageCodecPluginHeadless() = default; + virtual ~ImageCodecPluginHeadless() override = default; - virtual ~HeadlessImageDecoderClient() override = default; - - virtual Optional decode_image(ReadonlyBytes data) override + virtual Optional decode_image(ReadonlyBytes data) override { auto decoder = Gfx::ImageDecoder::try_create(data); if (!decoder) - return Web::ImageDecoding::DecodedImage { false, 0, Vector {} }; + return Web::Platform::DecodedImage { false, 0, Vector {} }; if (!decoder->frame_count()) - return Web::ImageDecoding::DecodedImage { false, 0, Vector {} }; + return Web::Platform::DecodedImage { false, 0, Vector {} }; - Vector frames; + Vector frames; for (size_t i = 0; i < decoder->frame_count(); ++i) { auto frame_or_error = decoder->frame(i); if (frame_or_error.is_error()) { @@ -265,15 +261,12 @@ public: } } - return Web::ImageDecoding::DecodedImage { + return Web::Platform::DecodedImage { decoder->is_animated(), static_cast(decoder->loop_count()), frames, }; } - -private: - explicit HeadlessImageDecoderClient() = default; }; static HashTable> s_all_requests; @@ -675,7 +668,7 @@ ErrorOr serenity_main(Main::Arguments arguments) args_parser.add_positional_argument(url, "URL to open", "url", Core::ArgsParser::Required::Yes); args_parser.parse(arguments); - Web::ImageDecoding::Decoder::initialize(HeadlessImageDecoderClient::create()); + Web::Platform::ImageCodecPlugin::install(*new ImageCodecPluginHeadless); Web::ResourceLoader::initialize(HeadlessRequestServer::create()); Web::WebSockets::WebSocketClientManager::initialize(HeadlessWebSocketClientManager::create());