diff options
author | ericrk <ericrk@chromium.org> | 2016-06-13 11:18:14 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-06-13 11:18:14 -0700 |
commit | b4da01d8f719f3c43d492e8f62a7e2c861e9ef27 (patch) | |
tree | 714d91a435b4de4c6e14998e6d0b30c25dc769b5 /src/image/SkImage_Gpu.cpp | |
parent | 6e472093009bf2fc4a8e53010b51040efcb71213 (diff) |
Add prescale option to deferred params
Currently, Skia always uploads GPU textures at full resolution. This
change allows us to pass a pre-scale mip level to the
deferred texture image logic, which causes us to pre-scale the image
to the given mip level, and upload that mip level instead of the full
image.
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2007113008
Review-Url: https://codereview.chromium.org/2007113008
Diffstat (limited to 'src/image/SkImage_Gpu.cpp')
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 51 |
1 files changed, 44 insertions, 7 deletions
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp index 9ad33ea2ba..7f459376e7 100644 --- a/src/image/SkImage_Gpu.cpp +++ b/src/image/SkImage_Gpu.cpp @@ -16,6 +16,7 @@ #include "SkGrPixelRef.h" #include "SkGrPriv.h" #include "SkImage_Gpu.h" +#include "SkMipMap.h" #include "SkPixelRef.h" SkImage_Gpu::SkImage_Gpu(int w, int h, uint32_t uniqueID, SkAlphaType at, GrTexture* tex, @@ -374,15 +375,44 @@ private: }; size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& proxy, - const DeferredTextureImageUsageParams[], + const DeferredTextureImageUsageParams params[], int paramCnt, void* buffer) const { + // Extract relevant min/max values from the params array. + int lowestPreScaleMipLevel = params[0].fPreScaleMipLevel; + SkFilterQuality highestFilterQuality = params[0].fQuality; + for (int i = 1; i < paramCnt; ++i) { + if (lowestPreScaleMipLevel > params[i].fPreScaleMipLevel) + lowestPreScaleMipLevel = params[i].fPreScaleMipLevel; + if (highestFilterQuality < params[i].fQuality) + highestFilterQuality = params[i].fQuality; + } + const bool fillMode = SkToBool(buffer); if (fillMode && !SkIsAlign8(reinterpret_cast<intptr_t>(buffer))) { return 0; } + // Calculate scaling parameters. + bool isScaled = lowestPreScaleMipLevel != 0; + + SkISize scaledSize; + if (isScaled) { + // SkMipMap::ComputeLevelSize takes an index into an SkMipMap. SkMipMaps don't contain the + // base level, so to get an SkMipMap index we must subtract one from the GL MipMap level. + scaledSize = SkMipMap::ComputeLevelSize(this->width(), this->height(), + lowestPreScaleMipLevel - 1); + } else { + scaledSize = SkISize::Make(this->width(), this->height()); + } + + // We never want to scale at higher than SW medium quality, as SW medium matches GPU high. + SkFilterQuality scaleFilterQuality = highestFilterQuality; + if (scaleFilterQuality > kMedium_SkFilterQuality) { + scaleFilterQuality = kMedium_SkFilterQuality; + } + const int maxTextureSize = proxy.fCaps->maxTextureSize(); - if (width() > maxTextureSize || height() > maxTextureSize) { + if (scaledSize.width() > maxTextureSize || scaledSize.height() > maxTextureSize) { return 0; } @@ -391,7 +421,7 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox size_t pixelSize = 0; size_t ctSize = 0; int ctCount = 0; - if (this->peekPixels(&pixmap)) { + if (!isScaled && this->peekPixels(&pixmap)) { info = pixmap.info(); pixelSize = SkAlign8(pixmap.getSafeSize()); if (pixmap.ctable()) { @@ -403,16 +433,23 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox // In the future we will access the cacherator and get the exact data that we want to (e.g. // yuv planes) upload. SkAutoTUnref<SkData> data(this->refEncoded()); - if (!data) { + if (!data && !this->peekPixels(nullptr)) { return 0; } SkAlphaType at = this->isOpaque() ? kOpaque_SkAlphaType : kPremul_SkAlphaType; - info = SkImageInfo::MakeN32(this->width(), this->height(), at); + info = SkImageInfo::MakeN32(scaledSize.width(), scaledSize.height(), at); pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr)); if (fillMode) { pixmap.alloc(info); - if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHint)) { - return 0; + if (isScaled) { + if (!this->scalePixels(pixmap, scaleFilterQuality, + SkImage::kDisallow_CachingHint)) { + return 0; + } + } else { + if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHint)) { + return 0; + } } SkASSERT(!pixmap.ctable()); } |