Initialize unfilled textures based on GrCaps

This is especially relevant on WebGL, where there
can be a large performance hit to dealing with
uninitialized textures.

Change-Id: Ic8469ec833464a88fe846c72fc02a9af5d43d0d5
Bug: skia:8378
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/206396
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Kevin Lubick <kjlubick@google.com>
diff --git a/src/gpu/GrDrawOpAtlas.cpp b/src/gpu/GrDrawOpAtlas.cpp
index 94afadc..0d9cd80 100644
--- a/src/gpu/GrDrawOpAtlas.cpp
+++ b/src/gpu/GrDrawOpAtlas.cpp
@@ -515,7 +515,13 @@
     SkASSERT(SkIsPow2(fTextureWidth) && SkIsPow2(fTextureHeight));
 
     GrSurfaceDesc desc;
-    desc.fFlags = kNone_GrSurfaceFlags;
+    if (proxyProvider->caps()->shouldInitializeTextures()) {
+        // The atlas isn't guaranteed to touch all its pixels so, for platforms that benefit
+        // from complete initialization, clear everything.
+        desc.fFlags = kPerformInitialClear_GrSurfaceFlag;
+    } else {
+        desc.fFlags = kNone_GrSurfaceFlags;
+    }
     desc.fWidth = fTextureWidth;
     desc.fHeight = fTextureHeight;
     desc.fConfig = fPixelConfig;
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 7638bf1..c02818a 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -7,6 +7,7 @@
 
 #include "GrSWMaskHelper.h"
 
+#include "GrCaps.h"
 #include "GrProxyProvider.h"
 #include "GrRecordingContext.h"
 #include "GrRecordingContextPriv.h"
@@ -115,15 +116,9 @@
         surfaceFlags |= GrInternalSurfaceFlags::kNoPendingIO;
     }
     auto clearFlag = kNone_GrSurfaceFlags;
-    // In a WASM build on Firefox, we see warnings like
-    // WebGL warning: texSubImage2D: This operation requires zeroing texture data. This is slow.
-    // WebGL warning: texSubImage2D: Texture has not been initialized prior to a partial upload,
-    //                forcing the browser to clear it. This may be slow.
-    // Setting the initial clear seems to make those warnings go away and offers a substantial
-    // boost in performance in Firefox. Chrome sees a more modest increase.
-#if IS_WEBGL==1
-    clearFlag = kPerformInitialClear_GrSurfaceFlag;
-#endif
+    if (context->priv().caps()->shouldInitializeTextures() && fit == SkBackingFit::kApprox) {
+        clearFlag = kPerformInitialClear_GrSurfaceFlag;
+    }
     return context->priv().proxyProvider()->createTextureProxy(
             std::move(img), clearFlag, 1, SkBudgeted::kYes, fit, surfaceFlags);
 }
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
index fdbcb79..1153742 100644
--- a/src/gpu/GrYUVProvider.cpp
+++ b/src/gpu/GrYUVProvider.cpp
@@ -6,6 +6,8 @@
  */
 
 #include "GrYUVProvider.h"
+
+#include "GrCaps.h"
 #include "GrClip.h"
 #include "GrColorSpaceXform.h"
 #include "GrProxyProvider.h"
@@ -17,8 +19,8 @@
 #include "SkCachedData.h"
 #include "SkRefCnt.h"
 #include "SkResourceCache.h"
-#include "SkYUVPlanesCache.h"
 #include "SkYUVAIndex.h"
+#include "SkYUVPlanesCache.h"
 #include "effects/GrYUVtoRGBEffect.h"
 
 sk_sp<SkCachedData> GrYUVProvider::getPlanes(SkYUVASizeInfo* size,
@@ -148,7 +150,11 @@
                                                           dataStoragePtr);
 
         auto proxyProvider = ctx->priv().proxyProvider();
-        yuvTextureProxies[i] = proxyProvider->createTextureProxy(yuvImage, kNone_GrSurfaceFlags,
+        auto clearFlag = kNone_GrSurfaceFlags;
+        if (ctx->priv().caps()->shouldInitializeTextures() && fit == SkBackingFit::kApprox) {
+            clearFlag = kPerformInitialClear_GrSurfaceFlag;
+        }
+        yuvTextureProxies[i] = proxyProvider->createTextureProxy(yuvImage, clearFlag,
                                                                  1, SkBudgeted::kYes, fit);
 
         SkASSERT(yuvTextureProxies[i]->width() == yuvSizeInfo.fSizes[i].fWidth);