Chromium Code Reviews| Index: src/image/SkImage_Gpu.cpp |
| diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp |
| index f026ebcb378c89740bf8dcf1f82cee98a2566991..cbd3c01b6adbfd0d616f3099d4ee08a142cb22fb 100644 |
| --- a/src/image/SkImage_Gpu.cpp |
| +++ b/src/image/SkImage_Gpu.cpp |
| @@ -341,15 +341,36 @@ 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. |
| + const int scaleDivisor = powf(2.0f, lowestPreScaleMipLevel); |
|
bsalomon
2016/05/26 13:12:54
1 << lowestPrecaleMipLevel?
Should we do some sor
ericrk
2016/06/09 19:46:05
Using the helper function that now exists in SkMip
|
| + const bool isScaled = scaleDivisor != 1; |
| + const int scaledWidth = this->width() / scaleDivisor; |
|
bsalomon
2016/05/26 13:12:54
I think this should probably be consistent with th
ericrk
2016/06/09 19:46:05
Cblume added one, using it now.
|
| + const int scaledHeight = this->height() / scaleDivisor; |
| + // 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 (scaledWidth > maxTextureSize || scaledHeight > maxTextureSize) { |
| return 0; |
| } |
| @@ -358,7 +379,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()) { |
| @@ -370,16 +391,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(scaledWidth, scaledHeight, 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()); |
| } |