Skip to content

Commit

Permalink
[Skia] Add support for favicons on GTK
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=270811

Reviewed by Carlos Garcia Campos.

* Source/WebCore/PlatformGTK.cmake:
* Source/WebCore/SourcesGTK.txt:
* Source/WebCore/platform/graphics/gtk/GdkSkiaUtilities.cpp: Added.
(WebCore::skiaImageToGdkTexture):
* Source/WebCore/platform/graphics/gtk/GdkSkiaUtilities.h: Added.
* Source/WebKit/UIProcess/API/glib/WebKitFaviconDatabase.cpp:
(webkitFaviconDatabaseGetFaviconInternal):
(webkit_favicon_database_get_favicon_finish):

Canonical link: https://commits.webkit.org/275982@main
  • Loading branch information
TingPing committed Mar 12, 2024
1 parent 7617085 commit e9c4929
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 8 deletions.
1 change: 1 addition & 0 deletions Source/WebCore/PlatformGTK.cmake
Expand Up @@ -57,6 +57,7 @@ list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
platform/graphics/gbm/PlatformDisplayGBM.h

platform/graphics/gtk/GdkCairoUtilities.h
platform/graphics/gtk/GdkSkiaUtilities.h

platform/graphics/x11/PlatformDisplayX11.h
platform/graphics/x11/XErrorTrapper.h
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/SourcesGTK.txt
Expand Up @@ -70,6 +70,7 @@ platform/graphics/gbm/PlatformDisplayGBM.cpp @no-unify

platform/graphics/gtk/ColorGtk.cpp
platform/graphics/gtk/GdkCairoUtilities.cpp
platform/graphics/gtk/GdkSkiaUtilities.cpp
platform/graphics/gtk/ImageAdapterGtk.cpp
platform/graphics/gtk/SystemFontDatabaseGTK.cpp

