2 * Copyright 2015 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "SkImage_Base.h"
11 #include "SkImageCacherator.h"
12 #include "SkImagePriv.h"
13 #include "SkPixelRef.h"
15 class SkImage_Generator : public SkImage_Base {
17 SkImage_Generator(SkImageCacherator::Validator* validator)
18 : INHERITED(validator->fInfo.width(), validator->fInfo.height(), validator->fUniqueID)
22 virtual SkImageInfo onImageInfo() const override {
25 SkAlphaType onAlphaType() const override {
26 return fCache.info().alphaType();
29 bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY, CachingHint) const override;
30 SkImageCacherator* peekCacherator() const override { return &fCache; }
31 SkData* onRefEncoded(GrContext*) const override;
32 sk_sp<SkImage> onMakeSubset(const SkIRect&) const override;
33 bool getROPixels(SkBitmap*, SkColorSpace* dstColorSpace, CachingHint) const override;
34 GrTexture* asTextureRef(GrContext*, const GrSamplerParams&, SkColorSpace*,
35 sk_sp<SkColorSpace>*) const override;
36 bool onIsLazyGenerated() const override { return true; }
39 mutable SkImageCacherator fCache;
41 typedef SkImage_Base INHERITED;
44 ///////////////////////////////////////////////////////////////////////////////
46 bool SkImage_Generator::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
47 int srcX, int srcY, CachingHint chint) const {
48 SkColorSpace* dstColorSpace = dstInfo.colorSpace();
50 if (kDisallow_CachingHint == chint) {
51 SkImageCacherator::CachedFormat cacheFormat = fCache.chooseCacheFormat(dstColorSpace);
52 if (fCache.lockAsBitmapOnlyIfAlreadyCached(&bm, cacheFormat)) {
53 return bm.readPixels(dstInfo, dstPixels, dstRB, srcX, srcY);
55 // Try passing the caller's buffer directly down to the generator. If this fails we
56 // may still succeed in the general case, as the generator may prefer some other
57 // config, which we could then convert via SkBitmap::readPixels.
58 if (fCache.directGeneratePixels(dstInfo, dstPixels, dstRB, srcX, srcY)) {
65 if (this->getROPixels(&bm, dstColorSpace, chint)) {
66 return bm.readPixels(dstInfo, dstPixels, dstRB, srcX, srcY);
71 SkData* SkImage_Generator::onRefEncoded(GrContext* ctx) const {
72 return fCache.refEncoded(ctx);
75 bool SkImage_Generator::getROPixels(SkBitmap* bitmap, SkColorSpace* dstColorSpace,
76 CachingHint chint) const {
77 return fCache.lockAsBitmap(bitmap, this, dstColorSpace, chint);
80 GrTexture* SkImage_Generator::asTextureRef(GrContext* ctx, const GrSamplerParams& params,
81 SkColorSpace* dstColorSpace,
82 sk_sp<SkColorSpace>* texColorSpace) const {
83 return fCache.lockAsTexture(ctx, params, dstColorSpace, texColorSpace, this);
86 sk_sp<SkImage> SkImage_Generator::onMakeSubset(const SkIRect& subset) const {
87 SkASSERT(fCache.info().bounds().contains(subset));
88 SkASSERT(fCache.info().bounds() != subset);
90 const SkIRect generatorSubset = subset.makeOffset(fCache.fOrigin.x(), fCache.fOrigin.y());
91 SkImageCacherator::Validator validator(fCache.fSharedGenerator, &generatorSubset);
92 return validator ? sk_sp<SkImage>(new SkImage_Generator(&validator)) : nullptr;
95 sk_sp<SkImage> SkImage::MakeFromGenerator(SkImageGenerator* generator, const SkIRect* subset) {
96 SkImageCacherator::Validator validator(SkImageCacherator::SharedGenerator::Make(generator),
99 return validator ? sk_make_sp<SkImage_Generator>(&validator) : nullptr;