Make not-reusing-scratch-textures only apply to texture uploads

https://codereview.chromium.org/53133002/



git-svn-id: http://skia.googlecode.com/svn/trunk@12037 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index bfca12f..bcc71f4 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -392,7 +392,8 @@
 // hit)
 bool GrClipMaskManager::getMaskTexture(int32_t clipStackGenID,
                                        const SkIRect& clipSpaceIBounds,
-                                       GrTexture** result) {
+                                       GrTexture** result,
+                                       bool willUpload) {
     bool cached = fAACache.canReuse(clipStackGenID, clipSpaceIBounds);
     if (!cached) {
 
@@ -402,7 +403,7 @@
         fAACache.reset();
 
         GrTextureDesc desc;
-        desc.fFlags = kRenderTarget_GrTextureFlagBit;
+        desc.fFlags = willUpload ? kNone_GrTextureFlags : kRenderTarget_GrTextureFlagBit;
         desc.fWidth = clipSpaceIBounds.width();
         desc.fHeight = clipSpaceIBounds.height();
         desc.fConfig = kRGBA_8888_GrPixelConfig;
@@ -427,7 +428,7 @@
     SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
 
     GrTexture* result;
-    if (this->getMaskTexture(clipStackGenID, clipSpaceIBounds, &result)) {
+    if (this->getMaskTexture(clipStackGenID, clipSpaceIBounds, &result, false)) {
         fCurrClipMaskType = kAlpha_ClipMaskType;
         return result;
     }
@@ -925,7 +926,7 @@
     SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
 
     GrTexture* result;
-    if (this->getMaskTexture(clipStackGenID, clipSpaceIBounds, &result)) {
+    if (this->getMaskTexture(clipStackGenID, clipSpaceIBounds, &result, true)) {
         return result;
     }
 
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index fa93987..015c801 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -121,10 +121,11 @@
 
     // Gets a texture to use for the clip mask. If true is returned then a cached mask was found
     // that already contains the rasterization of the clip stack, otherwise an uninitialized texture
-    // is returned.
+    // is returned. 'willUpload' is set when the alpha mask needs to be uploaded from the CPU.
     bool getMaskTexture(int32_t clipStackGenID,
                         const SkIRect& clipSpaceIBounds,
-                        GrTexture** result);
+                        GrTexture** result,
+                        bool willUpload);
 
     bool useSWOnlyPath(const GrReducedClip::ElementList& elements);
 
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index e3fc400..967738a 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -447,9 +447,9 @@
              !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit) ||
              (inDesc.fConfig != kAlpha_8_GrPixelConfig));
 
-    if (!fGpu->caps()->reuseScratchTextures()) {
-        // If we're never recycling scratch textures we can
-        // always make them the right size
+    if (!fGpu->caps()->reuseScratchTextures() &&
+        !(inDesc.fFlags & kRenderTarget_GrTextureFlagBit)) {
+        // If we're never recycling this texture we can always make it the right size
         return create_scratch_texture(fGpu, fTextureCache, inDesc);
     }
 
@@ -514,7 +514,7 @@
     // for the creation ref. Assert refcnt == 1.
     SkASSERT(texture->unique());
 
-    if (fGpu->caps()->reuseScratchTextures()) {
+    if (fGpu->caps()->reuseScratchTextures() || NULL != texture->asRenderTarget()) {
         // Since this texture came from an AutoScratchTexture it should
         // still be in the exclusive pile. Recycle it.
         fTextureCache->makeNonExclusive(texture->getCacheEntry());
@@ -542,7 +542,7 @@
     // while it was locked (to avoid two callers simultaneously getting
     // the same texture).
     if (texture->getCacheEntry()->key().isScratch()) {
-        if (fGpu->caps()->reuseScratchTextures()) {
+        if (fGpu->caps()->reuseScratchTextures() || NULL != texture->asRenderTarget()) {
             fTextureCache->makeNonExclusive(texture->getCacheEntry());
             this->purgeCache();
         } else if (texture->unique() && texture->getDeferredRefCount() <= 0) {
diff --git a/src/gpu/GrDrawTargetCaps.h b/src/gpu/GrDrawTargetCaps.h
index b0a721c..3c7fd6a 100644
--- a/src/gpu/GrDrawTargetCaps.h
+++ b/src/gpu/GrDrawTargetCaps.h
@@ -37,6 +37,11 @@
     bool bufferLockSupport() const { return fBufferLockSupport; }
     bool pathRenderingSupport() const { return fPathRenderingSupport; }
     bool dstReadInShaderSupport() const { return fDstReadInShaderSupport; }
+
+    // Scratch textures not being reused means that those scratch textures
+    // that we upload to (i.e., don't have a render target) will not be 
+    // recycled in the texture cache. This is to prevent ghosting by drivers
+    // (in particular for deferred architectures).
     bool reuseScratchTextures() const { return fReuseScratchTextures; }
 
     int maxRenderTargetSize() const { return fMaxRenderTargetSize; }
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 624b796..5fb944b 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -138,6 +138,9 @@
     // writing since no one else will be using 'texture'
     bool reuseScratch = fContext->getGpu()->caps()->reuseScratchTextures();
 
+    // Since we're uploading to it, 'texture' shouldn't have a render target.
+    SkASSERT(NULL == texture->asRenderTarget());
+
     texture->writePixels(0, 0, fBM.width(), fBM.height(),
                          kAlpha_8_GrPixelConfig,
                          fBM.getPixels(), fBM.rowBytes(),