Simplify SkImageCacherator slightly

- lockAsBitmap supported reading back textures to a bitmap, but this was
  only used by one GM. Removed all of that code, and merged the two bitmap
  functions together.
- To make the GM cleaner, don't use SkImageCacherator directly - construct
  actual images.

Bug: skia:
Change-Id: Iad17184a02a72f89ccc851fa158764d6c871befa
Reviewed-on: https://skia-review.googlesource.com/14192
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
This commit is contained in:
Brian Osman 2017-04-24 16:44:03 -04:00 committed by Skia Commit-Bot
parent 42a2a20b91
commit a28e2b07b7
4 changed files with 49 additions and 114 deletions

View File

@ -9,6 +9,7 @@
#include "SkCanvas.h"
#include "SkImage.h"
#include "SkImageCacherator.h"
#include "SkImage_Base.h"
#include "SkMakeUnique.h"
#include "SkPictureRecorder.h"
#include "SkSurface.h"
@ -286,8 +287,8 @@ class ImageCacheratorGM : public skiagm::GM {
SkString fName;
std::unique_ptr<SkImageGenerator> (*fFactory)(GrContext*, sk_sp<SkPicture>);
sk_sp<SkPicture> fPicture;
std::unique_ptr<SkImageCacherator> fCache;
std::unique_ptr<SkImageCacherator> fCacheSubset;
sk_sp<SkImage> fImage;
sk_sp<SkImage> fImageSubset;
public:
ImageCacheratorGM(const char suffix[],
@ -316,43 +317,46 @@ protected:
void makeCaches(GrContext* ctx) {
auto gen = fFactory(ctx, fPicture);
SkDEBUGCODE(const uint32_t genID = gen->uniqueID();)
fCache.reset(SkImageCacherator::NewFromGenerator(std::move(gen)));
fImage = SkImage::MakeFromGenerator(std::move(gen));
const SkIRect subset = SkIRect::MakeLTRB(50, 50, 100, 100);
gen = fFactory(ctx, fPicture);
SkDEBUGCODE(const uint32_t genSubsetID = gen->uniqueID();)
fCacheSubset.reset(SkImageCacherator::NewFromGenerator(std::move(gen), &subset));
fImageSubset = SkImage::MakeFromGenerator(std::move(gen), &subset);
// whole caches should have the same ID as the generator. Subsets should be diff
SkASSERT(fCache->uniqueID() == genID);
SkASSERT(fCacheSubset->uniqueID() != genID);
SkASSERT(fCacheSubset->uniqueID() != genSubsetID);
SkDEBUGCODE(SkImageCacherator* cache = as_IB(fImage)->peekCacherator();)
SkDEBUGCODE(SkImageCacherator* cacheSubset = as_IB(fImageSubset)->peekCacherator();)
SkASSERT(cache);
SkASSERT(cacheSubset);
SkASSERT(cache->uniqueID() == genID);
SkASSERT(cacheSubset->uniqueID() != genID);
SkASSERT(cacheSubset->uniqueID() != genSubsetID);
SkASSERT(fCache->info().dimensions() == SkISize::Make(100, 100));
SkASSERT(fCacheSubset->info().dimensions() == SkISize::Make(50, 50));
SkASSERT(cache->info().dimensions() == SkISize::Make(100, 100));
SkASSERT(cacheSubset->info().dimensions() == SkISize::Make(50, 50));
}
static void draw_as_bitmap(SkCanvas* canvas, SkImageCacherator* cache, SkScalar x, SkScalar y) {
static void draw_as_bitmap(SkCanvas* canvas, SkImage* image, SkScalar x, SkScalar y) {
SkBitmap bitmap;
cache->lockAsBitmap(canvas->getGrContext(), &bitmap, nullptr,
canvas->imageInfo().colorSpace());
as_IB(image)->getROPixels(&bitmap, canvas->imageInfo().colorSpace());
canvas->drawBitmap(bitmap, x, y);
}
static void draw_as_tex(SkCanvas* canvas, SkImageCacherator* cache, SkScalar x, SkScalar y) {
static void draw_as_tex(SkCanvas* canvas, SkImage* image, SkScalar x, SkScalar y) {
#if SK_SUPPORT_GPU
sk_sp<SkColorSpace> texColorSpace;
sk_sp<GrTextureProxy> proxy(
cache->lockAsTextureProxy(canvas->getGrContext(), GrSamplerParams::ClampBilerp(),
canvas->imageInfo().colorSpace(), &texColorSpace,
nullptr, nullptr));
as_IB(image)->asTextureProxyRef(canvas->getGrContext(), GrSamplerParams::ClampBilerp(),
canvas->imageInfo().colorSpace(), &texColorSpace,
nullptr));
if (!proxy) {
// show placeholder if we have no texture
SkPaint paint;
paint.setStyle(SkPaint::kStroke_Style);
SkRect r = SkRect::MakeXYWH(x, y, SkIntToScalar(cache->info().width()),
SkIntToScalar(cache->info().width()));
SkRect r = SkRect::MakeXYWH(x, y, SkIntToScalar(image->width()),
SkIntToScalar(image->width()));
canvas->drawRect(r, paint);
canvas->drawLine(r.left(), r.top(), r.right(), r.bottom(), paint);
canvas->drawLine(r.left(), r.bottom(), r.right(), r.top(), paint);
@ -360,11 +364,10 @@ protected:
}
// No API to draw a GrTexture directly, so we cheat and create a private image subclass
sk_sp<SkImage> image(new SkImage_Gpu(canvas->getGrContext(),
cache->uniqueID(), kPremul_SkAlphaType,
std::move(proxy), std::move(texColorSpace),
SkBudgeted::kNo));
canvas->drawImage(image.get(), x, y);
sk_sp<SkImage> texImage(new SkImage_Gpu(canvas->getGrContext(), image->uniqueID(),
kPremul_SkAlphaType, std::move(proxy),
std::move(texColorSpace), SkBudgeted::kNo));
canvas->drawImage(texImage.get(), x, y);
#endif
}
@ -375,11 +378,11 @@ protected:
// Draw the tex first, so it doesn't hit a lucky cache from the raster version. This
// way we also can force the generateTexture call.
draw_as_tex(canvas, fCache.get(), 310, 0);
draw_as_tex(canvas, fCacheSubset.get(), 310+101, 0);
draw_as_tex(canvas, fImage.get(), 310, 0);
draw_as_tex(canvas, fImageSubset.get(), 310+101, 0);
draw_as_bitmap(canvas, fCache.get(), 150, 0);
draw_as_bitmap(canvas, fCacheSubset.get(), 150+101, 0);
draw_as_bitmap(canvas, fImage.get(), 150, 0);
draw_as_bitmap(canvas, fImageSubset.get(), 150+101, 0);
}
void onDraw(SkCanvas* canvas) override {

View File

@ -199,9 +199,9 @@ static bool generate_pixels(SkImageGenerator* gen, const SkPixmap& pmap, int ori
return true;
}
bool SkImageCacherator::tryLockAsBitmap(SkBitmap* bitmap, const SkImage* client,
SkImage::CachingHint chint, CachedFormat format,
const SkImageInfo& info) {
bool SkImageCacherator::lockAsBitmap(SkBitmap* bitmap, const SkImage* client,
SkImage::CachingHint chint, CachedFormat format,
const SkImageInfo& info) {
if (this->lockAsBitmapOnlyIfAlreadyCached(bitmap, format)) {
return true;
}
@ -243,79 +243,11 @@ bool SkImageCacherator::tryLockAsBitmap(SkBitmap* bitmap, const SkImage* client,
*bitmap = tmpBitmap;
bitmap->pixelRef()->setImmutableWithID(uniqueID);
}
check_output_bitmap(*bitmap, uniqueID);
return true;
}
bool SkImageCacherator::lockAsBitmap(GrContext* context, SkBitmap* bitmap, const SkImage* client,
SkColorSpace* dstColorSpace,
SkImage::CachingHint chint) {
CachedFormat format = this->chooseCacheFormat(dstColorSpace);
SkImageInfo cacheInfo = this->buildCacheInfo(format);
const uint32_t uniqueID = this->getUniqueID(format);
if (this->tryLockAsBitmap(bitmap, client, chint, format, cacheInfo)) {
return check_output_bitmap(*bitmap, uniqueID);
}
#if SK_SUPPORT_GPU
if (!context) {
bitmap->reset();
return false;
}
// Try to get a texture and read it back to raster (and then cache that with our ID)
sk_sp<GrTextureProxy> proxy;
{
ScopedGenerator generator(fSharedGenerator);
proxy = generator->generateTexture(context, cacheInfo, fOrigin);
}
if (!proxy) {
bitmap->reset();
return false;
}
const auto desc = SkBitmapCacheDesc::Make(uniqueID, fInfo.width(), fInfo.height());
SkBitmapCache::RecPtr rec;
SkPixmap pmap;
if (SkImage::kAllow_CachingHint == chint) {
rec = SkBitmapCache::Alloc(desc, cacheInfo, &pmap);
if (!rec) {
bitmap->reset();
return false;
}
} else {
if (!bitmap->tryAllocPixels(cacheInfo)) {
bitmap->reset();
return false;
}
}
sk_sp<GrSurfaceContext> sContext(context->contextPriv().makeWrappedSurfaceContext(
proxy,
fInfo.refColorSpace())); // src colorSpace
if (!sContext) {
bitmap->reset();
return false;
}
if (!sContext->readPixels(pmap.info(), pmap.writable_addr(), pmap.rowBytes(), 0, 0)) {
bitmap->reset();
return false;
}
if (rec) {
SkBitmapCache::Add(std::move(rec), bitmap);
if (client) {
as_IB(client)->notifyAddedToCache();
}
}
return check_output_bitmap(*bitmap, uniqueID);
#else
return false;
#endif
}
//////////////////////////////////////////////////////////////////////////////////////////////////
// Abstraction of GrCaps that handles the cases where we don't have a caps pointer (because
@ -628,7 +560,7 @@ sk_sp<GrTextureProxy> SkImageCacherator::lockTextureProxy(GrContext* ctx,
// 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->lockAsBitmap(&bitmap, client, chint, format, cacheInfo)) {
sk_sp<GrTextureProxy> proxy;
if (willBeMipped) {
proxy = GrGenerateMipMapsAndUploadToTextureProxy(ctx, bitmap, dstColorSpace);

View File

@ -42,16 +42,6 @@ public:
kNumCachedFormats,
};
/**
* On success (true), bitmap will point to the pixels for this generator. If this returns
* false, the bitmap will be reset to empty.
*
* If not NULL, the client will be notified (->notifyAddedToCache()) when resources are
* added to the cache on its behalf.
*/
bool lockAsBitmap(GrContext*, SkBitmap*, const SkImage* client, SkColorSpace* dstColorSpace,
SkImage::CachingHint = SkImage::kAllow_CachingHint);
#if SK_SUPPORT_GPU
/**
* Returns a ref() on the texture produced by this generator. The caller must call unref()
@ -130,8 +120,16 @@ private:
CachedFormat chooseCacheFormat(SkColorSpace* dstColorSpace, const GrCaps* = nullptr);
SkImageInfo buildCacheInfo(CachedFormat);
bool tryLockAsBitmap(SkBitmap*, const SkImage*, SkImage::CachingHint, CachedFormat,
const SkImageInfo&);
/**
* On success (true), bitmap will point to the pixels for this generator. If this returns
* false, the bitmap will be reset to empty.
*
* If not NULL, the client will be notified (->notifyAddedToCache()) when resources are
* added to the cache on its behalf.
*/
bool lockAsBitmap(SkBitmap*, const SkImage*, SkImage::CachingHint, CachedFormat,
const SkImageInfo&);
#if SK_SUPPORT_GPU
// Returns the texture proxy. If the cacherator is generating the texture and wants to cache it,
// it should use the passed in key (if the key is valid).

View File

@ -80,7 +80,9 @@ SkData* SkImage_Lazy::onRefEncoded(GrContext* ctx) const {
bool SkImage_Lazy::getROPixels(SkBitmap* bitmap, SkColorSpace* dstColorSpace,
CachingHint chint) const {
return fCache.lockAsBitmap(nullptr, bitmap, this, dstColorSpace, chint);
SkImageCacherator::CachedFormat cacheFormat = fCache.chooseCacheFormat(dstColorSpace);
SkImageInfo cacheInfo = fCache.buildCacheInfo(cacheFormat);
return fCache.lockAsBitmap(bitmap, this, chint, cacheFormat, cacheInfo);
}
#if SK_SUPPORT_GPU