Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit ac6129d

Browse files
authored
made opaque wide gamut images take up 32 bits per pixel (#39691)
1 parent cb1ef6f commit ac6129d

File tree

4 files changed

+61
-5
lines changed

4 files changed

+61
-5
lines changed

lib/ui/BUILD.gn

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,7 @@ if (enable_unittests) {
206206
fixtures = [
207207
"fixtures/DashInNooglerHat.jpg",
208208
"fixtures/DashInNooglerHat%20WithSpace.jpg",
209+
"fixtures/DisplayP3Logo.jpg",
209210
"fixtures/DisplayP3Logo.png",
210211
"fixtures/Horizontal.jpg",
211212
"fixtures/Horizontal.png",

lib/ui/fixtures/DisplayP3Logo.jpg

4.77 KB
Loading

lib/ui/painting/image_decoder_impeller.cc

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ static std::optional<impeller::PixelFormat> ToPixelFormat(SkColorType type) {
9696
return impeller::PixelFormat::kR8G8B8A8UNormInt;
9797
case kRGBA_F16_SkColorType:
9898
return impeller::PixelFormat::kR16G16B16A16Float;
99+
case kBGR_101010x_XR_SkColorType:
100+
return impeller::PixelFormat::kB10G10R10XR;
99101
default:
100102
return std::nullopt;
101103
}
@@ -137,11 +139,9 @@ std::shared_ptr<SkBitmap> ImageDecoderImpeller::DecompressTexture(
137139
ChooseCompatibleAlphaType(base_image_info.alphaType());
138140
SkImageInfo image_info;
139141
if (is_wide_gamut) {
140-
// TODO(gaaclarke): Branch on alpha_type so it's 32bpp for opaque images.
141-
// I tried using kBGRA_1010102_SkColorType and
142-
// kBGR_101010x_SkColorType but Skia fails to decode the
143-
// image that way.
144-
SkColorType color_type = kRGBA_F16_SkColorType;
142+
SkColorType color_type = alpha_type == SkAlphaType::kOpaque_SkAlphaType
143+
? kBGR_101010x_XR_SkColorType
144+
: kRGBA_F16_SkColorType;
145145
image_info =
146146
base_image_info.makeWH(decode_size.width(), decode_size.height())
147147
.makeColorType(color_type)

lib/ui/painting/image_decoder_unittests.cc

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ TEST_F(ImageDecoderFixtureTest, ImpellerWideGamutDisplayP3) {
309309
ImageDecoderImpeller::DecompressTexture(
310310
descriptor.get(), SkISize::Make(100, 100), {100, 100},
311311
/*supports_wide_gamut=*/true);
312+
ASSERT_TRUE(wide_bitmap);
312313
ASSERT_EQ(wide_bitmap->colorType(), kRGBA_F16_SkColorType);
313314
ASSERT_TRUE(wide_bitmap->colorSpace()->isSRGB());
314315
const SkPixmap& wide_pixmap = wide_bitmap->pixmap();
@@ -333,6 +334,60 @@ TEST_F(ImageDecoderFixtureTest, ImpellerWideGamutDisplayP3) {
333334
#endif // IMPELLER_SUPPORTS_RENDERING
334335
}
335336

337+
namespace {
338+
float DecodeBGR10(uint32_t x) {
339+
const float max = 1.25098f;
340+
const float min = -0.752941f;
341+
const float intercept = min;
342+
const float slope = (max - min) / 1024.0f;
343+
return (x * slope) + intercept;
344+
}
345+
} // namespace
346+
347+
TEST_F(ImageDecoderFixtureTest, ImpellerWideGamutDisplayP3Opaque) {
348+
auto data = OpenFixtureAsSkData("DisplayP3Logo.jpg");
349+
auto image = SkImage::MakeFromEncoded(data);
350+
ASSERT_TRUE(image != nullptr);
351+
ASSERT_EQ(SkISize::Make(100, 100), image->dimensions());
352+
353+
ImageGeneratorRegistry registry;
354+
std::shared_ptr<ImageGenerator> generator =
355+
registry.CreateCompatibleGenerator(data);
356+
ASSERT_TRUE(generator);
357+
358+
auto descriptor = fml::MakeRefCounted<ImageDescriptor>(std::move(data),
359+
std::move(generator));
360+
361+
#if IMPELLER_SUPPORTS_RENDERING
362+
std::shared_ptr<SkBitmap> wide_bitmap =
363+
ImageDecoderImpeller::DecompressTexture(
364+
descriptor.get(), SkISize::Make(100, 100), {100, 100},
365+
/*supports_wide_gamut=*/true);
366+
ASSERT_TRUE(wide_bitmap);
367+
ASSERT_EQ(wide_bitmap->colorType(), kBGR_101010x_XR_SkColorType);
368+
ASSERT_TRUE(wide_bitmap->colorSpace()->isSRGB());
369+
const SkPixmap& wide_pixmap = wide_bitmap->pixmap();
370+
const uint32_t* pixel_ptr = static_cast<const uint32_t*>(wide_pixmap.addr());
371+
bool found_deep_red = false;
372+
for (int i = 0; i < wide_pixmap.width() * wide_pixmap.height(); ++i) {
373+
uint32_t pixel = *pixel_ptr++;
374+
float blue = DecodeBGR10((pixel >> 0) & 0x3ff);
375+
float green = DecodeBGR10((pixel >> 10) & 0x3ff);
376+
float red = DecodeBGR10((pixel >> 20) & 0x3ff);
377+
if (fabsf(red - 1.0931f) < 0.01f && fabsf(green - -0.2268f) < 0.01f &&
378+
fabsf(blue - -0.1501f) < 0.01f) {
379+
found_deep_red = true;
380+
break;
381+
}
382+
}
383+
ASSERT_TRUE(found_deep_red);
384+
std::shared_ptr<SkBitmap> bitmap = ImageDecoderImpeller::DecompressTexture(
385+
descriptor.get(), SkISize::Make(100, 100), {100, 100},
386+
/*supports_wide_gamut=*/false);
387+
ASSERT_EQ(bitmap->colorType(), kRGBA_8888_SkColorType);
388+
#endif // IMPELLER_SUPPORTS_RENDERING
389+
}
390+
336391
TEST_F(ImageDecoderFixtureTest, ImpellerNonWideGamut) {
337392
auto data = OpenFixtureAsSkData("Horizontal.jpg");
338393
auto image = SkImage::MakeFromEncoded(data);

0 commit comments

Comments
 (0)