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