| 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 |  | 
|---|
| 18 | class GrRecordingContext; | 
|---|
| 19 | class GrSurfaceProxyView; | 
|---|
| 20 | class GrSamplerState; | 
|---|
| 21 | class SkBitmap; | 
|---|
| 22 | class SkData; | 
|---|
| 23 | class SkMatrix; | 
|---|
| 24 | class SkPaint; | 
|---|
| 25 | class SkPicture; | 
|---|
| 26 |  | 
|---|
| 27 | enum class GrImageTexGenPolicy : int; | 
|---|
| 28 |  | 
|---|
| 29 | class SK_API SkImageGenerator { | 
|---|
| 30 | public: | 
|---|
| 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 |  | 
|---|
| 170 | protected: | 
|---|
| 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 |  | 
|---|
| 189 | private: | 
|---|
| 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 |  | 
|---|