aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/SkImageCacherator.cpp
diff options
context:
space:
mode:
authorGravatar Brian Osman <brianosman@google.com>2016-11-15 18:07:26 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-11-15 18:07:40 +0000
commit57ae6cfe01b811aaead80872ed9e5e1d30f35f81 (patch)
tree12dd094a0ba392e374f906cb62426df5d5213d60 /src/core/SkImageCacherator.cpp
parentd6010879c6271b66acd4498e892a24de0ffaf15e (diff)
Revert "Support decoding images to multiple formats, depending on usage"
This reverts commit c73a1ecbed64652b3d7aa8dc6face9a2205ce830. Reason for revert: ANGLE and CommandBuffer failures Original change's description: > Support decoding images to multiple formats, depending on usage > > Our codec generator will now preserve any asked-for color space, and > convert the encoded data to that representation. Cacherator now > allows decoding an image to both legacy (nullptr color space), and > color-correct formats. In color-correct mode, we choose the best > decoded format, based on the original properties, and our backend's > capabilities. Preference is given to the native format, when it's > already texturable (sRGB 8888 or F16 linear). Otherwise, we prefer > linear F16, and fall back to sRGB when that's not an option. > > BUG=skia:5907 > > GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4438 > > Change-Id: I847c243dcfb72d8c0f1f6fc73c09547adea933f0 > Reviewed-on: https://skia-review.googlesource.com/4438 > Reviewed-by: Matt Sarett <msarett@google.com> > Commit-Queue: Brian Osman <brianosman@google.com> > TBR=mtklein@google.com,bsalomon@google.com,msarett@google.com,brianosman@google.com,reed@google.com NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true Change-Id: I1818f937464573d601f64e5a1f1eb43f5a778f4e Reviewed-on: https://skia-review.googlesource.com/4832 Commit-Queue: Brian Osman <brianosman@google.com> Reviewed-by: Brian Osman <brianosman@google.com>
Diffstat (limited to 'src/core/SkImageCacherator.cpp')
-rw-r--r--src/core/SkImageCacherator.cpp255
1 files changed, 24 insertions, 231 deletions
diff --git a/src/core/SkImageCacherator.cpp b/src/core/SkImageCacherator.cpp
index d6f816e8ef..54045d5821 100644
--- a/src/core/SkImageCacherator.cpp
+++ b/src/core/SkImageCacherator.cpp
@@ -7,7 +7,6 @@
#include "SkBitmap.h"
#include "SkBitmapCache.h"
-#include "SkColorSpace_Base.h"
#include "SkImage_Base.h"
#include "SkImageCacherator.h"
#include "SkMallocPixelRef.h"
@@ -85,19 +84,8 @@ SkImageCacherator::Validator::Validator(sk_sp<SharedGenerator> gen, const SkIRec
subset = &bounds;
}
- fInfo = info.makeWH(subset->width(), subset->height());
+ fInfo = info.makeWH(subset->width(), subset->height());
fOrigin = SkIPoint::Make(subset->x(), subset->y());
-
- // If the encoded data is in a strange color space (it's not an XYZ matrix space), we won't be
- // able to preserve the gamut of the encoded data when we decode it. Instead, we'll have to
- // decode to a known color space (linear sRGB is a good choice). But we need to adjust the
- // stored color space, because drawing code will ask the SkImage for its color space, which
- // will in turn ask the cacherator. If we return the A2B color space, then we will be unable to
- // construct a source-to-dest gamut transformation matrix.
- if (fInfo.colorSpace() &&
- SkColorSpace_Base::Type::kXYZ != as_CSB(fInfo.colorSpace())->type()) {
- fInfo = fInfo.makeColorSpace(SkColorSpace::MakeNamed(SkColorSpace::kSRGBLinear_Named));
- }
}
SkImageCacherator* SkImageCacherator::NewFromGenerator(SkImageGenerator* gen,
@@ -111,12 +99,8 @@ SkImageCacherator::SkImageCacherator(Validator* validator)
: fSharedGenerator(std::move(validator->fSharedGenerator)) // we take ownership
, fInfo(validator->fInfo)
, fOrigin(validator->fOrigin)
+ , fUniqueID(validator->fUniqueID)
{
- fUniqueIDs[kLegacy_CachedFormat] = validator->fUniqueID;
- for (int i = 1; i < kNumCachedFormats; ++i) {
- // We lazily allocate IDs for non-default caching cases
- fUniqueIDs[i] = kNeedNewImageUniqueID;
- }
SkASSERT(fSharedGenerator);
}
@@ -137,26 +121,24 @@ static bool check_output_bitmap(const SkBitmap& bitmap, uint32_t expectedID) {
// Note, this returns a new, mutable, bitmap, with a new genID.
// If you want the immutable bitmap with the same ID as our cacherator, call tryLockAsBitmap()
//
-bool SkImageCacherator::generateBitmap(SkBitmap* bitmap, const SkImageInfo& decodeInfo) {
+bool SkImageCacherator::generateBitmap(SkBitmap* bitmap) {
SkBitmap::Allocator* allocator = SkResourceCache::GetAllocator();
ScopedGenerator generator(fSharedGenerator);
const SkImageInfo& genInfo = generator->getInfo();
- if (decodeInfo.dimensions() == genInfo.dimensions()) {
+ if (fInfo.dimensions() == genInfo.dimensions()) {
SkASSERT(fOrigin.x() == 0 && fOrigin.y() == 0);
// fast-case, no copy needed
- return generator->tryGenerateBitmap(bitmap, decodeInfo, allocator);
+ return generator->tryGenerateBitmap(bitmap, fInfo, allocator);
} else {
// need to handle subsetting, so we first generate the full size version, and then
// "read" from it to get our subset. See https://bug.skia.org/4213
SkBitmap full;
- if (!generator->tryGenerateBitmap(&full,
- decodeInfo.makeWH(genInfo.width(), genInfo.height()),
- allocator)) {
+ if (!generator->tryGenerateBitmap(&full, genInfo, allocator)) {
return false;
}
- if (!bitmap->tryAllocPixels(decodeInfo, nullptr, full.getColorTable())) {
+ if (!bitmap->tryAllocPixels(fInfo, nullptr, full.getColorTable())) {
return false;
}
return full.readPixels(bitmap->info(), bitmap->getPixels(), bitmap->rowBytes(),
@@ -177,28 +159,22 @@ bool SkImageCacherator::directGeneratePixels(const SkImageInfo& info, void* pixe
//////////////////////////////////////////////////////////////////////////////////////////////////
-bool SkImageCacherator::lockAsBitmapOnlyIfAlreadyCached(SkBitmap* bitmap, CachedFormat format) {
- return kNeedNewImageUniqueID != fUniqueIDs[format] &&
- SkBitmapCache::Find(fUniqueIDs[format], bitmap) &&
- check_output_bitmap(*bitmap, fUniqueIDs[format]);
+bool SkImageCacherator::lockAsBitmapOnlyIfAlreadyCached(SkBitmap* bitmap) {
+ return SkBitmapCache::Find(fUniqueID, bitmap) && check_output_bitmap(*bitmap, fUniqueID);
}
bool SkImageCacherator::tryLockAsBitmap(SkBitmap* bitmap, const SkImage* client,
- SkImage::CachingHint chint, CachedFormat format,
- const SkImageInfo& info) {
- if (this->lockAsBitmapOnlyIfAlreadyCached(bitmap, format)) {
+ SkImage::CachingHint chint) {
+ if (this->lockAsBitmapOnlyIfAlreadyCached(bitmap)) {
return true;
}
- if (!this->generateBitmap(bitmap, info)) {
+ if (!this->generateBitmap(bitmap)) {
return false;
}
- if (kNeedNewImageUniqueID == fUniqueIDs[format]) {
- fUniqueIDs[format] = SkNextID::ImageID();
- }
- bitmap->pixelRef()->setImmutableWithID(fUniqueIDs[format]);
+ bitmap->pixelRef()->setImmutableWithID(fUniqueID);
if (SkImage::kAllow_CachingHint == chint) {
- SkBitmapCache::Add(fUniqueIDs[format], *bitmap);
+ SkBitmapCache::Add(fUniqueID, *bitmap);
if (client) {
as_IB(client)->notifyAddedToCache();
}
@@ -207,17 +183,9 @@ bool SkImageCacherator::tryLockAsBitmap(SkBitmap* bitmap, const SkImage* client,
}
bool SkImageCacherator::lockAsBitmap(SkBitmap* bitmap, const SkImage* client,
- SkDestinationSurfaceColorMode colorMode,
SkImage::CachingHint chint) {
- CachedFormat format = chooseCacheFormat(colorMode);
- SkImageInfo cacheInfo = buildCacheInfo(format);
-
- if (kNeedNewImageUniqueID == fUniqueIDs[format]) {
- fUniqueIDs[format] = SkNextID::ImageID();
- }
-
- if (this->tryLockAsBitmap(bitmap, client, chint, format, cacheInfo)) {
- return check_output_bitmap(*bitmap, fUniqueIDs[format]);
+ if (this->tryLockAsBitmap(bitmap, client, chint)) {
+ return check_output_bitmap(*bitmap, fUniqueID);
}
#if SK_SUPPORT_GPU
@@ -226,8 +194,7 @@ bool SkImageCacherator::lockAsBitmap(SkBitmap* bitmap, const SkImage* client,
{
ScopedGenerator generator(fSharedGenerator);
- SkIRect subset = SkIRect::MakeXYWH(fOrigin.x(), fOrigin.y(),
- cacheInfo.width(), cacheInfo.height());
+ SkIRect subset = SkIRect::MakeXYWH(fOrigin.x(), fOrigin.y(), fInfo.width(), fInfo.height());
tex.reset(generator->generateTexture(nullptr, &subset));
}
if (!tex) {
@@ -235,27 +202,27 @@ bool SkImageCacherator::lockAsBitmap(SkBitmap* bitmap, const SkImage* client,
return false;
}
- if (!bitmap->tryAllocPixels(cacheInfo)) {
+ if (!bitmap->tryAllocPixels(fInfo)) {
bitmap->reset();
return false;
}
const uint32_t pixelOpsFlags = 0;
if (!tex->readPixels(0, 0, bitmap->width(), bitmap->height(),
- SkImageInfo2GrPixelConfig(cacheInfo, *tex->getContext()->caps()),
+ SkImageInfo2GrPixelConfig(fInfo, *tex->getContext()->caps()),
bitmap->getPixels(), bitmap->rowBytes(), pixelOpsFlags)) {
bitmap->reset();
return false;
}
- bitmap->pixelRef()->setImmutableWithID(fUniqueIDs[format]);
+ bitmap->pixelRef()->setImmutableWithID(fUniqueID);
if (SkImage::kAllow_CachingHint == chint) {
- SkBitmapCache::Add(fUniqueIDs[format], *bitmap);
+ SkBitmapCache::Add(fUniqueID, *bitmap);
if (client) {
as_IB(client)->notifyAddedToCache();
}
}
- return check_output_bitmap(*bitmap, fUniqueIDs[format]);
+ return check_output_bitmap(*bitmap, fUniqueID);
#else
return false;
#endif
@@ -301,171 +268,6 @@ static GrTexture* set_key_and_return(GrTexture* tex, const GrUniqueKey& key) {
return tex;
}
-// Abstraction of GrCaps that handles the cases where we don't have a caps pointer (because
-// we're in raster mode), or where GPU support is entirely missing.
-struct CacheCaps {
- CacheCaps(const GrCaps* caps) : fCaps(caps) {}
-
-#if SK_SUPPORT_GPU
- bool supportsHalfFloat() const {
- return !fCaps || fCaps->isConfigTexturable(kRGBA_half_GrPixelConfig);
- }
-
- bool supportsSRGB() const {
- return !fCaps || fCaps->isConfigTexturable(kSRGBA_8888_GrPixelConfig);
- }
-
- bool supportsSBGR() const {
- return !fCaps || fCaps->isConfigTexturable(kSBGRA_8888_GrPixelConfig);
- }
-#else
- bool supportsHalfFloat() const { return true; }
- bool supportsSRGB() const { return true; }
- bool supportsSBGR() const { return true; }
-#endif
-
- const GrCaps* fCaps;
-};
-
-SkImageCacherator::CachedFormat SkImageCacherator::chooseCacheFormat(
- SkDestinationSurfaceColorMode colorMode,
- const GrCaps* grCaps) {
- SkColorSpace* cs = fInfo.colorSpace();
- if (!cs || SkDestinationSurfaceColorMode::kLegacy == colorMode) {
- return kLegacy_CachedFormat;
- }
-
- CacheCaps caps(grCaps);
- switch (fInfo.colorType()) {
- case kUnknown_SkColorType:
- case kAlpha_8_SkColorType:
- case kRGB_565_SkColorType:
- case kARGB_4444_SkColorType:
- // We don't support color space on these formats, so always decode in legacy mode:
- // TODO: Ask the codec to decode these to something else (at least sRGB 8888)?
- return kLegacy_CachedFormat;
-
- case kIndex_8_SkColorType:
- // We can't draw from indexed textures with a color space, so ask the codec to expand
- if (cs->gammaCloseToSRGB()) {
- if (caps.supportsSRGB()) {
- return kSRGB8888_CachedFormat;
- } else if (caps.supportsHalfFloat()) {
- return kLinearF16_CachedFormat;
- } else {
- return kLegacy_CachedFormat;
- }
- } else {
- if (caps.supportsHalfFloat()) {
- return kLinearF16_CachedFormat;
- } else if (caps.supportsSRGB()) {
- return kSRGB8888_CachedFormat;
- } else {
- return kLegacy_CachedFormat;
- }
- }
-
- case kGray_8_SkColorType:
- // TODO: What do we do with grayscale sources that have strange color spaces attached?
- // The codecs and color space xform don't handle this correctly (yet), so drop it on
- // the floor. (Also, inflating by a factor of 8 is going to be unfortunate).
- // As it is, we don't directly support sRGB grayscale, so ask the codec to convert
- // it for us. This bypasses some really sketchy code GrUploadPixmapToTexture.
- if (cs->gammaCloseToSRGB() && caps.supportsSRGB()) {
- return kSRGB8888_CachedFormat;
- } else {
- return kLegacy_CachedFormat;
- }
-
- case kRGBA_8888_SkColorType:
- if (cs->gammaCloseToSRGB()) {
- if (caps.supportsSRGB()) {
- return kAsIs_CachedFormat;
- } else if (caps.supportsHalfFloat()) {
- return kLinearF16_CachedFormat;
- } else {
- return kLegacy_CachedFormat;
- }
- } else {
- if (caps.supportsHalfFloat()) {
- return kLinearF16_CachedFormat;
- } else if (caps.supportsSRGB()) {
- return kSRGB8888_CachedFormat;
- } else {
- return kLegacy_CachedFormat;
- }
- }
-
- case kBGRA_8888_SkColorType:
- // Odd case. sBGRA isn't a real thing, so we may not have this texturable.
- if (caps.supportsSBGR()) {
- if (cs->gammaCloseToSRGB()) {
- return kAsIs_CachedFormat;
- } else if (caps.supportsHalfFloat()) {
- return kLinearF16_CachedFormat;
- } else if (caps.supportsSRGB()) {
- return kSRGB8888_CachedFormat;
- } else {
- // sBGRA support without sRGBA is highly unlikely (impossible?) Nevertheless.
- return kLegacy_CachedFormat;
- }
- } else {
- if (cs->gammaCloseToSRGB()) {
- if (caps.supportsSRGB()) {
- return kSRGB8888_CachedFormat;
- } else if (caps.supportsHalfFloat()) {
- return kLinearF16_CachedFormat;
- } else {
- return kLegacy_CachedFormat;
- }
- } else {
- if (caps.supportsHalfFloat()) {
- return kLinearF16_CachedFormat;
- } else if (caps.supportsSRGB()) {
- return kSRGB8888_CachedFormat;
- } else {
- return kLegacy_CachedFormat;
- }
- }
- }
-
- case kRGBA_F16_SkColorType:
- if (!caps.supportsHalfFloat()) {
- if (caps.supportsSRGB()) {
- return kSRGB8888_CachedFormat;
- } else {
- return kLegacy_CachedFormat;
- }
- } else if (cs->gammaIsLinear()) {
- return kAsIs_CachedFormat;
- } else {
- return kLinearF16_CachedFormat;
- }
- }
- SkDEBUGFAIL("Unreachable");
- return kLegacy_CachedFormat;
-}
-
-SkImageInfo SkImageCacherator::buildCacheInfo(CachedFormat format) {
- switch (format) {
- case kLegacy_CachedFormat:
- return fInfo.makeColorSpace(nullptr);
- case kAsIs_CachedFormat:
- return fInfo;
- case kLinearF16_CachedFormat:
- return fInfo
- .makeColorType(kRGBA_F16_SkColorType)
- .makeColorSpace(as_CSB(fInfo.colorSpace())->makeLinearGamma());
- case kSRGB8888_CachedFormat:
- return fInfo
- .makeColorType(kRGBA_8888_SkColorType)
- .makeColorSpace(as_CSB(fInfo.colorSpace())->makeSRGBGamma());
- default:
- SkDEBUGFAIL("Invalid cached format");
- return fInfo;
- }
-}
-
/*
* We have a 5 ways to try to return a texture (in sorted order)
*
@@ -512,16 +314,7 @@ GrTexture* SkImageCacherator::lockTexture(GrContext* ctx, const GrUniqueKey& key
}
}
- // Determine which cached format we're going to use (which may involve decoding to a different
- // info than the generator provides).
- CachedFormat format = chooseCacheFormat(colorMode, ctx->caps());
-
- // The CachedFormat is both an index for which cache "slot" we'll use to store this particular
- // decoded variant of the encoded data, and also a recipe for how to transform the original
- // info to get the one that we're going to decode to.
- SkImageInfo cacheInfo = buildCacheInfo(format);
-
- const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(cacheInfo, *ctx->caps());
+ const GrSurfaceDesc desc = GrImageInfoToSurfaceDesc(fInfo, *ctx->caps());
#ifdef SK_SUPPORT_COMPRESSED_TEXTURES_IN_CACHERATOR
// 3. Ask the generator to return a compressed form that the GPU might support
@@ -550,7 +343,7 @@ GrTexture* SkImageCacherator::lockTexture(GrContext* ctx, const GrUniqueKey& key
// 5. Ask the generator to return RGB(A) data, which the GPU can convert
SkBitmap bitmap;
- if (this->tryLockAsBitmap(&bitmap, client, chint, format, cacheInfo)) {
+ if (this->tryLockAsBitmap(&bitmap, client, chint)) {
GrTexture* tex = nullptr;
if (willBeMipped) {
tex = GrGenerateMipMapsAndUploadToTexture(ctx, bitmap, colorMode);