Pass color types when creating texture with initial data.

One describes the color type use case for the texture and the other
the color type of the texel data, a la writePixels().

Bug: skia:6718

Change-Id: I3ca2ab9f76aaeca4b2861a171b1aaacaa0709d1e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/240679
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index a7a3bb1..efc000f 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -99,11 +99,12 @@
     return false;
 }
 
-static bool validate_texel_levels(int w, int h, const GrMipLevel* texels, int mipLevelCount,
-                                  int bpp, const GrCaps* caps) {
+static bool validate_texel_levels(int w, int h, GrColorType texelColorType,
+                                  const GrMipLevel* texels, int mipLevelCount, const GrCaps* caps) {
     SkASSERT(mipLevelCount > 0);
     bool hasBasePixels = texels[0].fPixels;
     int levelsWithPixelsCnt = 0;
+    auto bpp = GrColorTypeBytesPerPixel(texelColorType);
     for (int currentMipLevel = 0; currentMipLevel < mipLevelCount; ++currentMipLevel) {
         if (texels[currentMipLevel].fPixels) {
             const size_t minRowBytes = w * bpp;
@@ -141,21 +142,20 @@
     return levelsWithPixelsCnt == 1 || levelsWithPixelsCnt == mipLevelCount;
 }
 
-sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& desc,
-                                      const GrBackendFormat& format,
-                                      GrRenderable renderable,
-                                      int renderTargetSampleCnt,
-                                      SkBudgeted budgeted,
-                                      GrProtected isProtected,
-                                      const GrMipLevel texels[],
-                                      int texelLevelCount) {
-    TRACE_EVENT0("skia.gpu", TRACE_FUNC);
+sk_sp<GrTexture> GrGpu::createTextureCommon(const GrSurfaceDesc& desc,
+                                            const GrBackendFormat& format,
+                                            GrRenderable renderable,
+                                            int renderTargetSampleCnt,
+                                            SkBudgeted budgeted,
+                                            GrProtected isProtected,
+                                            int mipLevelCount,
+                                            uint32_t levelClearMask) {
     if (this->caps()->isFormatCompressed(format)) {
         // Call GrGpu::createCompressedTexture.
         return nullptr;
     }
 
-    GrMipMapped mipMapped = texelLevelCount > 1 ? GrMipMapped::kYes : GrMipMapped::kNo;
+    GrMipMapped mipMapped = mipLevelCount > 1 ? GrMipMapped::kYes : GrMipMapped::kNo;
     if (!this->caps()->validateSurfaceParams({desc.fWidth, desc.fHeight}, format, desc.fConfig,
                                              renderable, renderTargetSampleCnt, mipMapped)) {
         return nullptr;
@@ -167,9 +167,64 @@
     }
     // Attempt to catch un- or wrongly initialized sample counts.
     SkASSERT(renderTargetSampleCnt > 0 && renderTargetSampleCnt <= 64);
+    this->handleDirtyContext();
+    auto tex = this->onCreateTexture(desc,
+                                     format,
+                                     renderable,
+                                     renderTargetSampleCnt,
+                                     budgeted,
+                                     isProtected,
+                                     mipLevelCount,
+                                     levelClearMask);
+    if (tex) {
+        SkASSERT(tex->backendFormat() == format);
+        SkASSERT(GrRenderable::kNo == renderable || tex->asRenderTarget());
+        if (!this->caps()->reuseScratchTextures() && renderable == GrRenderable::kNo) {
+            tex->resourcePriv().removeScratchKey();
+        }
+        fStats.incTextureCreates();
+        if (renderTargetSampleCnt > 1 && !this->caps()->msaaResolvesAutomatically()) {
+            SkASSERT(GrRenderable::kYes == renderable);
+            tex->asRenderTarget()->setRequiresManualMSAAResolve();
+        }
+    }
+    return tex;
+}
+
+sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& desc,
+                                      const GrBackendFormat& format,
+                                      GrRenderable renderable,
+                                      int renderTargetSampleCnt,
+                                      GrMipMapped mipMapped,
+                                      SkBudgeted budgeted,
+                                      GrProtected isProtected) {
+    int mipLevelCount = 1;
+    if (mipMapped == GrMipMapped::kYes) {
+        mipLevelCount = 32 - SkCLZ(static_cast<uint32_t>(SkTMax(desc.fWidth, desc.fHeight)));
+    }
+    uint32_t levelClearMask =
+            this->caps()->shouldInitializeTextures() ? (1 << mipLevelCount) - 1 : 0;
+    auto tex = this->createTextureCommon(desc, format, renderable, renderTargetSampleCnt, budgeted,
+                                         isProtected, mipLevelCount, levelClearMask);
+    if (tex && mipMapped == GrMipMapped::kYes && levelClearMask) {
+        tex->texturePriv().markMipMapsClean();
+    }
+    return tex;
+}
+
+sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& desc,
+                                      const GrBackendFormat& format,
+                                      GrRenderable renderable,
+                                      int renderTargetSampleCnt,
+                                      SkBudgeted budgeted,
+                                      GrProtected isProtected,
+                                      GrColorType textureColorType,
+                                      GrColorType srcColorType,
+                                      const GrMipLevel texels[],
+                                      int texelLevelCount) {
+    TRACE_EVENT0("skia.gpu", TRACE_FUNC);
     if (texelLevelCount) {
-        int bpp = GrBytesPerPixel(desc.fConfig);
-        if (!validate_texel_levels(desc.fWidth, desc.fHeight, texels, texelLevelCount, bpp,
+        if (!validate_texel_levels(desc.fWidth, desc.fHeight, srcColorType, texels, texelLevelCount,
                                    this->caps())) {
             return nullptr;
         }
@@ -189,31 +244,15 @@
         }
     }
 
-    this->handleDirtyContext();
-    sk_sp<GrTexture> tex = this->onCreateTexture(desc,
-                                                 format,
-                                                 renderable,
-                                                 renderTargetSampleCnt,
-                                                 budgeted,
-                                                 isProtected,
-                                                 mipLevelCount,
-                                                 levelClearMask);
-
+    auto tex = this->createTextureCommon(desc, format, renderable, renderTargetSampleCnt, budgeted,
+                                         isProtected, texelLevelCount, levelClearMask);
     if (tex) {
-        SkASSERT(tex->backendFormat() == format);
-        SkASSERT(GrRenderable::kNo == renderable || tex->asRenderTarget());
-        if (!this->caps()->reuseScratchTextures() && renderable == GrRenderable::kNo) {
-            tex->resourcePriv().removeScratchKey();
-        }
-        fStats.incTextureCreates();
         bool markMipLevelsClean = false;
         // Currently if level 0 does not have pixels then no other level may, as enforced by
         // validate_texel_levels.
         if (texelLevelCount && texels[0].fPixels) {
-            auto textureColorType = GrPixelConfigToColorType(desc.fConfig);
-            auto dataColorType = textureColorType;
             if (!this->writePixels(tex.get(), 0, 0, desc.fWidth, desc.fHeight, textureColorType,
-                                   dataColorType, texels, texelLevelCount)) {
+                                   srcColorType, texels, texelLevelCount)) {
                 return nullptr;
             }
             // Currently if level[1] of mip map has pixel data then so must all other levels.
@@ -226,21 +265,10 @@
         if (markMipLevelsClean) {
             tex->texturePriv().markMipMapsClean();
         }
-        if (renderTargetSampleCnt > 1 && !this->caps()->msaaResolvesAutomatically()) {
-            SkASSERT(GrRenderable::kYes == renderable);
-            tex->asRenderTarget()->setRequiresManualMSAAResolve();
-        }
     }
     return tex;
 }
 
-sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& desc, const GrBackendFormat& format,
-                                      GrRenderable renderable, int renderTargetSampleCnt,
-                                      SkBudgeted budgeted, GrProtected isProtected) {
-    return this->createTexture(desc, format, renderable, renderTargetSampleCnt, budgeted,
-                               isProtected, nullptr, 0);
-}
-
 sk_sp<GrTexture> GrGpu::createCompressedTexture(int width, int height,
                                                 const GrBackendFormat& format,
                                                 SkImage::CompressionType compressionType,
@@ -454,8 +482,7 @@
         return false;
     }
 
-    size_t bpp = GrColorTypeBytesPerPixel(srcColorType);
-    if (!validate_texel_levels(width, height, texels, mipLevelCount, bpp, this->caps())) {
+    if (!validate_texel_levels(width, height, srcColorType, texels, mipLevelCount, this->caps())) {
         return false;
     }