From 05caed919c47863026bdad3c50e75978eb83ef89 Mon Sep 17 00:00:00 2001 From: Oleg Romashin Date: Thu, 23 Sep 2010 16:06:27 -0700 Subject: [PATCH] Bug 598531 - pixman hitting slow path. disable scaling. r=roc a=blocking-fennec --- gfx/layers/ThebesLayerBuffer.cpp | 12 ++++++++++++ gfx/thebes/gfxContext.cpp | 16 +--------------- gfx/thebes/gfxMatrix.cpp | 20 ++++++++++++++++++++ gfx/thebes/gfxMatrix.h | 7 +++++++ 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/gfx/layers/ThebesLayerBuffer.cpp b/gfx/layers/ThebesLayerBuffer.cpp index bbbb199ba8a..8665ebca995 100644 --- a/gfx/layers/ThebesLayerBuffer.cpp +++ b/gfx/layers/ThebesLayerBuffer.cpp @@ -106,11 +106,23 @@ ThebesLayerBuffer::DrawBufferQuadrant(gfxContext* aTarget, 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); diff --git a/gfx/thebes/gfxContext.cpp b/gfx/thebes/gfxContext.cpp index fd54d8fcc1c..eb4d6cddee7 100644 --- a/gfx/thebes/gfxContext.cpp +++ b/gfx/thebes/gfxContext.cpp @@ -318,26 +318,12 @@ gfxContext::CurrentMatrix() const return gfxMatrix(*reinterpret_cast(&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(&mat)).NudgeToIntegers(); cairo_set_matrix(mCairo, &mat); } diff --git a/gfx/thebes/gfxMatrix.cpp b/gfx/thebes/gfxMatrix.cpp index 1fc04c35658..e1e85146a50 100644 --- a/gfx/thebes/gfxMatrix.cpp +++ b/gfx/thebes/gfxMatrix.cpp @@ -193,3 +193,23 @@ gfx3DMatrix::Is2D(gfxMatrix* aMatrix) const } 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); +} diff --git a/gfx/thebes/gfxMatrix.h b/gfx/thebes/gfxMatrix.h index 98b5271212f..839b4cfe5c3 100644 --- a/gfx/thebes/gfxMatrix.h +++ b/gfx/thebes/gfxMatrix.h @@ -258,6 +258,13 @@ public: 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;