blob: d4a79a2e235f059998e8c978b35632e009b08ae7 [file] [log] [blame]
halcanary@google.comad04eb42013-11-21 15:32:08 +00001/*
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
reed4b3d3be2015-09-17 13:35:19 -070011#include "SkBitmap.h"
commit-bot@chromium.org00f8d6c2014-05-29 15:57:20 +000012#include "SkColor.h"
Matt Sarette94255d2017-01-09 12:38:59 -050013#include "SkImage.h"
rileyaabaef862014-09-12 17:45:58 -070014#include "SkImageInfo.h"
msarett4984c3c2016-03-10 05:44:43 -080015#include "SkYUVSizeInfo.h"
halcanary@google.comad04eb42013-11-21 15:32:08 +000016
reed8f343722015-08-13 13:32:39 -070017class GrContext;
Mike Reed34a2ca12016-10-20 15:37:41 -040018class GrContextThreadSafeProxy;
Robert Phillips4447b642017-03-03 11:10:18 -050019class GrTextureProxy;
Brian Salomon2bbdcc42017-09-07 12:36:34 -040020class GrSamplerState;
halcanary@google.comedd370f2013-12-10 21:11:12 +000021class SkBitmap;
halcanary@google.comad04eb42013-11-21 15:32:08 +000022class SkData;
fmalita1dedc3d2015-08-04 13:53:14 -070023class SkMatrix;
24class SkPaint;
25class SkPicture;
halcanary@google.comedd370f2013-12-10 21:11:12 +000026
Hal Canary14f73902018-06-14 14:57:12 -040027class SK_API SkImageGenerator {
halcanary@google.comad04eb42013-11-21 15:32:08 +000028public:
29 /**
30 * The PixelRef which takes ownership of this SkImageGenerator
31 * will call the image generator's destructor.
32 */
33 virtual ~SkImageGenerator() { }
34
reed8f343722015-08-13 13:32:39 -070035 uint32_t uniqueID() const { return fUniqueID; }
36
halcanary@google.comad04eb42013-11-21 15:32:08 +000037 /**
Brian Osman47858972017-04-25 10:02:12 -040038 * Return a ref to the encoded (i.e. compressed) representation
39 * of this data.
halcanary@google.comad04eb42013-11-21 15:32:08 +000040 *
41 * If non-NULL is returned, the caller is responsible for calling
42 * unref() on the data when it is finished.
43 */
Ben Wagnerbdf54332018-05-15 14:12:14 -040044 sk_sp<SkData> refEncodedData() {
45 return this->onRefEncodedData();
46 }
halcanary@google.comad04eb42013-11-21 15:32:08 +000047
48 /**
reed3ef71e32015-03-19 08:31:14 -070049 * Return the ImageInfo associated with this generator.
halcanary@google.comad04eb42013-11-21 15:32:08 +000050 */
reed3ef71e32015-03-19 08:31:14 -070051 const SkImageInfo& getInfo() const { return fInfo; }
halcanary@google.comad04eb42013-11-21 15:32:08 +000052
scroggo95526622015-03-17 05:02:17 -070053 /**
Brian Osman5bbd0762017-05-08 11:07:42 -040054 * Can this generator be used to produce images that will be drawable to the specified context
55 * (or to CPU, if context is nullptr)?
56 */
57 bool isValid(GrContext* context) const {
58 return this->onIsValid(context);
59 }
60
61 /**
halcanary@google.comad04eb42013-11-21 15:32:08 +000062 * Decode into the given pixels, a block of memory of size at
63 * least (info.fHeight - 1) * rowBytes + (info.fWidth *
64 * bytesPerPixel)
65 *
commit-bot@chromium.orgdd597992013-12-02 22:32:54 +000066 * Repeated calls to this function should give the same results,
67 * allowing the PixelRef to be immutable.
68 *
Matt Sarettebb1b5c2017-05-12 11:41:27 -040069 * @param info A description of the format
halcanary@google.comad04eb42013-11-21 15:32:08 +000070 * expected by the caller. This can simply be identical
71 * to the info returned by getInfo().
72 *
73 * This contract also allows the caller to specify
74 * different output-configs, which the implementation can
75 * decide to support or not.
76 *
scroggo08649082015-02-13 11:13:34 -080077 * A size that does not match getInfo() implies a request
78 * to scale. If the generator cannot perform this scale,
Matt Sarettebb1b5c2017-05-12 11:41:27 -040079 * it will return false.
scroggo08649082015-02-13 11:13:34 -080080 *
Matt Sarettebb1b5c2017-05-12 11:41:27 -040081 * kIndex_8_SkColorType is not supported.
commit-bot@chromium.org00f8d6c2014-05-29 15:57:20 +000082 *
scroggo5315fd42015-07-09 09:08:00 -070083 * @return true on success.
halcanary@google.comad04eb42013-11-21 15:32:08 +000084 */
Matt Sarettebb1b5c2017-05-12 11:41:27 -040085 struct Options {
86 Options()
87 : fBehavior(SkTransferFunctionBehavior::kIgnore)
88 {}
89
90 SkTransferFunctionBehavior fBehavior;
91 };
92 bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options* options);
commit-bot@chromium.org00f8d6c2014-05-29 15:57:20 +000093
94 /**
Matt Sarettebb1b5c2017-05-12 11:41:27 -040095 * Simplified version of getPixels() that uses the default Options.
commit-bot@chromium.org00f8d6c2014-05-29 15:57:20 +000096 */
scroggo5315fd42015-07-09 09:08:00 -070097 bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
commit-bot@chromium.org00f8d6c2014-05-29 15:57:20 +000098
sugoi518d83d2014-07-21 11:37:39 -070099 /**
msarett4984c3c2016-03-10 05:44:43 -0800100 * If decoding to YUV is supported, this returns true. Otherwise, this
101 * returns false and does not modify any of the parameters.
sugoi518d83d2014-07-21 11:37:39 -0700102 *
msarett4984c3c2016-03-10 05:44:43 -0800103 * @param sizeInfo Output parameter indicating the sizes and required
104 * allocation widths of the Y, U, and V planes.
105 * @param colorSpace Output parameter.
sugoi518d83d2014-07-21 11:37:39 -0700106 */
msarett4984c3c2016-03-10 05:44:43 -0800107 bool queryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const;
108
109 /**
110 * Returns true on success and false on failure.
111 * This always attempts to perform a full decode. If the client only
112 * wants size, it should call queryYUV8().
113 *
114 * @param sizeInfo Needs to exactly match the values returned by the
115 * query, except the WidthBytes may be larger than the
116 * recommendation (but not smaller).
117 * @param planes Memory for each of the Y, U, and V planes.
118 */
119 bool getYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]);
sugoi518d83d2014-07-21 11:37:39 -0700120
Robert Phillips4447b642017-03-03 11:10:18 -0500121#if SK_SUPPORT_GPU
reedb5d818a2015-01-06 11:30:45 -0800122 /**
reed8f343722015-08-13 13:32:39 -0700123 * If the generator can natively/efficiently return its pixels as a GPU image (backed by a
124 * texture) this will return that image. If not, this will return NULL.
125 *
Brian Osman222e9ad2016-12-14 15:42:36 -0500126 * This routine also supports retrieving only a subset of the pixels. That subset is specified
127 * by the following rectangle:
128 *
129 * subset = SkIRect::MakeXYWH(origin.x(), origin.y(), info.width(), info.height())
130 *
131 * If subset is not contained inside the generator's bounds, this returns false.
132 *
133 * whole = SkIRect::MakeWH(getInfo().width(), getInfo().height())
134 * if (!whole.contains(subset)) {
135 * return false;
136 * }
137 *
reed8f343722015-08-13 13:32:39 -0700138 * Regarding the GrContext parameter:
139 *
Robert Phillips4447b642017-03-03 11:10:18 -0500140 * It must be non-NULL. The generator should only succeed if:
reed8f343722015-08-13 13:32:39 -0700141 * - its internal context is the same
142 * - it can somehow convert its texture into one that is valid for the provided context.
Greg Danielf88c12e2017-10-09 09:57:35 -0400143 *
144 * If the willNeedMipMaps flag is true, the generator should try to create a TextureProxy that
145 * at least has the mip levels allocated and the base layer filled in. If this is not possible,
146 * the generator is allowed to return a non mipped proxy, but this will have some additional
147 * overhead in later allocating mips and copying of the base layer.
reed8f343722015-08-13 13:32:39 -0700148 */
Robert Phillips4447b642017-03-03 11:10:18 -0500149 sk_sp<GrTextureProxy> generateTexture(GrContext*, const SkImageInfo& info,
Christopher Cameron77e96662017-07-08 01:47:47 -0700150 const SkIPoint& origin,
Greg Danielf88c12e2017-10-09 09:57:35 -0400151 SkTransferFunctionBehavior behavior,
152 bool willNeedMipMaps);
Robert Phillips4447b642017-03-03 11:10:18 -0500153#endif
reed8f343722015-08-13 13:32:39 -0700154
Florin Malitaca795352016-11-16 14:45:34 -0500155 /**
reedb5d818a2015-01-06 11:30:45 -0800156 * If the default image decoder system can interpret the specified (encoded) data, then
157 * this returns a new ImageGenerator for it. Otherwise this returns NULL. Either way
158 * the caller is still responsible for managing their ownership of the data.
159 */
Mike Reed185130c2017-02-15 15:14:16 -0500160 static std::unique_ptr<SkImageGenerator> MakeFromEncoded(sk_sp<SkData>);
reedb5d818a2015-01-06 11:30:45 -0800161
fmalita1dedc3d2015-08-04 13:53:14 -0700162 /** Return a new image generator backed by the specified picture. If the size is empty or
163 * the picture is NULL, this returns NULL.
164 * The optional matrix and paint arguments are passed to drawPicture() at rasterization
165 * time.
166 */
Mike Reed185130c2017-02-15 15:14:16 -0500167 static std::unique_ptr<SkImageGenerator> MakeFromPicture(const SkISize&, sk_sp<SkPicture>,
168 const SkMatrix*, const SkPaint*,
169 SkImage::BitDepth,
170 sk_sp<SkColorSpace>);
fmalita1dedc3d2015-08-04 13:53:14 -0700171
commit-bot@chromium.org00f8d6c2014-05-29 15:57:20 +0000172protected:
Cary Clarkd98f78c2018-04-26 08:32:37 -0400173 static constexpr int kNeedNewImageUniqueID = 0;
aleksandar.stojiljkovic95167752016-05-02 01:43:38 -0700174
175 SkImageGenerator(const SkImageInfo& info, uint32_t uniqueId = kNeedNewImageUniqueID);
reed3ef71e32015-03-19 08:31:14 -0700176
Ben Wagnerbdf54332018-05-15 14:12:14 -0400177 virtual sk_sp<SkData> onRefEncodedData() { return nullptr; }
Matt Sarett861a90f2017-05-17 10:23:30 -0400178 virtual bool onGetPixels(const SkImageInfo&, void*, size_t, const Options&) { return false; }
Brian Osman07454222017-05-12 09:46:56 -0400179 virtual bool onIsValid(GrContext*) const { return true; }
Brian Osman07454222017-05-12 09:46:56 -0400180 virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const { return false; }
181 virtual bool onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) { return false; }
reed3ef71e32015-03-19 08:31:14 -0700182
Robert Phillips4447b642017-03-03 11:10:18 -0500183#if SK_SUPPORT_GPU
Stan Ilievba81af22017-06-08 15:16:53 -0400184 enum class TexGenType {
185 kNone, //image generator does not implement onGenerateTexture
186 kCheap, //onGenerateTexture is implemented and it is fast (does not render offscreen)
187 kExpensive, //onGenerateTexture is implemented and it is relatively slow
188 };
189
190 virtual TexGenType onCanGenerateTexture() const { return TexGenType::kNone; }
Christopher Cameron77e96662017-07-08 01:47:47 -0700191 virtual sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&, const SkIPoint&,
Greg Danielf88c12e2017-10-09 09:57:35 -0400192 SkTransferFunctionBehavior,
193 bool willNeedMipMaps); // returns nullptr
Robert Phillips4447b642017-03-03 11:10:18 -0500194#endif
reed8f343722015-08-13 13:32:39 -0700195
reed3ef71e32015-03-19 08:31:14 -0700196private:
197 const SkImageInfo fInfo;
reed8f343722015-08-13 13:32:39 -0700198 const uint32_t fUniqueID;
reed1c846342015-07-09 11:47:36 -0700199
Brian Osmandf7e0752017-04-26 16:20:28 -0400200 friend class SkImage_Lazy;
Matt Sarettd531ca02017-03-24 16:31:19 -0400201
reedd7c05bf2015-07-09 14:08:49 -0700202 // This is our default impl, which may be different on different platforms.
203 // It is called from NewFromEncoded() after it has checked for any runtime factory.
204 // The SkData will never be NULL, as that will have been checked by NewFromEncoded.
Mike Reed185130c2017-02-15 15:14:16 -0500205 static std::unique_ptr<SkImageGenerator> MakeFromEncodedImpl(sk_sp<SkData>);
Hal Canary51382992018-06-15 20:27:52 -0400206
207 SkImageGenerator(SkImageGenerator&&) = delete;
208 SkImageGenerator(const SkImageGenerator&) = delete;
209 SkImageGenerator& operator=(SkImageGenerator&&) = delete;
210 SkImageGenerator& operator=(const SkImageGenerator&) = delete;
halcanary@google.comad04eb42013-11-21 15:32:08 +0000211};
212
213#endif // SkImageGenerator_DEFINED