From a4cc0703d1b789a63a12dfe52b8774c1b53ae3b6 Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Tue, 15 Apr 2025 02:07:47 +0200 Subject: [PATCH] LibGfx: Make Skia surface construction/destruction thread-safe With this change we ensure that Skia surfaces are allowed to be created or destroyed only by one thread at a time. Not enforcing this before resulted in "Single owner failure." assertion crashes in debug mode on pages with canvas elements. --- Libraries/LibGfx/PaintingSurface.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/Libraries/LibGfx/PaintingSurface.cpp b/Libraries/LibGfx/PaintingSurface.cpp index ab8f7d0399d..e364dd105ed 100644 --- a/Libraries/LibGfx/PaintingSurface.cpp +++ b/Libraries/LibGfx/PaintingSurface.cpp @@ -40,8 +40,10 @@ NonnullRefPtr PaintingSurface::create_with_size(RefPtr(context, size, surface, bitmap))); } + context->lock(); auto surface = SkSurfaces::RenderTarget(context->sk_context(), skgpu::Budgeted::kNo, image_info); VERIFY(surface); + context->unlock(); return adopt_ref(*new PaintingSurface(make(context, size, surface, nullptr))); } @@ -58,6 +60,11 @@ NonnullRefPtr PaintingSurface::wrap_bitmap(Bitmap& bitmap) #ifdef AK_OS_MACOS NonnullRefPtr PaintingSurface::wrap_iosurface(Core::IOSurfaceHandle const& iosurface_handle, RefPtr context, Origin origin) { + context->lock(); + ScopeGuard unlock_guard([&context] { + context->unlock(); + }); + auto metal_texture = context->metal_context().create_texture_from_iosurface(iosurface_handle); IntSize const size { metal_texture->width(), metal_texture->height() }; auto image_info = SkImageInfo::Make(size.width(), size.height(), kBGRA_8888_SkColorType, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()); @@ -85,7 +92,12 @@ PaintingSurface::PaintingSurface(NonnullOwnPtr&& impl) { } -PaintingSurface::~PaintingSurface() = default; +PaintingSurface::~PaintingSurface() +{ + lock_context(); + m_impl->surface = nullptr; + unlock_context(); +} void PaintingSurface::read_into_bitmap(Bitmap& bitmap) { @@ -127,7 +139,9 @@ SkSurface& PaintingSurface::sk_surface() const void PaintingSurface::notify_content_will_change() { + lock_context(); m_impl->surface->notifyContentWillChange(SkSurface::kDiscard_ContentChangeMode); + unlock_context(); } template<>