--- a/gfx/2d/Matrix.h
+++ b/gfx/2d/Matrix.h
@@ -716,16 +716,17 @@ public:
size_t TransformAndClipRect(const RectTyped<SourceUnits, F>& aRect,
const RectTyped<TargetUnits, F>& aClip,
PointTyped<TargetUnits, F>* aVerts) const
{
// Initialize a double-buffered array of points in homogenous space with
// the input rectangle, aRect.
Point4DTyped<UnknownUnits, F> points[2][kTransformAndClipRectMaxVerts];
Point4DTyped<UnknownUnits, F>* dstPoint = points[0];
+
*dstPoint++ = *this * Point4DTyped<UnknownUnits, F>(aRect.x, aRect.y, 0, 1);
*dstPoint++ = *this * Point4DTyped<UnknownUnits, F>(aRect.XMost(), aRect.y, 0, 1);
*dstPoint++ = *this * Point4DTyped<UnknownUnits, F>(aRect.XMost(), aRect.YMost(), 0, 1);
*dstPoint++ = *this * Point4DTyped<UnknownUnits, F>(aRect.x, aRect.YMost(), 0, 1);
// View frustum clipping planes are described as normals originating from
// the 0,0,0,0 origin.
Point4DTyped<UnknownUnits, F> planeNormals[4];
@@ -734,24 +735,25 @@ public:
planeNormals[2] = Point4DTyped<UnknownUnits, F>(0.0, 1.0, 0.0, -aClip.y);
planeNormals[3] = Point4DTyped<UnknownUnits, F>(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();
-
Point4DTyped<UnknownUnits, F>* srcPoint = points[plane & 1];
Point4DTyped<UnknownUnits, F>* srcPointEnd = dstPoint;
+
dstPoint = points[~plane & 1];
+ Point4DTyped<UnknownUnits, F>* dstPointStart = dstPoint;
Point4DTyped<UnknownUnits, F>* prevPoint = srcPointEnd - 1;
F prevDot = planeNormals[plane].DotProduct(*prevPoint);
- while (srcPoint < srcPointEnd) {
+ while (srcPoint < srcPointEnd && ((dstPoint - dstPointStart) < kTransformAndClipRectMaxVerts)) {
F 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.
F t = -prevDot / (nextDot - prevDot);
*dstPoint++ = *srcPoint * t + *prevPoint * (1.0 - t);
}
@@ -760,16 +762,20 @@ public:
// Emit any source points that are on the positive side of the
// clipping plane.
*dstPoint++ = *srcPoint;
}
prevPoint = srcPoint++;
prevDot = nextDot;
}
+
+ if (dstPoint == dstPointStart) {
+ break;
+ }
}
size_t dstPointCount = 0;
size_t srcPointCount = dstPoint - points[0];
for (Point4DTyped<UnknownUnits, F>* srcPoint = points[0]; srcPoint < points[0] + srcPointCount; srcPoint++) {
PointTyped<TargetUnits, F> p;
if (srcPoint->w == 0.0) {
@@ -783,17 +789,17 @@ public:
if (dstPointCount == 0 || p != aVerts[dstPointCount - 1]) {
aVerts[dstPointCount++] = p;
}
}
return dstPointCount;
}
- static const size_t kTransformAndClipRectMaxVerts = 32;
+ static const int kTransformAndClipRectMaxVerts = 32;
static Matrix4x4Typed From2D(const Matrix &aMatrix) {
Matrix4x4Typed matrix;
matrix._11 = aMatrix._11;
matrix._12 = aMatrix._12;
matrix._21 = aMatrix._21;
matrix._22 = aMatrix._22;
matrix._41 = aMatrix._31;