1/*
2 * Copyright 2013 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 SkImageGenerator_DEFINED
9#define SkImageGenerator_DEFINED
10
11#include "include/core/SkBitmap.h"
12#include "include/core/SkColor.h"
13#include "include/core/SkImage.h"
14#include "include/core/SkImageInfo.h"
15#include "include/core/SkYUVAIndex.h"
16#include "include/core/SkYUVASizeInfo.h"
17
18class GrRecordingContext;
19class GrSurfaceProxyView;
20class GrSamplerState;
21class SkBitmap;
22class SkData;
23class SkMatrix;
24class SkPaint;
25class SkPicture;
26
27enum class GrImageTexGenPolicy : int;
28
29class SK_API SkImageGenerator {
30public:
31 /**
32 * The PixelRef which takes ownership of this SkImageGenerator
33 * will call the image generator's destructor.
34 */
35 virtual ~SkImageGenerator() { }
36
37 uint32_t uniqueID() const { return fUniqueID; }
38
39 /**
40 * Return a ref to the encoded (i.e. compressed) representation
41 * of this data.
42 *
43 * If non-NULL is returned, the caller is responsible for calling
44 * unref() on the data when it is finished.
45 */
46 sk_sp<SkData> refEncodedData() {
47 return this->onRefEncodedData();
48 }
49
50 /**
51 * Return the ImageInfo associated with this generator.
52 */
53 const SkImageInfo& getInfo() const { return fInfo; }
54
55 /**
56 * Can this generator be used to produce images that will be drawable to the specified context
57 * (or to CPU, if context is nullptr)?
58 */
59 bool isValid(GrRecordingContext* context) const {
60 return this->onIsValid(context);
61 }
62
63 /** Deprecated.
64 */
65 bool isValid(GrContext* context) const;
66
67 /**
68 * Decode into the given pixels, a block of memory of size at
69 * least (info.fHeight - 1) * rowBytes + (info.fWidth *
70 * bytesPerPixel)
71 *
72 * Repeated calls to this function should give the same results,
73 * allowing the PixelRef to be immutable.
74 *
75 * @param info A description of the format
76 * expected by the caller. This can simply be identical
77 * to the info returned by getInfo().
78 *
79 * This contract also allows the caller to specify
80 * different output-configs, which the implementation can
81 * decide to support or not.
82 *
83 * A size that does not match getInfo() implies a request
84 * to scale. If the generator cannot perform this scale,
85 * it will return false.
86 *
87 * @return true on success.
88 */
89 bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
90
91 bool getPixels(const SkPixmap& pm) {
92 return this->getPixels(pm.info(), pm.writable_addr(), pm.rowBytes());
93 }
94
95 /**
96 * If decoding to YUV is supported, this returns true. Otherwise, this
97 * returns false and does not modify any of the parameters.
98 *
99 * @param sizeInfo Output parameter indicating the sizes and required
100 * allocation widths of the Y, U, V, and A planes.
101 * @param yuvaIndices How the YUVA planes are organized/used
102 * @param colorSpace Output parameter.
103 */
104 bool queryYUVA8(SkYUVASizeInfo* sizeInfo,
105 SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
106 SkYUVColorSpace* colorSpace) const;
107
108 /**
109 * Returns true on success and false on failure.
110 * This always attempts to perform a full decode. If the client only
111 * wants size, it should call queryYUVA8().
112 *
113 * @param sizeInfo Needs to exactly match the values returned by the
114 * query, except the WidthBytes may be larger than the
115 * recommendation (but not smaller).
116 * @param yuvaIndices Needs to exactly match the values returned by the query.
117 * @param planes Memory for the Y, U, V, and A planes. Note that, depending on the
118 * settings in yuvaIndices, anywhere from 1..4 planes could be returned.
119 */
120 bool getYUVA8Planes(const SkYUVASizeInfo& sizeInfo,
121 const SkYUVAIndex yuvaIndices[SkYUVAIndex::kIndexCount],
122 void* planes[]);
123
124#if SK_SUPPORT_GPU
125 /**
126 * If the generator can natively/efficiently return its pixels as a GPU image (backed by a
127 * texture) this will return that image. If not, this will return NULL.
128 *
129 * This routine also supports retrieving only a subset of the pixels. That subset is specified
130 * by the following rectangle:
131 *
132 * subset = SkIRect::MakeXYWH(origin.x(), origin.y(), info.width(), info.height())
133 *
134 * If subset is not contained inside the generator's bounds, this returns false.
135 *
136 * whole = SkIRect::MakeWH(getInfo().width(), getInfo().height())
137 * if (!whole.contains(subset)) {
138 * return false;
139 * }
140 *
141 * Regarding the GrContext parameter:
142 *
143 * It must be non-NULL. The generator should only succeed if:
144 * - its internal context is the same
145 * - it can somehow convert its texture into one that is valid for the provided context.
146 *
147 * If the willNeedMipMaps flag is true, the generator should try to create a TextureProxy that
148 * at least has the mip levels allocated and the base layer filled in. If this is not possible,
149 * the generator is allowed to return a non mipped proxy, but this will have some additional
150 * overhead in later allocating mips and copying of the base layer.
151 *
152 * GrImageTexGenPolicy determines whether or not a new texture must be created (and its budget
153 * status) or whether this may (but is not required to) return a pre-existing texture that is
154 * retained by the generator (kDraw).
155 */
156 GrSurfaceProxyView generateTexture(GrRecordingContext*, const SkImageInfo& info,
157 const SkIPoint& origin, GrMipmapped, GrImageTexGenPolicy);
158
159#endif
160
161 /**
162 * If the default image decoder system can interpret the specified (encoded) data, then
163 * this returns a new ImageGenerator for it. Otherwise this returns NULL. Either way
164 * the caller is still responsible for managing their ownership of the data.
165 */
166 static std::unique_ptr<SkImageGenerator> MakeFromEncoded(sk_sp<SkData>);
167
168 /** Return a new image generator backed by the specified picture. If the size is empty or
169 * the picture is NULL, this returns NULL.
170 * The optional matrix and paint arguments are passed to drawPicture() at rasterization
171 * time.
172 */
173 static std::unique_ptr<SkImageGenerator> MakeFromPicture(const SkISize&, sk_sp<SkPicture>,
174 const SkMatrix*, const SkPaint*,
175 SkImage::BitDepth,
176 sk_sp<SkColorSpace>);
177
178protected:
179 static constexpr int kNeedNewImageUniqueID = 0;
180
181 SkImageGenerator(const SkImageInfo& info, uint32_t uniqueId = kNeedNewImageUniqueID);
182
183 virtual sk_sp<SkData> onRefEncodedData() { return nullptr; }
184 struct Options {};
185 virtual bool onGetPixels(const SkImageInfo&, void*, size_t, const Options&) { return false; }
186 virtual bool onIsValid(GrRecordingContext*) const { return true; }
187 virtual bool onQueryYUVA8(SkYUVASizeInfo*, SkYUVAIndex[SkYUVAIndex::kIndexCount],
188 SkYUVColorSpace*) const { return false; }
189 virtual bool onGetYUVA8Planes(const SkYUVASizeInfo&, const SkYUVAIndex[SkYUVAIndex::kIndexCount],
190 void*[4] /*planes*/) { return false; }
191#if SK_SUPPORT_GPU
192 // returns nullptr
193 virtual GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&,
194 const SkIPoint&, GrMipmapped, GrImageTexGenPolicy);
195#endif
196
197private:
198 const SkImageInfo fInfo;
199 const uint32_t fUniqueID;
200
201 friend class SkImage_Lazy;
202
203 // This is our default impl, which may be different on different platforms.
204 // It is called from NewFromEncoded() after it has checked for any runtime factory.
205 // The SkData will never be NULL, as that will have been checked by NewFromEncoded.
206 static std::unique_ptr<SkImageGenerator> MakeFromEncodedImpl(sk_sp<SkData>);
207
208 SkImageGenerator(SkImageGenerator&&) = delete;
209 SkImageGenerator(const SkImageGenerator&) = delete;
210 SkImageGenerator& operator=(SkImageGenerator&&) = delete;
211 SkImageGenerator& operator=(const SkImageGenerator&) = delete;
212};
213
214#endif // SkImageGenerator_DEFINED
215