From 49f16e13f3e0c419d79c60dc2a32d0033c1b4761 Mon Sep 17 00:00:00 2001 From: Aaron Clarke Date: Thu, 9 Feb 2023 12:37:39 -0800 Subject: [PATCH] made opaque wide gamut images take up 32 bits per pixel --- lib/ui/BUILD.gn | 1 + lib/ui/fixtures/DisplayP3Logo.jpg | Bin 0 -> 4886 bytes lib/ui/painting/image_decoder_impeller.cc | 10 ++-- lib/ui/painting/image_decoder_unittests.cc | 55 +++++++++++++++++++++ 4 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 lib/ui/fixtures/DisplayP3Logo.jpg diff --git a/lib/ui/BUILD.gn b/lib/ui/BUILD.gn index 3f12eed206863..121375ada52b7 100644 --- a/lib/ui/BUILD.gn +++ b/lib/ui/BUILD.gn @@ -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", diff --git a/lib/ui/fixtures/DisplayP3Logo.jpg b/lib/ui/fixtures/DisplayP3Logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..ea6a104d4faee82957c43778d96c1dea9f10ffed GIT binary patch literal 4886 zcmeHKeNa@_6+dr3_*iXqaY?Br!*juifV<1`z2l;=yCBpJ%Zg}VtX*~=u)==$-opi^ zjg7>nq1LZx{ODvt05uUz2N9Gwjwad~Q;mW^6*Y}95^X`_M@1{n>%DJ*C8?yD{#(xO zefPKLp7XosoOgHTT<#+G1x(FK&rAn`09c4Vz+HnnLxsHvz-WX>00;mv5d=bn2=oDB zI*54;kVVWG#bzP~1V}#ymk)N|-ml!fmmZ zQY=|W72BO!`JE%jeU&H}C4RSK-t~wI9Uu%xPhtu=ArlptsK7)8CMqydfr$$I|5d=(%Ti9%z(_xh`X8me!hI=-$kgdpn9SMf znTrg3-!BNUxZP#g+2Leqb4D7u?B#sYzt7w7V;+l@ai^M0i!dIUG4{#B9=^SY3v)47 z|I_*nN$WCBI1V1ouIdd@`s|*GBsSFaqLm>uR8}|5qPs#g!X^*v#u#5BWHbs2;Y}D9 zdvOECg95#bdCetQ_x)1z%1kQ_dxe(JVvbdC-F$ z7;r-wSfCO}FhT4%_Hn$u4qV8(5@_UC3?;xKpH!s53>3nd-~=luAR1vcsL)X3IwM~s z54(r!7wywk{|!KUjN`Z?K3&!^faXL1NxM%Mkpv)}1n^0_+d^A-I(%Id6roGpy}bZG zdKqBadE`^T6ve9fbz*WFfcSHcyZ<79|C<0$H*wsPI*xl<49)v(B68rfF1WG0$gVw1aAcR7JNGKNL14;Y}t%FD^4w@O0 z>NhRN;xAt%Q@^_T-GH#P=8uBS9p8k<7Sd}2CC~jN`en z-uK?$ccA59Yulm2?H_)8;^d$HeCm_apLSm8>hAgL#Y?@{zP$d`jlQpM-unC9d-osw z^Wos5$N$245g_!Yg`VEbzLS>}?f;b7Xkxy+E`tvJ!?6g^S11smS0zLu z@)Ke4^Y`P$e^>%|3B)pKR5(OJU{9e?jJ}fs`~pVTelXy!q8q$F*9(({1UgJYDa?nV z6?HXHj~8*UMo<$`>m9Z&(WUK;^9MTDuuCG^iZ#s})?cV=Nx3?EFyrx%{q9v`l*1sS z)p_zM`jVUlpC#8dT#Trz0q*>F$aaSRF6j2k@XdwG&n~<7X=hvCkT}=MOz++r{MNPT z{ZZ7u$jF7)?FB1)PQBCg&W?;3S(o$Lj$2W`qPb9&<54+x|#?f z*D+?7ksYj~JM62Uv7@J{w&_qHWiMb}SrQx^zUtuq)>7-ap6oMWzu)a>ERgD(72QL| z;YqnO)Og~4)9$E#kGY}tgTYWk?3s;EPTa5OpYOLM_ANivv4C7(GiNfNWT$U?iN_RI zT~+=wYqRWUK?5sJc6g`mfp62YMY;acJ)BhX!f3e=+WO>D=9D|JDy8n|M?=W^u;V%6f4Mvt} literal 0 HcmV?d00001 diff --git a/lib/ui/painting/image_decoder_impeller.cc b/lib/ui/painting/image_decoder_impeller.cc index 73e0888108776..dd112f792684c 100644 --- a/lib/ui/painting/image_decoder_impeller.cc +++ b/lib/ui/painting/image_decoder_impeller.cc @@ -96,6 +96,8 @@ static std::optional 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; } @@ -137,11 +139,9 @@ std::shared_ptr 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) diff --git a/lib/ui/painting/image_decoder_unittests.cc b/lib/ui/painting/image_decoder_unittests.cc index 947239321cf22..587ae4dfbaaa6 100644 --- a/lib/ui/painting/image_decoder_unittests.cc +++ b/lib/ui/painting/image_decoder_unittests.cc @@ -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(); @@ -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 generator = + registry.CreateCompatibleGenerator(data); + ASSERT_TRUE(generator); + + auto descriptor = fml::MakeRefCounted(std::move(data), + std::move(generator)); + +#if IMPELLER_SUPPORTS_RENDERING + std::shared_ptr 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(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 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);