surfaceflinger: Add support for secondary color matrix

* Add a new binder transaction for applying a secondary color matrix
   using RenderEngine. This stacks with the primary color matrix
   (if set for a11y) to enable GPU-based display calibration.

Change-Id: I766455bfb5212e2dcc8ad0cb8ebdddbda87af732
This commit is contained in:
Steve Kondik 2016-04-12 13:14:26 -07:00
parent 31d9cccf23
commit 2b4df0ba7c
2 changed files with 33 additions and 3 deletions

View File

@ -156,6 +156,7 @@ SurfaceFlinger::SurfaceFlinger()
mHWVsyncAvailable(false), mHWVsyncAvailable(false),
mDaltonize(false), mDaltonize(false),
mHasColorMatrix(false), mHasColorMatrix(false),
mHasSecondaryColorMatrix(false),
mHasPoweredOff(false), mHasPoweredOff(false),
mFrameBuckets(), mFrameBuckets(),
mTotalTime(0), mTotalTime(0),
@ -1193,7 +1194,7 @@ void SurfaceFlinger::setUpHWComposer() {
for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) { for (size_t i=0 ; cur!=end && i<count ; ++i, ++cur) {
const sp<Layer>& layer(currentLayers[i]); const sp<Layer>& layer(currentLayers[i]);
layer->setGeometry(hw, *cur); layer->setGeometry(hw, *cur);
if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix) { if (mDebugDisableHWC || mDebugRegion || mDaltonize || mHasColorMatrix || mHasSecondaryColorMatrix) {
cur->setSkip(true); cur->setSkip(true);
} }
} }
@ -1958,11 +1959,14 @@ void SurfaceFlinger::doDisplayComposition(const sp<const DisplayDevice>& hw,
} }
} }
if (CC_LIKELY(!mDaltonize && !mHasColorMatrix)) { if (CC_LIKELY(!mDaltonize && !mHasColorMatrix && !mHasSecondaryColorMatrix)) {
if (!doComposeSurfaces(hw, dirtyRegion)) return; if (!doComposeSurfaces(hw, dirtyRegion)) return;
} else { } else {
RenderEngine& engine(getRenderEngine()); RenderEngine& engine(getRenderEngine());
mat4 colorMatrix = mColorMatrix; mat4 colorMatrix = mColorMatrix;
if (mHasSecondaryColorMatrix) {
colorMatrix = mHasColorMatrix ? (colorMatrix * mSecondaryColorMatrix) : mSecondaryColorMatrix;
}
if (mDaltonize) { if (mDaltonize) {
colorMatrix = colorMatrix * mDaltonizer(); colorMatrix = colorMatrix * mDaltonizer();
} }
@ -2948,7 +2952,8 @@ void SurfaceFlinger::dumpAllLocked(const Vector<String16>& args, size_t& index,
result.appendFormat(" h/w composer %s and %s\n", result.appendFormat(" h/w composer %s and %s\n",
hwc.initCheck()==NO_ERROR ? "present" : "not present", hwc.initCheck()==NO_ERROR ? "present" : "not present",
(mDebugDisableHWC || mDebugRegion || mDaltonize (mDebugDisableHWC || mDebugRegion || mDaltonize
|| mHasColorMatrix) ? "disabled" : "enabled"); || mHasColorMatrix
|| mHasSecondaryColorMatrix) ? "disabled" : "enabled");
hwc.dump(result); hwc.dump(result);
/* /*
@ -3158,6 +3163,28 @@ status_t SurfaceFlinger::onTransact(
mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n)); mSFEventThread->setPhaseOffset(static_cast<nsecs_t>(n));
return NO_ERROR; return NO_ERROR;
} }
case 1030: {
// apply a secondary color matrix
// this will be combined with any other transformations
n = data.readInt32();
mHasSecondaryColorMatrix = 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 < 4; i++) {
for (size_t j = 0; j < 4; j++) {
mSecondaryColorMatrix[i][j] = data.readFloat();
}
}
} else {
mSecondaryColorMatrix = mat4();
}
invalidateHwcGeometry();
repaintEverything();
return NO_ERROR;
}
} }
} }
return err; return err;

View File

@ -553,6 +553,9 @@ private:
mat4 mColorMatrix; mat4 mColorMatrix;
bool mHasColorMatrix; bool mHasColorMatrix;
mat4 mSecondaryColorMatrix;
bool mHasSecondaryColorMatrix;
// Static screen stats // Static screen stats
bool mHasPoweredOff; bool mHasPoweredOff;
static const size_t NUM_BUCKETS = 8; // < 1-7, 7+ static const size_t NUM_BUCKETS = 8; // < 1-7, 7+