aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/image
diff options
context:
space:
mode:
authorGravatar Eric Karl <ericrk@chromium.org>2017-06-12 10:05:49 -0700
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-06-12 18:27:48 +0000
commit7a8c84c6c92565842aeea27d4971fbd78d523f7a (patch)
tree703d50fbd35830c529db5ed97388503189135360 /src/image
parenta8d45e522097d4efe3b12bc26158870bd76299b7 (diff)
Reland DeferredTextureImageData low-bit-depth/dithering support
Cause DeferredTextureImageData functionality to support low bit depth (4444, 565) image formats (with dithering). Updated to handle colorspace + 4444 colortype correctly. Bug: 720105 Change-Id: Ib7e14d937849f4f6b08fda6992a240bb203d0089 Reviewed-on: https://skia-review.googlesource.com/19094 Commit-Queue: Eric Karl <ericrk@chromium.org> Reviewed-by: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/image')
-rw-r--r--src/image/SkImage.cpp3
-rw-r--r--src/image/SkImage_Gpu.cpp54
2 files changed, 45 insertions, 12 deletions
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index 858aa9b029..7ec7b35156 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -347,7 +347,8 @@ sk_sp<SkImage> SkImage::MakeFromTexture(GrContext* ctx,
size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy&,
const DeferredTextureImageUsageParams[],
int paramCnt, void* buffer,
- SkColorSpace* dstColorSpace) const {
+ SkColorSpace* dstColorSpace,
+ SkColorType dstColorType) const {
return 0;
}
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index 55ceba06d2..19b0bc1bae 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -597,10 +597,22 @@ private:
offsetof(DeferredTextureImage, member), \
sizeof(DeferredTextureImage::member));
+static bool SupportsColorSpace(SkColorType colorType) {
+ switch (colorType) {
+ case kRGBA_8888_SkColorType:
+ case kBGRA_8888_SkColorType:
+ case kRGBA_F16_SkColorType:
+ return true;
+ default:
+ return false;
+ }
+}
+
size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& proxy,
const DeferredTextureImageUsageParams params[],
int paramCnt, void* buffer,
- SkColorSpace* dstColorSpace) const {
+ SkColorSpace* dstColorSpace,
+ SkColorType dstColorType) const {
// Some quick-rejects where is makes no sense to return CPU data
// e.g.
// - texture backed
@@ -613,6 +625,12 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
return 0;
}
+ bool supportsColorSpace = SupportsColorSpace(dstColorType);
+ // Quick reject if the caller requests a color space with an unsupported color type.
+ if (SkToBool(dstColorSpace) && !supportsColorSpace) {
+ return 0;
+ }
+
// Extract relevant min/max values from the params array.
int lowestPreScaleMipLevel = params[0].fPreScaleMipLevel;
SkFilterQuality highestFilterQuality = params[0].fQuality;
@@ -657,7 +675,8 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
SkAutoPixmapStorage pixmap;
SkImageInfo info;
size_t pixelSize = 0;
- if (!isScaled && this->peekPixels(&pixmap) && !pixmap.ctable()) {
+ if (!isScaled && this->peekPixels(&pixmap) && !pixmap.ctable() &&
+ pixmap.info().colorType() == dstColorType) {
info = pixmap.info();
pixelSize = SkAlign8(pixmap.getSafeSize());
if (!dstColorSpace) {
@@ -680,24 +699,35 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
info = info.makeColorSpace(nullptr);
}
}
- if (kIndex_8_SkColorType == info.colorType()) {
- // Force Index8 to be N32 instead. Index8 is unsupported in Ganesh.
- info = info.makeColorType(kN32_SkColorType);
- }
+ // Force color type to be the requested type.
+ info = info.makeColorType(dstColorType);
pixelSize = SkAlign8(SkAutoPixmapStorage::AllocSize(info, nullptr));
if (fillMode) {
- pixmap.alloc(info);
+ // Always decode to N32 and convert to the requested type if necessary.
+ SkImageInfo decodeInfo = info.makeColorType(kN32_SkColorType);
+ SkAutoPixmapStorage decodePixmap;
+ decodePixmap.alloc(decodeInfo);
+
if (isScaled) {
- if (!this->scalePixels(pixmap, scaleFilterQuality,
+ if (!this->scalePixels(decodePixmap, scaleFilterQuality,
SkImage::kDisallow_CachingHint)) {
return 0;
}
} else {
- if (!this->readPixels(pixmap, 0, 0, SkImage::kDisallow_CachingHint)) {
+ if (!this->readPixels(decodePixmap, 0, 0, SkImage::kDisallow_CachingHint)) {
return 0;
}
}
- SkASSERT(!pixmap.ctable());
+ SkASSERT(!decodePixmap.ctable());
+
+ if (decodeInfo.colorType() != info.colorType()) {
+ pixmap.alloc(info);
+ // Convert and copy the decoded pixmap to the target pixmap.
+ decodePixmap.readPixels(pixmap.info(), pixmap.writable_addr(), pixmap.rowBytes(), 0,
+ 0);
+ } else {
+ pixmap = std::move(decodePixmap);
+ }
}
}
int mipMapLevelCount = 1;
@@ -735,10 +765,11 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
SkColorSpaceTransferFn fn;
if (info.colorSpace()) {
SkASSERT(dstColorSpace);
+ SkASSERT(supportsColorSpace);
colorSpaceOffset = size;
colorSpaceSize = info.colorSpace()->writeToMemory(nullptr);
size += colorSpaceSize;
- } else if (this->colorSpace() && this->colorSpace()->isNumericalTransferFn(&fn)) {
+ } else if (supportsColorSpace && this->colorSpace() && this->colorSpace()->isNumericalTransferFn(&fn)) {
// In legacy mode, preserve the color space tag on the SkImage. This is only
// supported if the color space has a parametric transfer function.
SkASSERT(!dstColorSpace);
@@ -762,6 +793,7 @@ size_t SkImage::getDeferredTextureImageData(const GrContextThreadSafeProxy& prox
SkDestinationSurfaceColorMode colorMode = SkDestinationSurfaceColorMode::kLegacy;
if (proxy.fCaps->srgbSupport() && SkToBool(dstColorSpace) &&
info.colorSpace() && info.colorSpace()->gammaCloseToSRGB()) {
+ SkASSERT(supportsColorSpace);
colorMode = SkDestinationSurfaceColorMode::kGammaAndColorSpaceAware;
}