Skia
2D Graphics Library
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"
14 #include "include/core/SkPixmap.h"
15 #include "include/core/SkRefCnt.h"
16 #include "include/core/SkSize.h"
17 #include "include/core/SkTypes.h"
19 #include "include/private/base/SkTo.h"
20 
21 #include <array>
22 #include <bitset>
23 #include <cstddef>
24 #include <tuple>
25 
30 class SK_API SkYUVAPixmapInfo {
31 public:
32  static constexpr auto kMaxPlanes = SkYUVAInfo::kMaxPlanes;
33 
36 
41  enum class DataType {
42  kUnorm8,
43  kUnorm16,
44  kFloat16,
45  kUnorm10_Unorm2,
46 
47  kLast = kUnorm10_Unorm2
48  };
49  static constexpr int kDataTypeCnt = static_cast<int>(DataType::kLast) + 1;
50 
51  class SK_API SupportedDataTypes {
52  public:
54  constexpr SupportedDataTypes() = default;
55 
57  static constexpr SupportedDataTypes All();
58 
63  constexpr bool supported(PlaneConfig, DataType) const;
64 
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 
80  static constexpr SkColorType DefaultColorTypeForDataType(DataType dataType, int numChannels);
81 
88  static std::tuple<int, DataType> NumChannelsAndDataType(SkColorType);
89 
91  SkYUVAPixmapInfo() = default;
92 
103  const SkColorType[kMaxPlanes],
104  const size_t rowBytes[kMaxPlanes]);
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 
123  int numPlanes() const { return fYUVAInfo.numPlanes(); }
124 
126  DataType dataType() const { return fDataType; }
127 
132  size_t rowBytes(int i) const { return fRowBytes[static_cast<size_t>(i)]; }
133 
135  const SkImageInfo& planeInfo(int i) const { return fPlaneInfos[static_cast<size_t>(i)]; }
136 
142  size_t computeTotalBytes(size_t planeSizes[kMaxPlanes] = nullptr) const;
143 
149  bool initPixmapsFromSingleAllocation(void* memory, SkPixmap pixmaps[kMaxPlanes]) const;
150 
155  bool isValid() const { return fYUVAInfo.isValid(); }
156 
158  bool isSupported(const SupportedDataTypes&) const;
159 
160 private:
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 
172 class SK_API SkYUVAPixmaps {
173 public:
175  static constexpr auto kMaxPlanes = SkYUVAPixmapInfo::kMaxPlanes;
176 
178 
180  static SkYUVAPixmaps Allocate(const SkYUVAPixmapInfo& yuvaPixmapInfo);
181 
187 
193 
199  static SkYUVAPixmaps FromExternalMemory(const SkYUVAPixmapInfo&, void* memory);
200 
207  static SkYUVAPixmaps FromExternalPixmaps(const SkYUVAInfo&, const SkPixmap[kMaxPlanes]);
208 
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 
219  bool isValid() const { return !fYUVAInfo.dimensions().isEmpty(); }
220 
221  const SkYUVAInfo& yuvaInfo() const { return fYUVAInfo; }
222 
223  DataType dataType() const { return fDataType; }
224 
226 
228  int numPlanes() const { return this->isValid() ? fYUVAInfo.numPlanes() : 0; }
229 
234  const std::array<SkPixmap, kMaxPlanes>& planes() const { return fPlanes; }
235 
240  const SkPixmap& plane(int i) const { return fPlanes[SkToSizeT(i)]; }
241 
247 
249  bool ownsStorage() const { return SkToBool(fData); }
250 
251 private:
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 
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  }
334  return kUnknown_SkColorType;
335 }
336 
337 #endif
SkColorType
Describes how pixel bits encode color.
Definition: SkColorType.h:19
@ kR16G16B16A16_unorm_SkColorType
pixel with a little endian uint16_t for red, green, blue
Definition: SkColorType.h:49
@ kR8G8_unorm_SkColorType
pixel with a uint8_t for red and green
Definition: SkColorType.h:42
@ kA16_unorm_SkColorType
pixel with a little endian uint16_t for alpha
Definition: SkColorType.h:47
@ kRGBA_F16_SkColorType
pixel with half floats for red, green, blue, alpha;
Definition: SkColorType.h:37
@ kGray_8_SkColorType
pixel with grayscale level in 8-bit byte
Definition: SkColorType.h:34
@ 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:44
@ 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:48
@ kUnknown_SkColorType
uninitialized
Definition: SkColorType.h:20
@ kR16G16_float_SkColorType
pixel with a half float for red and green
Definition: SkColorType.h:45
SkYUVColorSpace
Definition: SkImageInfo.h:68
SkPixmap provides a utility to pair SkImageInfo with pixels and row bytes.
Definition: SkPixmap.h:40
Specifies the structure of planes for a YUV image with optional alpha.
Definition: SkYUVAInfo.h:26
PlaneConfig
Specifies how YUV (and optionally A) are divided among planes.
Definition: SkYUVAInfo.h:47
static constexpr int kMaxPlanes
Definition: SkYUVAInfo.h:98
static constexpr int NumChannelsInPlane(PlaneConfig, int i)
Number of Y, U, V, A channels in the ith plane for a given PlaneConfig (or 0 if i is invalid).
Definition: SkYUVAInfo.h:272
Subsampling
UV subsampling is also specified in the enum value names using J:a:b notation (e.g.
Definition: SkYUVAInfo.h:73
static constexpr int NumPlanes(PlaneConfig)
Number of planes for a given PlaneConfig.
Definition: SkYUVAInfo.h:253
std::array< YUVALocation, kYUVAChannelCount > YUVALocations
Definition: SkYUVAInfo.h:32
Definition: SkYUVAPixmaps.h:51
constexpr bool supported(PlaneConfig, DataType) const
Checks whether there is a supported combination of color types for planes structured as indicated by ...
Definition: SkYUVAPixmaps.h:279
constexpr SupportedDataTypes()=default
Defaults to nothing supported.
void enableDataType(DataType, int numChannels)
Update to add support for pixmaps with numChannel channels where each channel is represented as DataT...
static constexpr SupportedDataTypes All()
All legal combinations of PlaneConfig and DataType are supported.
Definition: SkYUVAPixmaps.h:263
SkYUVAInfo combined with per-plane SkColorTypes and row bytes.
Definition: SkYUVAPixmaps.h:30
size_t rowBytes(int i) const
Row bytes for the ith plane.
Definition: SkYUVAPixmaps.h:132
SkYUVColorSpace yuvColorSpace() const
Definition: SkYUVAPixmaps.h:120
const SkImageInfo & planeInfo(int i) const
Image info for the ith plane, or default SkImageInfo if i >= numPlanes()
Definition: SkYUVAPixmaps.h:135
SkYUVAPixmapInfo(const SkYUVAPixmapInfo &)=default
SkYUVAPixmapInfo & operator=(const SkYUVAPixmapInfo &)=default
SkYUVAPixmapInfo()=default
Default SkYUVAPixmapInfo is invalid.
bool initPixmapsFromSingleAllocation(void *memory, SkPixmap pixmaps[kMaxPlanes]) const
Takes an allocation that is assumed to be at least computeTotalBytes() in size and configures the fir...
SkYUVAPixmapInfo(const SkYUVAInfo &, DataType, const size_t rowBytes[kMaxPlanes])
Like above but uses DefaultColorTypeForDataType to determine each plane's SkColorType.
bool operator==(const SkYUVAPixmapInfo &) const
static std::tuple< int, DataType > NumChannelsAndDataType(SkColorType)
If the SkColorType is supported for YUVA pixmaps this will return the number of YUVA channels that ca...
DataType
Data type for Y, U, V, and possibly A channels independent of how values are packed into planes.
Definition: SkYUVAPixmaps.h:41
@ 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
Definition: SkYUVAPixmaps.h:116
size_t computeTotalBytes(size_t planeSizes[kMaxPlanes]=nullptr) const
Determine size to allocate for all planes.
bool isValid() const
Returns true if this has been configured with a non-empty dimensioned SkYUVAInfo with compatible colo...
Definition: SkYUVAPixmaps.h:155
DataType dataType() const
The per-YUV[A] channel data type.
Definition: SkYUVAPixmaps.h:126
bool isSupported(const SupportedDataTypes &) const
Is this valid and does it use color types allowed by the passed SupportedDataTypes?
const SkYUVAInfo & yuvaInfo() const
Definition: SkYUVAPixmaps.h:118
static constexpr int kDataTypeCnt
Definition: SkYUVAPixmaps.h:49
int numPlanes() const
The number of SkPixmap planes, 0 if this SkYUVAPixmapInfo is invalid.
Definition: SkYUVAPixmaps.h:123
static constexpr auto kMaxPlanes
Definition: SkYUVAPixmaps.h:32
SkYUVAPixmapInfo(const SkYUVAInfo &, const SkColorType[kMaxPlanes], const size_t rowBytes[kMaxPlanes])
Initializes the SkYUVAPixmapInfo from a SkYUVAInfo with per-plane color types and row bytes.
static constexpr SkColorType DefaultColorTypeForDataType(DataType dataType, int numChannels)
Gets the default SkColorType to use with numChannels channels, each represented as DataType.
Definition: SkYUVAPixmaps.h:293
Helper to store SkPixmap planes as described by a SkYUVAPixmapInfo.
Definition: SkYUVAPixmaps.h:172
static SkYUVAPixmaps MakeCopy(const SkYUVAPixmaps &src)
Makes a deep copy of the src SkYUVAPixmaps.
DataType dataType() const
Definition: SkYUVAPixmaps.h:223
SkYUVAPixmaps(const SkYUVAPixmaps &)=default
SkYUVAPixmaps & operator=(SkYUVAPixmaps &&that)=default
static SkYUVAPixmaps FromExternalPixmaps(const SkYUVAInfo &, const SkPixmap[kMaxPlanes])
Wraps existing SkPixmaps.
static SkYUVAPixmaps FromData(const SkYUVAPixmapInfo &, sk_sp< SkData >)
Use storage in SkData as backing store for pixmaps' pixels.
SkYUVAPixmapInfo pixmapsInfo() const
~SkYUVAPixmaps()=default
SkYUVAPixmaps()=default
Default SkYUVAPixmaps is invalid.
const std::array< SkPixmap, kMaxPlanes > & planes() const
Access the SkPixmap planes.
Definition: SkYUVAPixmaps.h:234
int numPlanes() const
Number of pixmap planes or 0 if this SkYUVAPixmaps is invalid.
Definition: SkYUVAPixmaps.h:228
const SkPixmap & plane(int i) const
Get the ith SkPixmap plane.
Definition: SkYUVAPixmaps.h:240
bool ownsStorage() const
Does this SkPixmaps own the backing store of the planes?
Definition: SkYUVAPixmaps.h:249
static SkYUVAPixmaps Allocate(const SkYUVAPixmapInfo &yuvaPixmapInfo)
Allocate space for pixmaps' pixels in the SkYUVAPixmaps.
static SkYUVAPixmaps FromExternalMemory(const SkYUVAPixmapInfo &, void *memory)
Use passed in memory as backing store for pixmaps' pixels.
bool isValid() const
Does have initialized pixmaps compatible with its SkYUVAInfo.
Definition: SkYUVAPixmaps.h:219
const SkYUVAInfo & yuvaInfo() const
Definition: SkYUVAPixmaps.h:221
static SkColorType RecommendedRGBAColorType(DataType)
SkYUVAInfo::YUVALocations toYUVALocations() const
Computes a YUVALocations representation of the planar layout.
SkYUVAPixmaps(SkYUVAPixmaps &&that)=default
SkYUVAPixmaps & operator=(const SkYUVAPixmaps &that)=default
Describes pixel dimensions and encoding.
Definition: SkImageInfo.h:194