Support fp16 in hwui for HDR
Picking sRGB primaries and transfer with extended range bit as the
dataspace, because that's straightforward for EGL.
Then, rather than dimming SDR content, we instead just render as normal
so that we take advantage of the full bit depth
Bug: 236745178
Test: builds
Change-Id: Ica39a2c81be508effb97a8850b0c8e272c10a084
diff --git a/libs/hwui/Android.bp b/libs/hwui/Android.bp
index da728f9..e9552cc 100644
--- a/libs/hwui/Android.bp
+++ b/libs/hwui/Android.bp
@@ -720,7 +720,6 @@
],
shared_libs: [
"libmemunreachable",
- "server_configurable_flags",
],
srcs: [
"tests/unit/main.cpp",
diff --git a/libs/hwui/DeviceInfo.h b/libs/hwui/DeviceInfo.h
index d4af087..a5a841e 100644
--- a/libs/hwui/DeviceInfo.h
+++ b/libs/hwui/DeviceInfo.h
@@ -23,6 +23,7 @@
#include <mutex>
+#include "Properties.h"
#include "utils/Macros.h"
namespace android {
@@ -60,7 +61,13 @@
static void setWideColorDataspace(ADataSpace dataspace);
static void setSupportFp16ForHdr(bool supportFp16ForHdr);
- static bool isSupportFp16ForHdr() { return get()->mSupportFp16ForHdr; };
+ static bool isSupportFp16ForHdr() {
+ if (!Properties::hdr10bitPlus) {
+ return false;
+ }
+
+ return get()->mSupportFp16ForHdr;
+ };
static void setSupportMixedColorSpaces(bool supportMixedColorSpaces);
static bool isSupportMixedColorSpaces() { return get()->mSupportMixedColorSpaces; };
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index ad600d0..6d5b593 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -38,6 +38,9 @@
constexpr bool clip_surfaceviews() {
return false;
}
+constexpr bool hdr_10bit_plus() {
+ return false;
+}
} // namespace hwui_flags
#endif
@@ -104,6 +107,7 @@
float Properties::maxHdrHeadroomOn8bit = 5.f; // TODO: Refine this number
bool Properties::clipSurfaceViews = false;
+bool Properties::hdr10bitPlus = false;
StretchEffectBehavior Properties::stretchEffectBehavior = StretchEffectBehavior::ShaderHWUI;
@@ -174,6 +178,7 @@
clipSurfaceViews =
base::GetBoolProperty("debug.hwui.clip_surfaceviews", hwui_flags::clip_surfaceviews());
+ hdr10bitPlus = hwui_flags::hdr_10bit_plus();
return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw);
}
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index bca57e9..55544df 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -326,6 +326,7 @@
static float maxHdrHeadroomOn8bit;
static bool clipSurfaceViews;
+ static bool hdr10bitPlus;
static StretchEffectBehavior getStretchEffectBehavior() {
return stretchEffectBehavior;
diff --git a/libs/hwui/pipeline/skia/SkiaPipeline.cpp b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
index e0f1f6e..326b6ed 100644
--- a/libs/hwui/pipeline/skia/SkiaPipeline.cpp
+++ b/libs/hwui/pipeline/skia/SkiaPipeline.cpp
@@ -650,9 +650,14 @@
mSurfaceColorSpace = DeviceInfo::get()->getWideColorSpace();
break;
case ColorMode::Hdr:
- mSurfaceColorType = SkColorType::kN32_SkColorType;
- mSurfaceColorSpace = SkColorSpace::MakeRGB(
- GetExtendedTransferFunction(mTargetSdrHdrRatio), SkNamedGamut::kDisplayP3);
+ if (DeviceInfo::get()->isSupportFp16ForHdr()) {
+ mSurfaceColorType = SkColorType::kRGBA_F16_SkColorType;
+ mSurfaceColorSpace = SkColorSpace::MakeSRGB();
+ } else {
+ mSurfaceColorType = SkColorType::kN32_SkColorType;
+ mSurfaceColorSpace = SkColorSpace::MakeRGB(
+ GetExtendedTransferFunction(mTargetSdrHdrRatio), SkNamedGamut::kDisplayP3);
+ }
break;
case ColorMode::Hdr10:
mSurfaceColorType = SkColorType::kRGBA_1010102_SkColorType;
@@ -669,8 +674,13 @@
void SkiaPipeline::setTargetSdrHdrRatio(float ratio) {
if (mColorMode == ColorMode::Hdr || mColorMode == ColorMode::Hdr10) {
mTargetSdrHdrRatio = ratio;
- mSurfaceColorSpace = SkColorSpace::MakeRGB(GetExtendedTransferFunction(mTargetSdrHdrRatio),
- SkNamedGamut::kDisplayP3);
+
+ if (mColorMode == ColorMode::Hdr && DeviceInfo::get()->isSupportFp16ForHdr()) {
+ mSurfaceColorSpace = SkColorSpace::MakeSRGB();
+ } else {
+ mSurfaceColorSpace = SkColorSpace::MakeRGB(
+ GetExtendedTransferFunction(mTargetSdrHdrRatio), SkNamedGamut::kDisplayP3);
+ }
} else {
mTargetSdrHdrRatio = 1.f;
}
diff --git a/libs/hwui/renderthread/EglManager.cpp b/libs/hwui/renderthread/EglManager.cpp
index 94f35fd..c3415dd 100644
--- a/libs/hwui/renderthread/EglManager.cpp
+++ b/libs/hwui/renderthread/EglManager.cpp
@@ -438,22 +438,32 @@
colorMode = ColorMode::Default;
}
- if (DeviceInfo::get()->getWideColorType() == kRGBA_F16_SkColorType) {
+ // TODO: maybe we want to get rid of the WCG check if overlay properties just works?
+ const bool canUseFp16 = DeviceInfo::get()->isSupportFp16ForHdr() ||
+ DeviceInfo::get()->getWideColorType() == kRGBA_F16_SkColorType;
+
+ if (canUseFp16) {
if (mEglConfigF16 == EGL_NO_CONFIG_KHR) {
colorMode = ColorMode::Default;
} else {
config = mEglConfigF16;
}
}
+
if (EglExtensions.glColorSpace) {
attribs[0] = EGL_GL_COLORSPACE_KHR;
switch (colorMode) {
case ColorMode::Default:
attribs[1] = EGL_GL_COLORSPACE_LINEAR_KHR;
break;
+ case ColorMode::Hdr:
+ if (canUseFp16) {
+ attribs[1] = EGL_GL_COLORSPACE_SCRGB_EXT;
+ break;
+ // No fp16 support so fallthrough to HDR10
+ }
// We don't have an EGL colorspace for extended range P3 that's used for HDR
// So override it after configuring the EGL context
- case ColorMode::Hdr:
case ColorMode::Hdr10:
overrideWindowDataSpaceForHdr = true;
attribs[1] = EGL_GL_COLORSPACE_DISPLAY_P3_PASSTHROUGH_EXT;