halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 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 | |
reed | 4b3d3be | 2015-09-17 13:35:19 -0700 | [diff] [blame] | 11 | #include "SkBitmap.h" |
commit-bot@chromium.org | 00f8d6c | 2014-05-29 15:57:20 +0000 | [diff] [blame] | 12 | #include "SkColor.h" |
Matt Sarett | e94255d | 2017-01-09 12:38:59 -0500 | [diff] [blame] | 13 | #include "SkImage.h" |
rileya | abaef86 | 2014-09-12 17:45:58 -0700 | [diff] [blame] | 14 | #include "SkImageInfo.h" |
msarett | 4984c3c | 2016-03-10 05:44:43 -0800 | [diff] [blame] | 15 | #include "SkYUVSizeInfo.h" |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 16 | |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 17 | class GrContext; |
Mike Reed | 34a2ca1 | 2016-10-20 15:37:41 -0400 | [diff] [blame] | 18 | class GrContextThreadSafeProxy; |
Robert Phillips | 4447b64 | 2017-03-03 11:10:18 -0500 | [diff] [blame] | 19 | class GrTextureProxy; |
Brian Salomon | 2bbdcc4 | 2017-09-07 12:36:34 -0400 | [diff] [blame] | 20 | class GrSamplerState; |
halcanary@google.com | edd370f | 2013-12-10 21:11:12 +0000 | [diff] [blame] | 21 | class SkBitmap; |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 22 | class SkData; |
fmalita | 1dedc3d | 2015-08-04 13:53:14 -0700 | [diff] [blame] | 23 | class SkMatrix; |
| 24 | class SkPaint; |
| 25 | class SkPicture; |
halcanary@google.com | edd370f | 2013-12-10 21:11:12 +0000 | [diff] [blame] | 26 | |
Hal Canary | 14f7390 | 2018-06-14 14:57:12 -0400 | [diff] [blame] | 27 | class SK_API SkImageGenerator { |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 28 | public: |
| 29 | /** |
| 30 | * The PixelRef which takes ownership of this SkImageGenerator |
| 31 | * will call the image generator's destructor. |
| 32 | */ |
| 33 | virtual ~SkImageGenerator() { } |
| 34 | |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 35 | uint32_t uniqueID() const { return fUniqueID; } |
| 36 | |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 37 | /** |
Brian Osman | 4785897 | 2017-04-25 10:02:12 -0400 | [diff] [blame] | 38 | * Return a ref to the encoded (i.e. compressed) representation |
| 39 | * of this data. |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 40 | * |
| 41 | * If non-NULL is returned, the caller is responsible for calling |
| 42 | * unref() on the data when it is finished. |
| 43 | */ |
Ben Wagner | bdf5433 | 2018-05-15 14:12:14 -0400 | [diff] [blame] | 44 | sk_sp<SkData> refEncodedData() { |
| 45 | return this->onRefEncodedData(); |
| 46 | } |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 47 | |
| 48 | /** |
reed | 3ef71e3 | 2015-03-19 08:31:14 -0700 | [diff] [blame] | 49 | * Return the ImageInfo associated with this generator. |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 50 | */ |
reed | 3ef71e3 | 2015-03-19 08:31:14 -0700 | [diff] [blame] | 51 | const SkImageInfo& getInfo() const { return fInfo; } |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 52 | |
scroggo | 9552662 | 2015-03-17 05:02:17 -0700 | [diff] [blame] | 53 | /** |
Brian Osman | 5bbd076 | 2017-05-08 11:07:42 -0400 | [diff] [blame] | 54 | * 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.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 62 | * 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.org | dd59799 | 2013-12-02 22:32:54 +0000 | [diff] [blame] | 66 | * Repeated calls to this function should give the same results, |
| 67 | * allowing the PixelRef to be immutable. |
| 68 | * |
Matt Sarett | ebb1b5c | 2017-05-12 11:41:27 -0400 | [diff] [blame] | 69 | * @param info A description of the format |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 70 | * 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 | * |
scroggo | 0864908 | 2015-02-13 11:13:34 -0800 | [diff] [blame] | 77 | * A size that does not match getInfo() implies a request |
| 78 | * to scale. If the generator cannot perform this scale, |
Matt Sarett | ebb1b5c | 2017-05-12 11:41:27 -0400 | [diff] [blame] | 79 | * it will return false. |
scroggo | 0864908 | 2015-02-13 11:13:34 -0800 | [diff] [blame] | 80 | * |
Matt Sarett | ebb1b5c | 2017-05-12 11:41:27 -0400 | [diff] [blame] | 81 | * kIndex_8_SkColorType is not supported. |
commit-bot@chromium.org | 00f8d6c | 2014-05-29 15:57:20 +0000 | [diff] [blame] | 82 | * |
scroggo | 5315fd4 | 2015-07-09 09:08:00 -0700 | [diff] [blame] | 83 | * @return true on success. |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 84 | */ |
Matt Sarett | ebb1b5c | 2017-05-12 11:41:27 -0400 | [diff] [blame] | 85 | 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.org | 00f8d6c | 2014-05-29 15:57:20 +0000 | [diff] [blame] | 93 | |
| 94 | /** |
Matt Sarett | ebb1b5c | 2017-05-12 11:41:27 -0400 | [diff] [blame] | 95 | * Simplified version of getPixels() that uses the default Options. |
commit-bot@chromium.org | 00f8d6c | 2014-05-29 15:57:20 +0000 | [diff] [blame] | 96 | */ |
scroggo | 5315fd4 | 2015-07-09 09:08:00 -0700 | [diff] [blame] | 97 | bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); |
commit-bot@chromium.org | 00f8d6c | 2014-05-29 15:57:20 +0000 | [diff] [blame] | 98 | |
sugoi | 518d83d | 2014-07-21 11:37:39 -0700 | [diff] [blame] | 99 | /** |
msarett | 4984c3c | 2016-03-10 05:44:43 -0800 | [diff] [blame] | 100 | * If decoding to YUV is supported, this returns true. Otherwise, this |
| 101 | * returns false and does not modify any of the parameters. |
sugoi | 518d83d | 2014-07-21 11:37:39 -0700 | [diff] [blame] | 102 | * |
msarett | 4984c3c | 2016-03-10 05:44:43 -0800 | [diff] [blame] | 103 | * @param sizeInfo Output parameter indicating the sizes and required |
| 104 | * allocation widths of the Y, U, and V planes. |
| 105 | * @param colorSpace Output parameter. |
sugoi | 518d83d | 2014-07-21 11:37:39 -0700 | [diff] [blame] | 106 | */ |
msarett | 4984c3c | 2016-03-10 05:44:43 -0800 | [diff] [blame] | 107 | 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]); |
sugoi | 518d83d | 2014-07-21 11:37:39 -0700 | [diff] [blame] | 120 | |
Robert Phillips | 4447b64 | 2017-03-03 11:10:18 -0500 | [diff] [blame] | 121 | #if SK_SUPPORT_GPU |
reed | b5d818a | 2015-01-06 11:30:45 -0800 | [diff] [blame] | 122 | /** |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 123 | * 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 Osman | 222e9ad | 2016-12-14 15:42:36 -0500 | [diff] [blame] | 126 | * 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 | * |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 138 | * Regarding the GrContext parameter: |
| 139 | * |
Robert Phillips | 4447b64 | 2017-03-03 11:10:18 -0500 | [diff] [blame] | 140 | * It must be non-NULL. The generator should only succeed if: |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 141 | * - its internal context is the same |
| 142 | * - it can somehow convert its texture into one that is valid for the provided context. |
Greg Daniel | f88c12e | 2017-10-09 09:57:35 -0400 | [diff] [blame] | 143 | * |
| 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. |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 148 | */ |
Robert Phillips | 4447b64 | 2017-03-03 11:10:18 -0500 | [diff] [blame] | 149 | sk_sp<GrTextureProxy> generateTexture(GrContext*, const SkImageInfo& info, |
Christopher Cameron | 77e9666 | 2017-07-08 01:47:47 -0700 | [diff] [blame] | 150 | const SkIPoint& origin, |
Greg Daniel | f88c12e | 2017-10-09 09:57:35 -0400 | [diff] [blame] | 151 | SkTransferFunctionBehavior behavior, |
| 152 | bool willNeedMipMaps); |
Robert Phillips | 4447b64 | 2017-03-03 11:10:18 -0500 | [diff] [blame] | 153 | #endif |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 154 | |
Florin Malita | ca79535 | 2016-11-16 14:45:34 -0500 | [diff] [blame] | 155 | /** |
reed | b5d818a | 2015-01-06 11:30:45 -0800 | [diff] [blame] | 156 | * 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 Reed | 185130c | 2017-02-15 15:14:16 -0500 | [diff] [blame] | 160 | static std::unique_ptr<SkImageGenerator> MakeFromEncoded(sk_sp<SkData>); |
reed | b5d818a | 2015-01-06 11:30:45 -0800 | [diff] [blame] | 161 | |
fmalita | 1dedc3d | 2015-08-04 13:53:14 -0700 | [diff] [blame] | 162 | /** 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 Reed | 185130c | 2017-02-15 15:14:16 -0500 | [diff] [blame] | 167 | static std::unique_ptr<SkImageGenerator> MakeFromPicture(const SkISize&, sk_sp<SkPicture>, |
| 168 | const SkMatrix*, const SkPaint*, |
| 169 | SkImage::BitDepth, |
| 170 | sk_sp<SkColorSpace>); |
fmalita | 1dedc3d | 2015-08-04 13:53:14 -0700 | [diff] [blame] | 171 | |
commit-bot@chromium.org | 00f8d6c | 2014-05-29 15:57:20 +0000 | [diff] [blame] | 172 | protected: |
Cary Clark | d98f78c | 2018-04-26 08:32:37 -0400 | [diff] [blame] | 173 | static constexpr int kNeedNewImageUniqueID = 0; |
aleksandar.stojiljkovic | 9516775 | 2016-05-02 01:43:38 -0700 | [diff] [blame] | 174 | |
| 175 | SkImageGenerator(const SkImageInfo& info, uint32_t uniqueId = kNeedNewImageUniqueID); |
reed | 3ef71e3 | 2015-03-19 08:31:14 -0700 | [diff] [blame] | 176 | |
Ben Wagner | bdf5433 | 2018-05-15 14:12:14 -0400 | [diff] [blame] | 177 | virtual sk_sp<SkData> onRefEncodedData() { return nullptr; } |
Matt Sarett | 861a90f | 2017-05-17 10:23:30 -0400 | [diff] [blame] | 178 | virtual bool onGetPixels(const SkImageInfo&, void*, size_t, const Options&) { return false; } |
Brian Osman | 0745422 | 2017-05-12 09:46:56 -0400 | [diff] [blame] | 179 | virtual bool onIsValid(GrContext*) const { return true; } |
Brian Osman | 0745422 | 2017-05-12 09:46:56 -0400 | [diff] [blame] | 180 | virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const { return false; } |
| 181 | virtual bool onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) { return false; } |
reed | 3ef71e3 | 2015-03-19 08:31:14 -0700 | [diff] [blame] | 182 | |
Robert Phillips | 4447b64 | 2017-03-03 11:10:18 -0500 | [diff] [blame] | 183 | #if SK_SUPPORT_GPU |
Stan Iliev | ba81af2 | 2017-06-08 15:16:53 -0400 | [diff] [blame] | 184 | 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 Cameron | 77e9666 | 2017-07-08 01:47:47 -0700 | [diff] [blame] | 191 | virtual sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&, const SkIPoint&, |
Greg Daniel | f88c12e | 2017-10-09 09:57:35 -0400 | [diff] [blame] | 192 | SkTransferFunctionBehavior, |
| 193 | bool willNeedMipMaps); // returns nullptr |
Robert Phillips | 4447b64 | 2017-03-03 11:10:18 -0500 | [diff] [blame] | 194 | #endif |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 195 | |
reed | 3ef71e3 | 2015-03-19 08:31:14 -0700 | [diff] [blame] | 196 | private: |
| 197 | const SkImageInfo fInfo; |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 198 | const uint32_t fUniqueID; |
reed | 1c84634 | 2015-07-09 11:47:36 -0700 | [diff] [blame] | 199 | |
Brian Osman | df7e075 | 2017-04-26 16:20:28 -0400 | [diff] [blame] | 200 | friend class SkImage_Lazy; |
Matt Sarett | d531ca0 | 2017-03-24 16:31:19 -0400 | [diff] [blame] | 201 | |
reed | d7c05bf | 2015-07-09 14:08:49 -0700 | [diff] [blame] | 202 | // 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 Reed | 185130c | 2017-02-15 15:14:16 -0500 | [diff] [blame] | 205 | static std::unique_ptr<SkImageGenerator> MakeFromEncodedImpl(sk_sp<SkData>); |
Hal Canary | 5138299 | 2018-06-15 20:27:52 -0400 | [diff] [blame^] | 206 | |
| 207 | SkImageGenerator(SkImageGenerator&&) = delete; |
| 208 | SkImageGenerator(const SkImageGenerator&) = delete; |
| 209 | SkImageGenerator& operator=(SkImageGenerator&&) = delete; |
| 210 | SkImageGenerator& operator=(const SkImageGenerator&) = delete; |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 211 | }; |
| 212 | |
| 213 | #endif // SkImageGenerator_DEFINED |