Browse Source

LibWeb: Flip vertically PaintingSurface attached to WebGL context

OpenGL's origin is at the bottom-left corner, while Skia's origin is at
the top-left corner. This change adds a transformation to compensate for
this difference when rendering PaintingSurface attached to WebGL
context.
Aliaksandr Kalenik 8 months ago
parent
commit
45e0f50463

+ 4 - 0
Libraries/LibGfx/PaintingSurface.h

@@ -45,6 +45,9 @@ public:
 
     void flush() const;
 
+    bool flip_vertically() const { return m_flip_vertically; }
+    void set_flip_vertically() { m_flip_vertically = true; }
+
     ~PaintingSurface();
 
 private:
@@ -53,6 +56,7 @@ private:
     PaintingSurface(NonnullOwnPtr<Impl>&&);
 
     NonnullOwnPtr<Impl> m_impl;
+    bool m_flip_vertically { false };
 };
 
 }

+ 10 - 0
Libraries/LibWeb/Painting/DisplayListPlayerSkia.cpp

@@ -329,7 +329,17 @@ 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)

+ 1 - 0
Libraries/LibWeb/WebGL/OpenGLContext.cpp

@@ -122,6 +122,7 @@ void OpenGLContext::allocate_painting_surface_if_needed()
 
     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();
 
     auto width = m_size.width();
     auto height = m_size.height();