• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2015 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #include "SkImage_Base.h"
9 #include "SkBitmap.h"
10 #include "SkData.h"
11 #include "SkImageCacherator.h"
12 #include "SkImagePriv.h"
13 #include "SkPixelRef.h"
14 
15 class SkImage_Generator : public SkImage_Base {
16 public:
SkImage_Generator(SkImageCacherator::Validator * validator)17     SkImage_Generator(SkImageCacherator::Validator* validator)
18         : INHERITED(validator->fInfo.width(), validator->fInfo.height(), validator->fUniqueID)
19         , fCache(validator)
20     {}
21 
onImageInfo() const22     virtual SkImageInfo onImageInfo() const override {
23         return fCache.info();
24     }
onAlphaType() const25     SkAlphaType onAlphaType() const override {
26         return fCache.info().alphaType();
27     }
28 
29     bool onReadPixels(const SkImageInfo&, void*, size_t, int srcX, int srcY,
30                       CachingHint) const override;
31 #if SK_SUPPORT_GPU
32     sk_sp<GrTextureProxy> asTextureProxyRef(GrContext*, const GrSamplerParams&,
33                                             SkColorSpace*, sk_sp<SkColorSpace>*,
34                                             SkScalar scaleAdjust[2]) const override;
35 #endif
peekCacherator() const36     SkImageCacherator* peekCacherator() const override { return &fCache; }
37     SkData* onRefEncoded(GrContext*) const override;
38     sk_sp<SkImage> onMakeSubset(const SkIRect&) const override;
39     bool getROPixels(SkBitmap*, SkColorSpace* dstColorSpace, CachingHint) const override;
onIsLazyGenerated() const40     bool onIsLazyGenerated() const override { return true; }
41     sk_sp<SkImage> onMakeColorSpace(sk_sp<SkColorSpace>) const override;
42 
43 private:
44     mutable SkImageCacherator fCache;
45 
46     typedef SkImage_Base INHERITED;
47 };
48 
49 ///////////////////////////////////////////////////////////////////////////////
50 
onReadPixels(const SkImageInfo & dstInfo,void * dstPixels,size_t dstRB,int srcX,int srcY,CachingHint chint) const51 bool SkImage_Generator::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
52                                      int srcX, int srcY, CachingHint chint) const {
53     SkColorSpace* dstColorSpace = dstInfo.colorSpace();
54     SkBitmap bm;
55     if (kDisallow_CachingHint == chint) {
56         SkImageCacherator::CachedFormat cacheFormat = fCache.chooseCacheFormat(dstColorSpace);
57         if (fCache.lockAsBitmapOnlyIfAlreadyCached(&bm, cacheFormat)) {
58             return bm.readPixels(dstInfo, dstPixels, dstRB, srcX, srcY);
59         } else {
60             // Try passing the caller's buffer directly down to the generator. If this fails we
61             // may still succeed in the general case, as the generator may prefer some other
62             // config, which we could then convert via SkBitmap::readPixels.
63             if (fCache.directGeneratePixels(dstInfo, dstPixels, dstRB, srcX, srcY)) {
64                 return true;
65             }
66             // else fall through
67         }
68     }
69 
70     if (this->getROPixels(&bm, dstColorSpace, chint)) {
71         return bm.readPixels(dstInfo, dstPixels, dstRB, srcX, srcY);
72     }
73     return false;
74 }
75 
onRefEncoded(GrContext * ctx) const76 SkData* SkImage_Generator::onRefEncoded(GrContext* ctx) const {
77     return fCache.refEncoded(ctx);
78 }
79 
getROPixels(SkBitmap * bitmap,SkColorSpace * dstColorSpace,CachingHint chint) const80 bool SkImage_Generator::getROPixels(SkBitmap* bitmap, SkColorSpace* dstColorSpace,
81                                     CachingHint chint) const {
82     return fCache.lockAsBitmap(nullptr, bitmap, this, dstColorSpace, chint);
83 }
84 
85 #if SK_SUPPORT_GPU
asTextureProxyRef(GrContext * context,const GrSamplerParams & params,SkColorSpace * dstColorSpace,sk_sp<SkColorSpace> * texColorSpace,SkScalar scaleAdjust[2]) const86 sk_sp<GrTextureProxy> SkImage_Generator::asTextureProxyRef(GrContext* context,
87                                                            const GrSamplerParams& params,
88                                                            SkColorSpace* dstColorSpace,
89                                                            sk_sp<SkColorSpace>* texColorSpace,
90                                                            SkScalar scaleAdjust[2]) const {
91     return fCache.lockAsTextureProxy(context, params, dstColorSpace,
92                                      texColorSpace, this, scaleAdjust);
93 }
94 #endif
95 
onMakeSubset(const SkIRect & subset) const96 sk_sp<SkImage> SkImage_Generator::onMakeSubset(const SkIRect& subset) const {
97     SkASSERT(fCache.info().bounds().contains(subset));
98     SkASSERT(fCache.info().bounds() != subset);
99 
100     const SkIRect generatorSubset = subset.makeOffset(fCache.fOrigin.x(), fCache.fOrigin.y());
101     SkImageCacherator::Validator validator(fCache.fSharedGenerator, &generatorSubset);
102     return validator ? sk_sp<SkImage>(new SkImage_Generator(&validator)) : nullptr;
103 }
104 
onMakeColorSpace(sk_sp<SkColorSpace> target) const105 sk_sp<SkImage> SkImage_Generator::onMakeColorSpace(sk_sp<SkColorSpace> target) const {
106     SkBitmap dst;
107     SkImageInfo dstInfo = fCache.info().makeColorSpace(target);
108     if (kIndex_8_SkColorType == dstInfo.colorType() ||
109         kGray_8_SkColorType == dstInfo.colorType()) {
110         dstInfo = dstInfo.makeColorType(kN32_SkColorType);
111     }
112     dst.allocPixels(dstInfo);
113 
114     if (!fCache.directGeneratePixels(dstInfo, dst.getPixels(), dst.rowBytes(), 0, 0)) {
115         return nullptr;
116     }
117 
118     dst.setImmutable();
119     return SkImage::MakeFromBitmap(dst);
120 }
121 
MakeFromGenerator(std::unique_ptr<SkImageGenerator> generator,const SkIRect * subset)122 sk_sp<SkImage> SkImage::MakeFromGenerator(std::unique_ptr<SkImageGenerator> generator,
123                                           const SkIRect* subset) {
124     SkImageCacherator::Validator validator(
125                        SkImageCacherator::SharedGenerator::Make(std::move(generator)), subset);
126 
127     return validator ? sk_make_sp<SkImage_Generator>(&validator) : nullptr;
128 }
129