[SurfaceFlinger] Implement per layer color transformation.
Previously we introduced a new composer HAL API to set color transform for per
layer and added the plumbing in SurfaceFlinger. This patch implements the
functionality and alwasy mark those layers to fall back to GPU composition
until composer 2.3 is implemented.
BUG: 111562338
Test: Build, boot, flash, tested by setting a greyscale matrix on Settings
Test: adb shell /data/nativetest/SurfaceFlinger_test/SurfaceFlinger_test
Change-Id: If8d5ed52bf920d8cc962602196fb1b0b6e2955da
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 9410cdb..c37b3b1 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1604,6 +1604,11 @@
layer->forceClientComposition(displayId);
}
+ // TODO(b/111562338) remove when composer 2.3 is shipped.
+ if (layer->hasColorTransform()) {
+ layer->forceClientComposition(displayId);
+ }
+
if (layer->getForceClientComposition(displayId)) {
ALOGV("[%s] Requesting Client composition", layer->getName().string());
layer->setCompositionType(displayId, HWC2::Composition::Client);
@@ -2141,6 +2146,8 @@
ALOGE_IF(error != HWC2::Error::None,
"[SF] Failed to set surface damage: %s (%d)",
to_string(error).c_str(), static_cast<int32_t>(error));
+
+ error = (compositionInfo.hwc.hwcLayer)->setColorTransform(compositionInfo.hwc.colorTransform);
}
void SurfaceFlinger::configureDeviceComposition(const CompositionInfo& compositionInfo) const
@@ -3091,6 +3098,7 @@
const bool hasClientComposition = getBE().mHwc->hasClientComposition(displayId);
ATRACE_INT("hasClientComposition", hasClientComposition);
+ mat4 colorMatrix;
bool applyColorMatrix = false;
bool needsEnhancedColorMatrix = false;
@@ -3109,7 +3117,7 @@
const bool skipClientColorTransform = getBE().mHwc->hasCapability(
HWC2::Capability::SkipClientColorTransform);
- mat4 colorMatrix;
+ // Compute the global color transform matrix.
applyColorMatrix = !hasDeviceComposition && !skipClientColorTransform;
if (applyColorMatrix) {
colorMatrix = mDrawingState.colorMatrix;
@@ -3125,8 +3133,6 @@
colorMatrix *= mEnhancedSaturationMatrix;
}
- getRenderEngine().setupColorTransform(colorMatrix);
-
if (!display->makeCurrent()) {
ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
display->getDisplayName().c_str());
@@ -3205,6 +3211,19 @@
break;
}
case HWC2::Composition::Client: {
+ if (layer->hasColorTransform()) {
+ mat4 tmpMatrix;
+ if (applyColorMatrix) {
+ tmpMatrix = mDrawingState.colorMatrix;
+ }
+ tmpMatrix *= layer->getColorTransform();
+ if (needsEnhancedColorMatrix) {
+ tmpMatrix *= mEnhancedSaturationMatrix;
+ }
+ getRenderEngine().setColorTransform(tmpMatrix);
+ } else {
+ getRenderEngine().setColorTransform(colorMatrix);
+ }
layer->draw(renderArea, clip);
break;
}
@@ -3217,9 +3236,8 @@
firstLayer = false;
}
- if (applyColorMatrix || needsEnhancedColorMatrix) {
- getRenderEngine().setupColorTransform(mat4());
- }
+ // Clear color transform matrix at the end of the frame.
+ getRenderEngine().setColorTransform(mat4());
// disable scissor at the end of the frame
getBE().mRenderEngine->disableScissor();
@@ -3596,6 +3614,11 @@
if (layer->setColor(s.color))
flags |= eTraversalNeeded;
}
+ if (what & layer_state_t::eColorTransformChanged) {
+ if (layer->setColorTransform(s.colorTransform)) {
+ flags |= eTraversalNeeded;
+ }
+ }
if (what & layer_state_t::eMatrixChanged) {
// TODO: b/109894387
//
@@ -5441,7 +5464,9 @@
engine.clearWithColor(0, 0, 0, alpha);
traverseLayers([&](Layer* layer) {
+ engine.setColorTransform(layer->getColorTransform());
layer->draw(renderArea, useIdentityTransform);
+ engine.setColorTransform(mat4());
});
}