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:
parent
42a2a20b91
commit
a28e2b07b7
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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).
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user