зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changesets 230adc57e016 and 61bd6e2c6e72 (bug 1072898) for reftest failures.
CLOSED TREE
This commit is contained in:
Родитель
9f37b79c96
Коммит
37e75ba5e6
|
@ -227,81 +227,6 @@ Rect Matrix4x4::ProjectRectBounds(const Rect& aRect, const Rect &aClip) const
|
|||
return Rect(min_x, min_y, max_x - min_x, max_y - min_y);
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
Matrix4x4::TransformAndClipRect(const Rect& aRect, const Rect& aClip, Point* aVerts) const
|
||||
{
|
||||
// Initialize a double-buffered array of points in homogenous space with
|
||||
// the input rectangle, aRect.
|
||||
Point4D points[2][kTransformAndClipRectMaxVerts];
|
||||
Point4D* dstPoint = points[0];
|
||||
*dstPoint++ = *this * Point4D(aRect.x, aRect.y, 0, 1);
|
||||
*dstPoint++ = *this * Point4D(aRect.XMost(), aRect.y, 0, 1);
|
||||
*dstPoint++ = *this * Point4D(aRect.XMost(), aRect.YMost(), 0, 1);
|
||||
*dstPoint++ = *this * Point4D(aRect.x, aRect.YMost(), 0, 1);
|
||||
|
||||
// View frustum clipping planes are described as normals originating from
|
||||
// the 0,0,0,0 origin.
|
||||
Point4D planeNormals[4];
|
||||
planeNormals[0] = Point4D(1.0, 0.0, 0.0, -aClip.x);
|
||||
planeNormals[1] = Point4D(-1.0, 0.0, 0.0, aClip.XMost());
|
||||
planeNormals[2] = Point4D(0.0, 1.0, 0.0, -aClip.y);
|
||||
planeNormals[3] = Point4D(0.0, -1.0, 0.0, aClip.YMost());
|
||||
|
||||
// Iterate through each clipping plane and clip the polygon.
|
||||
// In each pass, we double buffer, alternating between points[0] and
|
||||
// points[1].
|
||||
for (int plane=0; plane < 4; plane++) {
|
||||
planeNormals[plane].Normalize();
|
||||
|
||||
Point4D* srcPoint = points[plane & 1];
|
||||
Point4D* srcPointEnd = dstPoint;
|
||||
dstPoint = points[~plane & 1];
|
||||
|
||||
Point4D* prevPoint = srcPointEnd - 1;
|
||||
float prevDot = planeNormals[plane].DotProduct(*prevPoint);
|
||||
while (srcPoint < srcPointEnd) {
|
||||
float nextDot = planeNormals[plane].DotProduct(*srcPoint);
|
||||
|
||||
if ((nextDot >= 0.0) != (prevDot >= 0.0)) {
|
||||
// An intersection with the clipping plane has been detected.
|
||||
// Interpolate to find the intersecting point and emit it.
|
||||
float t = -prevDot / (nextDot - prevDot);
|
||||
*dstPoint++ = *srcPoint * t + *prevPoint * (1.0 - t);
|
||||
}
|
||||
|
||||
if (nextDot >= 0.0) {
|
||||
// Emit any source points that are on the positive side of the
|
||||
// clipping plane.
|
||||
*dstPoint++ = *srcPoint;
|
||||
}
|
||||
|
||||
prevPoint = srcPoint++;
|
||||
prevDot = nextDot;
|
||||
}
|
||||
}
|
||||
|
||||
size_t dstPointCount = 0;
|
||||
size_t srcPointCount = dstPoint - points[0];
|
||||
for (Point4D* srcPoint = points[0]; srcPoint < points[0] + srcPointCount; srcPoint++) {
|
||||
|
||||
Point p;
|
||||
if (srcPoint->w == 0.0) {
|
||||
// If a point lies on the intersection of the clipping planes at
|
||||
// (0,0,0,0), we must avoid a division by zero w component.
|
||||
p = Point(0.0, 0.0);
|
||||
} else {
|
||||
p = srcPoint->As2DPoint();
|
||||
}
|
||||
// Emit only unique points
|
||||
if (dstPointCount == 0 || p != aVerts[dstPointCount - 1]) {
|
||||
aVerts[dstPointCount++] = p;
|
||||
}
|
||||
}
|
||||
|
||||
return dstPointCount;
|
||||
}
|
||||
|
||||
bool
|
||||
Matrix4x4::Invert()
|
||||
{
|
||||
|
|
|
@ -482,20 +482,7 @@ public:
|
|||
return *this * Point4D(aPoint.x, aPoint.y, z, 1);
|
||||
}
|
||||
|
||||
Rect ProjectRectBounds(const Rect& aRect, const Rect& aClip) const;
|
||||
|
||||
/**
|
||||
* TransformAndClipRect projects a rectangle and clips against view frustum
|
||||
* clipping planes in homogenous space so that its projected vertices are
|
||||
* constrained within the 2d rectangle passed in aClip.
|
||||
* The resulting vertices are populated in aVerts. aVerts must be
|
||||
* pre-allocated to hold at least kTransformAndClipRectMaxVerts Points.
|
||||
* The vertex count is returned by TransformAndClipRect. It is possible to
|
||||
* emit fewer that 3 vertices, indicating that aRect will not be visible
|
||||
* within aClip.
|
||||
*/
|
||||
size_t TransformAndClipRect(const Rect& aRect, const Rect& aClip, Point* aVerts) const;
|
||||
static const size_t kTransformAndClipRectMaxVerts = 32;
|
||||
Rect ProjectRectBounds(const Rect& aRect, const Rect &aClip) const;
|
||||
|
||||
static Matrix4x4 From2D(const Matrix &aMatrix) {
|
||||
Matrix4x4 matrix;
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
#ifdef MOZ_ENABLE_SKIA
|
||||
#include "skia/SkCanvas.h" // for SkCanvas
|
||||
#include "skia/SkBitmapDevice.h" // for SkBitmapDevice
|
||||
#include "skia/SkShader.h" // for SkShader
|
||||
#else
|
||||
#define PIXMAN_DONT_DEFINE_STDINT
|
||||
#include "pixman.h" // for pixman_f_transform, etc
|
||||
|
@ -183,7 +182,7 @@ DrawSurfaceWithTextureCoords(DrawTarget *aDest,
|
|||
|
||||
#ifdef MOZ_ENABLE_SKIA
|
||||
static SkMatrix
|
||||
MatrixToSkia(const Matrix4x4& aMatrix)
|
||||
Matrix3DToSkia(const gfx3DMatrix& aMatrix)
|
||||
{
|
||||
SkMatrix transform;
|
||||
transform.setAll(aMatrix._11,
|
||||
|
@ -202,34 +201,14 @@ MatrixToSkia(const Matrix4x4& aMatrix)
|
|||
static void
|
||||
Transform(DataSourceSurface* aDest,
|
||||
DataSourceSurface* aSource,
|
||||
const Matrix4x4& aTransform,
|
||||
const gfx3DMatrix& aTransform,
|
||||
const Point& aDestOffset)
|
||||
{
|
||||
// Skia does not correctly transform vertices that are behind the camera.
|
||||
// To work around this, we clip the geometry against the view frustum
|
||||
// clipping planes in homogenous space before passing them to Skia.
|
||||
// A Skia bitmap shader is initialized with a transformation matrix to
|
||||
// transform the texture contents of the polygon.
|
||||
|
||||
if (aTransform.IsSingular()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Matrix4x4 transform = aTransform;
|
||||
transform.PostTranslate(Point3D(-aDestOffset.x, -aDestOffset.y, 0));
|
||||
|
||||
IntSize srcSize = aSource->GetSize();
|
||||
IntSize destSize = aDest->GetSize();
|
||||
Point verts[Matrix4x4::kTransformAndClipRectMaxVerts];
|
||||
Rect srcRect = Rect(0, 0, srcSize.width, srcSize.height);
|
||||
Rect destRect = Rect(0, 0, destSize.width, destSize.height);
|
||||
size_t vertCount = transform.TransformAndClipRect(srcRect, destRect, verts);
|
||||
if (vertCount < 3) {
|
||||
// If we have fewer than 3 vertices, then the polygon has been completely
|
||||
// clipped out and there is nothing to render.
|
||||
return;
|
||||
}
|
||||
|
||||
SkImageInfo destInfo = SkImageInfo::Make(destSize.width,
|
||||
destSize.height,
|
||||
kBGRA_8888_SkColorType,
|
||||
|
@ -239,6 +218,7 @@ Transform(DataSourceSurface* aDest,
|
|||
destBitmap.setPixels((uint32_t*)aDest->GetData());
|
||||
SkCanvas destCanvas(destBitmap);
|
||||
|
||||
IntSize srcSize = aSource->GetSize();
|
||||
SkImageInfo srcInfo = SkImageInfo::Make(srcSize.width,
|
||||
srcSize.height,
|
||||
kBGRA_8888_SkColorType,
|
||||
|
@ -247,26 +227,16 @@ Transform(DataSourceSurface* aDest,
|
|||
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);
|
||||
SkMatrix localMatrix = MatrixToSkia(transform);
|
||||
SkShader* shader = SkShader::CreateBitmapShader(src,
|
||||
SkShader::kClamp_TileMode,
|
||||
SkShader::kClamp_TileMode,
|
||||
&localMatrix);
|
||||
paint.setShader(shader);
|
||||
shader->unref();
|
||||
|
||||
SkPath path;
|
||||
path.moveTo(verts[0].x, verts[0].y);
|
||||
for (size_t i=1; i<vertCount; i++) {
|
||||
path.lineTo(verts[i].x, verts[i].y);
|
||||
}
|
||||
path.close();
|
||||
|
||||
destCanvas.drawPath(path, paint);
|
||||
SkRect destRect = SkRect::MakeXYWH(0, 0, srcSize.width, srcSize.height);
|
||||
destCanvas.drawBitmapRectToRect(src, nullptr, destRect, &paint);
|
||||
}
|
||||
#else
|
||||
static pixman_transform
|
||||
|
@ -366,24 +336,12 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
|
|||
|
||||
Matrix newTransform;
|
||||
Rect transformBounds;
|
||||
Matrix4x4 new3DTransform;
|
||||
gfx3DMatrix new3DTransform;
|
||||
IntPoint offset = mRenderTarget->GetOrigin();
|
||||
|
||||
if (aTransform.Is2D()) {
|
||||
newTransform = aTransform.As2D();
|
||||
} else {
|
||||
// Get the bounds post-transform.
|
||||
new3DTransform = aTransform;
|
||||
Rect bounds = new3DTransform.TransformBounds(aRect);
|
||||
|
||||
transformBounds = bounds;
|
||||
transformBounds.RoundOut();
|
||||
|
||||
if (transformBounds.IsEmpty()) {
|
||||
// The quad has been completely clipped, nothing to draw.
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a temporary surface for the transform.
|
||||
dest = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(RoundOut(aRect).Size(), SurfaceFormat::B8G8R8A8);
|
||||
if (!dest) {
|
||||
|
@ -392,12 +350,20 @@ BasicCompositor::DrawQuad(const gfx::Rect& aRect,
|
|||
|
||||
dest->SetTransform(Matrix::Translation(-aRect.x, -aRect.y));
|
||||
|
||||
// Get the bounds post-transform.
|
||||
new3DTransform = To3DMatrix(aTransform);
|
||||
gfxRect bounds = new3DTransform.TransformBounds(ThebesRect(aRect));
|
||||
bounds.IntersectRect(bounds, gfxRect(offset.x, offset.y, buffer->GetSize().width, buffer->GetSize().height));
|
||||
|
||||
transformBounds = ToRect(bounds);
|
||||
transformBounds.RoundOut();
|
||||
|
||||
// Propagate the coordinate offset to our 2D draw target.
|
||||
newTransform = Matrix::Translation(transformBounds.x, transformBounds.y);
|
||||
|
||||
// When we apply the 3D transformation, we do it against a temporary
|
||||
// surface, so undo the coordinate offset.
|
||||
new3DTransform = Matrix4x4::Translation(aRect.x, aRect.y, 0) * new3DTransform;
|
||||
new3DTransform = gfx3DMatrix::Translation(aRect.x, aRect.y, 0) * new3DTransform;
|
||||
}
|
||||
|
||||
newTransform.PostTranslate(-offset.x, -offset.y);
|
||||
|
|
|
@ -56,7 +56,7 @@ pref(layout.css.will-change.enabled,true) == willchange-containing-block.html?wi
|
|||
pref(layout.css.will-change.enabled,true) != willchange-containing-block.html?willchange willchange-containing-block.html?noblock
|
||||
fuzzy-if(winWidget&&!layersGPUAccelerated,1,606) == scroll-perspective-1.html scroll-perspective-1-ref.html
|
||||
# Bugs
|
||||
== 1035611-1.html 1035611-1-ref.html # Bug 1072898 for !layersGPUAccelerated failures
|
||||
fails-if(!layersGPUAccelerated) == 1035611-1.html 1035611-1-ref.html # Bug 1072898 for !layersGPUAccelerated failures
|
||||
== animate-cube-radians.html animate-cube-radians-ref.html
|
||||
fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu)&&!layersGPUAccelerated,16,6) fuzzy-if(Mulet,16,9) == animate-cube-radians-zoom.html animate-cube-radians-zoom-ref.html
|
||||
!= animate-cube-radians-ref.html animate-cube-radians-zoom-ref.html
|
||||
|
|
Загрузка…
Ссылка в новой задаче