Flutter Engine
The Flutter Engine
SkYUVAPixmaps.cpp
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
9
15
16#include <algorithm>
17#include <cstdint>
18#include <utility>
19
21 if (numChannels < 1 || numChannels > 4) {
22 return;
23 }
24 fDataTypeSupport[static_cast<size_t>(type) + (numChannels - 1)*kDataTypeCnt] = true;
25}
26
27//////////////////////////////////////////////////////////////////////////////
28
29std::tuple<int, SkYUVAPixmapInfo::DataType> SkYUVAPixmapInfo::NumChannelsAndDataType(
30 SkColorType ct) {
31 // We could allow BGR[A] color types, but then we'd have to decide whether B should be the 0th
32 // or 2nd channel. Our docs currently say channel order is always R=0, G=1, B=2[, A=3].
33 switch (ct) {
35 case kGray_8_SkColorType: return {1, DataType::kUnorm8 };
38
42
45
51
52 default: return {0, DataType::kUnorm8 };
53 }
54}
55
57 const SkColorType colorTypes[kMaxPlanes],
58 const size_t rowBytes[kMaxPlanes])
59 : fYUVAInfo(yuvaInfo) {
60 if (!yuvaInfo.isValid()) {
61 *this = {};
62 SkASSERT(!this->isValid());
63 return;
64 }
65 SkISize planeDimensions[4];
66 int n = yuvaInfo.planeDimensions(planeDimensions);
67 size_t tempRowBytes[kMaxPlanes];
68 if (!rowBytes) {
69 for (int i = 0; i < n; ++i) {
70 tempRowBytes[i] = SkColorTypeBytesPerPixel(colorTypes[i]) * planeDimensions[i].width();
71 }
72 rowBytes = tempRowBytes;
73 }
74 bool ok = true;
75 for (size_t i = 0; i < static_cast<size_t>(n); ++i) {
76 fRowBytes[i] = rowBytes[i];
77 // Use kUnpremul so that we never multiply alpha when copying data in.
78 fPlaneInfos[i] = SkImageInfo::Make(planeDimensions[i],
79 colorTypes[i],
81 int numRequiredChannels = yuvaInfo.numChannelsInPlane(i);
82 SkASSERT(numRequiredChannels > 0);
83 auto [numColorTypeChannels, colorTypeDataType] = NumChannelsAndDataType(colorTypes[i]);
84 ok &= i == 0 || colorTypeDataType == fDataType;
85 ok &= numColorTypeChannels >= numRequiredChannels;
86 ok &= fPlaneInfos[i].validRowBytes(fRowBytes[i]);
87 fDataType = colorTypeDataType;
88 }
89 if (!ok) {
90 *this = {};
91 SkASSERT(!this->isValid());
92 } else {
93 SkASSERT(this->isValid());
94 }
95}
96
98 DataType dataType,
99 const size_t rowBytes[kMaxPlanes]) {
100 SkColorType colorTypes[kMaxPlanes] = {};
102 for (int i = 0; i < numPlanes; ++i) {
103 int numChannels = yuvaInfo.numChannelsInPlane(i);
104 colorTypes[i] = DefaultColorTypeForDataType(dataType, numChannels);
105 }
106 *this = SkYUVAPixmapInfo(yuvaInfo, colorTypes, rowBytes);
107}
108
110 bool result = fYUVAInfo == that.fYUVAInfo &&
111 fPlaneInfos == that.fPlaneInfos &&
112 fRowBytes == that.fRowBytes;
113 SkASSERT(!result || fDataType == that.fDataType);
114 return result;
115}
116
117size_t SkYUVAPixmapInfo::computeTotalBytes(size_t planeSizes[kMaxPlanes]) const {
118 if (!this->isValid()) {
119 if (planeSizes) {
120 std::fill_n(planeSizes, kMaxPlanes, 0);
121 }
122 return 0;
123 }
124 return fYUVAInfo.computeTotalBytes(fRowBytes.data(), planeSizes);
125}
126
128 SkPixmap pixmaps[kMaxPlanes]) const {
129 if (!this->isValid()) {
130 return false;
131 }
132 SkASSERT(pixmaps);
133 char* addr = static_cast<char*>(memory);
134 int n = this->numPlanes();
135 for (int i = 0; i < n; ++i) {
136 SkASSERT(fPlaneInfos[i].validRowBytes(fRowBytes[i]));
137 pixmaps[i].reset(fPlaneInfos[i], addr, fRowBytes[i]);
138 size_t planeSize = pixmaps[i].rowBytes()*pixmaps[i].height();
139 SkASSERT(planeSize);
140 addr += planeSize;
141 }
142 for (int i = n; i < kMaxPlanes; ++i) {
143 pixmaps[i] = {};
144 }
145 return true;
146}
147
148bool SkYUVAPixmapInfo::isSupported(const SupportedDataTypes& supportedDataTypes) const {
149 if (!this->isValid()) {
150 return false;
151 }
152 return supportedDataTypes.supported(fYUVAInfo.planeConfig(), fDataType);
153}
154
155//////////////////////////////////////////////////////////////////////////////
156
158 switch (dataType) {
160 // F16 has better GPU support than 16 bit unorm. Often "16" bit unorm values are actually
161 // lower precision.
165 }
167}
168
170 if (!yuvaPixmapInfo.isValid()) {
171 return {};
172 }
173 return SkYUVAPixmaps(yuvaPixmapInfo,
175}
176
178 if (!yuvaPixmapInfo.isValid()) {
179 return {};
180 }
181 if (yuvaPixmapInfo.computeTotalBytes() > data->size()) {
182 return {};
183 }
184 return SkYUVAPixmaps(yuvaPixmapInfo, std::move(data));
185}
186
188 if (!src.isValid()) {
189 return {};
190 }
191 SkYUVAPixmaps result = Allocate(src.pixmapsInfo());
192 int n = result.numPlanes();
193 for (int i = 0; i < n; ++i) {
194 // We use SkRectMemCpy rather than readPixels to ensure that we don't do any alpha type
195 // conversion.
196 const SkPixmap& s = src.plane(i);
197 const SkPixmap& d = result.plane(i);
198 SkRectMemcpy(d.writable_addr(),
199 d.rowBytes(),
200 s.addr(),
201 s.rowBytes(),
202 s.info().minRowBytes(),
203 s.height());
204 }
205 return result;
206}
207
209 void* memory) {
210 if (!yuvaPixmapInfo.isValid()) {
211 return {};
212 }
213 SkPixmap pixmaps[kMaxPlanes];
214 yuvaPixmapInfo.initPixmapsFromSingleAllocation(memory, pixmaps);
215 return SkYUVAPixmaps(yuvaPixmapInfo.yuvaInfo(), yuvaPixmapInfo.dataType(), pixmaps);
216}
217
219 const SkPixmap pixmaps[kMaxPlanes]) {
220 SkColorType colorTypes[kMaxPlanes] = {};
221 size_t rowBytes[kMaxPlanes] = {};
223 for (int i = 0; i < numPlanes; ++i) {
224 colorTypes[i] = pixmaps[i].colorType();
225 rowBytes[i] = pixmaps[i].rowBytes();
226 }
227 SkYUVAPixmapInfo yuvaPixmapInfo(yuvaInfo, colorTypes, rowBytes);
228 if (!yuvaPixmapInfo.isValid()) {
229 return {};
230 }
231 return SkYUVAPixmaps(yuvaInfo, yuvaPixmapInfo.dataType(), pixmaps);
232}
233
235 : fData(std::move(data))
236 , fYUVAInfo(yuvaPixmapInfo.yuvaInfo())
237 , fDataType(yuvaPixmapInfo.dataType()) {
238 SkASSERT(yuvaPixmapInfo.isValid());
239 SkASSERT(yuvaPixmapInfo.computeTotalBytes() <= fData->size());
241 fPlanes.data()));
242}
243
245 DataType dataType,
246 const SkPixmap pixmaps[kMaxPlanes])
247 : fYUVAInfo(yuvaInfo), fDataType(dataType) {
248 std::copy_n(pixmaps, yuvaInfo.numPlanes(), fPlanes.data());
249}
250
252 if (!this->isValid()) {
253 return {};
254 }
255 SkColorType colorTypes[kMaxPlanes] = {};
256 size_t rowBytes[kMaxPlanes] = {};
257 int numPlanes = this->numPlanes();
258 for (int i = 0; i < numPlanes; ++i) {
259 colorTypes[i] = fPlanes[i].colorType();
260 rowBytes[i] = fPlanes[i].rowBytes();
261 }
262 return {fYUVAInfo, colorTypes, rowBytes};
263}
264
266 uint32_t channelFlags[] = {SkColorTypeChannelFlags(fPlanes[0].colorType()),
269 SkColorTypeChannelFlags(fPlanes[3].colorType())};
270 auto result = fYUVAInfo.toYUVALocations(channelFlags);
273 SkASSERT(numPlanes == this->numPlanes());
274 return result;
275}
SkAssertResult(font.textToGlyphs("Hello", 5, SkTextEncoding::kUTF8, glyphs, std::size(glyphs))==count)
kUnpremul_SkAlphaType
#define SkUNREACHABLE
Definition: SkAssert.h:135
#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
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
Definition: SkColorType.h:21
@ kRGB_101010x_SkColorType
pixel with 10 bits each for red, green, blue; in 32-bit word
Definition: SkColorType.h:29
@ 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
@ kRGB_888x_SkColorType
pixel with 8 bits each for red, green, blue; in 32-bit word
Definition: SkColorType.h:25
@ 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
@ kRGBA_F16Norm_SkColorType
pixel with half floats in [0,1] for red, green, blue, alpha;
Definition: SkColorType.h:36
@ kR16G16_float_SkColorType
pixel with a half float for red and green
Definition: SkColorType.h:46
static SkColorType colorType(AImageDecoder *decoder, const AImageDecoderHeaderInfo *headerInfo)
static bool ok(int result)
static uint32_t SkColorTypeChannelFlags(SkColorType ct)
SK_API int SkColorTypeBytesPerPixel(SkColorType ct)
Definition: SkImageInfo.cpp:16
static void SkRectMemcpy(void *dst, size_t dstRB, const void *src, size_t srcRB, size_t trimRowBytes, int rowCount)
Definition: SkRectMemcpy.h:16
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
GLenum type
static sk_sp< SkData > MakeUninitialized(size_t length)
Definition: SkData.cpp:116
void * writable_data()
Definition: SkData.h:52
size_t size() const
Definition: SkData.h:30
int numPlanes() const
Definition: SkYUVAInfo.h:204
size_t computeTotalBytes(const size_t rowBytes[kMaxPlanes], size_t planeSizes[kMaxPlanes]=nullptr) const
Definition: SkYUVAInfo.cpp:325
YUVALocations toYUVALocations(const uint32_t *channelFlags) const
Definition: SkYUVAInfo.cpp:358
PlaneConfig planeConfig() const
Definition: SkYUVAInfo.h:160
int planeDimensions(SkISize planeDimensions[kMaxPlanes]) const
Definition: SkYUVAInfo.h:192
std::array< YUVALocation, kYUVAChannelCount > YUVALocations
Definition: SkYUVAInfo.h:32
bool isValid() const
Definition: SkYUVAInfo.h:233
int numChannelsInPlane(int i) const
Definition: SkYUVAInfo.h:206
constexpr bool supported(PlaneConfig, DataType) const
void enableDataType(DataType, int numChannels)
size_t rowBytes(int i) const
const SkYUVAInfo & yuvaInfo() const
SkYUVAPixmapInfo()=default
bool initPixmapsFromSingleAllocation(void *memory, SkPixmap pixmaps[kMaxPlanes]) const
bool operator==(const SkYUVAPixmapInfo &) const
@ 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
size_t computeTotalBytes(size_t planeSizes[kMaxPlanes]=nullptr) const
bool isValid() const
DataType dataType() const
bool isSupported(const SupportedDataTypes &) const
static std::tuple< int, DataType > NumChannelsAndDataType(SkColorType)
static constexpr int kDataTypeCnt
Definition: SkYUVAPixmaps.h:49
int numPlanes() const
static constexpr auto kMaxPlanes
Definition: SkYUVAPixmaps.h:32
static constexpr SkColorType DefaultColorTypeForDataType(DataType dataType, int numChannels)
static SkYUVAPixmaps FromData(const SkYUVAPixmapInfo &, sk_sp< SkData >)
DataType dataType() const
const SkYUVAInfo & yuvaInfo() const
SkYUVAPixmapInfo pixmapsInfo() const
static SkYUVAPixmaps Allocate(const SkYUVAPixmapInfo &yuvaPixmapInfo)
SkYUVAPixmaps()=default
static SkYUVAPixmaps MakeCopy(const SkYUVAPixmaps &src)
static SkYUVAPixmaps FromExternalPixmaps(const SkYUVAInfo &, const SkPixmap[kMaxPlanes])
static SkYUVAPixmaps FromExternalMemory(const SkYUVAPixmapInfo &, void *memory)
int numPlanes() const
static SkColorType RecommendedRGBAColorType(DataType)
bool isValid() const
SkYUVAInfo::YUVALocations toYUVALocations() const
static constexpr auto kMaxPlanes
VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE auto & d
Definition: main.cc:19
struct MyStruct s
GAsyncResult * result
SkYUVAPixmapInfo::DataType DataType
Definition: ref_ptr.h:256
Definition: SkSize.h:16
constexpr int32_t width() const
Definition: SkSize.h:36
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
static bool AreValidLocations(const SkYUVAInfo::YUVALocations &locations, int *numPlanes=nullptr)
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63