Bug 598531 - pixman hitting slow path. disable scaling. r=roc a=blocking-fennec
authorOleg Romashin <romaxa@gmail.com>
Thu, 23 Sep 2010 16:06:27 -0700
changeset 54550 c4791f0195bff2c8fc0e98efc6e96995f2c8fcf1
parent 54549 626d22af7eff9a78d6191c012ba83dc95f08392d
child 54551 66336224dfa4ec242230666b95cb7b881e0886a3
push id15944
push userromaxa@gmail.com
push dateThu, 23 Sep 2010 23:13:12 +0000
treeherdermozilla-central@66336224dfa4 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersroc, blocking-fennec
bugs598531
milestone2.0b7pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 598531 - pixman hitting slow path. disable scaling. r=roc a=blocking-fennec
gfx/layers/ThebesLayerBuffer.cpp
gfx/thebes/gfxContext.cpp
gfx/thebes/gfxMatrix.cpp
gfx/thebes/gfxMatrix.h
--- a/gfx/layers/ThebesLayerBuffer.cpp
+++ b/gfx/layers/ThebesLayerBuffer.cpp
@@ -101,21 +101,33 @@ ThebesLayerBuffer::DrawBufferQuadrant(gf
   gfxPoint quadrantTranslation(quadrantRect.x, quadrantRect.y);
   nsRefPtr<gfxPattern> pattern = new gfxPattern(mBuffer);
 
 #ifdef MOZ_GFX_OPTIMIZE_MOBILE
   gfxPattern::GraphicsFilter filter = gfxPattern::FILTER_NEAREST;
   pattern->SetFilter(filter);
 #endif
 
+  gfxContextMatrixAutoSaveRestore saveMatrix(aTarget);
+
   // Transform from user -> buffer space.
   gfxMatrix transform;
   transform.Scale(aXRes, aYRes);
   transform.Translate(-quadrantTranslation);
 
+  // in common cases the matrix after scaling by 1/aRes is close to 1.0,
+  // so we want to make it 1.0 in both cases
+  transform.Scale(1.0 / aXRes, 1.0 / aYRes);
+  transform.NudgeToIntegers();
+
+  gfxMatrix ctxMatrix = aTarget->CurrentMatrix();
+  ctxMatrix.Scale(1.0 / aXRes, 1.0 / aYRes);
+  ctxMatrix.NudgeToIntegers();
+  aTarget->SetMatrix(ctxMatrix);
+
   pattern->SetMatrix(transform);
   aTarget->SetPattern(pattern);
 
   if (aOpacity != 1.0) {
     aTarget->Save();
     aTarget->Clip();
     aTarget->Paint(aOpacity);
     aTarget->Restore();
--- a/gfx/thebes/gfxContext.cpp
+++ b/gfx/thebes/gfxContext.cpp
@@ -313,36 +313,22 @@ gfxContext::IdentityMatrix()
 gfxMatrix
 gfxContext::CurrentMatrix() const
 {
     cairo_matrix_t mat;
     cairo_get_matrix(mCairo, &mat);
     return gfxMatrix(*reinterpret_cast<gfxMatrix*>(&mat));
 }
 
-static void NudgeToInteger(double *aVal)
-{
-    float f = float(*aVal);
-    float r = NS_roundf(f);
-    if (f == r) {
-        *aVal = r;
-    }
-}
-
 void
 gfxContext::NudgeCurrentMatrixToIntegers()
 {
     cairo_matrix_t mat;
     cairo_get_matrix(mCairo, &mat);
-    NudgeToInteger(&mat.xx);
-    NudgeToInteger(&mat.xy);
-    NudgeToInteger(&mat.yx);
-    NudgeToInteger(&mat.yy);
-    NudgeToInteger(&mat.x0);
-    NudgeToInteger(&mat.y0);
+    gfxMatrix(*reinterpret_cast<gfxMatrix*>(&mat)).NudgeToIntegers();
     cairo_set_matrix(mCairo, &mat);
 }
 
 gfxPoint
 gfxContext::DeviceToUser(const gfxPoint& point) const
 {
     gfxPoint ret = point;
     cairo_device_to_user(mCairo, &ret.x, &ret.y);
--- a/gfx/thebes/gfxMatrix.cpp
+++ b/gfx/thebes/gfxMatrix.cpp
@@ -188,8 +188,28 @@ gfx3DMatrix::Is2D(gfxMatrix* aMatrix) co
     aMatrix->yx = _12;
     aMatrix->xy = _21;
     aMatrix->yy = _22;
     aMatrix->x0 = _41;
     aMatrix->y0 = _42;
   }
   return PR_TRUE;
 }
+
+static void NudgeToInteger(double *aVal)
+{
+    float f = float(*aVal);
+    float r = NS_roundf(f);
+    if (f == r) {
+        *aVal = r;
+    }
+}
+
+void
+gfxMatrix::NudgeToIntegers(void)
+{
+    NudgeToInteger(&xx);
+    NudgeToInteger(&xy);
+    NudgeToInteger(&yx);
+    NudgeToInteger(&yy);
+    NudgeToInteger(&x0);
+    NudgeToInteger(&y0);
+}
--- a/gfx/thebes/gfxMatrix.h
+++ b/gfx/thebes/gfxMatrix.h
@@ -253,15 +253,22 @@ public:
             minor = det / major;
 
         if (xMajor)
             return gfxSize(major, minor);
 
         return gfxSize(minor, major);
     }
 
+    /**
+     * Snap matrix components that are close to integers
+     * to integers. In particular, components that are integral when
+     * converted to single precision are set to those integers.
+     */
+    void NudgeToIntegers(void);
+
 private:
     static PRBool FuzzyEqual(gfxFloat aV1, gfxFloat aV2) {
         return fabs(aV2 - aV1) < 1e-6;
     }
 };
 
 #endif /* GFX_MATRIX_H */