Expand Down
78 changes: 78 additions & 0 deletions Source/WebCore/platform/graphics/gtk/GdkSkiaUtilities.cpp
@@ -0,0 +1,78 @@
/*
* Copyright (C) 2024 Igalia S.L.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "config.h"
#include "GdkSkiaUtilities.h"

#if USE(SKIA)

#if !USE(GTK4)
#include <graphics/cairo/RefPtrCairo.h>
#endif

IGNORE_CLANG_WARNINGS_BEGIN("cast-align")
#include <skia/core/SkPixmap.h>
IGNORE_CLANG_WARNINGS_END

namespace WebCore {

#if USE(GTK4)
GRefPtr<GdkTexture> skiaImageToGdkTexture(SkImage& image)
{
SkPixmap pixmap;
if (!image.peekPixels(&pixmap))
return { };

GRefPtr<GBytes> bytes = adoptGRef(g_bytes_new_with_free_func(pixmap.addr(), pixmap.computeByteSize(), [](gpointer data) {
static_cast<SkImage*>(data)->unref();
}, SkRef(&image)));

return adoptGRef(gdk_memory_texture_new(pixmap.width(), pixmap.height(), GDK_MEMORY_DEFAULT, bytes.get(), pixmap.rowBytes()));
}

#else

RefPtr<cairo_surface_t> skiaImageToCairoSurface(SkImage& image)
{
SkPixmap pixmap;
if (!image.peekPixels(&pixmap))
return { };

RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create_for_data(pixmap.writable_addr8(0, 0), CAIRO_FORMAT_ARGB32, pixmap.width(), pixmap.height(), pixmap.rowBytes()));
if (cairo_surface_status(surface.get()) != CAIRO_STATUS_SUCCESS)
return { };

static cairo_user_data_key_t surfaceDataKey;
cairo_surface_set_user_data(surface.get(), &surfaceDataKey, SkRef(&image), [](void* data) {
static_cast<SkImage*>(data)->unref();
});

return surface;
}
#endif

} // namespace WebCore

#endif // #if USE(SKIA)
49 changes: 49 additions & 0 deletions Source/WebCore/platform/graphics/gtk/GdkSkiaUtilities.h
@@ -0,0 +1,49 @@
/*
* Copyright (C) 2024 Igalia S.L.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#pragma once

#if USE(SKIA)

#include <skia/core/SkImage.h>
#include <wtf/glib/GRefPtr.h>

#if USE(GTK4)
#include <gdk/gdk.h>
#else
#include <cairo.h>
#endif

namespace WebCore {

#if USE(GTK4)
GRefPtr<GdkTexture> skiaImageToGdkTexture(SkImage&);
#else
RefPtr<cairo_surface_t> skiaImageToCairoSurface(SkImage&);
#endif

}

#endif // USE(SKIA)
25 changes: 17 additions & 8 deletions Source/WebKit/UIProcess/API/glib/WebKitFaviconDatabase.cpp
Expand Up @@ -36,6 +36,7 @@

#if PLATFORM(GTK)
#include <WebCore/GdkCairoUtilities.h>
#include <WebCore/GdkSkiaUtilities.h>
#include <WebCore/RefPtrCairo.h>
#endif

Expand Down Expand Up @@ -187,21 +188,22 @@ void webkitFaviconDatabaseGetFaviconInternal(WebKitFaviconDatabase* database, co
}

GRefPtr<GTask> task = adoptGRef(g_task_new(database, cancellable, callback, userData));
#if USE(CAIRO)
WebKitFaviconDatabasePrivate* priv = database->priv;
priv->iconDatabase->loadIconForPageURL(String::fromUTF8(pageURI), isEphemeral ? IconDatabase::AllowDatabaseWrite::No : IconDatabase::AllowDatabaseWrite::Yes,
[task = WTFMove(task), pageURI = CString(pageURI)](RefPtr<cairo_surface_t>&& icon) {
[task = WTFMove(task), pageURI = CString(pageURI)](PlatformImagePtr&& icon) {
if (!icon) {
g_task_return_new_error(task.get(), WEBKIT_FAVICON_DATABASE_ERROR, WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_UNKNOWN,
_("Unknown favicon for page %s"), pageURI.data());
return;
}
#if USE(CAIRO)
g_task_return_pointer(task.get(), icon.leakRef(), reinterpret_cast<GDestroyNotify>(cairo_surface_destroy));
});
#elif USE(SKIA)
notImplemented();
g_task_return_new_error(task.get(), WEBKIT_FAVICON_DATABASE_ERROR, WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_UNKNOWN, _("Unknown favicon for page %s"), pageURI);
g_task_return_pointer(task.get(), SkRef(icon.get()), [](gpointer data) {
static_cast<SkImage*>(data)->unref();
});
#endif
});
}

/**
Expand Down Expand Up @@ -254,18 +256,25 @@ cairo_surface_t* webkit_favicon_database_get_favicon_finish(WebKitFaviconDatabas
#if USE(CAIRO)
auto image = adoptRef(static_cast<cairo_surface_t*>(g_task_propagate_pointer(G_TASK(result), error)));
auto texture = image ? cairoSurfaceToGdkTexture(image.get()) : nullptr;
if (texture)
return texture.leakRef();
#elif USE(SKIA)
notImplemented();
auto* image = static_cast<SkImage*>(g_task_propagate_pointer(G_TASK(result), error));
auto texture = image ? skiaImageToGdkTexture(*image) : nullptr;
#endif

if (texture)
return texture.leakRef();
// FIXME: Add a new WEBKIT_FAVICON_DATABASE_ERROR
if (error && !*error)
g_set_error_literal(error, WEBKIT_FAVICON_DATABASE_ERROR, WEBKIT_FAVICON_DATABASE_ERROR_FAVICON_UNKNOWN, _("Failed to create texture"));
return nullptr;
#else
#if USE(SKIA)
auto* image = static_cast<SkImage*>(g_task_propagate_pointer(G_TASK(result), error));
return image ? skiaImageToCairoSurface(*image).leakRef() : nullptr;
#else
return static_cast<cairo_surface_t*>(g_task_propagate_pointer(G_TASK(result), error));
#endif
#endif
}
#endif

Expand Down

0 comments on commit e9c4929

Please sign in to comment.