From 30d915c361ba195ebcd3d08df9d146b08e42593a Mon Sep 17 00:00:00 2001 From: Aliaksandr Kalenik Date: Fri, 20 Dec 2024 16:46:12 +0100 Subject: [PATCH] LibGfx+LibWeb: Specify bottom left origin for WebGL's PaintingSurface By doing that we eliminate the need for the vertical flip flag. As a side effect it fixes the bug when doing: `canvasContext2d.drawImage(canvasWithWebGLContext, 0, 0);` produced a flipped image because we didn't account for different origin while serializing PaintingSurface into Gfx::Bitmap. Visual progress on https://ciechanow.ski/curves-and-surfaces/ --- Libraries/LibGfx/PaintingSurface.cpp | 15 +++++++++++++-- Libraries/LibGfx/PaintingSurface.h | 11 ++++++----- .../LibWeb/Painting/DisplayListPlayerSkia.cpp | 10 ---------- Libraries/LibWeb/WebGL/OpenGLContext.cpp | 3 +-- 4 files changed, 20 insertions(+), 19 deletions(-) diff --git a/Libraries/LibGfx/PaintingSurface.cpp b/Libraries/LibGfx/PaintingSurface.cpp index b2a12549851..bfdbe572426 100644 --- a/Libraries/LibGfx/PaintingSurface.cpp +++ b/Libraries/LibGfx/PaintingSurface.cpp @@ -56,7 +56,7 @@ NonnullRefPtr PaintingSurface::wrap_bitmap(Bitmap& bitmap) } #ifdef AK_OS_MACOS -NonnullRefPtr PaintingSurface::wrap_iosurface(Core::IOSurfaceHandle const& iosurface_handle, RefPtr context) +NonnullRefPtr PaintingSurface::wrap_iosurface(Core::IOSurfaceHandle const& iosurface_handle, RefPtr context, Origin origin) { auto metal_texture = context->metal_context().create_texture_from_iosurface(iosurface_handle); IntSize const size { metal_texture->width(), metal_texture->height() }; @@ -64,7 +64,18 @@ NonnullRefPtr PaintingSurface::wrap_iosurface(Core::IOSurfaceHa 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); - auto surface = SkSurfaces::WrapBackendRenderTarget(context->sk_context(), backend_render_target, kTopLeft_GrSurfaceOrigin, kBGRA_8888_SkColorType, nullptr, nullptr); + GrSurfaceOrigin sk_origin; + switch (origin) { + case Origin::TopLeft: + sk_origin = kTopLeft_GrSurfaceOrigin; + break; + case Origin::BottomLeft: + sk_origin = kBottomLeft_GrSurfaceOrigin; + break; + default: + VERIFY_NOT_REACHED(); + } + auto surface = SkSurfaces::WrapBackendRenderTarget(context->sk_context(), backend_render_target, sk_origin, kBGRA_8888_SkColorType, nullptr, nullptr); return adopt_ref(*new PaintingSurface(make(size, surface, nullptr, context))); } #endif diff --git a/Libraries/LibGfx/PaintingSurface.h b/Libraries/LibGfx/PaintingSurface.h index a070b62d0aa..be204d8bf29 100644 --- a/Libraries/LibGfx/PaintingSurface.h +++ b/Libraries/LibGfx/PaintingSurface.h @@ -24,11 +24,16 @@ namespace Gfx { class PaintingSurface : public RefCounted { public: + enum class Origin { + TopLeft, + BottomLeft, + }; + static NonnullRefPtr create_with_size(RefPtr context, Gfx::IntSize size, Gfx::BitmapFormat color_type, Gfx::AlphaType alpha_type); static NonnullRefPtr wrap_bitmap(Bitmap&); #ifdef AK_OS_MACOS - static NonnullRefPtr wrap_iosurface(Core::IOSurfaceHandle const&, RefPtr); + static NonnullRefPtr wrap_iosurface(Core::IOSurfaceHandle const&, RefPtr, Origin = Origin::TopLeft); #endif void read_into_bitmap(Bitmap&); @@ -47,9 +52,6 @@ public: void flush() const; - bool flip_vertically() const { return m_flip_vertically; } - void set_flip_vertically() { m_flip_vertically = true; } - ~PaintingSurface(); private: @@ -58,7 +60,6 @@ private: PaintingSurface(NonnullOwnPtr&&); NonnullOwnPtr m_impl; - bool m_flip_vertically { false }; }; } diff --git a/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp b/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp index 7044e86b9e5..9cc02935fbb 100644 --- a/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp +++ b/Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp @@ -152,17 +152,7 @@ void DisplayListPlayerSkia::draw_painting_surface(DrawPaintingSurface const& com auto& canvas = surface().canvas(); auto image = sk_surface.makeImageSnapshot(); SkPaint paint; - if (command.surface->flip_vertically()) { - canvas.save(); - SkMatrix matrix; - matrix.setIdentity(); - matrix.preScale(1, -1, dst_rect.centerX(), dst_rect.centerY()); - canvas.concat(matrix); - } canvas.drawImageRect(image, src_rect, dst_rect, to_skia_sampling_options(command.scaling_mode), &paint, SkCanvas::kStrict_SrcRectConstraint); - if (command.surface->flip_vertically()) { - canvas.restore(); - } } void DisplayListPlayerSkia::draw_scaled_immutable_bitmap(DrawScaledImmutableBitmap const& command) diff --git a/Libraries/LibWeb/WebGL/OpenGLContext.cpp b/Libraries/LibWeb/WebGL/OpenGLContext.cpp index 2067d901a1b..db3b9544424 100644 --- a/Libraries/LibWeb/WebGL/OpenGLContext.cpp +++ b/Libraries/LibWeb/WebGL/OpenGLContext.cpp @@ -126,8 +126,7 @@ void OpenGLContext::allocate_painting_surface_if_needed() VERIFY(!m_size.is_empty()); auto iosurface = Core::IOSurfaceHandle::create(m_size.width(), m_size.height()); - m_painting_surface = Gfx::PaintingSurface::wrap_iosurface(iosurface, m_skia_backend_context); - m_painting_surface->set_flip_vertically(); + m_painting_surface = Gfx::PaintingSurface::wrap_iosurface(iosurface, m_skia_backend_context, Gfx::PaintingSurface::Origin::BottomLeft); auto width = m_size.width(); auto height = m_size.height();