Plumb dst color space in many places, rather than "mode"
[platform/upstream/libSkiaSharp.git] / src / image / SkImage_Generator.cpp
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:
17     SkImage_Generator(SkImageCacherator::Validator* validator)
18         : INHERITED(validator->fInfo.width(), validator->fInfo.height(), validator->fUniqueID)
19         , fCache(validator)
20     {}
21
22     virtual SkImageInfo onImageInfo() const override {
23         return fCache.info();
24     }
25     SkAlphaType onAlphaType() const override {
26         return fCache.info().alphaType();
27     }
28
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; }
37
38 private:
39     mutable SkImageCacherator fCache;
40
41     typedef SkImage_Base INHERITED;
42 };
43
44 ///////////////////////////////////////////////////////////////////////////////
45
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();
49     SkBitmap bm;
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);
54         } else {
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)) {
59                 return true;
60             }
61             // else fall through
62         }
63     }
64
65     if (this->getROPixels(&bm, dstColorSpace, chint)) {
66         return bm.readPixels(dstInfo, dstPixels, dstRB, srcX, srcY);
67     }
68     return false;
69 }
70
71 SkData* SkImage_Generator::onRefEncoded(GrContext* ctx) const {
72     return fCache.refEncoded(ctx);
73 }
74
75 bool SkImage_Generator::getROPixels(SkBitmap* bitmap, SkColorSpace* dstColorSpace,
76                                     CachingHint chint) const {
77     return fCache.lockAsBitmap(bitmap, this, dstColorSpace, chint);
78 }
79
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);
84 }
85
86 sk_sp<SkImage> SkImage_Generator::onMakeSubset(const SkIRect& subset) const {
87     SkASSERT(fCache.info().bounds().contains(subset));
88     SkASSERT(fCache.info().bounds() != subset);
89
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;
93 }
94
95 sk_sp<SkImage> SkImage::MakeFromGenerator(SkImageGenerator* generator, const SkIRect* subset) {
96     SkImageCacherator::Validator validator(SkImageCacherator::SharedGenerator::Make(generator),
97                                            subset);
98
99     return validator ? sk_make_sp<SkImage_Generator>(&validator) : nullptr;
100 }