diff options
author | Eric Karl <ericrk@chromium.org> | 2017-06-12 10:05:49 -0700 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-06-12 18:27:48 +0000 |
commit | 7a8c84c6c92565842aeea27d4971fbd78d523f7a (patch) | |
tree | 703d50fbd35830c529db5ed97388503189135360 /src/image | |
parent | a8d45e522097d4efe3b12bc26158870bd76299b7 (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.cpp | 3 | ||||
-rw-r--r-- | src/image/SkImage_Gpu.cpp | 54 |
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; } |