Jelajahi Sumber

LibWeb: Allow construction of PaintingSurface directly from IOSurface

Previously, constructing a PaintingSurface from an IOSurface required
wrapping IOSurface into a Metal texture before passing it to the
PaintingSurface constructor. This process was cumbersome, as the caller
needed access to a MetalContext to perform the wrapping.

With this change SkiaBackendContext maintains a reference to the
MetalContext which makes it possible to do:
IOSurface -> MetalTexture -> SkSurface within a PaintingSurface
constructor.
Aliaksandr Kalenik 8 bulan lalu
induk
melakukan
e683700fe6

+ 1 - 0
Libraries/LibGfx/Forward.h

@@ -28,6 +28,7 @@ class Palette;
 class PaletteImpl;
 class Path;
 class ShareableBitmap;
+class SkiaBackendContext;
 struct SystemTheme;
 
 template<typename T>

+ 4 - 2
Libraries/LibGfx/MetalContext.h

@@ -11,6 +11,8 @@ static_assert(false, "This file must only be used for macOS");
 #endif
 
 #include <AK/Forward.h>
+#include <AK/RefCounted.h>
+#include <AK/RefPtr.h>
 #include <LibCore/IOSurface.h>
 
 namespace Gfx {
@@ -24,7 +26,7 @@ public:
     virtual ~MetalTexture() {};
 };
 
-class MetalContext {
+class MetalContext : public RefCounted<MetalContext> {
 public:
     virtual void const* device() const = 0;
     virtual void const* queue() const = 0;
@@ -34,6 +36,6 @@ public:
     virtual ~MetalContext() {};
 };
 
-OwnPtr<MetalContext> get_metal_context();
+RefPtr<MetalContext> get_metal_context();
 
 }

+ 2 - 2
Libraries/LibGfx/MetalContext.mm

@@ -67,7 +67,7 @@ private:
     id<MTLCommandQueue> m_queue;
 };
 
-OwnPtr<MetalContext> get_metal_context()
+RefPtr<MetalContext> get_metal_context()
 {
     auto device = MTLCreateSystemDefaultDevice();
     if (!device) {
@@ -82,7 +82,7 @@ OwnPtr<MetalContext> get_metal_context()
         return {};
     }
 
-    return make<MetalContextImpl>(device, queue);
+    return adopt_ref(*new MetalContextImpl(device, queue));
 }
 
 }

+ 5 - 4
Libraries/LibGfx/PaintingSurface.cpp

@@ -56,13 +56,14 @@ NonnullRefPtr<PaintingSurface> PaintingSurface::wrap_bitmap(Bitmap& bitmap)
 }
 
 #ifdef AK_OS_MACOS
-NonnullRefPtr<PaintingSurface> PaintingSurface::wrap_metal_surface(Gfx::MetalTexture& metal_texture, RefPtr<SkiaBackendContext> context)
+NonnullRefPtr<PaintingSurface> PaintingSurface::wrap_iosurface(Core::IOSurfaceHandle const& iosurface_handle, RefPtr<SkiaBackendContext> context)
 {
-    IntSize const size { metal_texture.width(), metal_texture.height() };
+    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);
     GrMtlTextureInfo mtl_info;
-    mtl_info.fTexture = sk_ret_cfp(metal_texture.texture());
-    auto backend_render_target = GrBackendRenderTargets::MakeMtl(metal_texture.width(), metal_texture.height(), mtl_info);
+    mtl_info.fTexture = sk_ret_cfp(metal_texture->texture());
+    auto backend_render_target = GrBackendRenderTargets::MakeMtl(metal_texture->width(), metal_texture->height(), mtl_info);
     auto surface = SkSurfaces::WrapBackendRenderTarget(context->sk_context(), backend_render_target, kTopLeft_GrSurfaceOrigin, kBGRA_8888_SkColorType, nullptr, nullptr);
     return adopt_ref(*new PaintingSurface(make<Impl>(size, surface, nullptr, context)));
 }

+ 1 - 1
Libraries/LibGfx/PaintingSurface.h

@@ -28,7 +28,7 @@ public:
     static NonnullRefPtr<PaintingSurface> wrap_bitmap(Bitmap&);
 
 #ifdef AK_OS_MACOS
-    static NonnullRefPtr<PaintingSurface> wrap_metal_surface(Gfx::MetalTexture&, RefPtr<SkiaBackendContext>);
+    static NonnullRefPtr<PaintingSurface> wrap_iosurface(Core::IOSurfaceHandle const&, RefPtr<SkiaBackendContext>);
 #endif
 
     void read_into_bitmap(Bitmap&);

