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

Made opaque wide gamut images take up 32 bits per pixel #39691

Merged
merged 1 commit into from
Feb 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/ui/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ if (enable_unittests) {
fixtures = [
"fixtures/DashInNooglerHat.jpg",
"fixtures/DashInNooglerHat%20WithSpace.jpg",
"fixtures/DisplayP3Logo.jpg",
"fixtures/DisplayP3Logo.png",
"fixtures/Horizontal.jpg",
"fixtures/Horizontal.png",
Expand Down
Binary file added lib/ui/fixtures/DisplayP3Logo.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 5 additions & 5 deletions lib/ui/painting/image_decoder_impeller.cc
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,8 @@ static std::optional<impeller::PixelFormat> ToPixelFormat(SkColorType type) {
return impeller::PixelFormat::kR8G8B8A8UNormInt;
case kRGBA_F16_SkColorType:
return impeller::PixelFormat::kR16G16B16A16Float;
case kBGR_101010x_XR_SkColorType:
return impeller::PixelFormat::kB10G10R10XR;
default:
return std::nullopt;
}
Expand Down Expand Up @@ -137,11 +139,9 @@ std::shared_ptr<SkBitmap> ImageDecoderImpeller::DecompressTexture(
ChooseCompatibleAlphaType(base_image_info.alphaType());
SkImageInfo image_info;
if (is_wide_gamut) {
// TODO(gaaclarke): Branch on alpha_type so it's 32bpp for opaque images.
// I tried using kBGRA_1010102_SkColorType and
// kBGR_101010x_SkColorType but Skia fails to decode the
// image that way.
SkColorType color_type = kRGBA_F16_SkColorType;
SkColorType color_type = alpha_type == SkAlphaType::kOpaque_SkAlphaType
? kBGR_101010x_XR_SkColorType
: kRGBA_F16_SkColorType;
image_info =
base_image_info.makeWH(decode_size.width(), decode_size.height())
.makeColorType(color_type)
Expand Down
55 changes: 55 additions & 0 deletions lib/ui/painting/image_decoder_unittests.cc
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,7 @@ TEST_F(ImageDecoderFixtureTest, ImpellerWideGamutDisplayP3) {
ImageDecoderImpeller::DecompressTexture(
descriptor.get(), SkISize::Make(100, 100), {100, 100},
/*supports_wide_gamut=*/true);
ASSERT_TRUE(wide_bitmap);
ASSERT_EQ(wide_bitmap->colorType(), kRGBA_F16_SkColorType);
ASSERT_TRUE(wide_bitmap->colorSpace()->isSRGB());
const SkPixmap& wide_pixmap = wide_bitmap->pixmap();
Expand All @@ -333,6 +334,60 @@ TEST_F(ImageDecoderFixtureTest, ImpellerWideGamutDisplayP3) {
#endif // IMPELLER_SUPPORTS_RENDERING
}

namespace {
float DecodeBGR10(uint32_t x) {
const float max = 1.25098f;
const float min = -0.752941f;
const float intercept = min;
const float slope = (max - min) / 1024.0f;
return (x * slope) + intercept;
}
} // namespace

TEST_F(ImageDecoderFixtureTest, ImpellerWideGamutDisplayP3Opaque) {
auto data = OpenFixtureAsSkData("DisplayP3Logo.jpg");
auto image = SkImage::MakeFromEncoded(data);
ASSERT_TRUE(image != nullptr);
ASSERT_EQ(SkISize::Make(100, 100), image->dimensions());

ImageGeneratorRegistry registry;
std::shared_ptr<ImageGenerator> generator =
registry.CreateCompatibleGenerator(data);
ASSERT_TRUE(generator);

auto descriptor = fml::MakeRefCounted<ImageDescriptor>(std::move(data),
std::move(generator));

#if IMPELLER_SUPPORTS_RENDERING
std::shared_ptr<SkBitmap> wide_bitmap =
ImageDecoderImpeller::DecompressTexture(
descriptor.get(), SkISize::Make(100, 100), {100, 100},
/*supports_wide_gamut=*/true);
ASSERT_TRUE(wide_bitmap);
ASSERT_EQ(wide_bitmap->colorType(), kBGR_101010x_XR_SkColorType);
ASSERT_TRUE(wide_bitmap->colorSpace()->isSRGB());
const SkPixmap& wide_pixmap = wide_bitmap->pixmap();
const uint32_t* pixel_ptr = static_cast<const uint32_t*>(wide_pixmap.addr());
bool found_deep_red = false;
for (int i = 0; i < wide_pixmap.width() * wide_pixmap.height(); ++i) {
uint32_t pixel = *pixel_ptr++;
float blue = DecodeBGR10((pixel >> 0) & 0x3ff);
float green = DecodeBGR10((pixel >> 10) & 0x3ff);
float red = DecodeBGR10((pixel >> 20) & 0x3ff);
if (fabsf(red - 1.0931f) < 0.01f && fabsf(green - -0.2268f) < 0.01f &&
fabsf(blue - -0.1501f) < 0.01f) {
found_deep_red = true;
break;
}
}
ASSERT_TRUE(found_deep_red);
std::shared_ptr<SkBitmap> bitmap = ImageDecoderImpeller::DecompressTexture(
descriptor.get(), SkISize::Make(100, 100), {100, 100},
/*supports_wide_gamut=*/false);
ASSERT_EQ(bitmap->colorType(), kRGBA_8888_SkColorType);
#endif // IMPELLER_SUPPORTS_RENDERING
}

TEST_F(ImageDecoderFixtureTest, ImpellerNonWideGamut) {
auto data = OpenFixtureAsSkData("Horizontal.jpg");
auto image = SkImage::MakeFromEncoded(data);
Expand Down