aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/image/SkImage_Lazy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/image/SkImage_Lazy.cpp')
-rw-r--r--src/image/SkImage_Lazy.cpp133
1 files changed, 133 insertions, 0 deletions
diff --git a/src/image/SkImage_Lazy.cpp b/src/image/SkImage_Lazy.cpp
new file mode 100644
index 0000000000..b1f243b151
--- /dev/null
+++ b/src/image/SkImage_Lazy.cpp
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "SkImage_Base.h"
+#include "SkBitmap.h"
+#include "SkData.h"
+#include "SkImageCacherator.h"
+#include "SkImagePriv.h"
+#include "SkPixelRef.h"
+
+class SkImage_Lazy : public SkImage_Base {
+public:
+ SkImage_Lazy(SkImageCacherator::Validator* validator)
+ : INHERITED(validator->fInfo.width(), validator->fInfo.height(), validator->fUniqueID)
+ , fCache(validator)
+ {}
+
+ virtual SkImageInfo onImageInfo() const override {
+ return fCache.info();
+ }
+ SkAlphaType onAlphaType() const override {
+ return fCache.info().alphaType();
+ }
+
+ bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY,
+ CachingHint) const override;
+#if SK_SUPPORT_GPU
+ sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerParams&,
+ SkColorSpace*, sk_sp<SkColorSpace>*,
+ SkScalar scaleAdjust[2]) const override;
+#endif
+ SkImageCacherator* peekCacherator() const override { return &fCache; }
+ SkData* onRefEncoded(GrContext*) const override;
+ sk_sp<SkImage> onMakeSubset(const SkIRect&) const override;
+ bool getROPixels(SkBitmap*, SkColorSpace* dstColorSpace, CachingHint) const override;
+ bool onIsLazyGenerated() const override { return true; }
+ sk_sp<SkImage> onMakeColorSpace(sk_sp<SkColorSpace>) const override;
+
+private:
+ mutable SkImageCacherator fCache;
+
+ typedef SkImage_Base INHERITED;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+bool SkImage_Lazy::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
+ int srcX, int srcY, CachingHint chint) const {
+ SkColorSpace* dstColorSpace = dstInfo.colorSpace();
+ SkBitmap bm;
+ if (kDisallow_CachingHint == chint) {
+ SkImageCacherator::CachedFormat cacheFormat = fCache.chooseCacheFormat(dstColorSpace);
+ if (fCache.lockAsBitmapOnlyIfAlreadyCached(&bm, cacheFormat)) {
+ return bm.readPixels(dstInfo, dstPixels, dstRB, srcX, srcY);
+ } else {
+ // Try passing the caller's buffer directly down to the generator. If this fails we
+ // may still succeed in the general case, as the generator may prefer some other
+ // config, which we could then convert via SkBitmap::readPixels.
+ if (fCache.directGeneratePixels(dstInfo, dstPixels, dstRB, srcX, srcY,
+ SkTransferFunctionBehavior::kRespect)) {
+ return true;
+ }
+ // else fall through
+ }
+ }
+
+ if (this->getROPixels(&bm, dstColorSpace, chint)) {
+ return bm.readPixels(dstInfo, dstPixels, dstRB, srcX, srcY);
+ }
+ return false;
+}
+
+SkData* SkImage_Lazy::onRefEncoded(GrContext* ctx) const {
+ return fCache.refEncoded(ctx);
+}
+
+bool SkImage_Lazy::getROPixels(SkBitmap* bitmap, SkColorSpace* dstColorSpace,
+ CachingHint chint) const {
+ return fCache.lockAsBitmap(nullptr, bitmap, this, dstColorSpace, chint);
+}
+
+#if SK_SUPPORT_GPU
+sk_sp<GrTextureProxy> SkImage_Lazy::asTextureProxyRef(GrContext* context,
+ const GrSamplerParams& params,
+ SkColorSpace* dstColorSpace,
+ sk_sp<SkColorSpace>* texColorSpace,
+ SkScalar scaleAdjust[2]) const {
+ return fCache.lockAsTextureProxy(context, params, dstColorSpace,
+ texColorSpace, this, scaleAdjust);
+}
+#endif
+
+sk_sp<SkImage> SkImage_Lazy::onMakeSubset(const SkIRect& subset) const {
+ SkASSERT(fCache.info().bounds().contains(subset));
+ SkASSERT(fCache.info().bounds() != subset);
+
+ const SkIRect generatorSubset = subset.makeOffset(fCache.fOrigin.x(), fCache.fOrigin.y());
+ SkImageCacherator::Validator validator(fCache.fSharedGenerator, &generatorSubset);
+ return validator ? sk_sp<SkImage>(new SkImage_Lazy(&validator)) : nullptr;
+}
+
+sk_sp<SkImage> SkImage_Lazy::onMakeColorSpace(sk_sp<SkColorSpace> target) const {
+ SkBitmap dst;
+ SkImageInfo dstInfo = fCache.info().makeColorSpace(target);
+ if (kIndex_8_SkColorType == dstInfo.colorType() ||
+ kGray_8_SkColorType == dstInfo.colorType() ||
+ kRGB_565_SkColorType == dstInfo.colorType()) {
+ dstInfo = dstInfo.makeColorType(kN32_SkColorType);
+ }
+ dst.allocPixels(dstInfo);
+
+ // Use kIgnore for transfer function behavior. This is used by the SkColorSpaceXformCanvas,
+ // which wants to pre-xform the inputs but ignore the transfer function on blends.
+ if (!fCache.directGeneratePixels(dstInfo, dst.getPixels(), dst.rowBytes(), 0, 0,
+ SkTransferFunctionBehavior::kIgnore)) {
+ return nullptr;
+ }
+
+ dst.setImmutable();
+ return SkImage::MakeFromBitmap(dst);
+}
+
+sk_sp<SkImage> SkImage::MakeFromGenerator(std::unique_ptr<SkImageGenerator> generator,
+ const SkIRect* subset) {
+ SkImageCacherator::Validator validator(
+ SkImageCacherator::SharedGenerator::Make(std::move(generator)), subset);
+
+ return validator ? sk_make_sp<SkImage_Lazy>(&validator) : nullptr;
+}