Relanding 7914



git-svn-id: http://skia.googlecode.com/svn/trunk@7940 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 3bdb332..99068c7 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -397,7 +397,11 @@
         desc.fFlags = kRenderTarget_GrTextureFlagBit;
         desc.fWidth = clipSpaceIBounds.width();
         desc.fHeight = clipSpaceIBounds.height();
-        desc.fConfig = kAlpha_8_GrPixelConfig;
+        desc.fConfig = kRGBA_8888_GrPixelConfig;
+        if (this->getContext()->isConfigRenderable(kAlpha_8_GrPixelConfig)) {
+            // We would always like A8 but it isn't supported on all platforms
+            desc.fConfig = kAlpha_8_GrPixelConfig;
+        }
 
         fAACache.acquireMask(clipStackGenID, desc, clipSpaceIBounds);
     }
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index 65f3e0f..4722e68 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -433,6 +433,11 @@
         desc.fHeight = GrMax(MIN_SIZE, GrNextPow2(desc.fHeight));
     }
 
+    // Renderable A8 targets are not universally supported (e.g., not on ANGLE)
+    GrAssert(this->isConfigRenderable(kAlpha_8_GrPixelConfig) ||
+             !(desc.fFlags & kRenderTarget_GrTextureFlagBit) ||
+             (desc.fConfig != kAlpha_8_GrPixelConfig));
+
     GrResource* resource = NULL;
     int origWidth = desc.fWidth;
     int origHeight = desc.fHeight;
@@ -1473,7 +1478,10 @@
                 }
                 swapRAndB = false; // we will handle the swap in the draw.
 
-                GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit);
+                // We protect the existing geometry here since it may not be
+                // clear to the caller that a draw operation (i.e., drawSimpleRect)
+                // can be invoked in this method
+                GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit);
                 GrDrawState* drawState = fGpu->drawState();
                 GrAssert(effect);
                 drawState->setEffect(0, effect);
@@ -1660,7 +1668,10 @@
         return false;
     }
 
-    GrDrawTarget::AutoStateRestore  asr(fGpu, GrDrawTarget::kReset_ASRInit);
+    // writeRenderTargetPixels can be called in the midst of drawing another
+    // object (e.g., when uploading a SW path rendering to the gpu while 
+    // drawing a rect) so preserve the current geometry.
+    GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit);
     GrDrawState* drawState = fGpu->drawState();
     GrAssert(effect);
     drawState->setEffect(0, effect);
diff --git a/src/gpu/effects/GrTextureDomainEffect.cpp b/src/gpu/effects/GrTextureDomainEffect.cpp
index 39c992e..5b1c72f 100644
--- a/src/gpu/effects/GrTextureDomainEffect.cpp
+++ b/src/gpu/effects/GrTextureDomainEffect.cpp
@@ -70,12 +70,33 @@
         builder->fFSCode.append(";\n");
     } else {
         GrAssert(GrTextureDomainEffect::kDecal_WrapMode == effect.wrapMode());
-        builder->fFSCode.append("\tbvec4 outside;\n");
-        builder->fFSCode.appendf("\toutside.xy = lessThan(%s, %s.xy);\n", coords, domain);
-        builder->fFSCode.appendf("\toutside.zw = greaterThan(%s, %s.zw);\n", coords, domain);
-        builder->fFSCode.appendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ", outputColor);
-        builder->appendTextureLookupAndModulate(&builder->fFSCode, inputColor, samplers[0], coords);
-        builder->fFSCode.append(";\n");
+
+        if (kImagination_GrGLVendor == builder->ctxInfo().vendor()) {
+            // On the NexusS and GalaxyNexus, the other path (with the 'any' 
+            // call) causes the compilation error "Calls to any function that 
+            // may require a gradient calculation inside a conditional block 
+            // may return undefined results". This appears to be an issue with
+            // the 'any' call since even the simple "result=black; if (any())
+            // result=white;" code fails to compile.
+            builder->fFSCode.appendf("\tvec4 outside = vec4(0.0, 0.0, 0.0, 0.0);\n");
+            builder->fFSCode.appendf("\tvec4 inside = ");
+            builder->appendTextureLookupAndModulate(&builder->fFSCode, inputColor, samplers[0], coords);
+            builder->fFSCode.appendf(";\n");
+
+            builder->fFSCode.appendf("\tfloat x = abs(2.0*(%s.x - %s.x)/(%s.z - %s.x) - 1.0);\n", 
+                                     coords, domain, domain, domain);
+            builder->fFSCode.appendf("\tfloat y = abs(2.0*(%s.y - %s.y)/(%s.w - %s.y) - 1.0);\n", 
+                                     coords, domain, domain, domain);
+            builder->fFSCode.appendf("\tfloat blend = step(1.0, max(x, y));\n");
+            builder->fFSCode.appendf("\t%s = mix(inside, outside, blend);\n", outputColor);
+        } else {
+            builder->fFSCode.append("\tbvec4 outside;\n");
+            builder->fFSCode.appendf("\toutside.xy = lessThan(%s, %s.xy);\n", coords, domain);
+            builder->fFSCode.appendf("\toutside.zw = greaterThan(%s, %s.zw);\n", coords, domain);
+            builder->fFSCode.appendf("\t%s = any(outside) ? vec4(0.0, 0.0, 0.0, 0.0) : ", outputColor);
+            builder->appendTextureLookupAndModulate(&builder->fFSCode, inputColor, samplers[0], coords);
+            builder->fFSCode.append(";\n");
+        }
     }
 }
 
diff --git a/src/gpu/gl/GrGLShaderBuilder.h b/src/gpu/gl/GrGLShaderBuilder.h
index d50fbce..ce1e6d1 100644
--- a/src/gpu/gl/GrGLShaderBuilder.h
+++ b/src/gpu/gl/GrGLShaderBuilder.h
@@ -187,6 +187,8 @@
     // TODO: Make this do all the compiling, linking, etc.
     void finished(GrGLuint programID);
 
+    const GrGLContextInfo& ctxInfo() const { return fCtxInfo; }
+
 private:
     typedef GrTAllocator<GrGLShaderVar> VarArray;