Fix some issues in gpu device with perspective. Add a gm that would have caught them.

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



git-svn-id: http://skia.googlecode.com/svn/trunk@2256 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp
index 8eb8c63..6de3169 100644
--- a/gpu/src/GrContext.cpp
+++ b/gpu/src/GrContext.cpp
@@ -18,6 +18,7 @@
 #include "GrResourceCache.h"
 #include "GrStencilBuffer.h"
 #include "GrTextStrike.h"
+#include "SkTLazy.h"
 #include "SkTrace.h"
 
 // Using MSAA seems to be slower for some yet unknown reason.
@@ -592,22 +593,37 @@
               GrIntToScalar(getRenderTarget()->height()));
     GrAutoMatrix am;
     GrMatrix inverse;
+    SkTLazy<GrPaint> tmpPaint;
+    const GrPaint* p = &paint;
     // We attempt to map r by the inverse matrix and draw that. mapRect will
     // map the four corners and bound them with a new rect. This will not
     // produce a correct result for some perspective matrices.
-    if (!this->getMatrix().hasPerspective() &&
-        fGpu->getViewInverse(&inverse)) {
+    if (!this->getMatrix().hasPerspective()) {
+        if (!fGpu->getViewInverse(&inverse)) {
+            GrPrintf("Could not invert matrix");
+            return;
+        }
         inverse.mapRect(&r);
     } else {
+        if (paint.getActiveMaskStageMask() || paint.getActiveStageMask()) {
+            if (!fGpu->getViewInverse(&inverse)) {
+                GrPrintf("Could not invert matrix");
+                return;
+            }
+            tmpPaint.set(paint);
+            tmpPaint.get()->preConcatActiveSamplerMatrices(inverse);
+            p = tmpPaint.get();
+        }
         am.set(this, GrMatrix::I());
     }
-    GrPaint tmpPaint;
-    const GrPaint* p = &paint;
     // by definition this fills the entire clip, no need for AA
     if (paint.fAntiAlias) {
-        tmpPaint = paint;
-        tmpPaint.fAntiAlias = false;
-        p = &tmpPaint;
+        if (!tmpPaint.isValid()) {
+            tmpPaint.set(paint);
+            p = tmpPaint.get();
+        }
+        GrAssert(p == tmpPaint.get());
+        tmpPaint.get()->fAntiAlias = false;
     }
     this->drawRect(*p, r);
 }