mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1097776 - Use Skia for unaccelerated rendering of 3D transforms. r=jrmuizel
This commit is contained in:
parent
c5ad8858c8
commit
eea67df22d
@ -17,8 +17,8 @@
|
||||
#include <algorithm>
|
||||
#include "ImageContainer.h"
|
||||
#include "gfxPrefs.h"
|
||||
#define PIXMAN_DONT_DEFINE_STDINT
|
||||
#include "pixman.h" // for pixman_f_transform, etc
|
||||
#include "skia/SkCanvas.h" // for SkCanvas
|
||||
#include "skia/SkBitmapDevice.h" // for SkBitmapDevice
|
||||
|
||||
namespace mozilla {
|
||||
using namespace mozilla::gfx;
|
||||
@ -168,75 +168,62 @@ DrawSurfaceWithTextureCoords(DrawTarget *aDest,
|
||||
mode, aMask, aMaskTransform, &matrix);
|
||||
}
|
||||
|
||||
static pixman_transform
|
||||
Matrix3DToPixman(const gfx3DMatrix& aMatrix)
|
||||
static SkMatrix
|
||||
Matrix3DToSkia(const gfx3DMatrix& aMatrix)
|
||||
{
|
||||
pixman_f_transform transform;
|
||||
SkMatrix transform;
|
||||
transform.setAll(aMatrix._11,
|
||||
aMatrix._21,
|
||||
aMatrix._41,
|
||||
aMatrix._12,
|
||||
aMatrix._22,
|
||||
aMatrix._42,
|
||||
aMatrix._14,
|
||||
aMatrix._24,
|
||||
aMatrix._44);
|
||||
|
||||
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;
|
||||
return transform;
|
||||
}
|
||||
|
||||
static void
|
||||
PixmanTransform(DataSourceSurface* aDest,
|
||||
SkiaTransform(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);
|
||||
if (aTransform.IsSingular()) {
|
||||
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);
|
||||
IntSize destSize = aDest->GetSize();
|
||||
SkImageInfo destInfo = SkImageInfo::Make(destSize.width,
|
||||
destSize.height,
|
||||
kBGRA_8888_SkColorType,
|
||||
kPremul_SkAlphaType);
|
||||
SkBitmap destBitmap;
|
||||
destBitmap.setInfo(destInfo, aDest->Stride());
|
||||
destBitmap.setPixels((uint32_t*)aDest->GetData());
|
||||
SkCanvas destCanvas(new SkBitmapDevice(destBitmap));
|
||||
|
||||
pixman_image_unref(dest);
|
||||
pixman_image_unref(src);
|
||||
IntSize srcSize = aSource->GetSize();
|
||||
SkImageInfo srcInfo = SkImageInfo::Make(srcSize.width,
|
||||
srcSize.height,
|
||||
kBGRA_8888_SkColorType,
|
||||
kPremul_SkAlphaType);
|
||||
SkBitmap src;
|
||||
src.setInfo(srcInfo, aSource->Stride());
|
||||
src.setPixels((uint32_t*)aSource->GetData());
|
||||
|
||||
gfx3DMatrix transform = aTransform;
|
||||
transform.TranslatePost(Point3D(-aDestOffset.x, -aDestOffset.y, 0));
|
||||
destCanvas.setMatrix(Matrix3DToSkia(transform));
|
||||
|
||||
SkPaint paint;
|
||||
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setFilterLevel(SkPaint::kLow_FilterLevel);
|
||||
SkRect destRect = SkRect::MakeXYWH(0, 0, srcSize.width, srcSize.height);
|
||||
destCanvas.drawBitmapRectToRect(src, nullptr, destRect, &paint);
|
||||
}
|
||||
|
||||
static inline IntRect
|
||||
@ -377,12 +364,12 @@ 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);
|
||||
Factory::CreateDataSourceSurface(RoundOut(transformBounds).Size(), SurfaceFormat::B8G8R8A8, true);
|
||||
if (NS_WARN_IF(!temp)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PixmanTransform(temp, source, new3DTransform, transformBounds.TopLeft());
|
||||
SkiaTransform(temp, source, new3DTransform, transformBounds.TopLeft());
|
||||
|
||||
transformBounds.MoveTo(0, 0);
|
||||
buffer->DrawSurface(temp, transformBounds, transformBounds);
|
||||
|
@ -46,9 +46,8 @@
|
||||
#include "nsRect.h" // for nsIntRect
|
||||
#include "nsRegion.h" // for nsIntRegion, etc
|
||||
#include "nsTArray.h" // for nsAutoTArray
|
||||
#define PIXMAN_DONT_DEFINE_STDINT
|
||||
#include "pixman.h" // for pixman_f_transform, etc
|
||||
|
||||
#include "skia/SkCanvas.h" // for SkCanvas
|
||||
#include "skia/SkBitmapDevice.h" // for SkBitmapDevice
|
||||
class nsIWidget;
|
||||
|
||||
namespace mozilla {
|
||||
@ -605,75 +604,62 @@ BasicLayerManager::SetRoot(Layer* aLayer)
|
||||
mRoot = aLayer;
|
||||
}
|
||||
|
||||
static pixman_transform
|
||||
BasicLayerManager_Matrix3DToPixman(const gfx3DMatrix& aMatrix)
|
||||
static SkMatrix
|
||||
BasicLayerManager_Matrix3DToSkia(const gfx3DMatrix& aMatrix)
|
||||
{
|
||||
pixman_f_transform transform;
|
||||
SkMatrix transform;
|
||||
transform.setAll(aMatrix._11,
|
||||
aMatrix._21,
|
||||
aMatrix._41,
|
||||
aMatrix._12,
|
||||
aMatrix._22,
|
||||
aMatrix._42,
|
||||
aMatrix._14,
|
||||
aMatrix._24,
|
||||
aMatrix._44);
|
||||
|
||||
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;
|
||||
return transform;
|
||||
}
|
||||
|
||||
static void
|
||||
PixmanTransform(const gfxImageSurface* aDest,
|
||||
SkiaTransform(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);
|
||||
if (aTransform.IsSingular()) {
|
||||
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);
|
||||
IntSize destSize = ToIntSize(aDest->GetSize());
|
||||
SkImageInfo destInfo = SkImageInfo::Make(destSize.width,
|
||||
destSize.height,
|
||||
kBGRA_8888_SkColorType,
|
||||
kPremul_SkAlphaType);
|
||||
SkBitmap destBitmap;
|
||||
destBitmap.setInfo(destInfo, aDest->Stride());
|
||||
destBitmap.setPixels((uint32_t*)aDest->Data());
|
||||
SkCanvas destCanvas(new SkBitmapDevice(destBitmap));
|
||||
|
||||
pixman_image_unref(dest);
|
||||
pixman_image_unref(src);
|
||||
IntSize srcSize = aSrc->GetSize();
|
||||
SkImageInfo srcInfo = SkImageInfo::Make(srcSize.width,
|
||||
srcSize.height,
|
||||
kBGRA_8888_SkColorType,
|
||||
kPremul_SkAlphaType);
|
||||
SkBitmap src;
|
||||
src.setInfo(srcInfo, aSrc->Stride());
|
||||
src.setPixels((uint32_t*)aSrc->GetData());
|
||||
|
||||
gfx3DMatrix transform = aTransform;
|
||||
transform.TranslatePost(Point3D(-aDestOffset.x, -aDestOffset.y, 0));
|
||||
destCanvas.setMatrix(BasicLayerManager_Matrix3DToSkia(transform));
|
||||
|
||||
SkPaint paint;
|
||||
paint.setXfermodeMode(SkXfermode::kSrc_Mode);
|
||||
paint.setAntiAlias(true);
|
||||
paint.setFilterLevel(SkPaint::kLow_FilterLevel);
|
||||
SkRect destRect = SkRect::MakeXYWH(0, 0, srcSize.width, srcSize.height);
|
||||
destCanvas.drawBitmapRectToRect(src, nullptr, destRect, &paint);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -716,7 +702,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.
|
||||
PixmanTransform(destImage, aSource->GetDataSurface(), translation * aTransform, offset);
|
||||
SkiaTransform(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.
|
||||
|
@ -1843,5 +1843,5 @@ test-pref(dom.webcomponents.enabled,true) == 1066554-1.html 1066554-1-ref.html
|
||||
== 1069716-1.html 1069716-1-ref.html
|
||||
== 1078262-1.html about:blank
|
||||
test-pref(layout.testing.overlay-scrollbars.always-visible,false) == 1081072-1.html 1081072-1-ref.html
|
||||
== 1081185-1.html 1081185-1-ref.html
|
||||
fuzzy-if(winWidget&&!layersGPUAccelerated,1,31) == 1081185-1.html 1081185-1-ref.html
|
||||
== 1097437-1.html 1097437-1-ref.html
|
@ -35,12 +35,12 @@ fuzzy-if(winWidget,102,580) fuzzy-if(d2d,143,681) fuzzy-if(OSX==10.8,224,924) fu
|
||||
!= backface-visibility-1a.html about:blank
|
||||
== backface-visibility-1b.html about:blank
|
||||
== backface-visibility-1c.html about:blank
|
||||
== backface-visibility-2.html backface-visibility-2-ref.html
|
||||
fuzzy-if(winWidget&&!layersGPUAccelerated,1,251) == backface-visibility-2.html backface-visibility-2-ref.html
|
||||
== backface-visibility-3.html backface-visibility-3-ref.html
|
||||
!= perspective-origin-1a.html rotatex-perspective-1a.html
|
||||
random-if(Android&&AndroidVersion==17) == perspective-origin-1b.html perspective-origin-1a.html
|
||||
random-if(Android&&!browserIsRemote) == perspective-origin-2a.html perspective-origin-2-ref.html # bug 732568
|
||||
== perspective-origin-3a.html perspective-origin-3-ref.html
|
||||
fuzzy-if(winWidget&&!layersGPUAccelerated,1,61) == perspective-origin-3a.html perspective-origin-3-ref.html
|
||||
== perspective-origin-4a.html perspective-origin-4-ref.html
|
||||
!= sorting-1a.html sorting-1-ref.html
|
||||
# Parallel planes, different z depth
|
||||
@ -50,8 +50,8 @@ random-if(Android&&!browserIsRemote) == perspective-origin-2a.html perspective-o
|
||||
== sorting-3a.html green-rect.html
|
||||
# Different, but equivalent (for the given transform) transform origins
|
||||
== rotatex-transformorigin-1a.html rotatex-transformorigin-1-ref.html
|
||||
== overflow-hidden-1a.html overflow-hidden-1-ref.html
|
||||
fuzzy-if((gtk2Widget&&layersOMTC)||(winWidget&&!layersGPUAccelerated),1,86) == overflow-hidden-1a.html overflow-hidden-1-ref.html
|
||||
== transform-style-flat-1a.html transform-style-flat-1-ref.html
|
||||
pref(layout.css.will-change.enabled,true) == willchange-containing-block.html?willchange willchange-containing-block.html?ref
|
||||
pref(layout.css.will-change.enabled,true) != willchange-containing-block.html?willchange willchange-containing-block.html?noblock
|
||||
== scroll-perspective-1.html scroll-perspective-1-ref.html
|
||||
fuzzy-if(winWidget&&!layersGPUAccelerated,1,606) == scroll-perspective-1.html scroll-perspective-1-ref.html
|
||||
|
Loading…
Reference in New Issue
Block a user