Skip to content

Commit

Permalink
[GTK][Skia] Add support for non-accelerated rendering
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=270788

Reviewed by Adrian Perez de Castro.

GTK uses cairo for non-accelerated rendering, so we need to render the
ShareableBitmap with skia, but into a cairo surface.

* Source/WebCore/platform/graphics/skia/ShareableBitmapSkia.cpp:
(WebCore::ShareableBitmap::paint):
* Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp:
(WebKit::BackingStore::incorporateUpdate):
(WebKit::BackingStore::scroll):

Canonical link: https://commits.webkit.org/276018@main
  • Loading branch information
carlosgcampos committed Mar 13, 2024
1 parent 8efe423 commit 015bce0
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 8 deletions.
9 changes: 7 additions & 2 deletions Source/WebCore/platform/graphics/skia/ShareableBitmapSkia.cpp
Expand Up @@ -62,9 +62,14 @@ void ShareableBitmap::paint(GraphicsContext& context, const IntPoint& dstPoint,
paint(context, 1, dstPoint, srcRect);
}

void ShareableBitmap::paint(GraphicsContext&, float /*scaleFactor*/, const IntPoint&, const IntRect&)
void ShareableBitmap::paint(GraphicsContext& context, float scaleFactor, const IntPoint& dstPoint, const IntRect& srcRect)
{
notImplemented();
FloatRect scaledSrcRect(srcRect);
scaledSrcRect.scale(scaleFactor);
FloatRect scaledDestRect(dstPoint, srcRect.size());
scaledDestRect.scale(scaleFactor);
auto image = createPlatformImage(BackingStoreCopy::DontCopyBackingStore);
context.platformContext()->drawImageRect(image.get(), scaledSrcRect, scaledDestRect, { }, nullptr, { });
}

RefPtr<Image> ShareableBitmap::createImage()
Expand Down
38 changes: 32 additions & 6 deletions Source/WebKit/UIProcess/cairo/BackingStoreCairo.cpp
Expand Up @@ -40,6 +40,12 @@
#include <WebCore/GraphicsContextCairo.h>
#endif

#if USE(SKIA)
#include <WebCore/GraphicsContextSkia.h>
#include <skia/core/SkCanvas.h>
#include <skia/core/SkSurface.h>
#endif

namespace WebKit {
using namespace WebCore;

Expand Down Expand Up @@ -99,9 +105,10 @@ void BackingStore::incorporateUpdate(UpdateInfo&& updateInfo)

scroll(updateInfo.scrollRect, updateInfo.scrollOffset);

#if USE(CAIRO)
// Paint all update rects.
IntPoint updateRectLocation = updateInfo.updateRectBounds.location();

#if USE(CAIRO)
GraphicsContextCairo graphicsContext(m_surface.get());

// When m_webPageProxy.drawsBackground() is false, bitmap contains transparent parts as a background of the webpage.
Expand All @@ -114,7 +121,20 @@ void BackingStore::incorporateUpdate(UpdateInfo&& updateInfo)
bitmap->paint(graphicsContext, m_deviceScaleFactor, updateRect.location(), srcRect);
}
#elif USE(SKIA)
notImplemented();
cairo_surface_flush(m_surface.get());
auto imageInfo = SkImageInfo::MakeN32Premul(cairo_image_surface_get_width(m_surface.get()), cairo_image_surface_get_height(m_surface.get()));
auto surface = SkSurfaces::WrapPixels(imageInfo, cairo_image_surface_get_data(m_surface.get()), cairo_image_surface_get_stride(m_surface.get()), nullptr);
GraphicsContextSkia graphicsContext(WTFMove(surface), RenderingMode::Unaccelerated, RenderingPurpose::ShareableLocalSnapshot);
graphicsContext.setCompositeOperation(WebCore::CompositeOperator::Copy);
for (const auto& updateRect : updateInfo.updateRects) {
IntRect srcRect(updateRect);
srcRect.move(-updateRectLocation.x(), -updateRectLocation.y());
bitmap->paint(graphicsContext, m_deviceScaleFactor, updateRect.location(), srcRect);

IntRect damage(updateRect.location(), srcRect.size());
damage.scale(m_deviceScaleFactor);
cairo_surface_mark_dirty_rectangle(m_surface.get(), damage.x(), damage.y(), damage.width(), damage.height());
}
#endif
}

Expand All @@ -132,12 +152,18 @@ void BackingStore::scroll(const IntRect& scrollRect, const IntSize& scrollOffset
if (!m_scrollSurface)
m_scrollSurface = createCairoImageSurfaceWithFastMalloc(m_size, m_deviceScaleFactor);

#if USE(CAIRO)
#if USE(SKIA)
auto copyRectFromOneSurfaceToAnother = [](cairo_surface_t* src, cairo_surface_t* dst, const IntSize& sourceOffset, const IntRect& rect) {
RefPtr<cairo_t> cr = adoptRef(cairo_create(dst));
cairo_set_operator(cr.get(), CAIRO_OPERATOR_SOURCE);
cairo_set_source_surface(cr.get(), src, sourceOffset.width(), sourceOffset.height());
cairo_rectangle(cr.get(), rect.x(), rect.y(), rect.width(), rect.height());
cairo_fill(cr.get());
};
#endif

copyRectFromOneSurfaceToAnother(m_surface.get(), m_scrollSurface.get(), scrollOffset, targetRect);
copyRectFromOneSurfaceToAnother(m_scrollSurface.get(), m_surface.get(), { }, targetRect);
#elif USE(SKIA)
// FIXME: move copyRectFromOneSurfaceToAnother to a different file if we really need this with skia.
#endif
m_scrolledHysteresis.impulse();
}

Expand Down

0 comments on commit 015bce0

Please sign in to comment.