mozilla-skia-bmo1136958.patch
author Wolfgang Rosenauer <wr@rosenauer.org>
Sun, 22 Mar 2015 13:59:40 +0100
changeset 842 b199b6c7d84a
parent 841 d8a3e976dfba
permissions -rw-r--r--
37.0b5

From a8ab3ec3542469c1d4e0741121eb1be17cc0acb0 Mon Sep 17 00:00:00 2001
From: Mike Hommey <mh@glandium.org>
Date: Mon, 9 Mar 2015 08:42:19 +0900
Subject: [PATCH] Bug 1136958 - Reintroduce pixman code path removed in bug
 1097776 for --disable-skia builds

---
 gfx/layers/basic/BasicCompositor.cpp   | 94 +++++++++++++++++++++++++++++++---
 gfx/layers/basic/BasicLayerManager.cpp | 88 +++++++++++++++++++++++++++++--
 2 files changed, 171 insertions(+), 11 deletions(-)

diff --git a/gfx/layers/basic/BasicCompositor.cpp b/gfx/layers/basic/BasicCompositor.cpp
index 0bef076..000b591 100644
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -17,8 +17,13 @@
 #include <algorithm>
 #include "ImageContainer.h"
 #include "gfxPrefs.h"
+#ifdef MOZ_ENABLE_SKIA
 #include "skia/SkCanvas.h"              // for SkCanvas
 #include "skia/SkBitmapDevice.h"        // for SkBitmapDevice
+#else
+#define PIXMAN_DONT_DEFINE_STDINT
+#include "pixman.h"                     // for pixman_f_transform, etc
+#endif
 
 namespace mozilla {
 using namespace mozilla::gfx;
@@ -168,6 +173,7 @@ DrawSurfaceWithTextureCoords(DrawTarget *aDest,
                    mode, aMask, aMaskTransform, &matrix);
 }
 
+#ifdef MOZ_ENABLE_SKIA
 static SkMatrix
 Matrix3DToSkia(const gfx3DMatrix& aMatrix)
 {
@@ -186,10 +192,10 @@ Matrix3DToSkia(const gfx3DMatrix& aMatrix)
 }
 
 static void
