Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkYUVAPixmaps.h
Go to the documentation of this file.
1/*
2 * Copyright 2020 Google LLC
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 SkYUVAPixmaps_DEFINED
9#define SkYUVAPixmaps_DEFINED
10
12#include "include/core/SkData.h"
16#include "include/core/SkSize.h"
20
21#include <array>
22#include <bitset>
23#include <cstddef>
24#include <tuple>
25
26/**
27 * SkYUVAInfo combined with per-plane SkColorTypes and row bytes. Fully specifies the SkPixmaps
28 * for a YUVA image without the actual pixel memory and data.
29 */
31public:
32 static constexpr auto kMaxPlanes = SkYUVAInfo::kMaxPlanes;
33
36
37 /**
38 * Data type for Y, U, V, and possibly A channels independent of how values are packed into
39 * planes.
40 **/
41 enum class DataType {
42 kUnorm8, ///< 8 bit unsigned normalized
43 kUnorm16, ///< 16 bit unsigned normalized
44 kFloat16, ///< 16 bit (half) floating point
45 kUnorm10_Unorm2, ///< 10 bit unorm for Y, U, and V. 2 bit unorm for alpha (if present).
46
47 kLast = kUnorm10_Unorm2
48 };
49 static constexpr int kDataTypeCnt = static_cast<int>(DataType::kLast) + 1;
50
52 public:
53 /** Defaults to nothing supported. */
54 constexpr SupportedDataTypes() = default;
55
56 /** All legal combinations of PlaneConfig and DataType are supported. */
57 static constexpr SupportedDataTypes All();
58
59 /**
60 * Checks whether there is a supported combination of color types for planes structured
61 * as indicated by PlaneConfig with channel data types as indicated by DataType.
62 */
63 constexpr bool supported(PlaneConfig, DataType) const;
64
65 /**
66 * Update to add support for pixmaps with numChannel channels where each channel is
67 * represented as DataType.
68 */
69 void enableDataType(DataType, int numChannels);
70
71 private:
72 // The bit for DataType dt with n channels is at index kDataTypeCnt*(n-1) + dt.
73 std::bitset<kDataTypeCnt*4> fDataTypeSupport = {};
74 };
75
76 /**
77 * Gets the default SkColorType to use with numChannels channels, each represented as DataType.
78 * Returns kUnknown_SkColorType if no such color type.
79 */
80 static constexpr SkColorType DefaultColorTypeForDataType(DataType dataType, int numChannels);
81
82 /**
83 * If the SkColorType is supported for YUVA pixmaps this will return the number of YUVA channels
84 * that can be stored in a plane of this color type and what the DataType is of those channels.
85 * If the SkColorType is not supported as a YUVA plane the number of channels is reported as 0
86 * and the DataType returned should be ignored.
87 */
88 static std::tuple<int, DataType> NumChannelsAndDataType(SkColorType);
89
90 /** Default SkYUVAPixmapInfo is invalid. */
91 SkYUVAPixmapInfo() = default;
92
93 /**
94 * Initializes the SkYUVAPixmapInfo from a SkYUVAInfo with per-plane color types and row bytes.
95 * This will be invalid if the colorTypes aren't compatible with the SkYUVAInfo or if a
96 * rowBytes entry is not valid for the plane dimensions and color type. Color type and
97 * row byte values beyond the number of planes in SkYUVAInfo are ignored. All SkColorTypes
98 * must have the same DataType or this will be invalid.
99 *
100 * If rowBytes is nullptr then bpp*width is assumed for each plane.
101 */
103 const SkColorType[kMaxPlanes],
104 const size_t rowBytes[kMaxPlanes]);
105 /**
106 * Like above but uses DefaultColorTypeForDataType to determine each plane's SkColorType. If
107 * rowBytes is nullptr then bpp*width is assumed for each plane.
108 */
109 SkYUVAPixmapInfo(const SkYUVAInfo&, DataType, const size_t rowBytes[kMaxPlanes]);
110
112
114
115 bool operator==(const SkYUVAPixmapInfo&) const;
116 bool operator!=(const SkYUVAPixmapInfo& that) const { return !(*this == that); }
117
118 const SkYUVAInfo& yuvaInfo() const { return fYUVAInfo; }
119
120 SkYUVColorSpace yuvColorSpace() const { return fYUVAInfo.yuvColorSpace(); }
121
122 /** The number of SkPixmap planes, 0 if this SkYUVAPixmapInfo is invalid. */
123 int numPlanes() const { return fYUVAInfo.numPlanes(); }
124
125 /** The per-YUV[A] channel data type. */
126 DataType dataType() const { return fDataType; }
127
128 /**
129 * Row bytes for the ith plane. Returns zero if i >= numPlanes() or this SkYUVAPixmapInfo is
130 * invalid.
131 */
132 size_t rowBytes(int i) const { return fRowBytes[static_cast<size_t>(i)]; }
133
134 /** Image info for the ith plane, or default SkImageInfo if i >= numPlanes() */
135 const SkImageInfo& planeInfo(int i) const { return fPlaneInfos[static_cast<size_t>(i)]; }
136
137 /**
138 * Determine size to allocate for all planes. Optionally retrieves the per-plane sizes in
139 * planeSizes if not null. If total size overflows will return SIZE_MAX and set all planeSizes
140 * to SIZE_MAX. Returns 0 and fills planesSizes with 0 if this SkYUVAPixmapInfo is not valid.
141 */
142 size_t computeTotalBytes(size_t planeSizes[kMaxPlanes] = nullptr) const;
143
144 /**
145 * Takes an allocation that is assumed to be at least computeTotalBytes() in size and configures
146 * the first numPlanes() entries in pixmaps array to point into that memory. The remaining
147 * entries of pixmaps are default initialized. Fails if this SkYUVAPixmapInfo not valid.
148 */
149 bool initPixmapsFromSingleAllocation(void* memory, SkPixmap pixmaps[kMaxPlanes]) const;
150
151 /**
152 * Returns true if this has been configured with a non-empty dimensioned SkYUVAInfo with
153 * compatible color types and row bytes.
154 */
155 bool isValid() const { return fYUVAInfo.isValid(); }
156
157 /** Is this valid and does it use color types allowed by the passed SupportedDataTypes? */
158 bool isSupported(const SupportedDataTypes&) const;
159
160private:
161 SkYUVAInfo fYUVAInfo;
162 std::array<SkImageInfo, kMaxPlanes> fPlaneInfos = {};
163 std::array<size_t, kMaxPlanes> fRowBytes = {};
164 DataType fDataType = DataType::kUnorm8;
165 static_assert(kUnknown_SkColorType == 0, "default init isn't kUnknown");
166};
167
168/**
169 * Helper to store SkPixmap planes as described by a SkYUVAPixmapInfo. Can be responsible for
170 * allocating/freeing memory for pixmaps or use external memory.
171 */
173public:
175 static constexpr auto kMaxPlanes = SkYUVAPixmapInfo::kMaxPlanes;
176
177 static SkColorType RecommendedRGBAColorType(DataType);
178
179 /** Allocate space for pixmaps' pixels in the SkYUVAPixmaps. */
180 static SkYUVAPixmaps Allocate(const SkYUVAPixmapInfo& yuvaPixmapInfo);
181
182 /**
183 * Use storage in SkData as backing store for pixmaps' pixels. SkData is retained by the
184 * SkYUVAPixmaps.
185 */
186 static SkYUVAPixmaps FromData(const SkYUVAPixmapInfo&, sk_sp<SkData>);
187
188 /**
189 * Makes a deep copy of the src SkYUVAPixmaps. The returned SkYUVAPixmaps owns its planes'
190 * backing stores.
191 */
192 static SkYUVAPixmaps MakeCopy(const SkYUVAPixmaps& src);
193
194 /**
195 * Use passed in memory as backing store for pixmaps' pixels. Caller must ensure memory remains
196 * allocated while pixmaps are in use. There must be at least
197 * SkYUVAPixmapInfo::computeTotalBytes() allocated starting at memory.
198 */
199 static SkYUVAPixmaps FromExternalMemory(const SkYUVAPixmapInfo&, void* memory);
200
201 /**
202 * Wraps existing SkPixmaps. The SkYUVAPixmaps will have no ownership of the SkPixmaps' pixel
203 * memory so the caller must ensure it remains valid. Will return an invalid SkYUVAPixmaps if
204 * the SkYUVAInfo isn't compatible with the SkPixmap array (number of planes, plane dimensions,
205 * sufficient color channels in planes, ...).
206 */
207 static SkYUVAPixmaps FromExternalPixmaps(const SkYUVAInfo&, const SkPixmap[kMaxPlanes]);
208
209 /** Default SkYUVAPixmaps is invalid. */
210 SkYUVAPixmaps() = default;
211 ~SkYUVAPixmaps() = default;
212
213 SkYUVAPixmaps(SkYUVAPixmaps&& that) = default;
215 SkYUVAPixmaps(const SkYUVAPixmaps&) = default;
216 SkYUVAPixmaps& operator=(const SkYUVAPixmaps& that) = default;
217
218 /** Does have initialized pixmaps compatible with its SkYUVAInfo. */
219 bool isValid() const { return !fYUVAInfo.dimensions().isEmpty(); }
220
221 const SkYUVAInfo& yuvaInfo() const { return fYUVAInfo; }
222
223 DataType dataType() const { return fDataType; }
224
225 SkYUVAPixmapInfo pixmapsInfo() const;
226
227 /** Number of pixmap planes or 0 if this SkYUVAPixmaps is invalid. */
228 int numPlanes() const { return this->isValid() ? fYUVAInfo.numPlanes() : 0; }
229
230 /**
231 * Access the SkPixmap planes. They are default initialized if this is not a valid
232 * SkYUVAPixmaps.
233 */
234 const std::array<SkPixmap, kMaxPlanes>& planes() const { return fPlanes; }
235
236 /**
237 * Get the ith SkPixmap plane. SkPixmap will be default initialized if i >= numPlanes or this
238 * SkYUVAPixmaps is invalid.
239 */
240 const SkPixmap& plane(int i) const { return fPlanes[SkToSizeT(i)]; }
241
242 /**
243 * Computes a YUVALocations representation of the planar layout. The result is guaranteed to be
244 * valid if this->isValid().
245 */
246 SkYUVAInfo::YUVALocations toYUVALocations() const;
247
248 /** Does this SkPixmaps own the backing store of the planes? */
249 bool ownsStorage() const { return SkToBool(fData); }
250
251private:
253 SkYUVAPixmaps(const SkYUVAInfo&, DataType, const SkPixmap[kMaxPlanes]);
254
255 std::array<SkPixmap, kMaxPlanes> fPlanes = {};
256 sk_sp<SkData> fData;
257 SkYUVAInfo fYUVAInfo;
258 DataType fDataType;
259};
260
261//////////////////////////////////////////////////////////////////////////////
262
264 using ULL = unsigned long long; // bitset cons. takes this.
265 ULL bits = 0;
266 for (ULL c = 1; c <= 4; ++c) {
267 for (ULL dt = 0; dt <= ULL(kDataTypeCnt); ++dt) {
268 if (DefaultColorTypeForDataType(static_cast<DataType>(dt),
269 static_cast<int>(c)) != kUnknown_SkColorType) {
270 bits |= ULL(1) << (dt + static_cast<ULL>(kDataTypeCnt)*(c - 1));
271 }
272 }
273 }
274 SupportedDataTypes combinations;
275 combinations.fDataTypeSupport = bits;
276 return combinations;
277}
278
280 DataType type) const {
281 int n = SkYUVAInfo::NumPlanes(config);
282 for (int i = 0; i < n; ++i) {
283 auto c = static_cast<size_t>(SkYUVAInfo::NumChannelsInPlane(config, i));
284 SkASSERT(c >= 1 && c <= 4);
285 if (!fDataTypeSupport[static_cast<size_t>(type) +
286 (c - 1)*static_cast<size_t>(kDataTypeCnt)]) {
287 return false;
288 }
289 }
290 return true;
291}
292
294 int numChannels) {
295 switch (numChannels) {
296 case 1:
297 switch (dataType) {
302 }
303 break;
304 case 2:
305 switch (dataType) {
310 }
311 break;
312 case 3:
313 // None of these are tightly packed. The intended use case is for interleaved YUVA
314 // planes where we're forcing opaqueness by ignoring the alpha values.
315 // There are "x" rather than "A" variants for Unorm8 and Unorm10_Unorm2 but we don't
316 // choose them because 1) there is no inherent advantage and 2) there is better support
317 // in the GPU backend for the "A" versions.
318 switch (dataType) {
323 }
324 break;
325 case 4:
326 switch (dataType) {
331 }
332 break;
333 }
335}
336
337#endif
#define SK_API
Definition SkAPI.h:35
#define SkASSERT(cond)
Definition SkAssert.h:116
SkColorType
Definition SkColorType.h:19
@ kR16G16B16A16_unorm_SkColorType
pixel with a little endian uint16_t for red, green, blue
Definition SkColorType.h:50
@ kR8G8_unorm_SkColorType
pixel with a uint8_t for red and green
Definition SkColorType.h:43
@ kA16_unorm_SkColorType
pixel with a little endian uint16_t for alpha
Definition SkColorType.h:48
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition SkColorType.h:38
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition SkColorType.h:35
@ kRGBA_8888_SkColorType
pixel with 8 bits for red, green, blue, alpha; in 32-bit word
Definition SkColorType.h:24
@ kA16_float_SkColorType
pixel with a half float for alpha
Definition SkColorType.h:45
@ kRGBA_1010102_SkColorType
10 bits for red, green, blue; 2 bits for alpha; in 32-bit word
Definition SkColorType.h:27
@ kR16G16_unorm_SkColorType
pixel with a little endian uint16_t for red and green
Definition SkColorType.h:49
@ kUnknown_SkColorType
uninitialized
Definition SkColorType.h:20
@ kR16G16_float_SkColorType
pixel with a half float for red and green
Definition SkColorType.h:46
SkYUVColorSpace
Definition SkImageInfo.h:68
constexpr size_t SkToSizeT(S x)
Definition SkTo.h:31
static constexpr bool SkToBool(const T &x)
Definition SkTo.h:35
static constexpr int kMaxPlanes
Definition SkYUVAInfo.h:98
static constexpr int NumChannelsInPlane(PlaneConfig, int i)
Definition SkYUVAInfo.h:272
static constexpr int NumPlanes(PlaneConfig)
Definition SkYUVAInfo.h:253
std::array< YUVALocation, kYUVAChannelCount > YUVALocations
Definition SkYUVAInfo.h:32
constexpr bool supported(PlaneConfig, DataType) const
constexpr SupportedDataTypes()=default
static constexpr SupportedDataTypes All()
size_t rowBytes(int i) const
SkYUVColorSpace yuvColorSpace() const
SkYUVAPixmapInfo(const SkYUVAPixmapInfo &)=default
const SkYUVAInfo & yuvaInfo() const
SkYUVAPixmapInfo()=default
SkYUVAPixmapInfo & operator=(const SkYUVAPixmapInfo &)=default
@ kUnorm10_Unorm2
10 bit unorm for Y, U, and V. 2 bit unorm for alpha (if present).
@ kUnorm8
8 bit unsigned normalized
@ kUnorm16
16 bit unsigned normalized
@ kFloat16
16 bit (half) floating point
bool operator!=(const SkYUVAPixmapInfo &that) const
bool isValid() const
DataType dataType() const
static constexpr int kDataTypeCnt
int numPlanes() const
const SkImageInfo & planeInfo(int i) const
static constexpr auto kMaxPlanes
static constexpr SkColorType DefaultColorTypeForDataType(DataType dataType, int numChannels)
SkYUVAPixmaps & operator=(SkYUVAPixmaps &&that)=default
DataType dataType() const
SkYUVAPixmaps(const SkYUVAPixmaps &)=default
const SkYUVAInfo & yuvaInfo() const
const std::array< SkPixmap, kMaxPlanes > & planes() const
const SkPixmap & plane(int i) const
~SkYUVAPixmaps()=default
SkYUVAPixmaps()=default
int numPlanes() const
bool ownsStorage() const
bool isValid() const
SkYUVAPixmaps(SkYUVAPixmaps &&that)=default
SkYUVAPixmaps & operator=(const SkYUVAPixmaps &that)=default
bool operator==(const FlutterPoint &a, const FlutterPoint &b)
SkYUVAPixmapInfo::DataType DataType