scaling API on SkPixmap
BUG=skia:4481
Review URL: https://codereview.chromium.org/1463373002
diff --git a/gm/image.cpp b/gm/image.cpp
index 27cce23..03ed105 100644
--- a/gm/image.cpp
+++ b/gm/image.cpp
@@ -192,3 +192,111 @@
typedef skiagm::GM INHERITED;
};
DEF_GM( return new ImageGM; )
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+#include "SkPictureRecorder.h"
+
+static void draw_pixmap(SkCanvas* canvas, const SkPixmap& pmap) {
+ SkBitmap bitmap;
+ bitmap.installPixels(pmap.info(), (void*)pmap.addr(), pmap.rowBytes());
+ canvas->drawBitmap(bitmap, 0, 0, nullptr);
+}
+
+static void show_scaled_pixels(SkCanvas* canvas, SkImage* image) {
+ SkAutoCanvasRestore acr(canvas, true);
+
+ canvas->drawImage(image, 0, 0, nullptr);
+ canvas->translate(110, 10);
+
+ const SkImageInfo info = SkImageInfo::MakeN32Premul(40, 40);
+ SkAutoPixmapStorage storage;
+ storage.alloc(info);
+
+ const SkImage::CachingHint chints[] = {
+ SkImage::kAllow_CachingHint, // SkImage::kDisallow_CachingHint,
+ };
+ const SkFilterQuality qualities[] = {
+ kNone_SkFilterQuality, kLow_SkFilterQuality, kMedium_SkFilterQuality, kHigh_SkFilterQuality,
+ };
+
+ for (auto ch : chints) {
+ canvas->save();
+ for (auto q : qualities) {
+ if (image->scalePixels(storage, q, ch)) {
+ draw_pixmap(canvas, storage);
+ }
+ canvas->translate(70, 0);
+ }
+ canvas->restore();
+ canvas->translate(0, 45);
+ }
+}
+
+static void draw_contents(SkCanvas* canvas) {
+ SkPaint paint;
+ paint.setStyle(SkPaint::kStroke_Style);
+ paint.setStrokeWidth(20);
+ canvas->drawCircle(50, 50, 35, paint);
+}
+
+static SkImage* make_raster(const SkImageInfo& info, GrContext*) {
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRaster(info));
+ draw_contents(surface->getCanvas());
+ return surface->newImageSnapshot();
+}
+
+static SkImage* make_picture(const SkImageInfo& info, GrContext*) {
+ SkPictureRecorder recorder;
+ draw_contents(recorder.beginRecording(SkRect::MakeIWH(info.width(), info.height())));
+ SkAutoTUnref<SkPicture> pict(recorder.endRecording());
+ return SkImage::NewFromPicture(pict, info.dimensions(), nullptr, nullptr);
+}
+
+static SkImage* make_codec(const SkImageInfo& info, GrContext*) {
+ SkAutoTUnref<SkImage> image(make_raster(info, nullptr));
+ SkAutoTUnref<SkData> data(image->encode());
+ return SkImage::NewFromEncoded(data);
+}
+
+static SkImage* make_gpu(const SkImageInfo& info, GrContext* ctx) {
+ if (!ctx) { return nullptr; }
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTarget(ctx, SkSurface::kNo_Budgeted, info));
+ draw_contents(surface->getCanvas());
+ return surface->newImageSnapshot();
+}
+
+typedef SkImage* (*ImageMakerProc)(const SkImageInfo&, GrContext*);
+
+class ScalePixelsGM : public skiagm::GM {
+public:
+ ScalePixelsGM() {}
+
+protected:
+ SkString onShortName() override {
+ return SkString("scale-pixels");
+ }
+
+ SkISize onISize() override {
+ return SkISize::Make(960, 1200);
+ }
+
+ void onDraw(SkCanvas* canvas) override {
+ const SkImageInfo info = SkImageInfo::MakeN32Premul(100, 100);
+
+ const ImageMakerProc procs[] = {
+ make_raster, make_picture, make_codec, make_gpu,
+ };
+ for (auto& proc : procs) {
+ SkAutoTUnref<SkImage> image(proc(info, canvas->getGrContext()));
+ if (image) {
+ show_scaled_pixels(canvas, image);
+ }
+ canvas->translate(0, 120);
+ }
+ }
+
+private:
+ typedef skiagm::GM INHERITED;
+};
+DEF_GM( return new ScalePixelsGM; )
diff --git a/include/core/SkImage.h b/include/core/SkImage.h
index 667cf6b..d6b10a8 100644
--- a/include/core/SkImage.h
+++ b/include/core/SkImage.h
@@ -208,6 +208,16 @@
GrBackendObject getTextureHandle(bool flushPendingGrContextIO) const;
/**
+ * Hints to image calls where the system might cache computed intermediates (e.g. the results
+ * of decoding or a read-back from the GPU. Passing kAllow signals that the system's default
+ * behavior is fine. Passing kDisallow signals that caching should be avoided.
+ */
+ enum CachingHint {
+ kAllow_CachingHint,
+ kDisallow_CachingHint,
+ };
+
+ /**
* Copy the pixels from the image into the specified buffer (pixels + rowBytes),
* converting them into the requested format (dstInfo). The image pixels are read
* starting at the specified (srcX,srcY) location.
@@ -226,9 +236,19 @@
* - If the requested colortype/alphatype cannot be converted from the image's types.
*/
bool readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
- int srcX, int srcY) const;
+ int srcX, int srcY, CachingHint = kAllow_CachingHint) const;
- bool readPixels(const SkPixmap& dst, int srcX, int srcY) const;
+ bool readPixels(const SkPixmap& dst, int srcX, int srcY,
+ CachingHint = kAllow_CachingHint) const;
+
+ /**
+ * Copy the pixels from this image into the dst pixmap, converting as needed into dst's
+ * colortype/alphatype. If the conversion cannot be performed, false is returned.
+ *
+ * If dst's dimensions differ from the src dimension, the image will be scaled, applying the
+ * specified filter-quality.
+ */
+ bool scalePixels(const SkPixmap& dst, SkFilterQuality, CachingHint = kAllow_CachingHint) const;
/**
* Encode the image's pixels and return the result as a new SkData, which
diff --git a/include/core/SkPixmap.h b/include/core/SkPixmap.h
index faae85e..da97025 100644
--- a/include/core/SkPixmap.h
+++ b/include/core/SkPixmap.h
@@ -9,6 +9,7 @@
#define SkPixmap_DEFINED
#include "SkColor.h"
+#include "SkFilterQuality.h"
#include "SkImageInfo.h"
class SkColorTable;
@@ -135,6 +136,15 @@
}
/**
+ * Copy the pixels from this pixmap into the dst pixmap, converting as needed into dst's
+ * colortype/alphatype. If the conversion cannot be performed, false is returned.
+ *
+ * If dst's dimensions differ from the src dimension, the image will be scaled, applying the
+ * specified filter-quality.
+ */
+ bool scalePixels(const SkPixmap& dst, SkFilterQuality) const;
+
+ /**
* Returns true if pixels were written to (e.g. if colorType is kUnknown_SkColorType, this
* will return false). If subset does not intersect the bounds of this pixmap, returns false.
*/
diff --git a/src/core/SkBitmapController.cpp b/src/core/SkBitmapController.cpp
index 5cfa525..233e811 100644
--- a/src/core/SkBitmapController.cpp
+++ b/src/core/SkBitmapController.cpp
@@ -121,8 +121,10 @@
SkASSERT(fResultBitmap.getPixels());
fResultBitmap.setImmutable();
- if (SkBitmapCache::AddWH(desc, fResultBitmap)) {
- provider.notifyAddedToCache();
+ if (!provider.isVolatile()) {
+ if (SkBitmapCache::AddWH(desc, fResultBitmap)) {
+ provider.notifyAddedToCache();
+ }
}
}
diff --git a/src/core/SkBitmapProvider.cpp b/src/core/SkBitmapProvider.cpp
index cae744b..9cf2e9a 100644
--- a/src/core/SkBitmapProvider.cpp
+++ b/src/core/SkBitmapProvider.cpp
@@ -52,6 +52,14 @@
}
}
+bool SkBitmapProvider::isVolatile() const {
+ if (fImage) {
+ return false; // add flag to images?
+ } else {
+ return fBitmap.isVolatile();
+ }
+}
+
SkBitmapCacheDesc SkBitmapProvider::makeCacheDesc(int w, int h) const {
return fImage ? SkBitmapCacheDesc::Make(fImage, w, h) : SkBitmapCacheDesc::Make(fBitmap, w, h);
}
@@ -70,7 +78,7 @@
bool SkBitmapProvider::asBitmap(SkBitmap* bm) const {
if (fImage) {
- return as_IB(fImage)->getROPixels(bm);
+ return as_IB(fImage)->getROPixels(bm, SkImage::kAllow_CachingHint);
} else {
*bm = fBitmap;
return true;
diff --git a/src/core/SkBitmapProvider.h b/src/core/SkBitmapProvider.h
index 72964e4..9901c0f 100644
--- a/src/core/SkBitmapProvider.h
+++ b/src/core/SkBitmapProvider.h
@@ -27,6 +27,7 @@
bool validForDrawing() const;
SkImageInfo info() const;
+ bool isVolatile() const;
SkBitmapCacheDesc makeCacheDesc(int w, int h) const;
SkBitmapCacheDesc makeCacheDesc() const;
diff --git a/src/core/SkImageCacherator.cpp b/src/core/SkImageCacherator.cpp
index fb06a56..1c97656 100644
--- a/src/core/SkImageCacherator.cpp
+++ b/src/core/SkImageCacherator.cpp
@@ -110,7 +110,8 @@
//////////////////////////////////////////////////////////////////////////////////////////////////
-bool SkImageCacherator::tryLockAsBitmap(SkBitmap* bitmap, const SkImage* client) {
+bool SkImageCacherator::tryLockAsBitmap(SkBitmap* bitmap, const SkImage* client,
+ SkImage::CachingHint chint) {
if (SkBitmapCache::Find(fUniqueID, bitmap)) {
return check_output_bitmap(*bitmap, fUniqueID);
}
@@ -120,16 +121,18 @@
}
bitmap->pixelRef()->setImmutableWithID(fUniqueID);
- SkBitmapCache::Add(fUniqueID, *bitmap);
- if (client) {
- as_IB(client)->notifyAddedToCache();
+ if (SkImage::kAllow_CachingHint == chint) {
+ SkBitmapCache::Add(fUniqueID, *bitmap);
+ if (client) {
+ as_IB(client)->notifyAddedToCache();
+ }
}
-
return true;
}
-bool SkImageCacherator::lockAsBitmap(SkBitmap* bitmap, const SkImage* client) {
- if (this->tryLockAsBitmap(bitmap, client)) {
+bool SkImageCacherator::lockAsBitmap(SkBitmap* bitmap, const SkImage* client,
+ SkImage::CachingHint chint) {
+ if (this->tryLockAsBitmap(bitmap, client, chint)) {
return check_output_bitmap(*bitmap, fUniqueID);
}
@@ -160,11 +163,12 @@
}
bitmap->pixelRef()->setImmutableWithID(fUniqueID);
- SkBitmapCache::Add(fUniqueID, *bitmap);
- if (client) {
- as_IB(client)->notifyAddedToCache();
+ if (SkImage::kAllow_CachingHint == chint) {
+ SkBitmapCache::Add(fUniqueID, *bitmap);
+ if (client) {
+ as_IB(client)->notifyAddedToCache();
+ }
}
-
return check_output_bitmap(*bitmap, fUniqueID);
#else
return false;
@@ -220,7 +224,7 @@
* 5. Ask the generator to return RGB(A) data, which the GPU can convert
*/
GrTexture* SkImageCacherator::lockTexture(GrContext* ctx, const GrUniqueKey& key,
- const SkImage* client) {
+ const SkImage* client, SkImage::CachingHint chint) {
// 1. Check the cache for a pre-existing one
if (key.isValid()) {
if (GrTexture* tex = ctx->textureProvider()->findAndRefTextureByUniqueKey(key)) {
@@ -260,7 +264,7 @@
// 5. Ask the generator to return RGB(A) data, which the GPU can convert
SkBitmap bitmap;
- if (this->tryLockAsBitmap(&bitmap, client)) {
+ if (this->tryLockAsBitmap(&bitmap, client, chint)) {
GrTexture* tex = GrUploadBitmapToTexture(ctx, bitmap);
if (tex) {
return set_key_and_return(tex, key);
@@ -275,10 +279,13 @@
class Cacherator_GrTextureMaker : public GrTextureMaker {
public:
- Cacherator_GrTextureMaker(GrContext* context, SkImageCacherator* cacher, const SkImage* client)
+ Cacherator_GrTextureMaker(GrContext* context, SkImageCacherator* cacher, const SkImage* client,
+ SkImage::CachingHint chint)
: INHERITED(context, cacher->info().width(), cacher->info().height())
, fCacher(cacher)
- , fClient(client) {
+ , fClient(client)
+ , fCachingHint(chint)
+ {
if (client) {
GrMakeKeyFromImageID(&fOriginalKey, client->uniqueID(),
SkIRect::MakeWH(this->width(), this->height()));
@@ -291,7 +298,7 @@
// GrTexture* generateTextureForParams(const CopyParams&) override;
GrTexture* refOriginalTexture() override {
- return fCacher->lockTexture(this->context(), fOriginalKey, fClient);
+ return fCacher->lockTexture(this->context(), fOriginalKey, fClient, fCachingHint);
}
void makeCopyKey(const CopyParams& stretch, GrUniqueKey* paramsCopyKey) override {
@@ -310,23 +317,24 @@
SkImageCacherator* fCacher;
const SkImage* fClient;
GrUniqueKey fOriginalKey;
+ SkImage::CachingHint fCachingHint;
typedef GrTextureMaker INHERITED;
};
GrTexture* SkImageCacherator::lockAsTexture(GrContext* ctx, const GrTextureParams& params,
- const SkImage* client) {
+ const SkImage* client, SkImage::CachingHint chint) {
if (!ctx) {
return nullptr;
}
- return Cacherator_GrTextureMaker(ctx, this, client).refTextureForParams(params);
+ return Cacherator_GrTextureMaker(ctx, this, client, chint).refTextureForParams(params);
}
#else
GrTexture* SkImageCacherator::lockAsTexture(GrContext* ctx, const GrTextureParams&,
- const SkImage* client) {
+ const SkImage* client, SkImage::CachingHint) {
return nullptr;
}
diff --git a/src/core/SkImageCacherator.h b/src/core/SkImageCacherator.h
index 48a2814..5ba5422 100644
--- a/src/core/SkImageCacherator.h
+++ b/src/core/SkImageCacherator.h
@@ -36,7 +36,8 @@
* If not NULL, the client will be notified (->notifyAddedToCache()) when resources are
* added to the cache on its behalf.
*/
- bool lockAsBitmap(SkBitmap*, const SkImage* client);
+ bool lockAsBitmap(SkBitmap*, const SkImage* client,
+ SkImage::CachingHint = SkImage::kAllow_CachingHint);
/**
* Returns a ref() on the texture produced by this generator. The caller must call unref()
@@ -47,7 +48,8 @@
*
* The caller is responsible for calling texture->unref() when they are done.
*/
- GrTexture* lockAsTexture(GrContext*, const GrTextureParams&, const SkImage* client);
+ GrTexture* lockAsTexture(GrContext*, const GrTextureParams&, const SkImage* client,
+ SkImage::CachingHint = SkImage::kAllow_CachingHint);
/**
* If the underlying src naturally is represented by an encoded blob (in SkData), this returns
@@ -59,11 +61,12 @@
SkImageCacherator(SkImageGenerator*, const SkImageInfo&, const SkIPoint&, uint32_t uniqueID);
bool generateBitmap(SkBitmap*);
- bool tryLockAsBitmap(SkBitmap*, const SkImage*);
+ bool tryLockAsBitmap(SkBitmap*, const SkImage*, SkImage::CachingHint);
#if SK_SUPPORT_GPU
// Returns the texture. If the cacherator is generating the texture and wants to cache it,
// it should use the passed in key (if the key is valid).
- GrTexture* lockTexture(GrContext*, const GrUniqueKey& key, const SkImage* client);
+ GrTexture* lockTexture(GrContext*, const GrUniqueKey& key, const SkImage* client,
+ SkImage::CachingHint);
#endif
class ScopedGenerator {
diff --git a/src/core/SkPixmap.cpp b/src/core/SkPixmap.cpp
index c63bef9..718be88 100644
--- a/src/core/SkPixmap.cpp
+++ b/src/core/SkPixmap.cpp
@@ -205,6 +205,44 @@
return true;
}
+#include "SkBitmap.h"
+#include "SkCanvas.h"
+#include "SkSurface.h"
+#include "SkXfermode.h"
+
+bool SkPixmap::scalePixels(const SkPixmap& dst, SkFilterQuality quality) const {
+ // Can't do anthing with empty src or dst
+ if (this->width() <= 0 || this->height() <= 0 || dst.width() <= 0 || dst.height() <= 0) {
+ return false;
+ }
+
+ // no scaling involved?
+ if (dst.width() == this->width() && dst.height() == this->height()) {
+ return this->readPixels(dst);
+ }
+
+ SkBitmap bitmap;
+ // we will only ready from this pixmap, but the bitmap setting takes void*, hence the cast
+ void* readOnlyAddr = const_cast<void*>(this->addr());
+ if (!bitmap.installPixels(this->info(), readOnlyAddr, this->rowBytes())) {
+ return false;
+ }
+ bitmap.setIsVolatile(true); // so we don't try to cache it
+
+ SkAutoTUnref<SkSurface> surface(SkSurface::NewRasterDirect(dst.info(), dst.writable_addr(),
+ dst.rowBytes()));
+ if (!surface) {
+ return false;
+ }
+
+ SkPaint paint;
+ paint.setFilterQuality(quality);
+ paint.setXfermodeMode(SkXfermode::kSrc_Mode);
+ surface->getCanvas()->drawBitmapRect(bitmap, SkRect::MakeIWH(dst.width(), dst.height()),
+ &paint);
+ return true;
+}
+
//////////////////////////////////////////////////////////////////////////////////////////////////
SkAutoPixmapStorage::SkAutoPixmapStorage() : fStorage(nullptr) {}
diff --git a/src/image/SkImage.cpp b/src/image/SkImage.cpp
index b96f7d1..fdaadc5 100644
--- a/src/image/SkImage.cpp
+++ b/src/image/SkImage.cpp
@@ -48,12 +48,29 @@
}
bool SkImage::readPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
- int srcX, int srcY) const {
+ int srcX, int srcY, CachingHint chint) const {
SkReadPixelsRec rec(dstInfo, dstPixels, dstRowBytes, srcX, srcY);
if (!rec.trim(this->width(), this->height())) {
return false;
}
- return as_IB(this)->onReadPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY);
+ return as_IB(this)->onReadPixels(rec.fInfo, rec.fPixels, rec.fRowBytes, rec.fX, rec.fY, chint);
+}
+
+bool SkImage::scalePixels(const SkPixmap& dst, SkFilterQuality quality, CachingHint chint) const {
+ // Idea: If/when SkImageGenerator supports a native-scaling API (where the generator itself
+ // can scale more efficiently) we should take advantage of it here.
+ //
+ SkBitmap bm;
+ if (as_IB(this)->getROPixels(&bm, chint)) {
+ bm.lockPixels();
+ SkPixmap pmap;
+ // Note: By calling the pixmap scaler, we never cache the final result, so the chint
+ // is (currently) only being applied to the getROPixels. If we get a request to
+ // also attempt to cache the final (scaled) result, we would add that logic here.
+ //
+ return bm.peekPixels(&pmap) && pmap.scalePixels(dst, quality);
+ }
+ return false;
}
void SkImage::preroll(GrContext* ctx) const {
@@ -286,7 +303,7 @@
}
bool SkImage_Base::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
- int srcX, int srcY) const {
+ int srcX, int srcY, CachingHint) const {
if (!raster_canvas_supports(dstInfo)) {
return false;
}
@@ -317,8 +334,8 @@
return false;
}
-bool SkImage::readPixels(const SkPixmap& pmap, int srcX, int srcY) const {
- return this->readPixels(pmap.info(), pmap.writable_addr(), pmap.rowBytes(), srcX, srcY);
+bool SkImage::readPixels(const SkPixmap& pmap, int srcX, int srcY, CachingHint chint) const {
+ return this->readPixels(pmap.info(), pmap.writable_addr(), pmap.rowBytes(), srcX, srcY, chint);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/image/SkImage_Base.h b/src/image/SkImage_Base.h
index 3fe3444..c91430e 100644
--- a/src/image/SkImage_Base.h
+++ b/src/image/SkImage_Base.h
@@ -29,13 +29,13 @@
// Default impl calls onDraw
virtual bool onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
- int srcX, int srcY) const;
+ int srcX, int srcY, CachingHint) const;
virtual GrTexture* peekTexture() const { return nullptr; }
// return a read-only copy of the pixels. We promise to not modify them,
// but only inspect them (or encode them).
- virtual bool getROPixels(SkBitmap*) const = 0;
+ virtual bool getROPixels(SkBitmap*, CachingHint = kAllow_CachingHint) const = 0;
virtual SkImage* onApplyFilter(SkImageFilter*, SkIPoint* offset,
bool forceResultToOriginalSize) const;
diff --git a/src/image/SkImage_Generator.cpp b/src/image/SkImage_Generator.cpp
index 3465289..5031c24 100644
--- a/src/image/SkImage_Generator.cpp
+++ b/src/image/SkImage_Generator.cpp
@@ -21,12 +21,12 @@
, fCache(cache) // take ownership
{}
- bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY) const override;
+ bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY, CachingHint) const override;
const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const override;
SkData* onRefEncoded() const override;
bool isOpaque() const override { return fCache->info().isOpaque(); }
SkImage* onNewSubset(const SkIRect&) const override;
- bool getROPixels(SkBitmap*) const override;
+ bool getROPixels(SkBitmap*, CachingHint) const override;
GrTexture* asTextureRef(GrContext*, const GrTextureParams&) const override;
bool onIsLazyGenerated() const override { return true; }
@@ -39,9 +39,9 @@
///////////////////////////////////////////////////////////////////////////////
bool SkImage_Generator::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
- int srcX, int srcY) const {
+ int srcX, int srcY, CachingHint chint) const {
SkBitmap bm;
- if (this->getROPixels(&bm)) {
+ if (this->getROPixels(&bm, chint)) {
return bm.readPixels(dstInfo, dstPixels, dstRB, srcX, srcY);
}
return false;
@@ -55,8 +55,8 @@
return fCache->refEncoded();
}
-bool SkImage_Generator::getROPixels(SkBitmap* bitmap) const {
- return fCache->lockAsBitmap(bitmap, this);
+bool SkImage_Generator::getROPixels(SkBitmap* bitmap, CachingHint chint) const {
+ return fCache->lockAsBitmap(bitmap, this, chint);
}
GrTexture* SkImage_Generator::asTextureRef(GrContext* ctx, const GrTextureParams& params) const {
diff --git a/src/image/SkImage_Gpu.cpp b/src/image/SkImage_Gpu.cpp
index dd4bee3..346f798 100644
--- a/src/image/SkImage_Gpu.cpp
+++ b/src/image/SkImage_Gpu.cpp
@@ -45,7 +45,7 @@
return SkImageInfo::MakeN32(w, h, isOpaque ? kOpaque_SkAlphaType : kPremul_SkAlphaType);
}
-bool SkImage_Gpu::getROPixels(SkBitmap* dst) const {
+bool SkImage_Gpu::getROPixels(SkBitmap* dst, CachingHint chint) const {
if (SkBitmapCache::Find(this->uniqueID(), dst)) {
SkASSERT(dst->getGenerationID() == this->uniqueID());
SkASSERT(dst->isImmutable());
@@ -62,8 +62,10 @@
}
dst->pixelRef()->setImmutableWithID(this->uniqueID());
- SkBitmapCache::Add(this->uniqueID(), *dst);
- fAddedRasterVersionToCache.store(true);
+ if (kAllow_CachingHint == chint) {
+ SkBitmapCache::Add(this->uniqueID(), *dst);
+ fAddedRasterVersionToCache.store(true);
+ }
return true;
}
@@ -120,7 +122,7 @@
}
bool SkImage_Gpu::onReadPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
- int srcX, int srcY) const {
+ int srcX, int srcY, CachingHint) const {
GrPixelConfig config = SkImageInfo2GrPixelConfig(info.colorType(), info.alphaType(),
info.profileType());
uint32_t flags = 0;
diff --git a/src/image/SkImage_Gpu.h b/src/image/SkImage_Gpu.h
index d5080d7..ff3b12e 100644
--- a/src/image/SkImage_Gpu.h
+++ b/src/image/SkImage_Gpu.h
@@ -35,14 +35,14 @@
}
}
- bool getROPixels(SkBitmap*) const override;
+ bool getROPixels(SkBitmap*, CachingHint) const override;
GrTexture* asTextureRef(GrContext* ctx, const GrTextureParams& params) const override;
SkImage* onNewSubset(const SkIRect&) const override;
GrTexture* peekTexture() const override { return fTexture; }
bool isOpaque() const override;
bool onReadPixels(const SkImageInfo&, void* dstPixels, size_t dstRowBytes,
- int srcX, int srcY) const override;
+ int srcX, int srcY, CachingHint) const override;
SkImage* onApplyFilter(SkImageFilter*, SkIPoint* offset,
bool forceResultToOriginalSize) const override;
diff --git a/src/image/SkImage_Raster.cpp b/src/image/SkImage_Raster.cpp
index 9c90ba9..977dc01 100644
--- a/src/image/SkImage_Raster.cpp
+++ b/src/image/SkImage_Raster.cpp
@@ -66,10 +66,10 @@
SkImage_Raster(const SkImageInfo&, SkData*, size_t rb, SkColorTable*);
virtual ~SkImage_Raster();
- bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY) const override;
+ bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY, CachingHint) const override;
const void* onPeekPixels(SkImageInfo*, size_t* /*rowBytes*/) const override;
SkData* onRefEncoded() const override;
- bool getROPixels(SkBitmap*) const override;
+ bool getROPixels(SkBitmap*, CachingHint) const override;
GrTexture* asTextureRef(GrContext*, const GrTextureParams&) const override;
SkImage* onNewSubset(const SkIRect&) const override;
@@ -135,7 +135,7 @@
SkImage_Raster::~SkImage_Raster() {}
bool SkImage_Raster::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRowBytes,
- int srcX, int srcY) const {
+ int srcX, int srcY, CachingHint) const {
SkBitmap shallowCopy(fBitmap);
return shallowCopy.readPixels(dstInfo, dstPixels, dstRowBytes, srcX, srcY);
}
@@ -162,7 +162,7 @@
return nullptr;
}
-bool SkImage_Raster::getROPixels(SkBitmap* dst) const {
+bool SkImage_Raster::getROPixels(SkBitmap* dst, CachingHint) const {
*dst = fBitmap;
return true;
}