aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/image/SkImage_Gpu.cpp
diff options
context:
space:
mode:
authorGravatar ericrk <ericrk@chromium.org>2016-06-13 11:18:14 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-06-13 11:18:14 -0700
commitb4da01d8f719f3c43d492e8f62a7e2c861e9ef27 (patch)
tree714d91a435b4de4c6e14998e6d0b30c25dc769b5 /src/image/SkImage_Gpu.cpp
parent6e472093009bf2fc4a8e53010b51040efcb71213 (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.cpp51
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());
}