Plumb dst color space in many places, rather than "mode"
[platform/upstream/libSkiaSharp.git] / src / core / SkImageCacherator.h
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 #ifndef SkImageCacherator_DEFINED
9 #define SkImageCacherator_DEFINED
10
11 #include "SkImageGenerator.h"
12 #include "SkMutex.h"
13 #include "SkTemplates.h"
14
15 class GrCaps;
16 class GrContext;
17 class GrSamplerParams;
18 class GrUniqueKey;
19 class SkBitmap;
20 class SkImage;
21
22 /*
23  *  Internal class to manage caching the output of an ImageGenerator.
24  */
25 class SkImageCacherator {
26 public:
27     // Takes ownership of the generator
28     static SkImageCacherator* NewFromGenerator(SkImageGenerator*, const SkIRect* subset = nullptr);
29
30     ~SkImageCacherator();
31
32     const SkImageInfo& info() const { return fInfo; }
33     uint32_t uniqueID() const { return fUniqueIDs[kLegacy_CachedFormat]; }
34
35     enum CachedFormat {
36         kLegacy_CachedFormat,    // The format from the generator, with any color space stripped out
37         kAsIs_CachedFormat,      // The format from the generator, with no modification
38         kLinearF16_CachedFormat, // Half float RGBA with linear gamma
39         kSRGB8888_CachedFormat,  // sRGB bytes
40
41         kNumCachedFormats,
42     };
43
44     /**
45      *  On success (true), bitmap will point to the pixels for this generator. If this returns
46      *  false, the bitmap will be reset to empty.
47      *
48      *  If not NULL, the client will be notified (->notifyAddedToCache()) when resources are
49      *  added to the cache on its behalf.
50      */
51     bool lockAsBitmap(SkBitmap*, const SkImage* client, SkColorSpace* dstColorSpace,
52                       SkImage::CachingHint = SkImage::kAllow_CachingHint);
53
54     /**
55      *  Returns a ref() on the texture produced by this generator. The caller must call unref()
56      *  when it is done. Will return nullptr on failure.
57      *
58      *  If not NULL, the client will be notified (->notifyAddedToCache()) when resources are
59      *  added to the cache on its behalf.
60      *
61      *  The caller is responsible for calling texture->unref() when they are done.
62      */
63     GrTexture* lockAsTexture(GrContext*, const GrSamplerParams&, SkColorSpace* dstColorSpace,
64                              sk_sp<SkColorSpace>* texColorSpace, const SkImage* client,
65                              SkImage::CachingHint = SkImage::kAllow_CachingHint);
66
67     /**
68      *  If the underlying src naturally is represented by an encoded blob (in SkData), this returns
69      *  a ref to that data. If not, it returns null.
70      *
71      *  If a GrContext is specified, then the caller is only interested in gpu-specific encoded
72      *  formats, so others (e.g. PNG) can just return nullptr.
73      */
74     SkData* refEncoded(GrContext*);
75
76     // Only return true if the generate has already been cached.
77     bool lockAsBitmapOnlyIfAlreadyCached(SkBitmap*, CachedFormat);
78     // Call the underlying generator directly
79     bool directGeneratePixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
80                               int srcX, int srcY);
81
82     bool directAccessScaledImage(const SkRect& srcRect, const SkMatrix& totalMatrix,
83                                  SkFilterQuality, SkImageGenerator::ScaledImageRec*);
84
85 private:
86     // Ref-counted tuple(SkImageGenerator, SkMutex) which allows sharing of one generator
87     // among several cacherators.
88     class SharedGenerator final : public SkNVRefCnt<SharedGenerator> {
89     public:
90         static sk_sp<SharedGenerator> Make(SkImageGenerator* gen) {
91             return gen ? sk_sp<SharedGenerator>(new SharedGenerator(gen)) : nullptr;
92         }
93
94     private:
95         explicit SharedGenerator(SkImageGenerator* gen) : fGenerator(gen) { SkASSERT(gen); }
96
97         friend class ScopedGenerator;
98         friend class SkImageCacherator;
99
100         std::unique_ptr<SkImageGenerator> fGenerator;
101         SkMutex                           fMutex;
102     };
103     class ScopedGenerator;
104
105     struct Validator {
106         Validator(sk_sp<SharedGenerator>, const SkIRect* subset);
107
108         operator bool() const { return fSharedGenerator.get(); }
109
110         sk_sp<SharedGenerator> fSharedGenerator;
111         SkImageInfo            fInfo;
112         SkIPoint               fOrigin;
113         uint32_t               fUniqueID;
114     };
115
116     SkImageCacherator(Validator*);
117
118     CachedFormat chooseCacheFormat(SkColorSpace* dstColorSpace, const GrCaps* = nullptr);
119     SkImageInfo buildCacheInfo(CachedFormat);
120
121     bool generateBitmap(SkBitmap*, const SkImageInfo&);
122     bool tryLockAsBitmap(SkBitmap*, const SkImage*, SkImage::CachingHint, CachedFormat,
123                          const SkImageInfo&);
124 #if SK_SUPPORT_GPU
125     // Returns the texture. If the cacherator is generating the texture and wants to cache it,
126     // it should use the passed in key (if the key is valid).
127     GrTexture* lockTexture(GrContext*, const GrUniqueKey& key, const SkImage* client,
128                            SkImage::CachingHint, bool willBeMipped, SkColorSpace* dstColorSpace);
129     // Returns the color space of the texture that would be returned if you called lockTexture.
130     // Separate code path to allow querying of the color space for textures that cached (even
131     // externally).
132     sk_sp<SkColorSpace> getColorSpace(GrContext*, SkColorSpace* dstColorSpace);
133     void makeCacheKeyFromOrigKey(const GrUniqueKey& origKey, CachedFormat, GrUniqueKey* cacheKey);
134 #endif
135
136     sk_sp<SharedGenerator> fSharedGenerator;
137     const SkImageInfo      fInfo;
138     const SkIPoint         fOrigin;
139     uint32_t               fUniqueIDs[kNumCachedFormats];
140
141     friend class GrImageTextureMaker;
142     friend class SkImage;
143     friend class SkImage_Generator;
144 };
145
146 #endif