Revert "Defer mip-mapping until lazy proxy instantiation"
This reverts commit 475819cab73082c7ff33c3bf5c56b3871cdc1280.
Reason for revert: No, let's not defer.
Original change's description:
> Defer mip-mapping until lazy proxy instantiation
>
> - Remove some checks for truly impossible failures (levelCount < 0)
> - Use helper method to predict number of mips, then verify correct
> results in the lambda.
> - Split up SkMipMap::Build with a CanBuild helper, so GPU code can
> predict success/failure accurately.
> - This is going to simplify the case where we need to change the
> config for unsupported formats.
>
> Bug: skia:8375
> Change-Id: Ied523ab55c38b8c8e7e2ae983744ed400497939b
> Reviewed-on: https://skia-review.googlesource.com/154080
> Commit-Queue: Brian Osman <brianosman@google.com>
> Reviewed-by: Robert Phillips <robertphillips@google.com>
TBR=bsalomon@google.com,robertphillips@google.com,brianosman@google.com,reed@google.com
Change-Id: I04dbc458103f7bb5a7c28da28b0256d7a2b8b3d3
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: skia:8375
Reviewed-on: https://skia-review.googlesource.com/154304
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/src/core/SkMipMap.cpp b/src/core/SkMipMap.cpp
index adc1aae..7dbe319 100644
--- a/src/core/SkMipMap.cpp
+++ b/src/core/SkMipMap.cpp
@@ -312,168 +312,148 @@
return SkTo<int32_t>(size);
}
-struct SkMipMap::BuildParams {
- typedef void (*FilterProc)(void*, const void* srcPtr, size_t srcRB, int count);
- FilterProc fProc_1_2 = nullptr;
- FilterProc fProc_1_3 = nullptr;
- FilterProc fProc_2_1 = nullptr;
- FilterProc fProc_2_2 = nullptr;
- FilterProc fProc_2_3 = nullptr;
- FilterProc fProc_3_1 = nullptr;
- FilterProc fProc_3_2 = nullptr;
- FilterProc fProc_3_3 = nullptr;
-
- int fCountLevels = 0;
- size_t fSize = 0;
- size_t fStorageSize = 0;
-};
-
-bool SkMipMap::CanBuild(const SkImageInfo& info, SkMipMap::BuildParams* outParams) {
- BuildParams params;
-
- const SkColorType ct = info.colorType();
-
- switch (ct) {
- case kRGBA_8888_SkColorType:
- case kBGRA_8888_SkColorType:
- params.fProc_1_2 = downsample_1_2<ColorTypeFilter_8888>;
- params.fProc_1_3 = downsample_1_3<ColorTypeFilter_8888>;
- params.fProc_2_1 = downsample_2_1<ColorTypeFilter_8888>;
- params.fProc_2_2 = downsample_2_2<ColorTypeFilter_8888>;
- params.fProc_2_3 = downsample_2_3<ColorTypeFilter_8888>;
- params.fProc_3_1 = downsample_3_1<ColorTypeFilter_8888>;
- params.fProc_3_2 = downsample_3_2<ColorTypeFilter_8888>;
- params.fProc_3_3 = downsample_3_3<ColorTypeFilter_8888>;
- break;
- case kRGB_565_SkColorType:
- params.fProc_1_2 = downsample_1_2<ColorTypeFilter_565>;
- params.fProc_1_3 = downsample_1_3<ColorTypeFilter_565>;
- params.fProc_2_1 = downsample_2_1<ColorTypeFilter_565>;
- params.fProc_2_2 = downsample_2_2<ColorTypeFilter_565>;
- params.fProc_2_3 = downsample_2_3<ColorTypeFilter_565>;
- params.fProc_3_1 = downsample_3_1<ColorTypeFilter_565>;
- params.fProc_3_2 = downsample_3_2<ColorTypeFilter_565>;
- params.fProc_3_3 = downsample_3_3<ColorTypeFilter_565>;
- break;
- case kARGB_4444_SkColorType:
- params.fProc_1_2 = downsample_1_2<ColorTypeFilter_4444>;
- params.fProc_1_3 = downsample_1_3<ColorTypeFilter_4444>;
- params.fProc_2_1 = downsample_2_1<ColorTypeFilter_4444>;
- params.fProc_2_2 = downsample_2_2<ColorTypeFilter_4444>;
- params.fProc_2_3 = downsample_2_3<ColorTypeFilter_4444>;
- params.fProc_3_1 = downsample_3_1<ColorTypeFilter_4444>;
- params.fProc_3_2 = downsample_3_2<ColorTypeFilter_4444>;
- params.fProc_3_3 = downsample_3_3<ColorTypeFilter_4444>;
- break;
- case kAlpha_8_SkColorType:
- case kGray_8_SkColorType:
- params.fProc_1_2 = downsample_1_2<ColorTypeFilter_8>;
- params.fProc_1_3 = downsample_1_3<ColorTypeFilter_8>;
- params.fProc_2_1 = downsample_2_1<ColorTypeFilter_8>;
- params.fProc_2_2 = downsample_2_2<ColorTypeFilter_8>;
- params.fProc_2_3 = downsample_2_3<ColorTypeFilter_8>;
- params.fProc_3_1 = downsample_3_1<ColorTypeFilter_8>;
- params.fProc_3_2 = downsample_3_2<ColorTypeFilter_8>;
- params.fProc_3_3 = downsample_3_3<ColorTypeFilter_8>;
- break;
- case kRGBA_F16_SkColorType:
- params.fProc_1_2 = downsample_1_2<ColorTypeFilter_F16>;
- params.fProc_1_3 = downsample_1_3<ColorTypeFilter_F16>;
- params.fProc_2_1 = downsample_2_1<ColorTypeFilter_F16>;
- params.fProc_2_2 = downsample_2_2<ColorTypeFilter_F16>;
- params.fProc_2_3 = downsample_2_3<ColorTypeFilter_F16>;
- params.fProc_3_1 = downsample_3_1<ColorTypeFilter_F16>;
- params.fProc_3_2 = downsample_3_2<ColorTypeFilter_F16>;
- params.fProc_3_3 = downsample_3_3<ColorTypeFilter_F16>;
- break;
- default:
- return false;
- }
-
- if (info.width() <= 1 && info.height() <= 1) {
- return false;
- }
- // whip through our loop to compute the exact size needed
- params.fCountLevels = ComputeLevelCount(info.width(), info.height());
- for (int currentMipLevel = params.fCountLevels; currentMipLevel >= 0; currentMipLevel--) {
- SkISize mipSize = ComputeLevelSize(info.width(), info.height(), currentMipLevel);
- params.fSize += SkColorTypeMinRowBytes(ct, mipSize.fWidth) * mipSize.fHeight;
- }
-
- params.fStorageSize = SkMipMap::AllocLevelsSize(params.fCountLevels, params.fSize);
- if (0 == params.fStorageSize) {
- return false;
- }
-
- if (outParams) {
- *outParams = params;
- }
- return true;
-}
-
SkMipMap* SkMipMap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact) {
- BuildParams params;
- if (!CanBuild(src.info(), ¶ms)) {
- return nullptr;
- }
+ typedef void FilterProc(void*, const void* srcPtr, size_t srcRB, int count);
+
+ FilterProc* proc_1_2 = nullptr;
+ FilterProc* proc_1_3 = nullptr;
+ FilterProc* proc_2_1 = nullptr;
+ FilterProc* proc_2_2 = nullptr;
+ FilterProc* proc_2_3 = nullptr;
+ FilterProc* proc_3_1 = nullptr;
+ FilterProc* proc_3_2 = nullptr;
+ FilterProc* proc_3_3 = nullptr;
const SkColorType ct = src.colorType();
const SkAlphaType at = src.alphaType();
+ switch (ct) {
+ case kRGBA_8888_SkColorType:
+ case kBGRA_8888_SkColorType:
+ proc_1_2 = downsample_1_2<ColorTypeFilter_8888>;
+ proc_1_3 = downsample_1_3<ColorTypeFilter_8888>;
+ proc_2_1 = downsample_2_1<ColorTypeFilter_8888>;
+ proc_2_2 = downsample_2_2<ColorTypeFilter_8888>;
+ proc_2_3 = downsample_2_3<ColorTypeFilter_8888>;
+ proc_3_1 = downsample_3_1<ColorTypeFilter_8888>;
+ proc_3_2 = downsample_3_2<ColorTypeFilter_8888>;
+ proc_3_3 = downsample_3_3<ColorTypeFilter_8888>;
+ break;
+ case kRGB_565_SkColorType:
+ proc_1_2 = downsample_1_2<ColorTypeFilter_565>;
+ proc_1_3 = downsample_1_3<ColorTypeFilter_565>;
+ proc_2_1 = downsample_2_1<ColorTypeFilter_565>;
+ proc_2_2 = downsample_2_2<ColorTypeFilter_565>;
+ proc_2_3 = downsample_2_3<ColorTypeFilter_565>;
+ proc_3_1 = downsample_3_1<ColorTypeFilter_565>;
+ proc_3_2 = downsample_3_2<ColorTypeFilter_565>;
+ proc_3_3 = downsample_3_3<ColorTypeFilter_565>;
+ break;
+ case kARGB_4444_SkColorType:
+ proc_1_2 = downsample_1_2<ColorTypeFilter_4444>;
+ proc_1_3 = downsample_1_3<ColorTypeFilter_4444>;
+ proc_2_1 = downsample_2_1<ColorTypeFilter_4444>;
+ proc_2_2 = downsample_2_2<ColorTypeFilter_4444>;
+ proc_2_3 = downsample_2_3<ColorTypeFilter_4444>;
+ proc_3_1 = downsample_3_1<ColorTypeFilter_4444>;
+ proc_3_2 = downsample_3_2<ColorTypeFilter_4444>;
+ proc_3_3 = downsample_3_3<ColorTypeFilter_4444>;
+ break;
+ case kAlpha_8_SkColorType:
+ case kGray_8_SkColorType:
+ proc_1_2 = downsample_1_2<ColorTypeFilter_8>;
+ proc_1_3 = downsample_1_3<ColorTypeFilter_8>;
+ proc_2_1 = downsample_2_1<ColorTypeFilter_8>;
+ proc_2_2 = downsample_2_2<ColorTypeFilter_8>;
+ proc_2_3 = downsample_2_3<ColorTypeFilter_8>;
+ proc_3_1 = downsample_3_1<ColorTypeFilter_8>;
+ proc_3_2 = downsample_3_2<ColorTypeFilter_8>;
+ proc_3_3 = downsample_3_3<ColorTypeFilter_8>;
+ break;
+ case kRGBA_F16_SkColorType:
+ proc_1_2 = downsample_1_2<ColorTypeFilter_F16>;
+ proc_1_3 = downsample_1_3<ColorTypeFilter_F16>;
+ proc_2_1 = downsample_2_1<ColorTypeFilter_F16>;
+ proc_2_2 = downsample_2_2<ColorTypeFilter_F16>;
+ proc_2_3 = downsample_2_3<ColorTypeFilter_F16>;
+ proc_3_1 = downsample_3_1<ColorTypeFilter_F16>;
+ proc_3_2 = downsample_3_2<ColorTypeFilter_F16>;
+ proc_3_3 = downsample_3_3<ColorTypeFilter_F16>;
+ break;
+ default:
+ return nullptr;
+ }
+
+ if (src.width() <= 1 && src.height() <= 1) {
+ return nullptr;
+ }
+ // whip through our loop to compute the exact size needed
+ size_t size = 0;
+ int countLevels = ComputeLevelCount(src.width(), src.height());
+ for (int currentMipLevel = countLevels; currentMipLevel >= 0; currentMipLevel--) {
+ SkISize mipSize = ComputeLevelSize(src.width(), src.height(), currentMipLevel);
+ size += SkColorTypeMinRowBytes(ct, mipSize.fWidth) * mipSize.fHeight;
+ }
+
+ size_t storageSize = SkMipMap::AllocLevelsSize(countLevels, size);
+ if (0 == storageSize) {
+ return nullptr;
+ }
+
SkMipMap* mipmap;
if (fact) {
- SkDiscardableMemory* dm = fact(params.fStorageSize);
+ SkDiscardableMemory* dm = fact(storageSize);
if (nullptr == dm) {
return nullptr;
}
- mipmap = new SkMipMap(params.fStorageSize, dm);
+ mipmap = new SkMipMap(storageSize, dm);
} else {
- mipmap = new SkMipMap(sk_malloc_throw(params.fStorageSize), params.fStorageSize);
+ mipmap = new SkMipMap(sk_malloc_throw(storageSize), storageSize);
}
// init
mipmap->fCS = sk_ref_sp(src.info().colorSpace());
- mipmap->fCount = params.fCountLevels;
+ mipmap->fCount = countLevels;
mipmap->fLevels = (Level*)mipmap->writable_data();
SkASSERT(mipmap->fLevels);
Level* levels = mipmap->fLevels;
- uint8_t* baseAddr = (uint8_t*)&levels[params.fCountLevels];
+ uint8_t* baseAddr = (uint8_t*)&levels[countLevels];
uint8_t* addr = baseAddr;
int width = src.width();
int height = src.height();
uint32_t rowBytes;
SkPixmap srcPM(src);
- for (int i = 0; i < params.fCountLevels; ++i) {
- BuildParams::FilterProc proc;
+ for (int i = 0; i < countLevels; ++i) {
+ FilterProc* proc;
if (height & 1) {
if (height == 1) { // src-height is 1
if (width & 1) { // src-width is 3
- proc = params.fProc_3_1;
+ proc = proc_3_1;
} else { // src-width is 2
- proc = params.fProc_2_1;
+ proc = proc_2_1;
}
} else { // src-height is 3
if (width & 1) {
if (width == 1) { // src-width is 1
- proc = params.fProc_1_3;
+ proc = proc_1_3;
} else { // src-width is 3
- proc = params.fProc_3_3;
+ proc = proc_3_3;
}
} else { // src-width is 2
- proc = params.fProc_2_3;
+ proc = proc_2_3;
}
}
} else { // src-height is 2
if (width & 1) {
if (width == 1) { // src-width is 1
- proc = params.fProc_1_2;
+ proc = proc_1_2;
} else { // src-width is 3
- proc = params.fProc_3_2;
+ proc = proc_3_2;
}
} else { // src-width is 2
- proc = params.fProc_2_2;
+ proc = proc_2_2;
}
}
width = SkTMax(1, width >> 1);
@@ -500,7 +480,7 @@
srcPM = dstPM;
addr += height * rowBytes;
}
- SkASSERT(addr == baseAddr + params.fSize);
+ SkASSERT(addr == baseAddr + size);
SkASSERT(mipmap->fLevels);
return mipmap;
diff --git a/src/core/SkMipMap.h b/src/core/SkMipMap.h
index d35439c..c6fc24d 100644
--- a/src/core/SkMipMap.h
+++ b/src/core/SkMipMap.h
@@ -29,10 +29,6 @@
*/
class SkMipMap : public SkCachedData {
public:
- struct BuildParams;
-
- static bool CanBuild(const SkImageInfo& info, BuildParams*);
-
static SkMipMap* Build(const SkPixmap& src, SkDiscardableFactoryProc);
static SkMipMap* Build(const SkBitmap& src, SkDiscardableFactoryProc);
diff --git a/src/gpu/GrProxyProvider.cpp b/src/gpu/GrProxyProvider.cpp
index 77fc632..d09a1a2 100644
--- a/src/gpu/GrProxyProvider.cpp
+++ b/src/gpu/GrProxyProvider.cpp
@@ -279,7 +279,20 @@
return nullptr;
}
- ATRACE_ANDROID_FRAMEWORK("Upload MipMap Texture [%ux%u]", bitmap.width(), bitmap.height());
+ SkPixmap pixmap;
+ if (!bitmap.peekPixels(&pixmap)) {
+ return nullptr;
+ }
+
+ ATRACE_ANDROID_FRAMEWORK("Upload MipMap Texture [%ux%u]", pixmap.width(), pixmap.height());
+ sk_sp<SkMipMap> mipmaps(SkMipMap::Build(pixmap, nullptr));
+ if (!mipmaps) {
+ return nullptr;
+ }
+
+ if (mipmaps->countLevels() < 0) {
+ return nullptr;
+ }
// In non-ddl we will always instantiate right away. Thus we never want to copy the SkBitmap
// even if its mutable. In ddl, if the bitmap is mutable then we must make a copy since the
@@ -287,39 +300,30 @@
SkCopyPixelsMode copyMode = this->recordingDDL() ? kIfMutable_SkCopyPixelsMode
: kNever_SkCopyPixelsMode;
sk_sp<SkImage> baseLevel = SkMakeImageFromRasterBitmap(bitmap, copyMode);
+
if (!baseLevel) {
return nullptr;
}
- // This was never going to have mips anyway
- if (0 == SkMipMap::ComputeLevelCount(baseLevel->width(), baseLevel->height())) {
+ GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(pixmap.info());
+
+ if (0 == mipmaps->countLevels()) {
return this->createTextureProxy(baseLevel, kNone_GrSurfaceFlags, 1, SkBudgeted::kYes,
SkBackingFit::kExact);
}
- if (!SkMipMap::CanBuild(bitmap.info(), nullptr)) {
- return nullptr;
- }
-
- GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(bitmap.info());
-
sk_sp<GrTextureProxy> proxy = this->createLazyProxy(
- [desc, baseLevel](GrResourceProvider* resourceProvider) {
+ [desc, baseLevel, mipmaps](GrResourceProvider* resourceProvider) {
if (!resourceProvider) {
return sk_sp<GrTexture>();
}
+ const int mipLevelCount = mipmaps->countLevels() + 1;
+ std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
+
SkPixmap pixmap;
SkAssertResult(baseLevel->peekPixels(&pixmap));
- int mipLevelCount = 1;
- sk_sp<SkMipMap> mipmaps(SkMipMap::Build(pixmap, nullptr));
- if (mipmaps) {
- mipLevelCount += mipmaps->countLevels();
- }
-
- std::unique_ptr<GrMipLevel[]> texels(new GrMipLevel[mipLevelCount]);
-
// DDL TODO: Instead of copying all this info into GrMipLevels we should just plumb
// the use of SkMipMap down through Ganesh.
texels[0].fPixels = pixmap.addr();