Merge "[SurfaceFlinger] Decouple color management from wide color display property."
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index efaeaa2..ee69b83 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -23,6 +23,7 @@
"android.hardware.configstore-utils",
"android.hardware.configstore@1.0",
"android.hardware.configstore@1.1",
+ "android.hardware.configstore@1.2",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.composer@2.1",
"android.hardware.graphics.composer@2.2",
@@ -175,6 +176,7 @@
"android.frameworks.displayservice@1.0",
"android.hardware.configstore-utils",
"android.hardware.configstore@1.0",
+ "android.hardware.configstore@1.2",
"android.hardware.graphics.allocator@2.0",
"libbinder",
"libcutils",
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
index 2186594..136d12f 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.cpp
@@ -114,7 +114,7 @@
: RenderEngine(featureFlags),
mVpWidth(0),
mVpHeight(0),
- mPlatformHasWideColor((featureFlags & WIDE_COLOR_SUPPORT) != 0) {
+ mUseColorManagement(featureFlags & USE_COLOR_MANAGEMENT) {
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &mMaxTextureSize);
glGetIntegerv(GL_MAX_VIEWPORT_DIMS, mMaxViewportDims);
@@ -132,7 +132,7 @@
// mColorBlindnessCorrection = M;
- if (mPlatformHasWideColor) {
+ if (mUseColorManagement) {
ColorSpace srgb(ColorSpace::sRGB());
ColorSpace displayP3(ColorSpace::DisplayP3());
ColorSpace bt2020(ColorSpace::BT2020());
@@ -322,8 +322,8 @@
// BT2020 data space, in that case, the output data space is set to be
// BT2020_HLG or BT2020_PQ respectively. In GPU fall back we need
// to respect this and convert non-HDR content to HDR format.
- if (mPlatformHasWideColor) {
- Description wideColorState = mState;
+ if (mUseColorManagement) {
+ Description managedState = mState;
Dataspace inputStandard = static_cast<Dataspace>(mDataSpace & Dataspace::STANDARD_MASK);
Dataspace inputTransfer = static_cast<Dataspace>(mDataSpace & Dataspace::TRANSFER_MASK);
Dataspace outputStandard = static_cast<Dataspace>(mOutputDataSpace &
@@ -336,26 +336,26 @@
// The supported input color spaces are standard RGB, Display P3 and BT2020.
switch (inputStandard) {
case Dataspace::STANDARD_DCI_P3:
- wideColorState.setInputTransformMatrix(mDisplayP3ToXyz);
+ managedState.setInputTransformMatrix(mDisplayP3ToXyz);
break;
case Dataspace::STANDARD_BT2020:
- wideColorState.setInputTransformMatrix(mBt2020ToXyz);
+ managedState.setInputTransformMatrix(mBt2020ToXyz);
break;
default:
- wideColorState.setInputTransformMatrix(mSrgbToXyz);
+ managedState.setInputTransformMatrix(mSrgbToXyz);
break;
}
// The supported output color spaces are BT2020, Display P3 and standard RGB.
switch (outputStandard) {
case Dataspace::STANDARD_BT2020:
- wideColorState.setOutputTransformMatrix(mXyzToBt2020);
+ managedState.setOutputTransformMatrix(mXyzToBt2020);
break;
case Dataspace::STANDARD_DCI_P3:
- wideColorState.setOutputTransformMatrix(mXyzToDisplayP3);
+ managedState.setOutputTransformMatrix(mXyzToDisplayP3);
break;
default:
- wideColorState.setOutputTransformMatrix(mXyzToSrgb);
+ managedState.setOutputTransformMatrix(mXyzToSrgb);
break;
}
} else if (inputStandard != outputStandard) {
@@ -370,9 +370,9 @@
// - sRGB
// - Display P3
if (outputStandard == Dataspace::STANDARD_BT709) {
- wideColorState.setOutputTransformMatrix(mDisplayP3ToSrgb);
+ managedState.setOutputTransformMatrix(mDisplayP3ToSrgb);
} else if (outputStandard == Dataspace::STANDARD_DCI_P3) {
- wideColorState.setOutputTransformMatrix(mSrgbToDisplayP3);
+ managedState.setOutputTransformMatrix(mSrgbToDisplayP3);
}
}
@@ -380,44 +380,44 @@
// - there is a color matrix that is not an identity matrix, or
// - there is an output transform matrix that is not an identity matrix, or
// - the input transfer function doesn't match the output transfer function.
- if (wideColorState.hasColorMatrix() || wideColorState.hasOutputTransformMatrix() ||
+ if (managedState.hasColorMatrix() || managedState.hasOutputTransformMatrix() ||
inputTransfer != outputTransfer) {
switch (inputTransfer) {
case Dataspace::TRANSFER_ST2084:
- wideColorState.setInputTransferFunction(Description::TransferFunction::ST2084);
+ managedState.setInputTransferFunction(Description::TransferFunction::ST2084);
break;
case Dataspace::TRANSFER_HLG:
- wideColorState.setInputTransferFunction(Description::TransferFunction::HLG);
+ managedState.setInputTransferFunction(Description::TransferFunction::HLG);
break;
case Dataspace::TRANSFER_LINEAR:
- wideColorState.setInputTransferFunction(Description::TransferFunction::LINEAR);
+ managedState.setInputTransferFunction(Description::TransferFunction::LINEAR);
break;
default:
- wideColorState.setInputTransferFunction(Description::TransferFunction::SRGB);
+ managedState.setInputTransferFunction(Description::TransferFunction::SRGB);
break;
}
switch (outputTransfer) {
case Dataspace::TRANSFER_ST2084:
- wideColorState.setOutputTransferFunction(Description::TransferFunction::ST2084);
+ managedState.setOutputTransferFunction(Description::TransferFunction::ST2084);
break;
case Dataspace::TRANSFER_HLG:
- wideColorState.setOutputTransferFunction(Description::TransferFunction::HLG);
+ managedState.setOutputTransferFunction(Description::TransferFunction::HLG);
break;
default:
- wideColorState.setOutputTransferFunction(Description::TransferFunction::SRGB);
+ managedState.setOutputTransferFunction(Description::TransferFunction::SRGB);
break;
}
}
- ProgramCache::getInstance().useProgram(wideColorState);
+ ProgramCache::getInstance().useProgram(managedState);
glDrawArrays(mesh.getPrimitive(), 0, mesh.getVertexCount());
if (outputDebugPPMs) {
- static uint64_t wideColorFrameCount = 0;
+ static uint64_t managedColorFrameCount = 0;
std::ostringstream out;
- out << "/data/texture_out" << wideColorFrameCount++;
+ out << "/data/texture_out" << managedColorFrameCount++;
writePPM(out.str().c_str(), mVpWidth, mVpHeight);
}
} else {
diff --git a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
index f682225..d8cb73b 100644
--- a/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/GLES20RenderEngine.h
@@ -94,8 +94,9 @@
// Current output dataspace of the render engine
ui::Dataspace mOutputDataSpace = ui::Dataspace::UNKNOWN;
- // Currently only supporting sRGB, BT2020 and DisplayP3 color spaces
- const bool mPlatformHasWideColor = false;
+ // Whether device supports color management, currently color management
+ // supports sRGB, DisplayP3 color spaces.
+ const bool mUseColorManagement = false;
mat4 mSrgbToDisplayP3;
mat4 mDisplayP3ToSrgb;
mat3 mSrgbToXyz;
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 9dc6858..a1d0561 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -82,7 +82,7 @@
ProgramCache::~ProgramCache() {}
-void ProgramCache::primeCache(bool hasWideColor) {
+void ProgramCache::primeCache(bool useColorManagement) {
uint32_t shaderCount = 0;
uint32_t keyMask = Key::BLEND_MASK | Key::OPACITY_MASK | Key::ALPHA_MASK | Key::TEXTURE_MASK;
// Prime the cache for all combinations of the above masks,
@@ -105,7 +105,7 @@
}
// Prime for sRGB->P3 conversion
- if (hasWideColor) {
+ if (useColorManagement) {
Key shaderKey;
shaderKey.set(Key::BLEND_MASK | Key::TEXTURE_MASK | Key::OUTPUT_TRANSFORM_MATRIX_MASK |
Key::INPUT_TF_MASK | Key::OUTPUT_TF_MASK,
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.h b/services/surfaceflinger/RenderEngine/ProgramCache.h
index 983e7ba..424633e 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.h
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.h
@@ -161,7 +161,7 @@
~ProgramCache();
// Generate shaders to populate the cache
- void primeCache(bool hasWideColor);
+ void primeCache(bool useColorManagement);
// useProgram lookup a suitable program in the cache or generates one
// if none can be found.
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.cpp b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
index 39f7e30..e5dbe2f 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.cpp
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.cpp
@@ -596,7 +596,7 @@
}
void RenderEngine::primeCache() const {
- ProgramCache::getInstance().primeCache(mFeatureFlags & WIDE_COLOR_SUPPORT);
+ ProgramCache::getInstance().primeCache(mFeatureFlags & USE_COLOR_MANAGEMENT);
}
// ---------------------------------------------------------------------------
diff --git a/services/surfaceflinger/RenderEngine/RenderEngine.h b/services/surfaceflinger/RenderEngine/RenderEngine.h
index 2ed2cc7..6213784 100644
--- a/services/surfaceflinger/RenderEngine/RenderEngine.h
+++ b/services/surfaceflinger/RenderEngine/RenderEngine.h
@@ -56,7 +56,7 @@
class RenderEngine {
public:
enum FeatureFlag {
- WIDE_COLOR_SUPPORT = 1 << 0 // Platform has a wide color display
+ USE_COLOR_MANAGEMENT = 1 << 0, // Device manages color
};
virtual ~RenderEngine() = 0;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index eeb74ec..0181664 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -93,6 +93,7 @@
#include <android/hardware/configstore/1.0/ISurfaceFlingerConfigs.h>
#include <android/hardware/configstore/1.1/ISurfaceFlingerConfigs.h>
+#include <android/hardware/configstore/1.2/ISurfaceFlingerConfigs.h>
#include <android/hardware/configstore/1.1/types.h>
#include <configstore/Utils.h>
@@ -176,6 +177,7 @@
int64_t SurfaceFlinger::maxFrameBufferAcquiredBuffers;
// TODO(courtneygo): Rename hasWideColorDisplay to clarify its actual meaning.
bool SurfaceFlinger::hasWideColorDisplay;
+bool SurfaceFlinger::useColorManagement;
std::string getHwcServiceName() {
@@ -302,6 +304,8 @@
hasWideColorDisplay =
getBool<ISurfaceFlingerConfigs, &ISurfaceFlingerConfigs::hasWideColorDisplay>(false);
+ useColorManagement =
+ getBool<V1_2::ISurfaceFlingerConfigs, &V1_2::ISurfaceFlingerConfigs::useColorManagement>(false);
V1_1::DisplayOrientation primaryDisplayOrientation =
getDisplayOrientation< V1_1::ISurfaceFlingerConfigs, &V1_1::ISurfaceFlingerConfigs::primaryDisplayOrientation>(
@@ -597,11 +601,10 @@
mVsyncModulator.setEventThreads(mSFEventThread.get(), mEventThread.get());
// Get a RenderEngine for the given display / config (can't fail)
+ int32_t renderEngineFeature = 0;
+ renderEngineFeature |= (useColorManagement ? RE::RenderEngine::USE_COLOR_MANAGEMENT : 0);
getBE().mRenderEngine =
- RE::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888,
- hasWideColorDisplay
- ? RE::RenderEngine::WIDE_COLOR_SUPPORT
- : 0);
+ RE::impl::RenderEngine::create(HAL_PIXEL_FORMAT_RGBA_8888, renderEngineFeature);
LOG_ALWAYS_FATAL_IF(getBE().mRenderEngine == nullptr, "couldn't create RenderEngine");
LOG_ALWAYS_FATAL_IF(mVrFlingerRequestsDisplay,
@@ -1556,7 +1559,7 @@
layer->setPerFrameData(display);
}
- if (hasWideColorDisplay) {
+ if (useColorManagement) {
ColorMode colorMode;
Dataspace dataSpace;
RenderIntent renderIntent;
@@ -2214,7 +2217,7 @@
HdrCapabilities hdrCapabilities;
int32_t supportedPerFrameMetadata = 0;
- if (hasWideColorDisplay && displayId >= 0) {
+ if (useColorManagement && displayId >= 0) {
std::vector<ColorMode> modes = getHwComposer().getColorModes(displayId);
for (ColorMode colorMode : modes) {
if (isWideColorMode(colorMode)) {
@@ -4152,7 +4155,8 @@
}
void SurfaceFlinger::dumpWideColorInfo(String8& result) const {
- result.appendFormat("hasWideColorDisplay: %d\n", hasWideColorDisplay);
+ result.appendFormat("Device has wide color display: %d\n", hasWideColorDisplay);
+ result.appendFormat("Device uses color management: %d\n", useColorManagement);
result.appendFormat("DisplayColorSetting: %s\n",
decodeDisplayColorSetting(mDisplayColorSetting).c_str());
@@ -4727,7 +4731,9 @@
repaintEverything();
return NO_ERROR;
}
- case 1024: { // Is wide color gamut rendering/color management supported?
+ // TODO(b/111505327): Find out whether the usage of 1024 can switch to 1030,
+ // deprecate 1024 if they can.
+ case 1024: { // Does device have wide color gamut display?
reply->writeBool(hasWideColorDisplay);
return NO_ERROR;
}
@@ -4759,7 +4765,7 @@
DisplayColorSetting setting = static_cast<DisplayColorSetting>(data.readInt32());
switch (setting) {
case DisplayColorSetting::MANAGED:
- reply->writeBool(hasWideColorDisplay);
+ reply->writeBool(useColorManagement);
break;
case DisplayColorSetting::UNMANAGED:
reply->writeBool(true);
@@ -4807,6 +4813,11 @@
ATRACE_INT("PeriodDivisor", divisor);
return NO_ERROR;
}
+ // Is device color managed?
+ case 1030: {
+ reply->writeBool(useColorManagement);
+ return NO_ERROR;
+ }
}
}
return err;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index c95356e..9ef0d59 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -283,13 +283,13 @@
// FramebufferSurface
static int64_t maxFrameBufferAcquiredBuffers;
- // Indicate if platform supports color management on its
- // wide-color display. This is typically found on devices
- // with wide gamut (e.g. Display-P3) display.
- // This also allows devices with wide-color displays that don't
- // want to support color management to disable color management.
+ // Indicate if a device has wide color gamut display. This is typically
+ // found on devices with wide color gamut (e.g. Display-P3) display.
static bool hasWideColorDisplay;
+ // Indicate if device wants color management on its display.
+ static bool useColorManagement;
+
static char const* getServiceName() ANDROID_API {
return "SurfaceFlinger";
}
diff --git a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
index b4aec36..1f57b8e 100644
--- a/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
+++ b/services/surfaceflinger/tests/unittests/DisplayTransactionTest.cpp
@@ -137,6 +137,7 @@
// Default to no wide color display support configured
mFlinger.mutableHasWideColorDisplay() = false;
+ mFlinger.mutableUseColorManagement() = false;
mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
// Default to using HWC virtual displays
@@ -455,6 +456,7 @@
static void injectConfigChange(DisplayTransactionTest* test) {
test->mFlinger.mutableHasWideColorDisplay() = false;
+ test->mFlinger.mutableUseColorManagement() = false;
test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
}
@@ -473,6 +475,7 @@
static constexpr bool WIDE_COLOR_SUPPORTED = true;
static void injectConfigChange(DisplayTransactionTest* test) {
+ test->mFlinger.mutableUseColorManagement() = true;
test->mFlinger.mutableHasWideColorDisplay() = true;
test->mFlinger.mutableDisplayColorSetting() = DisplayColorSetting::UNMANAGED;
}
@@ -501,6 +504,7 @@
static constexpr bool WIDE_COLOR_SUPPORTED = false;
static void injectConfigChange(DisplayTransactionTest* test) {
+ test->mFlinger.mutableUseColorManagement() = true;
test->mFlinger.mutableHasWideColorDisplay() = true;
}
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 9df4264..d8e7581 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -113,6 +113,7 @@
*/
auto& mutableHasWideColorDisplay() { return SurfaceFlinger::hasWideColorDisplay; }
+ auto& mutableUseColorManagement() { return SurfaceFlinger::useColorManagement; }
auto& mutableDisplayTokens() { return mFlinger->mDisplayTokens; }
auto& mutableCurrentState() { return mFlinger->mCurrentState; }