• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "SkBitmap.h"
12 #include "SkColor.h"
13 #include "SkImage.h"
14 #include "SkImageInfo.h"
15 #include "SkYUVSizeInfo.h"
16 
17 class GrContext;
18 class GrContextThreadSafeProxy;
19 class GrTextureProxy;
20 class GrSamplerParams;
21 class SkBitmap;
22 class SkData;
23 class SkMatrix;
24 class SkPaint;
25 class SkPicture;
26 
27 class SK_API SkImageGenerator : public SkNoncopyable {
28 public:
29     /**
30      *  The PixelRef which takes ownership of this SkImageGenerator
31      *  will call the image generator's destructor.
32      */
~SkImageGenerator()33     virtual ~SkImageGenerator() { }
34 
uniqueID()35     uint32_t uniqueID() const { return fUniqueID; }
36 
37     /**
38      *  Return a ref to the encoded (i.e. compressed) representation,
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.
42      *
43      *  If non-NULL is returned, the caller is responsible for calling
44      *  unref() on the data when it is finished.
45      */
46     SkData* refEncodedData(GrContext* ctx = nullptr) {
47         return this->onRefEncodedData(ctx);
48     }
49 
50     /**
51      *  Return the ImageInfo associated with this generator.
52      */
getInfo()53     const SkImageInfo& getInfo() const { return fInfo; }
54 
55     /**
56      *  Decode into the given pixels, a block of memory of size at
57      *  least (info.fHeight - 1) * rowBytes + (info.fWidth *
58      *  bytesPerPixel)
59      *
60      *  Repeated calls to this function should give the same results,
61      *  allowing the PixelRef to be immutable.
62      *
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      *
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      *
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      *
82      *  @return true on success.
83      */
84     bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
85                    SkPMColor ctable[], int* ctableCount);
86 
87     /**
88      *  Simplified version of getPixels() that asserts that info is NOT kIndex8_SkColorType and
89      *  uses the default Options.
90      */
91     bool getPixels(const SkImageInfo& info, void* pixels, size_t rowBytes);
92 
93     /**
94      *  If decoding to YUV is supported, this returns true.  Otherwise, this
95      *  returns false and does not modify any of the parameters.
96      *
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.
100      */
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]);
114 
115 #if SK_SUPPORT_GPU
116     /**
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      *
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      *
132      *  Regarding the GrContext parameter:
133      *
134      *  It must be non-NULL. The generator should only succeed if:
135      *  - its internal context is the same
136      *  - it can somehow convert its texture into one that is valid for the provided context.
137      */
138     sk_sp<GrTextureProxy> generateTexture(GrContext*, const SkImageInfo& info,
139                                           const SkIPoint& origin);
140 #endif
141 
142     /**
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      */
147     static std::unique_ptr<SkImageGenerator> MakeFromEncoded(sk_sp<SkData>);
148 
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      */
154     static std::unique_ptr<SkImageGenerator> MakeFromPicture(const SkISize&, sk_sp<SkPicture>,
155                                                              const SkMatrix*, const SkPaint*,
156                                                              SkImage::BitDepth,
157                                                              sk_sp<SkColorSpace>);
158 
159     bool tryGenerateBitmap(SkBitmap* bm, const SkImageInfo& info, SkBitmap::Allocator* allocator);
160 
161 protected:
162     enum {
163         kNeedNewImageUniqueID = 0
164     };
165 
166     SkImageGenerator(const SkImageInfo& info, uint32_t uniqueId = kNeedNewImageUniqueID);
167 
168     virtual SkData* onRefEncodedData(GrContext* ctx);
169 
170     virtual bool onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
171                              SkPMColor ctable[], int* ctableCount);
172 
onQueryYUV8(SkYUVSizeInfo *,SkYUVColorSpace *)173     virtual bool onQueryYUV8(SkYUVSizeInfo*, SkYUVColorSpace*) const {
174         return false;
175     }
onGetYUV8Planes(const SkYUVSizeInfo &,void * [3])176     virtual bool onGetYUV8Planes(const SkYUVSizeInfo&, void*[3] /*planes*/) {
177         return false;
178     }
179 
180 #if SK_SUPPORT_GPU
181     virtual sk_sp<GrTextureProxy> onGenerateTexture(GrContext*, const SkImageInfo&,
182                                                     const SkIPoint&);
183 #endif
184 
185 private:
186     const SkImageInfo fInfo;
187     const uint32_t fUniqueID;
188 
189     // This is our default impl, which may be different on different platforms.
190     // It is called from NewFromEncoded() after it has checked for any runtime factory.
191     // The SkData will never be NULL, as that will have been checked by NewFromEncoded.
192     static std::unique_ptr<SkImageGenerator> MakeFromEncodedImpl(sk_sp<SkData>);
193 };
194 
195 #endif  // SkImageGenerator_DEFINED
196