Add SkMatrix::cheapEqualTo, use in Gr code

Review URL: http://codereview.appspot.com/5865057/



git-svn-id: http://skia.googlecode.com/svn/trunk@3488 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index c0ff42f..92ee2cb 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -85,8 +85,8 @@
         // are tightly packed
         GrAssert(kMemsetSize +  sizeof(fColor) + sizeof(fCoverage) +
                  sizeof(fFirstCoverageStage) + sizeof(fColorFilterMode) +
-                 sizeof(fSrcBlend) + sizeof(fDstBlend) + sizeof(GrMatrix) ==
-                 reinterpret_cast<uintptr_t>(&fEdgeAANumEdges) -
+                 sizeof(fSrcBlend) + sizeof(fDstBlend) ==
+                 reinterpret_cast<uintptr_t>(&fViewMatrix) -
                  reinterpret_cast<uintptr_t>(this));
 
         fEdgeAANumEdges = 0;
@@ -740,7 +740,13 @@
     // Most stages are usually not used, so conditionals here
     // reduce the expected number of bytes touched by 50%.
     bool operator ==(const GrDrawState& s) const {
-        if (memcmp(this, &s, this->leadingBytes())) return false;
+        if (memcmp(this, &s, this->leadingBytes())) {
+            return false;
+        }
+
+        if (!s.fViewMatrix.cheapEqualTo(fViewMatrix)) {
+            return false;
+        }
 
         for (int i = 0; i < kNumStages; i++) {
             if (fTextures[i] &&
@@ -766,6 +772,8 @@
     GrDrawState& operator =(const GrDrawState& s) {
         memcpy(this, &s, this->leadingBytes());
 
+        fViewMatrix = s.fViewMatrix;
+
         for (int i = 0; i < kNumStages; i++) {
             if (s.fTextures[i]) {
                 memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i],
@@ -799,9 +807,10 @@
     SkXfermode::Mode    fColorFilterMode;
     GrBlendCoeff        fSrcBlend;
     GrBlendCoeff        fDstBlend;
-    GrMatrix            fViewMatrix;
     // @}
 
+    GrMatrix            fViewMatrix;
+
     // @{ Data for GrTesselatedPathRenderer
     // TODO: currently ignored in copying & comparison for performance.
     // Must be considered if GrTesselatedPathRenderer is being used.
@@ -820,7 +829,7 @@
         // TODO: ignores GrTesselatedPathRenderer data structures. We don't
         // have a compile-time flag that lets us know if it's being used, and
         // checking at runtime seems to cost 5% performance.
-        return (size_t) ((unsigned char*)&fEdgeAANumEdges -
+        return (size_t) ((unsigned char*)&fViewMatrix -
                          (unsigned char*)&fBlendConstant);
     }
 
diff --git a/src/gpu/gl/GrGpuGLShaders.cpp b/src/gpu/gl/GrGpuGLShaders.cpp
index cb156f7..ec2d4e2 100644
--- a/src/gpu/gl/GrGpuGLShaders.cpp
+++ b/src/gpu/gl/GrGpuGLShaders.cpp
@@ -409,7 +409,7 @@
 
 void GrGpuGLShaders::flushViewMatrix() {
     const GrMatrix& vm = this->getDrawState().getViewMatrix();
-    if (GrGpuGLShaders::getHWViewMatrix() != vm) {
+    if (!GrGpuGLShaders::getHWViewMatrix().cheapEqualTo(vm)) {
 
         const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
         GrAssert(NULL != rt);
@@ -492,11 +492,13 @@
     const GrGLTexture* texture =
         static_cast<const GrGLTexture*>(drawState.getTexture(s));
     if (NULL != texture) {
+        const GrMatrix& hwMatrix = this->getHWSamplerMatrix(s);
+        const GrMatrix& samplerMatrix = drawState.getSampler(s).getMatrix();
         if (GrGLProgram::kUnusedUniform != uni &&
             (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
-            this->getHWSamplerMatrix(s) != drawState.getSampler(s).getMatrix())) {
+            !hwMatrix.cheapEqualTo(samplerMatrix))) {
 
-            GrMatrix m = drawState.getSampler(s).getMatrix();
+            GrMatrix m = samplerMatrix;
             GrSamplerState::SampleMode mode =
                 drawState.getSampler(s).getSampleMode();
             AdjustTextureMatrix(texture, mode, &m);