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 | 514baff | 2016-11-17 15:17:07 -0500 | [diff] [blame] | 20 | class GrSamplerParams; |
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 | |
scroggo | 0864908 | 2015-02-13 11:13:34 -0800 | [diff] [blame] | 27 | class SK_API SkImageGenerator : public SkNoncopyable { |
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 | /** |
| 38 | * Return a ref to the encoded (i.e. compressed) representation, |
reed | 05dd251 | 2016-01-05 09:16:19 -0800 | [diff] [blame] | 39 | * of this data. If the GrContext is non-null, then the caller is only interested in |
| 40 | * gpu-specific formats, so the impl may return null even if they have encoded data, |
| 41 | * assuming they know it is not suitable for the gpu. |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 42 | * |
| 43 | * If non-NULL is returned, the caller is responsible for calling |
| 44 | * unref() on the data when it is finished. |
| 45 | */ |
reed | 05dd251 | 2016-01-05 09:16:19 -0800 | [diff] [blame] | 46 | SkData* refEncodedData(GrContext* ctx = nullptr) { |
reed | 05dd251 | 2016-01-05 09:16:19 -0800 | [diff] [blame] | 47 | return this->onRefEncodedData(ctx); |
reed | 05dd251 | 2016-01-05 09:16:19 -0800 | [diff] [blame] | 48 | } |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 49 | |
| 50 | /** |
reed | 3ef71e3 | 2015-03-19 08:31:14 -0700 | [diff] [blame] | 51 | * Return the ImageInfo associated with this generator. |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 52 | */ |
reed | 3ef71e3 | 2015-03-19 08:31:14 -0700 | [diff] [blame] | 53 | const SkImageInfo& getInfo() const { return fInfo; } |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 54 | |
scroggo | 9552662 | 2015-03-17 05:02:17 -0700 | [diff] [blame] | 55 | /** |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 56 | * Decode into the given pixels, a block of memory of size at |
| 57 | * least (info.fHeight - 1) * rowBytes + (info.fWidth * |
| 58 | * bytesPerPixel) |
| 59 | * |
commit-bot@chromium.org | dd59799 | 2013-12-02 22:32:54 +0000 | [diff] [blame] | 60 | * Repeated calls to this function should give the same results, |
| 61 | * allowing the PixelRef to be immutable. |
| 62 | * |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 63 | * @param info A description of the format (config, size) |
| 64 | * expected by the caller. This can simply be identical |
| 65 | * to the info returned by getInfo(). |
| 66 | * |
| 67 | * This contract also allows the caller to specify |
| 68 | * different output-configs, which the implementation can |
| 69 | * decide to support or not. |
| 70 | * |
scroggo | 0864908 | 2015-02-13 11:13:34 -0800 | [diff] [blame] | 71 | * A size that does not match getInfo() implies a request |
| 72 | * to scale. If the generator cannot perform this scale, |
| 73 | * it will return kInvalidScale. |
| 74 | * |
commit-bot@chromium.org | 00f8d6c | 2014-05-29 15:57:20 +0000 | [diff] [blame] | 75 | * If info is kIndex8_SkColorType, then the caller must provide storage for up to 256 |
| 76 | * SkPMColor values in ctable. On success the generator must copy N colors into that storage, |
| 77 | * (where N is the logical number of table entries) and set ctableCount to N. |
| 78 | * |
| 79 | * If info is not kIndex8_SkColorType, then the last two parameters may be NULL. If ctableCount |
| 80 | * is not null, it will be set to 0. |
| 81 | * |
scroggo | 5315fd4 | 2015-07-09 09:08:00 -0700 | [diff] [blame] | 82 | * @return true on success. |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 83 | */ |
scroggo | 5315fd4 | 2015-07-09 09:08:00 -0700 | [diff] [blame] | 84 | bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, |
| 85 | SkPMColor ctable[], int* ctableCount); |
commit-bot@chromium.org | 00f8d6c | 2014-05-29 15:57:20 +0000 | [diff] [blame] | 86 | |
| 87 | /** |
scroggo | 9552662 | 2015-03-17 05:02:17 -0700 | [diff] [blame] | 88 | * Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and |
| 89 | * uses the default Options. |
commit-bot@chromium.org | 00f8d6c | 2014-05-29 15:57:20 +0000 | [diff] [blame] | 90 | */ |
scroggo | 5315fd4 | 2015-07-09 09:08:00 -0700 | [diff] [blame] | 91 | bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes); |
commit-bot@chromium.org | 00f8d6c | 2014-05-29 15:57:20 +0000 | [diff] [blame] | 92 | |
sugoi | 518d83d | 2014-07-21 11:37:39 -0700 | [diff] [blame] | 93 | /** |
msarett | 4984c3c | 2016-03-10 05:44:43 -0800 | [diff] [blame] | 94 | * If decoding to YUV is supported, this returns true. Otherwise, this |
| 95 | * returns false and does not modify any of the parameters. |
sugoi | 518d83d | 2014-07-21 11:37:39 -0700 | [diff] [blame] | 96 | * |
msarett | 4984c3c | 2016-03-10 05:44:43 -0800 | [diff] [blame] | 97 | * @param sizeInfo Output parameter indicating the sizes and required |
| 98 | * allocation widths of the Y, U, and V planes. |
| 99 | * @param colorSpace Output parameter. |
sugoi | 518d83d | 2014-07-21 11:37:39 -0700 | [diff] [blame] | 100 | */ |
msarett | 4984c3c | 2016-03-10 05:44:43 -0800 | [diff] [blame] | 101 | bool queryYUV8(SkYUVSizeInfo* sizeInfo, SkYUVColorSpace* colorSpace) const; |
| 102 | |
| 103 | /** |
| 104 | * Returns true on success and false on failure. |
| 105 | * This always attempts to perform a full decode. If the client only |
| 106 | * wants size, it should call queryYUV8(). |
| 107 | * |
| 108 | * @param sizeInfo Needs to exactly match the values returned by the |
| 109 | * query, except the WidthBytes may be larger than the |
| 110 | * recommendation (but not smaller). |
| 111 | * @param planes Memory for each of the Y, U, and V planes. |
| 112 | */ |
| 113 | bool getYUV8Planes(const SkYUVSizeInfo& sizeInfo, void* planes[3]); |
sugoi | 518d83d | 2014-07-21 11:37:39 -0700 | [diff] [blame] | 114 | |
Robert Phillips | 4447b64 | 2017-03-03 11:10:18 -0500 | [diff] [blame] | 115 | #if SK_SUPPORT_GPU |
reed | b5d818a | 2015-01-06 11:30:45 -0800 | [diff] [blame] | 116 | /** |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 117 | * If the generator can natively/efficiently return its pixels as a GPU image (backed by a |
| 118 | * texture) this will return that image. If not, this will return NULL. |
| 119 | * |
Brian Osman | 222e9ad | 2016-12-14 15:42:36 -0500 | [diff] [blame] | 120 | * This routine also supports retrieving only a subset of the pixels. That subset is specified |
| 121 | * by the following rectangle: |
| 122 | * |
| 123 | * subset = SkIRect::MakeXYWH(origin.x(), origin.y(), info.width(), info.height()) |
| 124 | * |
| 125 | * If subset is not contained inside the generator's bounds, this returns false. |
| 126 | * |
| 127 | * whole = SkIRect::MakeWH(getInfo().width(), getInfo().height()) |
| 128 | * if (!whole.contains(subset)) { |
| 129 | * return false; |
| 130 | * } |
| 131 | * |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 132 | * Regarding the GrContext parameter: |
| 133 | * |
Robert Phillips | 4447b64 | 2017-03-03 11:10:18 -0500 | [diff] [blame] | 134 | * It must be non-NULL. The generator should only succeed if: |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 135 | * - its internal context is the same |
| 136 | * - it can somehow convert its texture into one that is valid for the provided context. |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 137 | */ |
Robert Phillips | 4447b64 | 2017-03-03 11:10:18 -0500 | [diff] [blame] | 138 | sk_sp<GrTextureProxy> generateTexture(GrContext*, const SkImageInfo& info, |
| 139 | const SkIPoint& origin); |
| 140 | #endif |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 141 | |
Florin Malita | ca79535 | 2016-11-16 14:45:34 -0500 | [diff] [blame] | 142 | /** |
reed | b5d818a | 2015-01-06 11:30:45 -0800 | [diff] [blame] | 143 | * If the default image decoder system can interpret the specified (encoded) data, then |
| 144 | * this returns a new ImageGenerator for it. Otherwise this returns NULL. Either way |
| 145 | * the caller is still responsible for managing their ownership of the data. |
| 146 | */ |
Mike Reed | 185130c | 2017-02-15 15:14:16 -0500 | [diff] [blame] | 147 | static std::unique_ptr<SkImageGenerator> MakeFromEncoded(sk_sp<SkData>); |
reed | b5d818a | 2015-01-06 11:30:45 -0800 | [diff] [blame] | 148 | |
fmalita | 1dedc3d | 2015-08-04 13:53:14 -0700 | [diff] [blame] | 149 | /** Return a new image generator backed by the specified picture. If the size is empty or |
| 150 | * the picture is NULL, this returns NULL. |
| 151 | * The optional matrix and paint arguments are passed to drawPicture() at rasterization |
| 152 | * time. |
| 153 | */ |
Mike Reed | 185130c | 2017-02-15 15:14:16 -0500 | [diff] [blame] | 154 | static std::unique_ptr<SkImageGenerator> MakeFromPicture(const SkISize&, sk_sp<SkPicture>, |
| 155 | const SkMatrix*, const SkPaint*, |
| 156 | SkImage::BitDepth, |
| 157 | sk_sp<SkColorSpace>); |
fmalita | 1dedc3d | 2015-08-04 13:53:14 -0700 | [diff] [blame] | 158 | |
commit-bot@chromium.org | 00f8d6c | 2014-05-29 15:57:20 +0000 | [diff] [blame] | 159 | protected: |
aleksandar.stojiljkovic | 9516775 | 2016-05-02 01:43:38 -0700 | [diff] [blame] | 160 | enum { |
| 161 | kNeedNewImageUniqueID = 0 |
| 162 | }; |
| 163 | |
| 164 | SkImageGenerator(const SkImageInfo& info, uint32_t uniqueId = kNeedNewImageUniqueID); |
reed | 3ef71e3 | 2015-03-19 08:31:14 -0700 | [diff] [blame] | 165 | |
Mike Reed | df8599a | 2016-12-08 13:41:10 -0500 | [diff] [blame] | 166 | virtual SkData* onRefEncodedData(GrContext* ctx); |
reed | 3ef71e3 | 2015-03-19 08:31:14 -0700 | [diff] [blame] | 167 | |
scroggo | 5315fd4 | 2015-07-09 09:08:00 -0700 | [diff] [blame] | 168 | virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, |
| 169 | SkPMColor ctable[], int* ctableCount); |
msarett | 4984c3c | 2016-03-10 05:44:43 -0800 | [diff] [blame] | 170 | |
| 171 | virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const { |
| 172 | return false; |
| 173 | } |
| 174 | virtual bool onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) { |
| 175 | return false; |
| 176 | } |
reed | 3ef71e3 | 2015-03-19 08:31:14 -0700 | [diff] [blame] | 177 | |
Matt Sarett | d531ca0 | 2017-03-24 16:31:19 -0400 | [diff] [blame] | 178 | struct Options { |
| 179 | Options() |
| 180 | : fColorTable(nullptr) |
| 181 | , fColorTableCount(nullptr) |
| 182 | , fBehavior(SkTransferFunctionBehavior::kRespect) |
| 183 | {} |
| 184 | |
| 185 | SkPMColor* fColorTable; |
| 186 | int* fColorTableCount; |
| 187 | SkTransferFunctionBehavior fBehavior; |
| 188 | }; |
| 189 | bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, const Options* opts); |
| 190 | virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes, |
| 191 | const Options& opts) { |
| 192 | return this->onGetPixels(info, pixels, rowBytes, opts.fColorTable, opts.fColorTableCount); |
| 193 | } |
| 194 | |
Robert Phillips | 4447b64 | 2017-03-03 11:10:18 -0500 | [diff] [blame] | 195 | #if SK_SUPPORT_GPU |
| 196 | virtual sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&, |
| 197 | const SkIPoint&); |
| 198 | #endif |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 199 | |
reed | 3ef71e3 | 2015-03-19 08:31:14 -0700 | [diff] [blame] | 200 | private: |
| 201 | const SkImageInfo fInfo; |
reed | 8f34372 | 2015-08-13 13:32:39 -0700 | [diff] [blame] | 202 | const uint32_t fUniqueID; |
reed | 1c84634 | 2015-07-09 11:47:36 -0700 | [diff] [blame] | 203 | |
Matt Sarett | d531ca0 | 2017-03-24 16:31:19 -0400 | [diff] [blame] | 204 | friend class SkImageCacherator; |
| 205 | |
reed | d7c05bf | 2015-07-09 14:08:49 -0700 | [diff] [blame] | 206 | // This is our default impl, which may be different on different platforms. |
| 207 | // It is called from NewFromEncoded() after it has checked for any runtime factory. |
| 208 | // 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] | 209 | static std::unique_ptr<SkImageGenerator> MakeFromEncodedImpl(sk_sp<SkData>); |
halcanary@google.com | ad04eb4 | 2013-11-21 15:32:08 +0000 | [diff] [blame] | 210 | }; |
| 211 | |
| 212 | #endif // SkImageGenerator_DEFINED |