Loading services/surfaceflinger/SurfaceFlinger.cpp +46 −36 Original line number Diff line number Diff line Loading @@ -244,7 +244,6 @@ SurfaceFlinger::SurfaceFlinger(SurfaceFlinger::SkipInitializationTag) mPrimaryDispSync("PrimaryDispSync"), mPrimaryHWVsyncEnabled(false), mHWVsyncAvailable(false), mHasColorMatrix(false), mHasPoweredOff(false), mNumLayers(0), mVrFlingerRequestsDisplay(false), Loading Loading @@ -723,10 +722,13 @@ void SurfaceFlinger::init() { } void SurfaceFlinger::readPersistentProperties() { Mutex::Autolock _l(mStateLock); char value[PROPERTY_VALUE_MAX]; property_get("persist.sys.sf.color_saturation", value, "1.0"); mGlobalSaturationFactor = atof(value); updateColorMatrixLocked(); ALOGV("Saturation is set to %.2f", mGlobalSaturationFactor); property_get("persist.sys.sf.native_mode", value, "0"); Loading Loading @@ -1868,22 +1870,6 @@ void SurfaceFlinger::rebuildLayerStacks() { } } mat4 SurfaceFlinger::computeSaturationMatrix() const { if (mGlobalSaturationFactor == 1.0f) { return mat4(); } // Rec.709 luma coefficients float3 luminance{0.213f, 0.715f, 0.072f}; luminance *= 1.0f - mGlobalSaturationFactor; return mat4( vec4{luminance.r + mGlobalSaturationFactor, luminance.r, luminance.r, 0.0f}, vec4{luminance.g, luminance.g + mGlobalSaturationFactor, luminance.g, 0.0f}, vec4{luminance.b, luminance.b, luminance.b + mGlobalSaturationFactor, 0.0f}, vec4{0.0f, 0.0f, 0.0f, 1.0f} ); } // Returns a dataspace that fits all visible layers. The returned dataspace // can only be one of // Loading Loading @@ -2009,9 +1995,6 @@ void SurfaceFlinger::setUpHWComposer() { } } mat4 colorMatrix = mColorMatrix * computeSaturationMatrix() * mDaltonizer(); // Set the per-frame data for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { auto& displayDevice = mDisplays[displayId]; Loading @@ -2020,9 +2003,9 @@ void SurfaceFlinger::setUpHWComposer() { if (hwcId < 0) { continue; } if (colorMatrix != mPreviousColorMatrix) { displayDevice->setColorTransform(colorMatrix); status_t result = getBE().mHwc->setColorTransform(hwcId, colorMatrix); if (mDrawingState.colorMatrixChanged) { displayDevice->setColorTransform(mDrawingState.colorMatrix); status_t result = getBE().mHwc->setColorTransform(hwcId, mDrawingState.colorMatrix); ALOGE_IF(result != NO_ERROR, "Failed to set color transform on " "display %zd: %d", displayId, result); } Loading Loading @@ -2055,7 +2038,7 @@ void SurfaceFlinger::setUpHWComposer() { } } mPreviousColorMatrix = colorMatrix; mDrawingState.colorMatrixChanged = false; for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { auto& displayDevice = mDisplays[displayId]; Loading Loading @@ -2644,6 +2627,9 @@ void SurfaceFlinger::commitTransaction() mAnimCompositionPending = mAnimTransactionPending; mDrawingState = mCurrentState; // clear the "changed" flags in current state mCurrentState.colorMatrixChanged = false; mDrawingState.traverseInZOrder([](Layer* layer) { layer->commitChildList(); }); Loading Loading @@ -2896,9 +2882,8 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& displayDev mat4 legacySrgbSaturationMatrix = mLegacySrgbSaturationMatrix; const bool applyColorMatrix = !hasDeviceComposition && !skipClientColorTransform; if (applyColorMatrix) { mat4 colorMatrix = mColorMatrix * computeSaturationMatrix() * mDaltonizer(); oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix); legacySrgbSaturationMatrix = colorMatrix * legacySrgbSaturationMatrix; oldColorMatrix = getRenderEngine().setupColorTransform(mDrawingState.colorMatrix); legacySrgbSaturationMatrix = mDrawingState.colorMatrix * legacySrgbSaturationMatrix; } if (hasClientComposition) { Loading Loading @@ -4363,6 +4348,30 @@ bool SurfaceFlinger::startDdmConnection() return true; } void SurfaceFlinger::updateColorMatrixLocked() { mat4 colorMatrix; if (mGlobalSaturationFactor != 1.0f) { // Rec.709 luma coefficients float3 luminance{0.213f, 0.715f, 0.072f}; luminance *= 1.0f - mGlobalSaturationFactor; mat4 saturationMatrix = mat4( vec4{luminance.r + mGlobalSaturationFactor, luminance.r, luminance.r, 0.0f}, vec4{luminance.g, luminance.g + mGlobalSaturationFactor, luminance.g, 0.0f}, vec4{luminance.b, luminance.b, luminance.b + mGlobalSaturationFactor, 0.0f}, vec4{0.0f, 0.0f, 0.0f, 1.0f} ); colorMatrix = mClientColorMatrix * saturationMatrix * mDaltonizer(); } else { colorMatrix = mClientColorMatrix * mDaltonizer(); } if (mCurrentState.colorMatrix != colorMatrix) { mCurrentState.colorMatrix = colorMatrix; mCurrentState.colorMatrixChanged = true; setTransactionFlags(eTransactionNeeded); } } status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { switch (code) { case CREATE_CONNECTION: Loading Loading @@ -4497,6 +4506,7 @@ status_t SurfaceFlinger::onTransact( return NO_ERROR; } case 1014: { Mutex::Autolock _l(mStateLock); // daltonize n = data.readInt32(); switch (n % 10) { Loading @@ -4518,33 +4528,33 @@ status_t SurfaceFlinger::onTransact( } else { mDaltonizer.setMode(ColorBlindnessMode::Simulation); } invalidateHwcGeometry(); repaintEverything(); updateColorMatrixLocked(); return NO_ERROR; } case 1015: { Mutex::Autolock _l(mStateLock); // apply a color matrix n = data.readInt32(); if (n) { // color matrix is sent as a column-major mat4 matrix for (size_t i = 0 ; i < 4; i++) { for (size_t j = 0; j < 4; j++) { mColorMatrix[i][j] = data.readFloat(); mClientColorMatrix[i][j] = data.readFloat(); } } } else { mColorMatrix = mat4(); mClientColorMatrix = mat4(); } // Check that supplied matrix's last row is {0,0,0,1} so we can avoid // the division by w in the fragment shader float4 lastRow(transpose(mColorMatrix)[3]); float4 lastRow(transpose(mClientColorMatrix)[3]); if (any(greaterThan(abs(lastRow - float4{0, 0, 0, 1}), float4{1e-4f}))) { ALOGE("The color transform's last row must be (0, 0, 0, 1)"); } invalidateHwcGeometry(); repaintEverything(); updateColorMatrixLocked(); return NO_ERROR; } // This is an experimental interface Loading Loading @@ -4587,10 +4597,10 @@ status_t SurfaceFlinger::onTransact( return NO_ERROR; } case 1022: { // Set saturation boost Mutex::Autolock _l(mStateLock); mGlobalSaturationFactor = std::max(0.0f, std::min(data.readFloat(), 2.0f)); invalidateHwcGeometry(); repaintEverything(); updateColorMatrixLocked(); return NO_ERROR; } case 1023: { // Set native mode Loading services/surfaceflinger/SurfaceFlinger.h +14 −10 Original line number Diff line number Diff line Loading @@ -373,6 +373,10 @@ private: // always uses the Drawing StateSet. layersSortedByZ = other.layersSortedByZ; displays = other.displays; colorMatrixChanged = other.colorMatrixChanged; if (colorMatrixChanged) { colorMatrix = other.colorMatrix; } return *this; } Loading @@ -380,6 +384,9 @@ private: LayerVector layersSortedByZ; DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays; bool colorMatrixChanged = true; mat4 colorMatrix; void traverseInZOrder(const LayerVector::Visitor& visitor) const; void traverseInReverseZOrder(const LayerVector::Visitor& visitor) const; }; Loading Loading @@ -653,8 +660,6 @@ private: ui::ColorMode* outMode, ui::Dataspace* outDataSpace) const; mat4 computeSaturationMatrix() const; void setUpHWComposer(); void doComposition(); void doDebugFlashRegions(); Loading Loading @@ -741,6 +746,8 @@ private: // Check to see if we should handoff to vr flinger. void updateVrFlinger(); void updateColorMatrixLocked(); /* ------------------------------------------------------------------------ * Attributes */ Loading @@ -754,6 +761,11 @@ private: bool mAnimTransactionPending; SortedVector< sp<Layer> > mLayersPendingRemoval; // global color transform states Daltonizer mDaltonizer; float mGlobalSaturationFactor = 1.0f; mat4 mClientColorMatrix; // Can't be unordered_set because wp<> isn't hashable std::set<wp<IBinder>> mGraphicBufferProducerList; size_t mMaxGraphicBufferProducerListSize = MAX_LAYERS; Loading Loading @@ -844,12 +856,6 @@ private: bool mInjectVSyncs; Daltonizer mDaltonizer; mat4 mPreviousColorMatrix; mat4 mColorMatrix; bool mHasColorMatrix; // Static screen stats bool mHasPoweredOff; Loading @@ -867,8 +873,6 @@ private: DisplayColorSetting mDisplayColorSetting = DisplayColorSetting::MANAGED; // Applied on sRGB layers when the render intent is non-colorimetric. mat4 mLegacySrgbSaturationMatrix; // Applied globally. float mGlobalSaturationFactor = 1.0f; bool mBuiltinDisplaySupportsEnhance = false; using CreateBufferQueueFunction = Loading Loading
services/surfaceflinger/SurfaceFlinger.cpp +46 −36 Original line number Diff line number Diff line Loading @@ -244,7 +244,6 @@ SurfaceFlinger::SurfaceFlinger(SurfaceFlinger::SkipInitializationTag) mPrimaryDispSync("PrimaryDispSync"), mPrimaryHWVsyncEnabled(false), mHWVsyncAvailable(false), mHasColorMatrix(false), mHasPoweredOff(false), mNumLayers(0), mVrFlingerRequestsDisplay(false), Loading Loading @@ -723,10 +722,13 @@ void SurfaceFlinger::init() { } void SurfaceFlinger::readPersistentProperties() { Mutex::Autolock _l(mStateLock); char value[PROPERTY_VALUE_MAX]; property_get("persist.sys.sf.color_saturation", value, "1.0"); mGlobalSaturationFactor = atof(value); updateColorMatrixLocked(); ALOGV("Saturation is set to %.2f", mGlobalSaturationFactor); property_get("persist.sys.sf.native_mode", value, "0"); Loading Loading @@ -1868,22 +1870,6 @@ void SurfaceFlinger::rebuildLayerStacks() { } } mat4 SurfaceFlinger::computeSaturationMatrix() const { if (mGlobalSaturationFactor == 1.0f) { return mat4(); } // Rec.709 luma coefficients float3 luminance{0.213f, 0.715f, 0.072f}; luminance *= 1.0f - mGlobalSaturationFactor; return mat4( vec4{luminance.r + mGlobalSaturationFactor, luminance.r, luminance.r, 0.0f}, vec4{luminance.g, luminance.g + mGlobalSaturationFactor, luminance.g, 0.0f}, vec4{luminance.b, luminance.b, luminance.b + mGlobalSaturationFactor, 0.0f}, vec4{0.0f, 0.0f, 0.0f, 1.0f} ); } // Returns a dataspace that fits all visible layers. The returned dataspace // can only be one of // Loading Loading @@ -2009,9 +1995,6 @@ void SurfaceFlinger::setUpHWComposer() { } } mat4 colorMatrix = mColorMatrix * computeSaturationMatrix() * mDaltonizer(); // Set the per-frame data for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { auto& displayDevice = mDisplays[displayId]; Loading @@ -2020,9 +2003,9 @@ void SurfaceFlinger::setUpHWComposer() { if (hwcId < 0) { continue; } if (colorMatrix != mPreviousColorMatrix) { displayDevice->setColorTransform(colorMatrix); status_t result = getBE().mHwc->setColorTransform(hwcId, colorMatrix); if (mDrawingState.colorMatrixChanged) { displayDevice->setColorTransform(mDrawingState.colorMatrix); status_t result = getBE().mHwc->setColorTransform(hwcId, mDrawingState.colorMatrix); ALOGE_IF(result != NO_ERROR, "Failed to set color transform on " "display %zd: %d", displayId, result); } Loading Loading @@ -2055,7 +2038,7 @@ void SurfaceFlinger::setUpHWComposer() { } } mPreviousColorMatrix = colorMatrix; mDrawingState.colorMatrixChanged = false; for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) { auto& displayDevice = mDisplays[displayId]; Loading Loading @@ -2644,6 +2627,9 @@ void SurfaceFlinger::commitTransaction() mAnimCompositionPending = mAnimTransactionPending; mDrawingState = mCurrentState; // clear the "changed" flags in current state mCurrentState.colorMatrixChanged = false; mDrawingState.traverseInZOrder([](Layer* layer) { layer->commitChildList(); }); Loading Loading @@ -2896,9 +2882,8 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& displayDev mat4 legacySrgbSaturationMatrix = mLegacySrgbSaturationMatrix; const bool applyColorMatrix = !hasDeviceComposition && !skipClientColorTransform; if (applyColorMatrix) { mat4 colorMatrix = mColorMatrix * computeSaturationMatrix() * mDaltonizer(); oldColorMatrix = getRenderEngine().setupColorTransform(colorMatrix); legacySrgbSaturationMatrix = colorMatrix * legacySrgbSaturationMatrix; oldColorMatrix = getRenderEngine().setupColorTransform(mDrawingState.colorMatrix); legacySrgbSaturationMatrix = mDrawingState.colorMatrix * legacySrgbSaturationMatrix; } if (hasClientComposition) { Loading Loading @@ -4363,6 +4348,30 @@ bool SurfaceFlinger::startDdmConnection() return true; } void SurfaceFlinger::updateColorMatrixLocked() { mat4 colorMatrix; if (mGlobalSaturationFactor != 1.0f) { // Rec.709 luma coefficients float3 luminance{0.213f, 0.715f, 0.072f}; luminance *= 1.0f - mGlobalSaturationFactor; mat4 saturationMatrix = mat4( vec4{luminance.r + mGlobalSaturationFactor, luminance.r, luminance.r, 0.0f}, vec4{luminance.g, luminance.g + mGlobalSaturationFactor, luminance.g, 0.0f}, vec4{luminance.b, luminance.b, luminance.b + mGlobalSaturationFactor, 0.0f}, vec4{0.0f, 0.0f, 0.0f, 1.0f} ); colorMatrix = mClientColorMatrix * saturationMatrix * mDaltonizer(); } else { colorMatrix = mClientColorMatrix * mDaltonizer(); } if (mCurrentState.colorMatrix != colorMatrix) { mCurrentState.colorMatrix = colorMatrix; mCurrentState.colorMatrixChanged = true; setTransactionFlags(eTransactionNeeded); } } status_t SurfaceFlinger::CheckTransactCodeCredentials(uint32_t code) { switch (code) { case CREATE_CONNECTION: Loading Loading @@ -4497,6 +4506,7 @@ status_t SurfaceFlinger::onTransact( return NO_ERROR; } case 1014: { Mutex::Autolock _l(mStateLock); // daltonize n = data.readInt32(); switch (n % 10) { Loading @@ -4518,33 +4528,33 @@ status_t SurfaceFlinger::onTransact( } else { mDaltonizer.setMode(ColorBlindnessMode::Simulation); } invalidateHwcGeometry(); repaintEverything(); updateColorMatrixLocked(); return NO_ERROR; } case 1015: { Mutex::Autolock _l(mStateLock); // apply a color matrix n = data.readInt32(); if (n) { // color matrix is sent as a column-major mat4 matrix for (size_t i = 0 ; i < 4; i++) { for (size_t j = 0; j < 4; j++) { mColorMatrix[i][j] = data.readFloat(); mClientColorMatrix[i][j] = data.readFloat(); } } } else { mColorMatrix = mat4(); mClientColorMatrix = mat4(); } // Check that supplied matrix's last row is {0,0,0,1} so we can avoid // the division by w in the fragment shader float4 lastRow(transpose(mColorMatrix)[3]); float4 lastRow(transpose(mClientColorMatrix)[3]); if (any(greaterThan(abs(lastRow - float4{0, 0, 0, 1}), float4{1e-4f}))) { ALOGE("The color transform's last row must be (0, 0, 0, 1)"); } invalidateHwcGeometry(); repaintEverything(); updateColorMatrixLocked(); return NO_ERROR; } // This is an experimental interface Loading Loading @@ -4587,10 +4597,10 @@ status_t SurfaceFlinger::onTransact( return NO_ERROR; } case 1022: { // Set saturation boost Mutex::Autolock _l(mStateLock); mGlobalSaturationFactor = std::max(0.0f, std::min(data.readFloat(), 2.0f)); invalidateHwcGeometry(); repaintEverything(); updateColorMatrixLocked(); return NO_ERROR; } case 1023: { // Set native mode Loading
services/surfaceflinger/SurfaceFlinger.h +14 −10 Original line number Diff line number Diff line Loading @@ -373,6 +373,10 @@ private: // always uses the Drawing StateSet. layersSortedByZ = other.layersSortedByZ; displays = other.displays; colorMatrixChanged = other.colorMatrixChanged; if (colorMatrixChanged) { colorMatrix = other.colorMatrix; } return *this; } Loading @@ -380,6 +384,9 @@ private: LayerVector layersSortedByZ; DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays; bool colorMatrixChanged = true; mat4 colorMatrix; void traverseInZOrder(const LayerVector::Visitor& visitor) const; void traverseInReverseZOrder(const LayerVector::Visitor& visitor) const; }; Loading Loading @@ -653,8 +660,6 @@ private: ui::ColorMode* outMode, ui::Dataspace* outDataSpace) const; mat4 computeSaturationMatrix() const; void setUpHWComposer(); void doComposition(); void doDebugFlashRegions(); Loading Loading @@ -741,6 +746,8 @@ private: // Check to see if we should handoff to vr flinger. void updateVrFlinger(); void updateColorMatrixLocked(); /* ------------------------------------------------------------------------ * Attributes */ Loading @@ -754,6 +761,11 @@ private: bool mAnimTransactionPending; SortedVector< sp<Layer> > mLayersPendingRemoval; // global color transform states Daltonizer mDaltonizer; float mGlobalSaturationFactor = 1.0f; mat4 mClientColorMatrix; // Can't be unordered_set because wp<> isn't hashable std::set<wp<IBinder>> mGraphicBufferProducerList; size_t mMaxGraphicBufferProducerListSize = MAX_LAYERS; Loading Loading @@ -844,12 +856,6 @@ private: bool mInjectVSyncs; Daltonizer mDaltonizer; mat4 mPreviousColorMatrix; mat4 mColorMatrix; bool mHasColorMatrix; // Static screen stats bool mHasPoweredOff; Loading @@ -867,8 +873,6 @@ private: DisplayColorSetting mDisplayColorSetting = DisplayColorSetting::MANAGED; // Applied on sRGB layers when the render intent is non-colorimetric. mat4 mLegacySrgbSaturationMatrix; // Applied globally. float mGlobalSaturationFactor = 1.0f; bool mBuiltinDisplaySupportsEnhance = false; using CreateBufferQueueFunction = Loading