Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0147a17a authored by Romain Guy's avatar Romain Guy
Browse files

Add saturation boost feature to SurfaceFlinger

Bug: 62238038
Test: adb shell service call SurfaceFlinger 1022 f 1.5

The saturation boost will be set by framework to increase
the visual appeal of the sRGB mode. It simply modifies the
color transform matrix based on the supplied value (from
0.0 for black and white to 2.0 for 100% extra saturation).

Change-Id: I9832fbe0361acacc8b17300c37c006792c6c1618
parent a9638736
Loading
Loading
Loading
Loading
+29 −4
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <stdint.h>
#include <sys/types.h>
#include <algorithm>
#include <errno.h>
#include <math.h>
#include <mutex>
@@ -1675,9 +1676,25 @@ void SurfaceFlinger::rebuildLayerStacks() {
    }
}

mat4 SurfaceFlinger::computeSaturationMatrix() const {
    if (mSaturation == 1.0f) {
        return mat4();
    }

    // Rec.709 luma coefficients
    float3 luminance{0.213f, 0.715f, 0.072f};
    luminance *= 1.0f - mSaturation;
    return mat4(
        vec4{luminance.r + mSaturation, luminance.r, luminance.r, 0.0f},
        vec4{luminance.g, luminance.g + mSaturation, luminance.g, 0.0f},
        vec4{luminance.b, luminance.b, luminance.b + mSaturation, 0.0f},
        vec4{0.0f, 0.0f, 0.0f, 1.0f}
    );
}

// pickColorMode translates a given dataspace into the best available color mode.
// Currently only support sRGB and Display-P3.
android_color_mode SurfaceFlinger::pickColorMode(android_dataspace dataSpace) {
android_color_mode SurfaceFlinger::pickColorMode(android_dataspace dataSpace) const {
    switch (dataSpace) {
        // treat Unknown as regular SRGB buffer, since that's what the rest of the
        // system expects.
@@ -1700,7 +1717,8 @@ android_color_mode SurfaceFlinger::pickColorMode(android_dataspace dataSpace) {
    }
}

android_dataspace SurfaceFlinger::bestTargetDataSpace(android_dataspace a, android_dataspace b) {
android_dataspace SurfaceFlinger::bestTargetDataSpace(
        android_dataspace a, android_dataspace b) const {
    // Only support sRGB and Display-P3 right now.
    if (a == HAL_DATASPACE_DISPLAY_P3 || b == HAL_DATASPACE_DISPLAY_P3) {
        return HAL_DATASPACE_DISPLAY_P3;
@@ -1779,7 +1797,7 @@ void SurfaceFlinger::setUpHWComposer() {
    }


    mat4 colorMatrix = mColorMatrix * mDaltonizer();
    mat4 colorMatrix = mColorMatrix * computeSaturationMatrix() * mDaltonizer();

    // Set the per-frame data
    for (size_t displayId = 0; displayId < mDisplays.size(); ++displayId) {
@@ -3900,7 +3918,7 @@ status_t SurfaceFlinger::onTransact(
                // apply a color matrix
                n = data.readInt32();
                if (n) {
                    // color matrix is sent as a row-major mat4 matrix
                    // 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();
@@ -3960,6 +3978,13 @@ status_t SurfaceFlinger::onTransact(
                mUseHwcVirtualDisplays = !n;
                return NO_ERROR;
            }
            case 1022: { // Set saturation boost
                mSaturation = std::max(0.0f, std::min(data.readFloat(), 2.0f));

                invalidateHwcGeometry();
                repaintEverything();
                return NO_ERROR;
            }
        }
    }
    return err;
+7 −3
Original line number Diff line number Diff line
@@ -511,8 +511,10 @@ private:

    // Given a dataSpace, returns the appropriate color_mode to use
    // to display that dataSpace.
    android_color_mode pickColorMode(android_dataspace dataSpace);
    android_dataspace bestTargetDataSpace(android_dataspace a, android_dataspace b);
    android_color_mode pickColorMode(android_dataspace dataSpace) const;
    android_dataspace bestTargetDataSpace(android_dataspace a, android_dataspace b) const;

    mat4 computeSaturationMatrix() const;

    void setUpHWComposer();
    void doComposition();
@@ -747,6 +749,8 @@ private:
    std::atomic<bool> mVrFlingerRequestsDisplay;
    static bool useVrFlinger;
#endif

    float mSaturation = 1.0f;
};
}; // namespace android