Skip to content

Commit

Permalink
Added BGR10_XR support for decoding images.
Browse files Browse the repository at this point in the history
Bug: skia: https://bugs.chromium.org/p/skia/issues/detail?id=14071
Change-Id: I9727a7008fb84db8c7ce30b33429c343317814c6
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/640885
Reviewed-by: Brian Osman <brianosman@google.com>
Reviewed-by: John Stiles <johnstiles@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
  • Loading branch information
gaaclarke authored and SkCQ committed Feb 17, 2023
1 parent cece9fd commit 9d76772
Show file tree
Hide file tree
Showing 24 changed files with 95 additions and 1 deletion.
1 change: 1 addition & 0 deletions docs/examples/unexpected_setAlphaType.cpp
Expand Up @@ -28,6 +28,7 @@ static const char* colortype_name(SkColorType ct) {
case kRGB_101010x_SkColorType: return "RGB_101010x";
case kBGRA_1010102_SkColorType: return "BGRA_1010102";
case kBGR_101010x_SkColorType: return "BGR_101010x";
case kBGR_101010x_XR_SkColorType: return "BGR_101010x_xr";
case kGray_8_SkColorType: return "Gray_8";
case kRGBA_F16Norm_SkColorType: return "RGBA_F16Norm";
case kRGBA_F16_SkColorType: return "RGBA_F16";
Expand Down
1 change: 1 addition & 0 deletions gm/bitmapcopy.cpp
Expand Up @@ -38,6 +38,7 @@ static const char* color_type_name(SkColorType colorType) {
case kRGB_101010x_SkColorType: return "101010x";
case kBGRA_1010102_SkColorType: return "bgra1010102";
case kBGR_101010x_SkColorType: return "bgr101010x";
case kBGR_101010x_XR_SkColorType: return "bgr101010x_xr";
case kGray_8_SkColorType: return "G8";
case kRGBA_F16Norm_SkColorType: return "F16Norm";
case kRGBA_F16_SkColorType: return "F16";
Expand Down
1 change: 1 addition & 0 deletions include/core/SkColorType.h
Expand Up @@ -28,6 +28,7 @@ enum SkColorType : int {
kBGRA_1010102_SkColorType, //!< 10 bits for blue, green, red; 2 bits for alpha; in 32-bit word
kRGB_101010x_SkColorType, //!< pixel with 10 bits each for red, green, blue; in 32-bit word
kBGR_101010x_SkColorType, //!< pixel with 10 bits each for blue, green, red; in 32-bit word
kBGR_101010x_XR_SkColorType, //!< pixel with 10 bits each for blue, green, red; in 32-bit word, extended range
kGray_8_SkColorType, //!< pixel with grayscale level in 8-bit byte
kRGBA_F16Norm_SkColorType, //!< pixel with half floats in [0,1] for red, green, blue, alpha;
// in 64-bit word
Expand Down
1 change: 1 addition & 0 deletions include/private/gpu/ganesh/GrTypesPriv.h
Expand Up @@ -644,6 +644,7 @@ static constexpr GrColorType SkColorTypeToGrColorType(SkColorType ct) {
case kRGB_101010x_SkColorType: return GrColorType::kUnknown;
case kBGRA_1010102_SkColorType: return GrColorType::kBGRA_1010102;
case kBGR_101010x_SkColorType: return GrColorType::kUnknown;
case kBGR_101010x_XR_SkColorType: return GrColorType::kUnknown;
case kRGBA_F32_SkColorType: return GrColorType::kRGBA_F32;
case kR8G8_unorm_SkColorType: return GrColorType::kRG_88;
case kA16_unorm_SkColorType: return GrColorType::kAlpha_16;
Expand Down
6 changes: 5 additions & 1 deletion src/codec/SkCodec.cpp
Expand Up @@ -720,6 +720,9 @@ bool sk_select_xform_format(SkColorType colorType, bool forColorTable,
case kRGBA_F16_SkColorType:
*outFormat = skcms_PixelFormat_RGBA_hhhh;
break;
case kBGR_101010x_XR_SkColorType:
*outFormat = skcms_PixelFormat_BGR_101010x_XR;
break;
case kGray_8_SkColorType:
*outFormat = skcms_PixelFormat_G_8;
break;
Expand All @@ -734,7 +737,8 @@ bool SkCodec::initializeColorXform(const SkImageInfo& dstInfo, SkEncodedInfo::Al
fXformTime = kNo_XformTime;
bool needsColorXform = false;
if (this->usesColorXform()) {
if (kRGBA_F16_SkColorType == dstInfo.colorType()) {
if (kRGBA_F16_SkColorType == dstInfo.colorType() ||
kBGR_101010x_XR_SkColorType == dstInfo.colorType()) {
needsColorXform = true;
if (dstInfo.colorSpace()) {
dstInfo.colorSpace()->toProfile(&fDstProfile);
Expand Down
1 change: 1 addition & 0 deletions src/codec/SkJpegCodec.cpp
Expand Up @@ -477,6 +477,7 @@ bool SkJpegCodec::conversionSupported(const SkImageInfo& dstInfo, bool srcIsOpaq
fDecoderMgr->dinfo()->out_color_space = JCS_GRAYSCALE;
}
break;
case kBGR_101010x_XR_SkColorType:
case kRGBA_F16_SkColorType:
SkASSERT(needsColorXform);
fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
Expand Down
1 change: 1 addition & 0 deletions src/core/SkConvertPixels.cpp
Expand Up @@ -104,6 +104,7 @@ static bool convert_to_alpha8(const SkImageInfo& dstInfo, void* vdst, size
case kRGB_888x_SkColorType:
case kRGB_101010x_SkColorType:
case kBGR_101010x_SkColorType:
case kBGR_101010x_XR_SkColorType:
case kR8_unorm_SkColorType: {
for (int y = 0; y < srcInfo.height(); ++y) {
memset(dst, 0xFF, srcInfo.width());
Expand Down
2 changes: 2 additions & 0 deletions src/core/SkImageInfo.cpp
Expand Up @@ -26,6 +26,7 @@ int SkColorTypeBytesPerPixel(SkColorType ct) {
case kRGB_101010x_SkColorType: return 4;
case kBGRA_1010102_SkColorType: return 4;
case kBGR_101010x_SkColorType: return 4;
case kBGR_101010x_XR_SkColorType: return 4;
case kGray_8_SkColorType: return 1;
case kRGBA_F16Norm_SkColorType: return 8;
case kRGBA_F16_SkColorType: return 8;
Expand Down Expand Up @@ -223,6 +224,7 @@ bool SkColorTypeValidateAlphaType(SkColorType colorType, SkAlphaType alphaType,
case kRGB_888x_SkColorType:
case kRGB_101010x_SkColorType:
case kBGR_101010x_SkColorType:
case kBGR_101010x_XR_SkColorType:
case kR8_unorm_SkColorType:
alphaType = kOpaque_SkAlphaType;
break;
Expand Down
4 changes: 4 additions & 0 deletions src/core/SkImageInfoPriv.h
Expand Up @@ -24,6 +24,7 @@ static inline uint32_t SkColorTypeChannelFlags(SkColorType ct) {
case kRGB_101010x_SkColorType: return kRGB_SkColorChannelFlags;
case kBGRA_1010102_SkColorType: return kRGBA_SkColorChannelFlags;
case kBGR_101010x_SkColorType: return kRGB_SkColorChannelFlags;
case kBGR_101010x_XR_SkColorType: return kRGB_SkColorChannelFlags;
case kGray_8_SkColorType: return kGray_SkColorChannelFlag;
case kRGBA_F16Norm_SkColorType: return kRGBA_SkColorChannelFlags;
case kRGBA_F16_SkColorType: return kRGBA_SkColorChannelFlags;
Expand Down Expand Up @@ -61,6 +62,7 @@ static int SkColorTypeShiftPerPixel(SkColorType ct) {
case kRGB_101010x_SkColorType: return 2;
case kBGRA_1010102_SkColorType: return 2;
case kBGR_101010x_SkColorType: return 2;
case kBGR_101010x_XR_SkColorType: return 2;
case kGray_8_SkColorType: return 0;
case kRGBA_F16Norm_SkColorType: return 3;
case kRGBA_F16_SkColorType: return 3;
Expand Down Expand Up @@ -116,6 +118,7 @@ static inline bool SkColorTypeIsNormalized(SkColorType ct) {
case kR8_unorm_SkColorType:
return true;

case kBGR_101010x_XR_SkColorType:
case kRGBA_F16_SkColorType:
case kRGBA_F32_SkColorType:
case kR16G16_float_SkColorType:
Expand Down Expand Up @@ -149,6 +152,7 @@ static inline int SkColorTypeMaxBitsPerChannel(SkColorType ct) {
case kRGB_101010x_SkColorType:
case kBGRA_1010102_SkColorType:
case kBGR_101010x_SkColorType:
case kBGR_101010x_XR_SkColorType:
return 10;

case kRGBA_F16Norm_SkColorType:
Expand Down
1 change: 1 addition & 0 deletions src/core/SkMipmap.cpp
Expand Up @@ -546,6 +546,7 @@ SkMipmap* SkMipmap::Build(const SkPixmap& src, SkDiscardableFactoryProc fact,
case kRGB_888x_SkColorType: // TODO: use 8888?
case kRGB_101010x_SkColorType: // TODO: use 1010102?
case kBGR_101010x_SkColorType: // TODO: use 1010102?
case kBGR_101010x_XR_SkColorType: // TODO: use 1010102?
case kRGBA_F32_SkColorType:
return nullptr;

Expand Down
10 changes: 10 additions & 0 deletions src/core/SkPixmap.cpp
Expand Up @@ -106,6 +106,7 @@ float SkPixmap::getAlphaf(int x, int y) const {
case kRGB_888x_SkColorType:
case kRGB_101010x_SkColorType:
case kBGR_101010x_SkColorType:
case kBGR_101010x_XR_SkColorType:
case kR8_unorm_SkColorType:
return 1;
case kAlpha_8_SkColorType:
Expand Down Expand Up @@ -274,6 +275,10 @@ SkColor SkPixmap::getColor(int x, int y) const {
| (uint32_t)( ((value >> 20) & 0x3ff) * (255/1023.0f) ) << 0
| 0xff000000;
}
case kBGR_101010x_XR_SkColorType: {
SkASSERT(false);
return 0;
}
case kBGR_101010x_SkColorType: {
uint32_t value = *this->addr32(x, y);
// Convert 10-bit bgr to 8-bit bgr, and mask in 0xff alpha at the top.
Expand Down Expand Up @@ -448,6 +453,10 @@ SkColor4f SkPixmap::getColor4f(int x, int y) const {
}
return SkColor4f{r, g, b, a};
}
case kBGR_101010x_XR_SkColorType: {
SkASSERT(false);
return {};
}
case kRGB_101010x_SkColorType: {
uint32_t value = *this->addr32(x, y);
// Convert 10-bit rgb to float rgb, and mask in 0xff alpha at the top.
Expand Down Expand Up @@ -575,6 +584,7 @@ bool SkPixmap::computeIsOpaque() const {
case kRGB_888x_SkColorType:
case kRGB_101010x_SkColorType:
case kBGR_101010x_SkColorType:
case kBGR_101010x_XR_SkColorType:
case kR8_unorm_SkColorType:
return true;
case kARGB_4444_SkColorType: {
Expand Down
15 changes: 15 additions & 0 deletions src/core/SkRasterPipeline.cpp
Expand Up @@ -224,6 +224,11 @@ void SkRasterPipeline::append_load(SkColorType ct, const SkRasterPipeline_Memory
this->append(Op::swap_rb);
break;

case kBGR_101010x_XR_SkColorType: this->append(Op::load_1010102_xr, ctx);
this->append(Op::force_opaque);
this->append(Op::swap_rb);
break;

case kBGRA_8888_SkColorType: this->append(Op::load_8888, ctx);
this->append(Op::swap_rb);
break;
Expand Down Expand Up @@ -279,6 +284,11 @@ void SkRasterPipeline::append_load_dst(SkColorType ct, const SkRasterPipeline_Me
this->append(Op::swap_rb_dst);
break;

case kBGR_101010x_XR_SkColorType: this->append(Op::load_1010102_xr_dst, ctx);
this->append(Op::force_opaque_dst);
this->append(Op::swap_rb_dst);
break;

case kBGRA_8888_SkColorType: this->append(Op::load_8888_dst, ctx);
this->append(Op::swap_rb_dst);
break;
Expand Down Expand Up @@ -330,6 +340,11 @@ void SkRasterPipeline::append_store(SkColorType ct, const SkRasterPipeline_Memor
this->append(Op::store_1010102, ctx);
break;

case kBGR_101010x_XR_SkColorType: this->append(Op::force_opaque);
this->append(Op::swap_rb);
this->append(Op::store_1010102_xr, ctx);
break;

case kGray_8_SkColorType: this->append(Op::bt709_luminance_or_luma_to_alpha);
this->append(Op::store_a8, ctx);
break;
Expand Down
1 change: 1 addition & 0 deletions src/core/SkRasterPipelineBlitter.cpp
Expand Up @@ -229,6 +229,7 @@ SkBlitter* SkRasterPipelineBlitter::Create(const SkPixmap& dst,

case kUnknown_SkColorType:
case kAlpha_8_SkColorType:
case kBGR_101010x_XR_SkColorType:
case kRGBA_F16_SkColorType:
case kRGBA_F16Norm_SkColorType:
case kRGBA_F32_SkColorType:
Expand Down
1 change: 1 addition & 0 deletions src/core/SkRasterPipelineOpList.h
Expand Up @@ -67,6 +67,7 @@
M(load_f32) M(load_f32_dst) M(store_f32) M(gather_f32) \
M(load_rgf32) M(store_rgf32) \
M(load_1010102) M(load_1010102_dst) M(store_1010102) M(gather_1010102) \
M(load_1010102_xr) M(load_1010102_xr_dst) M(store_1010102_xr) \
M(store_u16_be) \
M(store_src_rg) M(load_src_rg) \
M(byte_tables) \
Expand Down
1 change: 1 addition & 0 deletions src/core/SkVM.cpp
Expand Up @@ -1210,6 +1210,7 @@ namespace skvm {
case kBGRA_1010102_SkColorType: return {UNORM, 10,10,10,2, 20,10, 0,30};
case kRGB_101010x_SkColorType: return {UNORM, 10,10,10,0, 0,10,20, 0};
case kBGR_101010x_SkColorType: return {UNORM, 10,10,10,0, 20,10, 0, 0};
case kBGR_101010x_XR_SkColorType: SkDEBUGFAIL("Not implemented."); return {UNORM, 10,10,10,0, 20,10, 0, 0};

case kR8G8_unorm_SkColorType: return {UNORM, 8, 8,0, 0, 0, 8,0,0};
case kR16G16_unorm_SkColorType: return {UNORM, 16,16,0, 0, 0,16,0,0};
Expand Down
1 change: 1 addition & 0 deletions src/core/SkVMBlitter.cpp
Expand Up @@ -147,6 +147,7 @@ namespace {

case kUnknown_SkColorType:
case kAlpha_8_SkColorType:
case kBGR_101010x_XR_SkColorType:
case kRGBA_F16_SkColorType:
case kRGBA_F16Norm_SkColorType:
case kRGBA_F32_SkColorType:
Expand Down
1 change: 1 addition & 0 deletions src/encode/SkPngEncoder.cpp
Expand Up @@ -350,6 +350,7 @@ static transform_scanline_proc choose_proc(const SkImageInfo& info) {
}
case kRGB_101010x_SkColorType: return transform_scanline_101010x;
case kBGR_101010x_SkColorType: return transform_scanline_bgr_101010x;
case kBGR_101010x_XR_SkColorType: SkASSERT(false); return nullptr;

case kAlpha_8_SkColorType:
return transform_scanline_A8_to_GrayAlpha;
Expand Down
28 changes: 28 additions & 0 deletions src/opts/SkRasterPipeline_opts.h
Expand Up @@ -1404,6 +1404,15 @@ SI void from_1010102(U32 rgba, F* r, F* g, F* b, F* a) {
*b = cast((rgba >> 20) & 0x3ff) * (1/1023.0f);
*a = cast((rgba >> 30) ) * (1/ 3.0f);
}
SI void from_1010102_xr(U32 rgba, F* r, F* g, F* b, F* a) {
static constexpr float min = -0.752941f;
static constexpr float max = 1.25098f;
static constexpr float range = max - min;
*r = cast((rgba ) & 0x3ff) * (1/1023.0f) * range + min;
*g = cast((rgba >> 10) & 0x3ff) * (1/1023.0f) * range + min;
*b = cast((rgba >> 20) & 0x3ff) * (1/1023.0f) * range + min;
*a = cast((rgba >> 30) ) * (1/ 3.0f);
}
SI void from_1616(U32 _1616, F* r, F* g) {
*r = cast((_1616 ) & 0xffff) * (1/65535.0f);
*g = cast((_1616 >> 16) & 0xffff) * (1/65535.0f);
Expand Down Expand Up @@ -2570,6 +2579,14 @@ STAGE(load_1010102_dst, const SkRasterPipeline_MemoryCtx* ctx) {
auto ptr = ptr_at_xy<const uint32_t>(ctx, dx,dy);
from_1010102(load<U32>(ptr, tail), &dr,&dg,&db,&da);
}
STAGE(load_1010102_xr, const SkRasterPipeline_MemoryCtx* ctx) {
auto ptr = ptr_at_xy<const uint32_t>(ctx, dx,dy);
from_1010102_xr(load<U32>(ptr, tail), &r,&g,&b,&a);
}
STAGE(load_1010102_xr_dst, const SkRasterPipeline_MemoryCtx* ctx) {
auto ptr = ptr_at_xy<const uint32_t>(ctx, dx,dy);
from_1010102_xr(load<U32>(ptr, tail), &dr,&dg,&db,&da);
}
STAGE(gather_1010102, const SkRasterPipeline_GatherCtx* ctx) {
const uint32_t* ptr;
U32 ix = ix_and_ptr(&ptr, ctx, r,g);
Expand All @@ -2584,6 +2601,17 @@ STAGE(store_1010102, const SkRasterPipeline_MemoryCtx* ctx) {
| to_unorm(a, 3) << 30;
store(ptr, px, tail);
}
STAGE(store_1010102_xr, const SkRasterPipeline_MemoryCtx* ctx) {
auto ptr = ptr_at_xy<uint32_t>(ctx, dx,dy);
static constexpr float min = -0.752941f;
static constexpr float max = 1.25098f;
static constexpr float range = max - min;
U32 px = to_unorm((r - min) / range, 1023)
| to_unorm((g - min) / range, 1023) << 10
| to_unorm((b - min) / range, 1023) << 20
| to_unorm(a, 3) << 30;
store(ptr, px, tail);
}

STAGE(load_f16, const SkRasterPipeline_MemoryCtx* ctx) {
auto ptr = ptr_at_xy<const uint64_t>(ctx, dx,dy);
Expand Down
4 changes: 4 additions & 0 deletions src/shaders/SkImageShader.cpp
Expand Up @@ -661,6 +661,10 @@ bool SkImageShader::appendStages(const SkStageRec& rec, const MatrixRec& mRec) c
p->append(SkRasterPipelineOp::force_opaque);
break;

case kBGR_101010x_XR_SkColorType:
SkASSERT(false);
break;

case kBGR_101010x_SkColorType:
p->append(SkRasterPipelineOp::gather_1010102, ctx);
p->append(SkRasterPipelineOp::force_opaque);
Expand Down
7 changes: 7 additions & 0 deletions tests/BackendAllocationTest.cpp
Expand Up @@ -617,6 +617,7 @@ void color_type_backend_allocation_test(const sk_gpu_test::ContextInfo& ctxInfo,
// RGB/BGR 101010x have no Ganesh correlate
{ kRGB_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
{ kBGR_101010x_SkColorType, { 0, 0.5f, 0, 0.5f } },
{ kBGR_101010x_XR_SkColorType, { 0, 0.5f, 0, 0.5f } },
{ kGray_8_SkColorType, kGrayCol },
{ kRGBA_F16Norm_SkColorType, SkColors::kLtGray },
{ kRGBA_F16_SkColorType, SkColors::kYellow },
Expand All @@ -642,6 +643,12 @@ void color_type_backend_allocation_test(const sk_gpu_test::ContextInfo& ctxInfo,
}
}

if (colorType == kBGR_101010x_XR_SkColorType) {
// Creating a texture with kBGR_101010x_XR_SkColorType is not
// implemented.
continue;
}

for (auto mipmapped : {GrMipmapped::kNo, GrMipmapped::kYes}) {
if (GrMipmapped::kYes == mipmapped && !caps->mipmapSupport()) {
continue;
Expand Down
2 changes: 2 additions & 0 deletions tests/ReadWritePixelsGpuTest.cpp
Expand Up @@ -86,6 +86,7 @@ static constexpr int min_rgb_channel_bits(SkColorType ct) {
case kRGB_101010x_SkColorType: return 10;
case kBGRA_1010102_SkColorType: return 10;
case kBGR_101010x_SkColorType: return 10;
case kBGR_101010x_XR_SkColorType: return 10;
case kGray_8_SkColorType: return 8; // counting gray as "rgb"
case kRGBA_F16Norm_SkColorType: return 10; // just counting the mantissa
case kRGBA_F16_SkColorType: return 10; // just counting the mantissa
Expand Down Expand Up @@ -115,6 +116,7 @@ static constexpr int alpha_channel_bits(SkColorType ct) {
case kRGB_101010x_SkColorType: return 0;
case kBGRA_1010102_SkColorType: return 2;
case kBGR_101010x_SkColorType: return 0;
case kBGR_101010x_XR_SkColorType: return 0;
case kGray_8_SkColorType: return 0;
case kRGBA_F16Norm_SkColorType: return 10; // just counting the mantissa
case kRGBA_F16_SkColorType: return 10; // just counting the mantissa
Expand Down
3 changes: 3 additions & 0 deletions tests/graphite/ReadWritePixelsGraphiteTest.cpp
Expand Up @@ -50,6 +50,7 @@ static constexpr int min_rgb_channel_bits(SkColorType ct) {
case kRGB_101010x_SkColorType: return 10;
case kBGRA_1010102_SkColorType: return 10;
case kBGR_101010x_SkColorType: return 10;
case kBGR_101010x_XR_SkColorType: return 10;
case kGray_8_SkColorType: return 8; // counting gray as "rgb"
case kRGBA_F16Norm_SkColorType: return 10; // just counting the mantissa
case kRGBA_F16_SkColorType: return 10; // just counting the mantissa
Expand Down Expand Up @@ -79,6 +80,7 @@ static constexpr int alpha_channel_bits(SkColorType ct) {
case kRGB_101010x_SkColorType: return 0;
case kBGRA_1010102_SkColorType: return 2;
case kBGR_101010x_SkColorType: return 0;
case kBGR_101010x_XR_SkColorType: return 0;
case kGray_8_SkColorType: return 0;
case kRGBA_F16Norm_SkColorType: return 10; // just counting the mantissa
case kRGBA_F16_SkColorType: return 10; // just counting the mantissa
Expand Down Expand Up @@ -448,6 +450,7 @@ static void graphite_read_pixels_test_driver(skiatest::Reporter* reporter,
// ComparePixels will end up converting these types to kUnknown
// because there's no corresponding GrColorType, and hence it will fail
if (readCT == kRGB_101010x_SkColorType ||
readCT == kBGR_101010x_XR_SkColorType ||
readCT == kBGR_101010x_SkColorType) {
continue;
}
Expand Down
1 change: 1 addition & 0 deletions tools/HashAndEncode.cpp
Expand Up @@ -36,6 +36,7 @@ HashAndEncode::HashAndEncode(const SkBitmap& bitmap) : fSize(bitmap.info().dimen
case kSRGBA_8888_SkColorType: srcFmt = skcms_PixelFormat_RGBA_8888_sRGB; break;
case kRGBA_1010102_SkColorType: srcFmt = skcms_PixelFormat_RGBA_1010102; break;
case kBGRA_1010102_SkColorType: srcFmt = skcms_PixelFormat_BGRA_1010102; break;
case kBGR_101010x_XR_SkColorType: srcFmt = skcms_PixelFormat_BGR_101010x_XR; break;
case kGray_8_SkColorType: srcFmt = skcms_PixelFormat_G_8; break;
// skcms doesn't have R_8. Pretend it's G_8, but see below for color space trickery:
case kR8_unorm_SkColorType: srcFmt = skcms_PixelFormat_G_8; break;
Expand Down

0 comments on commit 9d76772

Please sign in to comment.