-SkiaTransform(DataSourceSurface* aDest,
-              DataSourceSurface* aSource,
-              const gfx3DMatrix& aTransform,
-              const Point& aDestOffset)
+Transform(DataSourceSurface* aDest,
+          DataSourceSurface* aSource,
+          const gfx3DMatrix& aTransform,
+          const Point& aDestOffset)
 {
   if (aTransform.IsSingular()) {
     return;
@@ -225,6 +231,78 @@ SkiaTransform(DataSourceSurface* aDest,
   SkRect destRect = SkRect::MakeXYWH(0, 0, srcSize.width, srcSize.height);
   destCanvas.drawBitmapRectToRect(src, nullptr, destRect, &paint);
 }
+#else
+static pixman_transform
+Matrix3DToPixman(const gfx3DMatrix& aMatrix)
+{
+  pixman_f_transform transform;
+
+  transform.m[0][0] = aMatrix._11;
+  transform.m[0][1] = aMatrix._21;
+  transform.m[0][2] = aMatrix._41;
+  transform.m[1][0] = aMatrix._12;
+  transform.m[1][1] = aMatrix._22;
+  transform.m[1][2] = aMatrix._42;
+  transform.m[2][0] = aMatrix._14;
+  transform.m[2][1] = aMatrix._24;
+  transform.m[2][2] = aMatrix._44;
+
+  pixman_transform result;
+  pixman_transform_from_pixman_f_transform(&result, &transform);
+
+  return result;
+}
+
+static void
+Transform(DataSourceSurface* aDest,
+          DataSourceSurface* aSource,
+          const gfx3DMatrix& aTransform,
+          const Point& aDestOffset)
+{
+  IntSize destSize = aDest->GetSize();
+  pixman_image_t* dest = pixman_image_create_bits(PIXMAN_a8r8g8b8,
+                                                  destSize.width,
+                                                  destSize.height,
+                                                  (uint32_t*)aDest->GetData(),
+                                                  aDest->Stride());
+
+  IntSize srcSize = aSource->GetSize();
+  pixman_image_t* src = pixman_image_create_bits(PIXMAN_a8r8g8b8,
+                                                 srcSize.width,
+                                                 srcSize.height,
+                                                 (uint32_t*)aSource->GetData(),
+                                                 aSource->Stride());
+
+  NS_ABORT_IF_FALSE(src && dest, "Failed to create pixman images?");
+
+  pixman_transform pixTransform = Matrix3DToPixman(aTransform);
+  pixman_transform pixTransformInverted;
+
+  // If the transform is singular then nothing would be drawn anyway, return here
+  if (!pixman_transform_invert(&pixTransformInverted, &pixTransform)) {
+    pixman_image_unref(dest);
+    pixman_image_unref(src);
+    return;
+  }
+  pixman_image_set_transform(src, &pixTransformInverted);
+
+  pixman_image_composite32(PIXMAN_OP_SRC,
+                           src,
+                           nullptr,
+                           dest,
+                           aDestOffset.x,
+                           aDestOffset.y,
+                           0,
+                           0,
+                           0,
+                           0,
+                           destSize.width,
+                           destSize.height);
+
+  pixman_image_unref(dest);
+  pixman_image_unref(src);
+}
+#endif
 
 static inline IntRect
 RoundOut(Rect r)
@@ -364,12 +442,16 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
     RefPtr<SourceSurface> snapshot = dest->Snapshot();
     RefPtr<DataSourceSurface> source = snapshot->GetDataSurface();
     RefPtr<DataSourceSurface> temp =
-      Factory::CreateDataSourceSurface(RoundOut(transformBounds).Size(), SurfaceFormat::B8G8R8A8, true);
+      Factory::CreateDataSourceSurface(RoundOut(transformBounds).Size(), SurfaceFormat::B8G8R8A8
+#ifdef MOZ_ENABLE_SKIA
+        , true
+#endif
+        );
     if (NS_WARN_IF(!temp)) {
       return;
     }
 
-    SkiaTransform(temp, source, new3DTransform, transformBounds.TopLeft());
+    Transform(temp, source, new3DTransform, transformBounds.TopLeft());
 
     transformBounds.MoveTo(0, 0);
     buffer->DrawSurface(temp, transformBounds, transformBounds);
diff --git a/gfx/layers/basic/BasicLayerManager.cpp b/gfx/layers/basic/BasicLayerManager.cpp
index f4ec9e4..c849c27 100644
--- a/gfx/layers/basic/BasicLayerManager.cpp
+++ b/gfx/layers/basic/BasicLayerManager.cpp
@@ -46,8 +46,13 @@
 #include "nsRect.h"                     // for nsIntRect
 #include "nsRegion.h"                   // for nsIntRegion, etc
 #include "nsTArray.h"                   // for nsAutoTArray
+#ifdef MOZ_ENABLE_SKIA
 #include "skia/SkCanvas.h"              // for SkCanvas
 #include "skia/SkBitmapDevice.h"        // for SkBitmapDevice
+#else
+#define PIXMAN_DONT_DEFINE_STDINT
+#include "pixman.h"                     // for pixman_f_transform, etc
+#endif
 class nsIWidget;
 
 namespace mozilla {
@@ -601,6 +606,7 @@ BasicLayerManager::SetRoot(Layer* aLayer)
   mRoot = aLayer;
 }
 
+#ifdef MOZ_ENABLE_SKIA
 static SkMatrix
 BasicLayerManager_Matrix3DToSkia(const gfx3DMatrix& aMatrix)
 {
@@ -619,10 +625,10 @@ BasicLayerManager_Matrix3DToSkia(const gfx3DMatrix& aMatrix)
 }
 
 static void
-SkiaTransform(const gfxImageSurface* aDest,
-              RefPtr<DataSourceSurface> aSrc,
-              const gfx3DMatrix& aTransform,
-              gfxPoint aDestOffset)
+Transform(const gfxImageSurface* aDest,
+          RefPtr<DataSourceSurface> aSrc,
+          const gfx3DMatrix& aTransform,
+          gfxPoint aDestOffset)
 {
   if (aTransform.IsSingular()) {
     return;
@@ -658,6 +664,78 @@ SkiaTransform(const gfxImageSurface* aDest,
   SkRect destRect = SkRect::MakeXYWH(0, 0, srcSize.width, srcSize.height);
   destCanvas.drawBitmapRectToRect(src, nullptr, destRect, &paint);
 }
+#else
+static pixman_transform
+BasicLayerManager_Matrix3DToPixman(const gfx3DMatrix& aMatrix)
+{
+  pixman_f_transform transform;
+
+  transform.m[0][0] = aMatrix._11;
+  transform.m[0][1] = aMatrix._21;
+  transform.m[0][2] = aMatrix._41;
+  transform.m[1][0] = aMatrix._12;
+  transform.m[1][1] = aMatrix._22;
+  transform.m[1][2] = aMatrix._42;
+  transform.m[2][0] = aMatrix._14;
+  transform.m[2][1] = aMatrix._24;
+  transform.m[2][2] = aMatrix._44;
+
+  pixman_transform result;
+  pixman_transform_from_pixman_f_transform(&result, &transform);
+
+  return result;
+}
+
+static void
+Transform(const gfxImageSurface* aDest,
+          RefPtr<DataSourceSurface> aSrc,
+          const gfx3DMatrix& aTransform,
+          gfxPoint aDestOffset)
+{
+  IntSize destSize = ToIntSize(aDest->GetSize());
+  pixman_image_t* dest = pixman_image_create_bits(aDest->Format() == gfxImageFormat::ARGB32 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
+                                                  destSize.width,
+                                                  destSize.height,
+                                                  (uint32_t*)aDest->Data(),
+                                                  aDest->Stride());
+
+  IntSize srcSize = aSrc->GetSize();
+  pixman_image_t* src = pixman_image_create_bits(aSrc->GetFormat() == SurfaceFormat::B8G8R8A8 ? PIXMAN_a8r8g8b8 : PIXMAN_x8r8g8b8,
+                                                 srcSize.width,
+                                                 srcSize.height,
+                                                 (uint32_t*)aSrc->GetData(),
+                                                 aSrc->Stride());
+
+  NS_ABORT_IF_FALSE(src && dest, "Failed to create pixman images?");
+
+  pixman_transform pixTransform = BasicLayerManager_Matrix3DToPixman(aTransform);
+  pixman_transform pixTransformInverted;
+
+  // If the transform is singular then nothing would be drawn anyway, return here
+  if (!pixman_transform_invert(&pixTransformInverted, &pixTransform)) {
+    pixman_image_unref(dest);
+    pixman_image_unref(src);
+    return;
+  }
+  pixman_image_set_transform(src, &pixTransformInverted);
+
+  pixman_image_composite32(PIXMAN_OP_SRC,
+                           src,
+                           nullptr,
+                           dest,
+                           aDestOffset.x,
+                           aDestOffset.y,
+                           0,
+                           0,
+                           0,
+                           0,
+                           destSize.width,
+                           destSize.height);
+
+  pixman_image_unref(dest);
+  pixman_image_unref(src);
+}
+#endif
 
 /**
  * Transform a surface using a gfx3DMatrix and blit to the destination if
@@ -699,7 +777,7 @@ Transform3D(RefPtr<SourceSurface> aSource,
   gfx3DMatrix translation = gfx3DMatrix::Translation(aBounds.x, aBounds.y, 0);
 
   // Transform the content and offset it such that the content begins at the origin.
-  SkiaTransform(destImage, aSource->GetDataSurface(), translation * aTransform, offset);
+  Transform(destImage, aSource->GetDataSurface(), translation * aTransform, offset);
 
   // If we haven't actually drawn to aDest then return our temporary image so
   // that the caller can do this.
-- 
2.3.0.4.g34b1174