+ 11 - 5
Libraries/LibGfx/SkiaBackendContext.cpp

@@ -53,6 +53,8 @@ public:
 
     GrDirectContext* sk_context() const override { return m_context.get(); }
 
+    MetalContext& metal_context() override { VERIFY_NOT_REACHED(); }
+
 private:
     sk_sp<GrDirectContext> m_context;
     NonnullOwnPtr<skgpu::VulkanExtensions> m_extensions;
@@ -89,8 +91,9 @@ class SkiaMetalBackendContext final : public SkiaBackendContext {
     AK_MAKE_NONMOVABLE(SkiaMetalBackendContext);
 
 public:
-    SkiaMetalBackendContext(sk_sp<GrDirectContext> context)
+    SkiaMetalBackendContext(sk_sp<GrDirectContext> context, MetalContext& metal_context)
         : m_context(move(context))
+        , m_metal_context(move(metal_context))
     {
     }
 
@@ -105,17 +108,20 @@ public:
 
     GrDirectContext* sk_context() const override { return m_context.get(); }
 
+    MetalContext& metal_context() override { return m_metal_context; }
+
 private:
     sk_sp<GrDirectContext> m_context;
+    NonnullRefPtr<MetalContext> m_metal_context;
 };
 
-RefPtr<SkiaBackendContext> SkiaBackendContext::create_metal_context(Gfx::MetalContext const& metal_context)
+RefPtr<SkiaBackendContext> SkiaBackendContext::create_metal_context(MetalContext& metal_context)
 {
     GrMtlBackendContext backend_context;
-    backend_context.fDevice.retain((GrMTLHandle)metal_context.device());
-    backend_context.fQueue.retain((GrMTLHandle)metal_context.queue());
+    backend_context.fDevice.retain(metal_context.device());
+    backend_context.fQueue.retain(metal_context.queue());
     sk_sp<GrDirectContext> ctx = GrDirectContexts::MakeMetal(backend_context);
-    return adopt_ref(*new SkiaMetalBackendContext(ctx));
+    return adopt_ref(*new SkiaMetalBackendContext(ctx, metal_context));
 }
 #endif
 

+ 5 - 1
Libraries/LibGfx/SkiaBackendContext.h

@@ -22,6 +22,8 @@ class SkSurface;
 
 namespace Gfx {
 
+class MetalContext;
+
 class SkiaBackendContext : public RefCounted<SkiaBackendContext> {
     AK_MAKE_NONCOPYABLE(SkiaBackendContext);
     AK_MAKE_NONMOVABLE(SkiaBackendContext);
@@ -32,7 +34,7 @@ public:
 #endif
 
 #ifdef AK_OS_MACOS
-    static RefPtr<Gfx::SkiaBackendContext> create_metal_context(Gfx::MetalContext const&);
+    static RefPtr<Gfx::SkiaBackendContext> create_metal_context(MetalContext&);
 #endif
 
     SkiaBackendContext() {};
@@ -40,6 +42,8 @@ public:
 
     virtual void flush_and_submit(SkSurface*) {};
     virtual GrDirectContext* sk_context() const = 0;
+
+    virtual MetalContext& metal_context() = 0;
 };
 
 }

+ 1 - 2
Libraries/LibWeb/HTML/TraversableNavigable.cpp

@@ -1408,8 +1408,7 @@ void TraversableNavigable::paint(DevicePixelRect const& content_rect, Painting::
 #ifdef AK_OS_MACOS
         if (m_metal_context && m_skia_backend_context && is<Painting::IOSurfaceBackingStore>(target)) {
             auto& iosurface_backing_store = static_cast<Painting::IOSurfaceBackingStore&>(target);
-            auto texture = m_metal_context->create_texture_from_iosurface(iosurface_backing_store.iosurface_handle());
-            auto painting_surface = Gfx::PaintingSurface::wrap_metal_surface(*texture, m_skia_backend_context);
+            auto painting_surface = Gfx::PaintingSurface::wrap_iosurface(iosurface_backing_store.iosurface_handle(), *m_skia_backend_context);
             Painting::DisplayListPlayerSkia player(*m_skia_backend_context, painting_surface);
             player.execute(*display_list);
             return;

+ 1 - 1
Libraries/LibWeb/HTML/TraversableNavigable.h

@@ -149,7 +149,7 @@ private:
     RefPtr<Gfx::SkiaBackendContext> m_skia_backend_context;
 
 #ifdef AK_OS_MACOS
-    OwnPtr<Gfx::MetalContext> m_metal_context;
+    RefPtr<Gfx::MetalContext> m_metal_context;
 #endif
 };