Add P016 and P010 examples to wacky_yuv_formats GM

These formats are for HDR YUV.

This CL also adds partial support for Y416 but, without Ganesh support for RGBA_16161616, it can't be displayed.

Change-Id: I4218a104f2935d1395ee6c7c6792105092e1eeb3
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/214220
Commit-Queue: Robert Phillips <robertphillips@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
This commit is contained in:
Robert Phillips 2019-06-10 17:20:12 -04:00 committed by Skia Commit-Bot
parent 4cf5fd9945
commit bb74990a11

View File

@ -62,26 +62,82 @@ static const int kDomainPadding = 8;
static const int kPad = 1; static const int kPad = 1;
enum YUVFormat { enum YUVFormat {
// 4:2:0 formats, 24 bpp
kP016_YUVFormat, // 16-bit Y plane + 2x2 down sampled interleaved U/V plane (2 textures)
// 4:2:0 formats, "15 bpp" (but really 24 bpp)
kP010_YUVFormat, // same as kP016 except "10 bpp". Note that it is the same memory layout
// except that the bottom 6 bits are zeroed out (2 textures)
// TODO: we're cheating a bit w/ P010 and just treating it as unorm 16. This means its
// fully saturated values are 65504 rather than 65535 (that is just .9995 out of 1.0 though).
// 4:4:4 formats, 64 bpp
kY416_YUVFormat, // 16-bit AVYU values all interleaved (1 texture)
// 4:4:4 formats, 32 bpp // 4:4:4 formats, 32 bpp
kAYUV_YUVFormat, // 8-bit YUVA values all interleaved kAYUV_YUVFormat, // 8-bit YUVA values all interleaved (1 texture)
kY410_YUVFormat, // AVYU w/ 10bpp for YUV and 2 for A all interleaved kY410_YUVFormat, // AVYU w/ 10bpp for YUV and 2 for A all interleaved (1 texture)
// 4:2:0 formats, 12 bpp // 4:2:0 formats, 12 bpp
kNV12_YUVFormat, // 8-bit Y plane + 2x2 down sampled interleaved U/V planes kNV12_YUVFormat, // 8-bit Y plane + 2x2 down sampled interleaved U/V planes (2 textures)
kNV21_YUVFormat, // same as kNV12 but w/ U/V reversed in the interleaved plane kNV21_YUVFormat, // same as kNV12 but w/ U/V reversed in the interleaved texture (2 textures)
kI420_YUVFormat, // 8-bit Y plane + 2x2 down sampled U and V planes kI420_YUVFormat, // 8-bit Y plane + separate 2x2 down sampled U and V planes (3 textures)
kYV12_YUVFormat, // 8-bit Y plane + 2x2 down sampled V and U planes kYV12_YUVFormat, // 8-bit Y plane + separate 2x2 down sampled V and U planes (3 textures)
kLast_YUVFormat = kYV12_YUVFormat kLast_YUVFormat = kYV12_YUVFormat
}; };
static bool format_uses_16_bpp(YUVFormat yuvFormat) {
return kP016_YUVFormat == yuvFormat ||
kP010_YUVFormat == yuvFormat ||
kY416_YUVFormat == yuvFormat;
}
static bool format_has_builtin_alpha(YUVFormat yuvFormat) {
return kY416_YUVFormat == yuvFormat ||
kAYUV_YUVFormat == yuvFormat ||
kY410_YUVFormat == yuvFormat;
}
static bool format_cant_be_represented_with_pixmaps(YUVFormat yuvFormat) {
return kP016_YUVFormat == yuvFormat ||
kP010_YUVFormat == yuvFormat ||
kY416_YUVFormat == yuvFormat ||
kY410_YUVFormat == yuvFormat;
}
// Helper to setup the SkYUVAIndex array correctly // Helper to setup the SkYUVAIndex array correctly
// Skia allows the client to tack an additional alpha plane onto any of the standard opaque // Skia allows the client to tack an additional alpha plane onto any of the standard opaque
// formats (via the addExtraAlpha) flag. In this case it is assumed to be a stand-alone single- // formats (via the addExtraAlpha) flag. In this case it is assumed to be a stand-alone single-
// channel plane. // channel plane.
static void setup_yuv_indices(YUVFormat yuvFormat, bool addExtraAlpha, SkYUVAIndex yuvaIndices[4]) { static void setup_yuv_indices(YUVFormat yuvFormat, bool addExtraAlpha, SkYUVAIndex yuvaIndices[4]) {
switch (yuvFormat) { switch (yuvFormat) {
case kP016_YUVFormat: // fall through
case kP010_YUVFormat:
yuvaIndices[0].fIndex = 0;
yuvaIndices[0].fChannel = SkColorChannel::kR; // bc 16bit is stored in R16 format
yuvaIndices[1].fIndex = 1;
yuvaIndices[1].fChannel = SkColorChannel::kR;
yuvaIndices[2].fIndex = 1;
yuvaIndices[2].fChannel = SkColorChannel::kG;
if (addExtraAlpha) {
yuvaIndices[3].fIndex = 2;
yuvaIndices[3].fChannel = SkColorChannel::kR; // bc 16bit is stored in R16 format
} else {
yuvaIndices[3].fIndex = -1; // No alpha channel
}
break;
case kY416_YUVFormat:
SkASSERT(!addExtraAlpha); // this format already has an alpha channel
yuvaIndices[0].fIndex = 0;
yuvaIndices[0].fChannel = SkColorChannel::kG;
yuvaIndices[1].fIndex = 0;
yuvaIndices[1].fChannel = SkColorChannel::kB;
yuvaIndices[2].fIndex = 0;
yuvaIndices[2].fChannel = SkColorChannel::kR;
yuvaIndices[3].fIndex = 0;
yuvaIndices[3].fChannel = SkColorChannel::kA;
break;
case kAYUV_YUVFormat: case kAYUV_YUVFormat:
SkASSERT(!addExtraAlpha); // this format already has an alpha channel SkASSERT(!addExtraAlpha); // this format already has an alpha channel
yuvaIndices[0].fIndex = 0; yuvaIndices[0].fIndex = 0;
@ -328,6 +384,9 @@ static void convert_rgba_to_yuva_601_shared(SkColor col, uint8_t yuv[4],
float Ey = Kr * r + Kg * g + Kb * b; float Ey = Kr * r + Kg * g + Kb * b;
float Ecb = (b - Ey) / 1.402f; float Ecb = (b - Ey) / 1.402f;
float Ecr = (r - Ey) / 1.772; float Ecr = (r - Ey) / 1.772;
SkASSERT(Ey >= 0.0f && Ey <= 1.0f);
SkASSERT(Ecb >= -0.5f && Ecb <= 0.5f);
SkASSERT(Ecr >= -0.5f && Ecr <= 0.5f);
yuv[0] = SkScalarRoundToInt( range * Ey + off ); yuv[0] = SkScalarRoundToInt( range * Ey + off );
yuv[1] = SkScalarRoundToInt( 224 * Ecb + 128 ); yuv[1] = SkScalarRoundToInt( 224 * Ecb + 128 );
@ -358,6 +417,9 @@ static void convert_rgba_to_yuva_709(SkColor col, uint8_t yuv[4]) {
float Ey = Kr * r + Kg * g + Kb * b; float Ey = Kr * r + Kg * g + Kb * b;
float Ecb = (b - Ey) / 1.8556f; float Ecb = (b - Ey) / 1.8556f;
float Ecr = (r - Ey) / 1.5748; float Ecr = (r - Ey) / 1.5748;
SkASSERT(Ey >= 0.0f && Ey <= 1.0f);
SkASSERT(Ecb >= -0.5f && Ecb <= 0.5f);
SkASSERT(Ecr >= -0.5f && Ecr <= 0.5f);
yuv[0] = SkScalarRoundToInt( 219 * Ey + 16 ); yuv[0] = SkScalarRoundToInt( 219 * Ey + 16 );
yuv[1] = SkScalarRoundToInt( 224 * Ecb + 128 ); yuv[1] = SkScalarRoundToInt( 224 * Ecb + 128 );
@ -456,12 +518,73 @@ static void extract_planes(const SkBitmap& bm, SkYUVColorSpace yuvColorSpace, Pl
} }
} }
// Create a 2x2 downsampled SkBitmap. It is stored in an RGBA texture. It can optionally be
// uv (i.e., for P016, P010 and NV12) or vu (i.e., NV21).
static SkBitmap make_quarter_2_channel(const SkBitmap& fullY,
const SkBitmap& quarterU,
const SkBitmap& quarterV,
bool uv) {
SkBitmap result;
// There isn't a RG color type. Approx w/ RGBA.
result.allocPixels(SkImageInfo::Make(fullY.width()/2,
fullY.height()/2,
kRGBA_8888_SkColorType,
kUnpremul_SkAlphaType));
for (int y = 0; y < fullY.height()/2; ++y) {
for (int x = 0; x < fullY.width()/2; ++x) {
uint8_t u8 = *quarterU.getAddr8(x, y);
uint8_t v8 = *quarterV.getAddr8(x, y);
if (uv) {
// NOT premul!
// U and 0 swapped to match RGBA layout
*result.getAddr32(x, y) = SkColorSetARGB(0xFF, 0, v8, u8);
} else {
// NOT premul!
// V and 0 swapped to match RGBA layout
*result.getAddr32(x, y) = SkColorSetARGB(0xFF, 0, u8, v8);
}
}
}
return result;
}
// Recombine the separate planes into some YUV format // Recombine the separate planes into some YUV format
static void create_YUV(const PlaneData& planes, YUVFormat yuvFormat, static void create_YUV(const PlaneData& planes, YUVFormat yuvFormat,
SkBitmap resultBMs[], SkYUVAIndex yuvaIndices[4], bool opaque) { SkBitmap resultBMs[], SkYUVAIndex yuvaIndices[4], bool opaque) {
int nextLayer = 0; int nextLayer = 0;
switch (yuvFormat) { switch (yuvFormat) {
case kY416_YUVFormat: {
// Although this is 16 bpp, store the data in an 8 bpp SkBitmap
SkBitmap yuvaFull;
yuvaFull.allocPixels(SkImageInfo::Make(planes.fYFull.width(), planes.fYFull.height(),
kRGBA_8888_SkColorType, kUnpremul_SkAlphaType));
for (int y = 0; y < planes.fYFull.height(); ++y) {
for (int x = 0; x < planes.fYFull.width(); ++x) {
uint8_t Y = *planes.fYFull.getAddr8(x, y);
uint8_t U = *planes.fUFull.getAddr8(x, y);
uint8_t V = *planes.fVFull.getAddr8(x, y);
uint8_t A = *planes.fAFull.getAddr8(x, y);
// NOT premul!
// U and V swapped to match RGBA layout
SkColor c = SkColorSetARGB(A, U, Y, V);
*yuvaFull.getAddr32(x, y) = c;
}
}
resultBMs[nextLayer++] = yuvaFull;
setup_yuv_indices(yuvFormat, false, yuvaIndices);
break;
}
case kAYUV_YUVFormat: { case kAYUV_YUVFormat: {
SkBitmap yuvaFull; SkBitmap yuvaFull;
@ -516,26 +639,12 @@ static void create_YUV(const PlaneData& planes, YUVFormat yuvFormat,
setup_yuv_indices(yuvFormat, false, yuvaIndices); setup_yuv_indices(yuvFormat, false, yuvaIndices);
break; break;
} }
case kP016_YUVFormat: // fall through
case kP010_YUVFormat: // fall through
case kNV12_YUVFormat: { case kNV12_YUVFormat: {
SkBitmap uvQuarter; SkBitmap uvQuarter = make_quarter_2_channel(planes.fYFull,
planes.fUQuarter,
// There isn't a RG color type. Approx w/ RGBA. planes.fVQuarter, true);
uvQuarter.allocPixels(SkImageInfo::Make(planes.fYFull.width()/2,
planes.fYFull.height()/2,
kRGBA_8888_SkColorType,
kUnpremul_SkAlphaType));
for (int y = 0; y < planes.fYFull.height()/2; ++y) {
for (int x = 0; x < planes.fYFull.width()/2; ++x) {
uint8_t U = *planes.fUQuarter.getAddr8(x, y);
uint8_t V = *planes.fVQuarter.getAddr8(x, y);
// NOT premul!
// U and 0 swapped to match RGBA layout
*uvQuarter.getAddr32(x, y) = SkColorSetARGB(0xFF, 0, V, U);
}
}
resultBMs[nextLayer++] = planes.fYFull; resultBMs[nextLayer++] = planes.fYFull;
resultBMs[nextLayer++] = uvQuarter; resultBMs[nextLayer++] = uvQuarter;
@ -543,25 +652,9 @@ static void create_YUV(const PlaneData& planes, YUVFormat yuvFormat,
break; break;
} }
case kNV21_YUVFormat: { case kNV21_YUVFormat: {
SkBitmap vuQuarter; SkBitmap vuQuarter = make_quarter_2_channel(planes.fYFull,
planes.fUQuarter,
// There isn't a RG color type. Approx w/ RGBA. planes.fVQuarter, false);
vuQuarter.allocPixels(SkImageInfo::Make(planes.fYFull.width()/2,
planes.fYFull.height()/2,
kRGBA_8888_SkColorType,
kUnpremul_SkAlphaType));
for (int y = 0; y < planes.fYFull.height()/2; ++y) {
for (int x = 0; x < planes.fYFull.width()/2; ++x) {
uint8_t U = *planes.fUQuarter.getAddr8(x, y);
uint8_t V = *planes.fVQuarter.getAddr8(x, y);
// NOT premul!
// V and 0 swapped to match RGBA layout
*vuQuarter.getAddr32(x, y) = SkColorSetARGB(0xFF, 0, U, V);
}
}
resultBMs[nextLayer++] = planes.fYFull; resultBMs[nextLayer++] = planes.fYFull;
resultBMs[nextLayer++] = vuQuarter; resultBMs[nextLayer++] = vuQuarter;
@ -584,7 +677,7 @@ static void create_YUV(const PlaneData& planes, YUVFormat yuvFormat,
break; break;
} }
if (kAYUV_YUVFormat != yuvFormat && kY410_YUVFormat != yuvFormat && !opaque) { if (!format_has_builtin_alpha(yuvFormat) && !opaque) {
resultBMs[nextLayer] = planes.fAFull; resultBMs[nextLayer] = planes.fAFull;
} }
} }
@ -598,7 +691,7 @@ static uint8_t look_up(float x1, float y1, const SkBitmap& bm, SkColorChannel ch
int y = SkScalarFloorToInt(y1 * bm.height()); int y = SkScalarFloorToInt(y1 * bm.height());
if (kAlpha_8_SkColorType == bm.colorType()) { if (kAlpha_8_SkColorType == bm.colorType()) {
SkASSERT(SkColorChannel::kA == channel); SkASSERT(SkColorChannel::kA == channel || SkColorChannel::kR == channel);
result = *bm.getAddr8(x, y); result = *bm.getAddr8(x, y);
} else if (kRGBA_8888_SkColorType == bm.colorType()) { } else if (kRGBA_8888_SkColorType == bm.colorType()) {
SkColor c = *bm.getAddr32(x, y); SkColor c = *bm.getAddr32(x, y);
@ -801,7 +894,9 @@ static void draw_col_label(SkCanvas* canvas, int x, int yuvColorSpace, bool opaq
} }
static void draw_row_label(SkCanvas* canvas, int y, int yuvFormat) { static void draw_row_label(SkCanvas* canvas, int y, int yuvFormat) {
static const char* kYUVFormatNames[] = { "AYUV", "Y410", "NV12", "NV21", "I420", "YV12" }; static const char* kYUVFormatNames[] = {
"P016", "P010", "Y416", "AYUV", "Y410", "NV12", "NV21", "I420", "YV12"
};
GR_STATIC_ASSERT(SK_ARRAY_COUNT(kYUVFormatNames) == kLast_YUVFormat+1); GR_STATIC_ASSERT(SK_ARRAY_COUNT(kYUVFormatNames) == kLast_YUVFormat+1);
SkPaint paint; SkPaint paint;
@ -818,10 +913,134 @@ static void draw_row_label(SkCanvas* canvas, int y, int yuvFormat) {
canvas->drawString(rowLabel, 0, y, font, paint); canvas->drawString(rowLabel, 0, y, font, paint);
} }
static void make_RG_88(const GrCaps* caps,
const SkBitmap& bm, YUVFormat yuvFormat,
SkAutoTMalloc<uint8_t>* pixels,
GrBackendFormat* format) {
SkASSERT(kNV12_YUVFormat == yuvFormat || kNV21_YUVFormat == yuvFormat);
SkASSERT(kRGBA_8888_SkColorType == bm.colorType()); // uv stored in rg
pixels->reset(2 * sizeof(uint8_t) * bm.width() * bm.height());
uint8_t* currPixel = pixels->get();
for (int y = 0; y < bm.height(); ++y) {
for (int x = 0; x < bm.width(); ++x) {
SkColor color = bm.getColor(x, y);
uint8_t u8 = SkColorGetR(color);
uint8_t v8 = SkColorGetG(color);
currPixel[0] = u8;
currPixel[1] = v8;
currPixel += 2;
}
}
*format = caps->getBackendFormatFromGrColorType(GrColorType::kRG_88,
GrSRGBEncoded::kNo);
}
static void make_RG_1616(const GrCaps* caps,
const SkBitmap& bm, YUVFormat yuvFormat,
SkAutoTMalloc<uint8_t>* pixels,
GrBackendFormat* format) {
SkASSERT(kP016_YUVFormat == yuvFormat || kP010_YUVFormat == yuvFormat);
SkASSERT(kRGBA_8888_SkColorType == bm.colorType()); // uv stored in rg
uint16_t u16, v16;
pixels->reset(2 * sizeof(uint16_t) * bm.width() * bm.height());
uint16_t* currPixel = (uint16_t*) pixels->get();
for (int y = 0; y < bm.height(); ++y) {
for (int x = 0; x < bm.width(); ++x) {
SkColor color = bm.getColor(x, y);
if (kP016_YUVFormat == yuvFormat) {
u16 = SkScalarRoundToInt((SkColorGetR(color) / 255.0f) * 65535.0f);
v16 = SkScalarRoundToInt((SkColorGetG(color) / 255.0f) * 65535.0f);
} else {
u16 = SkScalarRoundToInt((SkColorGetR(color) / 255.0f) * 1023.0f);
v16 = SkScalarRoundToInt((SkColorGetG(color) / 255.0f) * 1023.0f);
u16 <<= 6;
v16 <<= 6;
}
currPixel[0] = u16;
currPixel[1] = v16;
currPixel += 2;
}
}
*format = caps->getBackendFormatFromGrColorType(GrColorType::kRG_1616,
GrSRGBEncoded::kNo);
}
static void make_RGBA_16(const GrCaps* caps,
const SkBitmap& bm,
YUVFormat yuvFormat,
SkAutoTMalloc<uint8_t>* pixels,
GrBackendFormat* format) {
SkASSERT(kY416_YUVFormat == yuvFormat);
SkASSERT(kRGBA_8888_SkColorType == bm.colorType());
uint16_t y16, u16, v16, a16;
pixels->reset(4 * sizeof(uint16_t) * bm.width() * bm.height());
uint16_t* currPixel = (uint16_t*) pixels->get();
for (int y = 0; y < bm.height(); ++y) {
for (int x = 0; x < bm.width(); ++x) {
SkColor color = bm.getColor(x, y);
y16 = SkScalarRoundToInt((SkColorGetR(color) / 255.0f) * 65535.0f);
u16 = SkScalarRoundToInt((SkColorGetG(color) / 255.0f) * 65535.0f);
v16 = SkScalarRoundToInt((SkColorGetB(color) / 255.0f) * 65535.0f);
a16 = SkScalarRoundToInt((SkColorGetA(color) / 255.0f) * 65535.0f);
currPixel[0] = y16;
currPixel[1] = u16;
currPixel[2] = v16;
currPixel[3] = a16;
currPixel += 4;
}
}
// For this to work we need GrColorType::kRGBA_16 support, i.e.:
// GL: RGBA16 (required in GL 3.0, added by GL_EXT_texture_norm16 for ES3.1)
// Vk: VK_FORMAT_R16G16B16A16_UNORM
// Mtl: MTLPixelFormatRGBA16Unorm
// *format = caps->getBackendFormatFromGrColorType(GrColorType::kRGBA_16161616,
// GrSRGBEncoded::kNo);
return;
}
static void make_R_16(const GrCaps* caps,
const SkBitmap& bm,
YUVFormat yuvFormat,
SkAutoTMalloc<uint8_t>* pixels,
GrBackendFormat* format) {
SkASSERT(kP016_YUVFormat == yuvFormat || kP010_YUVFormat == yuvFormat);
SkASSERT(kAlpha_8_SkColorType == bm.colorType());
uint16_t y16;
pixels->reset(sizeof(uint16_t) * bm.width() * bm.height());
uint16_t* currPixel = (uint16_t*) pixels->get();
for (int y = 0; y < bm.height(); ++y) {
for (int x = 0; x < bm.width(); ++x) {
uint8_t y8 = *bm.getAddr8(x, y);
if (kP016_YUVFormat == yuvFormat) {
y16 = SkScalarRoundToInt((y8 / 255.0f) * 65535.0f);
} else {
y16 = SkScalarRoundToInt((y8 / 255.0f) * 1023.0f);
y16 <<= 6;
}
currPixel[0] = y16;
currPixel += 1;
}
}
*format = caps->getBackendFormatFromGrColorType(GrColorType::kR_16, GrSRGBEncoded::kNo);
}
static GrBackendTexture create_yuva_texture(GrContext* context, const SkBitmap& bm, static GrBackendTexture create_yuva_texture(GrContext* context, const SkBitmap& bm,
SkYUVAIndex yuvaIndices[4], int texIndex) { SkYUVAIndex yuvaIndices[4], int texIndex,
YUVFormat yuvFormat) {
SkASSERT(texIndex >= 0 && texIndex <= 3); SkASSERT(texIndex >= 0 && texIndex <= 3);
int channelCount = 0; int channelCount = 0;
for (int i = 0; i < SkYUVAIndex::kIndexCount; ++i) { for (int i = 0; i < SkYUVAIndex::kIndexCount; ++i) {
@ -829,32 +1048,38 @@ static GrBackendTexture create_yuva_texture(GrContext* context, const SkBitmap&
++channelCount; ++channelCount;
} }
} }
// Need to create an RG texture for two-channel planes
GrBackendTexture tex; GrBackendTexture tex;
if (2 == channelCount) {
if (format_uses_16_bpp(yuvFormat) || 2 == channelCount) {
// Due to the limitations of SkPixmap these cases need to be handled separately
const GrCaps* caps = context->priv().caps(); const GrCaps* caps = context->priv().caps();
GrGpu* gpu = context->priv().getGpu(); GrGpu* gpu = context->priv().getGpu();
SkASSERT(kRGBA_8888_SkColorType == bm.colorType()); SkAutoTMalloc<uint8_t> pixels;
SkAutoTMalloc<char> pixels(2 * bm.width()*bm.height()); GrBackendFormat format;
char* currPixel = pixels;
for (int y = 0; y < bm.height(); ++y) { if (2 == channelCount) {
for (int x = 0; x < bm.width(); ++x) { if (format_uses_16_bpp(yuvFormat)) {
SkColor color = bm.getColor(x, y); make_RG_1616(caps, bm, yuvFormat, &pixels, &format);
currPixel[0] = SkColorGetR(color); } else {
currPixel[1] = SkColorGetG(color); make_RG_88(caps, bm, yuvFormat, &pixels, &format);
currPixel += 2; }
} else {
if (kRGBA_8888_SkColorType == bm.colorType()) {
make_RGBA_16(caps, bm, yuvFormat, &pixels, &format);
} else {
make_R_16(caps, bm, yuvFormat, &pixels, &format);
} }
} }
GrBackendFormat format = caps->getBackendFormatFromGrColorType(GrColorType::kRG_88,
GrSRGBEncoded::kNo);
tex = gpu->createBackendTexture(bm.width(), bm.height(), format, tex = gpu->createBackendTexture(bm.width(), bm.height(), format,
GrMipMapped::kNo, GrRenderable::kNo, GrMipMapped::kNo, GrRenderable::kNo,
pixels, 2*bm.width(), nullptr); pixels, 0, nullptr);
} } else {
if (!tex.isValid()) {
tex = context->priv().createBackendTexture(&bm.pixmap(), 1, GrRenderable::kNo); tex = context->priv().createBackendTexture(&bm.pixmap(), 1, GrRenderable::kNo);
} }
return tex; return tex;
} }
@ -876,6 +1101,10 @@ namespace skiagm {
// //
// JPEG 601 709 Identity // JPEG 601 709 Identity
// Transparent Opaque Transparent Opaque Transparent Opaque Transparent Opaque // Transparent Opaque Transparent Opaque Transparent Opaque Transparent Opaque
// originals
// P016
// P010
// Y416
// AYUV // AYUV
// Y410 // Y410
// NV12 // NV12
@ -943,7 +1172,7 @@ protected:
PlaneData planes; PlaneData planes;
extract_planes(fOriginalBMs[opaque], (SkYUVColorSpace) cs, &planes); extract_planes(fOriginalBMs[opaque], (SkYUVColorSpace) cs, &planes);
for (int format = kAYUV_YUVFormat; format <= kLast_YUVFormat; ++format) { for (int format = kP016_YUVFormat; format <= kLast_YUVFormat; ++format) {
SkBitmap resultBMs[4]; SkBitmap resultBMs[4];
SkYUVAIndex yuvaIndices[4]; SkYUVAIndex yuvaIndices[4];
@ -964,7 +1193,8 @@ protected:
for (int i = 0; i < numTextures; ++i) { for (int i = 0; i < numTextures; ++i) {
yuvaTextures[i] = create_yuva_texture(context, resultBMs[i], yuvaTextures[i] = create_yuva_texture(context, resultBMs[i],
yuvaIndices, i); yuvaIndices, i,
(YUVFormat) format);
if (yuvaTextures[i].isValid()) { if (yuvaTextures[i].isValid()) {
fBackendTextures.push_back(yuvaTextures[i]); fBackendTextures.push_back(yuvaTextures[i]);
} }
@ -972,8 +1202,9 @@ protected:
} }
int counterMod = counter % 3; int counterMod = counter % 3;
if (format == kY410_YUVFormat && counterMod == 2) { if (format_cant_be_represented_with_pixmaps((YUVFormat) format) &&
// This format doesn't work as pixmaps counterMod == 2) {
// These formats don't work as pixmaps
counterMod = 1; counterMod = 1;
} else if (fUseDomain && counterMod == 0) { } else if (fUseDomain && counterMod == 0) {
// Copies flatten to RGB when they copy the YUVA data, which doesn't // Copies flatten to RGB when they copy the YUVA data, which doesn't
@ -1055,7 +1286,7 @@ protected:
canvas->drawBitmapRect(fOriginalBMs[opaque], srcRect, dstRect, nullptr, constraint); canvas->drawBitmapRect(fOriginalBMs[opaque], srcRect, dstRect, nullptr, constraint);
dstRect.offset(0.f, dstRect.height() + kPad); dstRect.offset(0.f, dstRect.height() + kPad);
for (int format = kAYUV_YUVFormat; format <= kLast_YUVFormat; ++format) { for (int format = kP016_YUVFormat; format <= kLast_YUVFormat; ++format) {
draw_row_label(canvas, dstRect.fTop, format); draw_row_label(canvas, dstRect.fTop, format);
if (fUseTargetColorSpace && fImages[opaque][cs][format]) { if (fUseTargetColorSpace && fImages[opaque][cs][format]) {
// Making a CS-specific version of a kIdentity_SkYUVColorSpace YUV image // Making a CS-specific version of a kIdentity_SkYUVColorSpace YUV image
@ -1163,7 +1394,8 @@ protected:
GrBackendTexture yuvaTextures[4]; GrBackendTexture yuvaTextures[4];
for (int i = 0; i < numTextures; ++i) { for (int i = 0; i < numTextures; ++i) {
yuvaTextures[i] = create_yuva_texture(context, resultBMs[i], yuvaIndices, i); yuvaTextures[i] = create_yuva_texture(context, resultBMs[i], yuvaIndices, i,
kAYUV_YUVFormat);
if (yuvaTextures[i].isValid()) { if (yuvaTextures[i].isValid()) {
fBackendTextures.push_back(yuvaTextures[i]); fBackendTextures.push_back(yuvaTextures[i]);
} }