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/GrGpu.cpp b/src/gpu/GrGpu.cpp
index f007304..addbc15 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -100,7 +100,7 @@
}
static bool validate_levels(int w, int h, const GrMipLevel texels[], int mipLevelCount, int bpp,
- const GrCaps* caps) {
+ const GrCaps* caps, bool mustHaveDataForAllLevels = false) {
SkASSERT(mipLevelCount > 0);
bool hasBasePixels = texels[0].fPixels;
int levelsWithPixelsCnt = 0;
@@ -138,7 +138,10 @@
if (!hasBasePixels) {
return levelsWithPixelsCnt == 0;
}
- return levelsWithPixelsCnt == 1 || levelsWithPixelsCnt == mipLevelCount;
+ if (levelsWithPixelsCnt == 1 && !mustHaveDataForAllLevels) {
+ return true;
+ }
+ return levelsWithPixelsCnt == mipLevelCount;
}
sk_sp<GrTexture> GrGpu::createTexture(const GrSurfaceDesc& origDesc, SkBudgeted budgeted,
@@ -162,14 +165,15 @@
// Attempt to catch un- or wrongly initialized sample counts.
SkASSERT(desc.fSampleCnt > 0 && desc.fSampleCnt <= 64);
+ bool mustHaveDataForAllLevels = this->caps()->createTextureMustSpecifyAllLevels();
if (mipLevelCount) {
- if (desc.fFlags & kPerformInitialClear_GrSurfaceFlag) {
- return nullptr;
- }
int bpp = GrBytesPerPixel(desc.fConfig);
- if (!validate_levels(desc.fWidth, desc.fHeight, texels, mipLevelCount, bpp, this->caps())) {
+ if (!validate_levels(desc.fWidth, desc.fHeight, texels, mipLevelCount, bpp, this->caps(),
+ mustHaveDataForAllLevels)) {
return nullptr;
}
+ } else if (mustHaveDataForAllLevels) {
+ return nullptr;
}
this->handleDirtyContext();
@@ -201,6 +205,8 @@
height < 1 || height > this->caps()->maxTextureSize()) {
return nullptr;
}
+ // Note if we relax the requirement that data must be provided then we must check
+ // caps()->shouldInitializeTextures() here.
if (!data) {
return nullptr;
}