Line data Source code
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 GrTextureProxy;
19 : class GrUniqueKey;
20 : class SkBitmap;
21 : class SkImage;
22 :
23 : /*
24 : * Internal class to manage caching the output of an ImageGenerator.
25 : */
26 : class SkImageCacherator {
27 : public:
28 : static SkImageCacherator* NewFromGenerator(std::unique_ptr<SkImageGenerator>,
29 : const SkIRect* subset = nullptr);
30 :
31 : ~SkImageCacherator();
32 :
33 0 : const SkImageInfo& info() const { return fInfo; }
34 : uint32_t uniqueID() const { return this->getUniqueID(kLegacy_CachedFormat); }
35 :
36 : enum CachedFormat {
37 : kLegacy_CachedFormat, // The format from the generator, with any color space stripped out
38 : kLinearF16_CachedFormat, // Half float RGBA with linear gamma
39 : kSRGB8888_CachedFormat, // sRGB bytes
40 : kSBGR8888_CachedFormat, // sRGB bytes, in BGR order
41 :
42 : kNumCachedFormats,
43 : };
44 :
45 : /**
46 : * On success (true), bitmap will point to the pixels for this generator. If this returns
47 : * false, the bitmap will be reset to empty.
48 : *
49 : * If not NULL, the client will be notified (->notifyAddedToCache()) when resources are
50 : * added to the cache on its behalf.
51 : */
52 : bool lockAsBitmap(GrContext*, SkBitmap*, const SkImage* client, SkColorSpace* dstColorSpace,
53 : SkImage::CachingHint = SkImage::kAllow_CachingHint);
54 :
55 : #if SK_SUPPORT_GPU
56 : /**
57 : * Returns a ref() on the texture produced by this generator. The caller must call unref()
58 : * when it is done. Will return nullptr on failure.
59 : *
60 : * If not NULL, the client will be notified (->notifyAddedToCache()) when resources are
61 : * added to the cache on its behalf.
62 : *
63 : * The caller is responsible for calling proxy->unref() when they are done.
64 : *
65 : * The scaleAdjust in/out parameter will return any scale adjustment that needs
66 : * to be applied to the absolute texture coordinates in the case where the image
67 : * was resized to meet the sampling requirements (e.g., resized out to the next power of 2).
68 : * It can be null if the caller knows resizing will not be required.
69 : */
70 : sk_sp<GrTextureProxy> lockAsTextureProxy(GrContext*, const GrSamplerParams&,
71 : SkColorSpace* dstColorSpace,
72 : sk_sp<SkColorSpace>* texColorSpace,
73 : const SkImage* client,
74 : SkScalar scaleAdjust[2],
75 : SkImage::CachingHint = SkImage::kAllow_CachingHint);
76 : #endif
77 :
78 : /**
79 : * If the underlying src naturally is represented by an encoded blob (in SkData), this returns
80 : * a ref to that data. If not, it returns null.
81 : *
82 : * If a GrContext is specified, then the caller is only interested in gpu-specific encoded
83 : * formats, so others (e.g. PNG) can just return nullptr.
84 : */
85 : SkData* refEncoded(GrContext*);
86 :
87 : // Only return true if the generate has already been cached.
88 : bool lockAsBitmapOnlyIfAlreadyCached(SkBitmap*, CachedFormat);
89 : // Call the underlying generator directly
90 : bool directGeneratePixels(const SkImageInfo& dstInfo, void* dstPixels, size_t dstRB,
91 : int srcX, int srcY, SkTransferFunctionBehavior behavior);
92 :
93 : private:
94 : // Ref-counted tuple(SkImageGenerator, SkMutex) which allows sharing of one generator
95 : // among several cacherators.
96 0 : class SharedGenerator final : public SkNVRefCnt<SharedGenerator> {
97 : public:
98 0 : static sk_sp<SharedGenerator> Make(std::unique_ptr<SkImageGenerator> gen) {
99 0 : return gen ? sk_sp<SharedGenerator>(new SharedGenerator(std::move(gen))) : nullptr;
100 : }
101 :
102 : private:
103 0 : explicit SharedGenerator(std::unique_ptr<SkImageGenerator> gen)
104 0 : : fGenerator(std::move(gen))
105 : {
106 0 : SkASSERT(fGenerator);
107 0 : }
108 :
109 : friend class ScopedGenerator;
110 : friend class SkImageCacherator;
111 :
112 : std::unique_ptr<SkImageGenerator> fGenerator;
113 : SkMutex fMutex;
114 : };
115 : class ScopedGenerator;
116 :
117 0 : struct Validator {
118 : Validator(sk_sp<SharedGenerator>, const SkIRect* subset);
119 :
120 0 : MOZ_IMPLICIT operator bool() const { return fSharedGenerator.get(); }
121 :
122 : sk_sp<SharedGenerator> fSharedGenerator;
123 : SkImageInfo fInfo;
124 : SkIPoint fOrigin;
125 : uint32_t fUniqueID;
126 : };
127 :
128 : SkImageCacherator(Validator*);
129 :
130 : CachedFormat chooseCacheFormat(SkColorSpace* dstColorSpace, const GrCaps* = nullptr);
131 : SkImageInfo buildCacheInfo(CachedFormat);
132 :
133 : bool tryLockAsBitmap(SkBitmap*, const SkImage*, SkImage::CachingHint, CachedFormat,
134 : const SkImageInfo&);
135 : #if SK_SUPPORT_GPU
136 : // Returns the texture proxy. If the cacherator is generating the texture and wants to cache it,
137 : // it should use the passed in key (if the key is valid).
138 : sk_sp<GrTextureProxy> lockTextureProxy(GrContext*,
139 : const GrUniqueKey& key,
140 : const SkImage* client,
141 : SkImage::CachingHint,
142 : bool willBeMipped,
143 : SkColorSpace* dstColorSpace);
144 : // Returns the color space of the texture that would be returned if you called lockTexture.
145 : // Separate code path to allow querying of the color space for textures that cached (even
146 : // externally).
147 : sk_sp<SkColorSpace> getColorSpace(GrContext*, SkColorSpace* dstColorSpace);
148 : void makeCacheKeyFromOrigKey(const GrUniqueKey& origKey, CachedFormat, GrUniqueKey* cacheKey);
149 : #endif
150 :
151 : sk_sp<SharedGenerator> fSharedGenerator;
152 : const SkImageInfo fInfo;
153 : const SkIPoint fOrigin;
154 :
155 0 : struct IDRec {
156 : SkOnce fOnce;
157 : uint32_t fUniqueID;
158 : };
159 : mutable IDRec fIDRecs[kNumCachedFormats];
160 :
161 : uint32_t getUniqueID(CachedFormat) const;
162 :
163 : friend class GrImageTextureMaker;
164 : friend class SkImage;
165 : friend class SkImage_Generator;
166 : };
167 :
168 : #endif
|