Add API for pushing color transforms to SurfaceFlinger
BUG: 9057596
Change-Id: Iea0953366eac875b7968897a75472c25a137edb5
diff --git a/services/surfaceflinger/RenderEngine/ProgramCache.cpp b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
index 09b0ddc..38450c2 100644
--- a/services/surfaceflinger/RenderEngine/ProgramCache.cpp
+++ b/services/surfaceflinger/RenderEngine/ProgramCache.cpp
@@ -169,7 +169,7 @@
fs << "gl_FragColor.rgb = gl_FragColor.rgb/gl_FragColor.a;";
}
fs << "gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(2.2));";
- fs << "gl_FragColor = colorMatrix*gl_FragColor;";
+ fs << "gl_FragColor.rgb = mat3(colorMatrix) * gl_FragColor.rgb + vec3(colorMatrix[3]);";
fs << "gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / 2.2));";
if (!needs.isOpaque() && needs.isPremultiplied()) {
// and re-premultiply if needed after gamma correction
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index fa1ea09..d020871 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -114,7 +114,8 @@
mDebugInTransaction(0),
mLastTransactionTime(0),
mBootFinished(false),
- mDaltonize(false)
+ mDaltonize(false),
+ mHasColorMatrix(false)
{
ALOGI("SurfaceFlinger is starting");
@@ -869,7 +870,7 @@
for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
const sp<Layer>& layer(currentLayers[i]);
layer->setGeometry(hw, *cur);
- if (mDebugDisableHWC || mDebugRegion || mDaltonize) {
+ if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) {
cur->setSkip(true);
}
}
@@ -1483,11 +1484,17 @@
}
}
- if (CC_LIKELY(!mDaltonize)) {
+ if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) {
doComposeSurfaces(hw, dirtyRegion);
} else {
RenderEngine& engine(getRenderEngine());
- engine.beginGroup(mDaltonizer());
+ mat4 colorMatrix = mColorMatrix;
+ if (mDaltonize) {
+ // preserve last row of color matrix
+ colorMatrix = colorMatrix * mDaltonizer();
+ colorMatrix[3] = mColorMatrix[3];
+ }
+ engine.beginGroup(colorMatrix);
doComposeSurfaces(hw, dirtyRegion);
engine.endGroup();
}
@@ -2371,7 +2378,8 @@
colorizer.reset(result);
result.appendFormat(" h/w composer %s and %s\n",
hwc.initCheck()==NO_ERROR ? "present" : "not present",
- (mDebugDisableHWC || mDebugRegion || mDaltonize) ? "disabled" : "enabled");
+ (mDebugDisableHWC || mDebugRegion || mDaltonize
+ || mHasColorMatrix) ? "disabled" : "enabled");
hwc.dump(result);
/*
@@ -2534,8 +2542,33 @@
mDaltonize = n > 0;
invalidateHwcGeometry();
repaintEverything();
+ return NO_ERROR;
}
- return NO_ERROR;
+ case 1015: {
+ // apply a color matrix
+ n = data.readInt32();
+ mHasColorMatrix = n ? 1 : 0;
+ if (n) {
+ // color matrix is sent as mat3 matrix followed by vec3
+ // offset, then packed into a mat4 where the last row is
+ // the offset and extra values are 0
+ for (size_t i = 0 ; i < 3 ; i++) {
+ for (size_t j = 0; j < 3; j++) {
+ mColorMatrix[i][j] = data.readFloat();
+ }
+ mColorMatrix[i][3] = 0;
+ }
+ for (size_t i = 0; i < 3; i++) {
+ mColorMatrix[3][i] = data.readFloat();
+ }
+ mColorMatrix[3][3] = 0;
+ } else {
+ mColorMatrix = mat4();
+ }
+ invalidateHwcGeometry();
+ repaintEverything();
+ return NO_ERROR;
+ }
}
}
return err;
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 347e3e3..a0604bd 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -38,6 +38,7 @@
#include <binder/IMemory.h>
#include <ui/PixelFormat.h>
+#include <ui/mat4.h>
#include <gui/ISurfaceComposer.h>
#include <gui/ISurfaceComposerClient.h>
@@ -461,6 +462,9 @@
Daltonizer mDaltonizer;
bool mDaltonize;
+
+ mat4 mColorMatrix;
+ bool mHasColorMatrix;
};
// ---------------------------------------------------------------------------