Rework how initial clearing of texture works.
1) It only applies when a texture is created, not when recycled from cache
2) It is all textures or none, not a flag GrSurfaceDesc
3) It is implemented by GrGpu clearing the texture after creation if
such a thing is supported in underlying API. Otherwise, GrResourceProvider
must provide pre-zeroed mip levels.
4) Works for MIP mapped textures (all levels without initial data are cleared)
This could cause performance regressions in WebGL until we re-add the
ability to clear using glCear() in GL. Doing that requires making the "can
clear using GrGpu" caps query be per-format. Deferring doing that until
GrPixelConfig work is farther along.
Bug: skia:6718
Change-Id: I234715b9faaf61e8b44d54464497a17cd553585d
start
Change-Id: Ib84a8c3ece010cc3164b18895107e78484cbf76b
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/226977
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/gl/GrGLGpu.cpp b/src/gpu/gl/GrGLGpu.cpp
index fa92dff..1cd837c 100644
--- a/src/gpu/gl/GrGLGpu.cpp
+++ b/src/gpu/gl/GrGLGpu.cpp
@@ -1469,31 +1469,9 @@
int mipLevelCount) {
// We fail if the MSAA was requested and is not available.
if (GrGLCaps::kNone_MSFBOType == this->glCaps().msFBOType() && desc.fSampleCnt > 1) {
- //SkDebugf("MSAA RT requested but not supported on this platform.");
return return_null_texture();
}
- GrGLFormat glFormat =
- GrGLFormatFromGLEnum(this->glCaps().configSizedInternalFormat(desc.fConfig));
-
- bool performClear = (desc.fFlags & kPerformInitialClear_GrSurfaceFlag) &&
- !GrGLFormatIsCompressed(glFormat);
-
- GrMipLevel zeroLevel;
- std::unique_ptr<uint8_t[]> zeros;
- if (performClear && !this->glCaps().clearTextureSupport() &&
- !this->glCaps().canConfigBeFBOColorAttachment(desc.fConfig)) {
- size_t rowBytes = GrGLBytesPerFormat(glFormat) * desc.fWidth;
- size_t size = rowBytes * desc.fHeight;
- zeros.reset(new uint8_t[size]);
- memset(zeros.get(), 0, size);
- zeroLevel.fPixels = zeros.get();
- zeroLevel.fRowBytes = rowBytes;
- texels = &zeroLevel;
- mipLevelCount = 1;
- performClear = false;
- }
-
bool isRenderTarget = SkToBool(desc.fFlags & kRenderTarget_GrSurfaceFlag);
GrGLTexture::IDDesc idDesc;
@@ -1529,19 +1507,17 @@
SkDebugf("--- new texture [%d] size=(%d %d) config=%d\n",
idDesc.fInfo.fID, desc.fWidth, desc.fHeight, desc.fConfig);
#endif
- if (tex && performClear) {
- if (this->glCaps().clearTextureSupport()) {
- static constexpr uint32_t kZero = 0;
- GL_CALL(ClearTexImage(tex->textureID(), 0, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE, &kZero));
- } else {
- this->bindSurfaceFBOForPixelOps(tex.get(), GR_GL_FRAMEBUFFER, kDst_TempFBOTarget);
- this->disableScissor();
- this->disableWindowRectangles();
- this->flushColorWrite(true);
- this->flushClearColor(0, 0, 0, 0);
- GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
- this->unbindTextureFBOForPixelOps(GR_GL_FRAMEBUFFER, tex.get());
- fHWBoundRenderTargetUniqueID.makeInvalid();
+ bool clearLevelsWithoutData =
+ this->caps()->shouldInitializeTextures() && this->glCaps().clearTextureSupport();
+
+ if (clearLevelsWithoutData) {
+ static constexpr uint32_t kZero = 0;
+ int levelCnt = SkTMax(1, tex->texturePriv().maxMipMapLevel());
+ for (int i = 0; i < levelCnt; ++i) {
+ if (i >= mipLevelCount || !texels[i].fPixels) {
+ GL_CALL(ClearTexImage(tex->textureID(), i, GR_GL_RGBA, GR_GL_UNSIGNED_BYTE,
+ &kZero));
+ }
}
}
return std::move(tex);