From a8ab3ec3542469c1d4e0741121eb1be17cc0acb0 Mon Sep 17 00:00:00 2001 From: Mike Hommey 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 #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 snapshot = dest->Snapshot(); RefPtr source = snapshot->GetDataSurface(); RefPtr 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 aSrc, - const gfx3DMatrix& aTransform, - gfxPoint aDestOffset) +Transform(const gfxImageSurface* aDest, + RefPtr 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 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 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