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

Commit 8e50e696 authored by Chia-I Wu's avatar Chia-I Wu
Browse files

surfaceflinger: switch RE color matrices lazily

Client composition in doComposeSurfaces normally needs to handle

  N sRGB layers, when in ColorMode::SRGB
  N P3 layer and then M sRGB layers, when in ColorMode::DISPLAY_P3

Constantly switching and restoring RE color matrices when handling
sRGB layers is less efficient.  Do the switches lazily.

We don't really care about the current RE color matrix when
doComposeSurfaces is called, and we already assume it to be
identity.  Update RenderEngine::setupColorTransform not to return
the current color matrix.

Bug: 78891890
Test: night light under Boosted/Enhanced and sRGB/P3
Change-Id: I3b785c2a05f2e1679e486ab2497fc0e13993a791
parent 5e9a43e0
Loading
Loading
Loading
Loading
+1 −3
Original line number Diff line number Diff line
@@ -259,10 +259,8 @@ void GLES20RenderEngine::setupLayerBlackedOut() {
    mState.setTexture(texture);
}

mat4 GLES20RenderEngine::setupColorTransform(const mat4& colorTransform) {
    mat4 oldTransform = mState.getColorMatrix();
void GLES20RenderEngine::setupColorTransform(const mat4& colorTransform) {
    mState.setColorMatrix(colorTransform);
    return oldTransform;
}

void GLES20RenderEngine::disableTexturing() {
+1 −1
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ protected:
    virtual void setupLayerTexturing(const Texture& texture);
    virtual void setupLayerBlackedOut();
    virtual void setupFillWithColor(float r, float g, float b, float a);
    virtual mat4 setupColorTransform(const mat4& colorTransform);
    virtual void setupColorTransform(const mat4& colorTransform);
    virtual void disableTexturing();
    virtual void disableBlending();

+2 −2
Original line number Diff line number Diff line
@@ -112,7 +112,7 @@ public:
    virtual void setupLayerBlackedOut() = 0;
    virtual void setupFillWithColor(float r, float g, float b, float a) = 0;

    virtual mat4 setupColorTransform(const mat4& /* colorTransform */) = 0;
    virtual void setupColorTransform(const mat4& /* colorTransform */) = 0;

    virtual void disableTexturing() = 0;
    virtual void disableBlending() = 0;
@@ -224,7 +224,7 @@ public:

    void checkErrors() const override;

    mat4 setupColorTransform(const mat4& /* colorTransform */) override { return mat4(); }
    void setupColorTransform(const mat4& /* colorTransform */) override {}

    // internal to RenderEngine
    EGLDisplay getEGLDisplay() const;
+37 −24
Original line number Diff line number Diff line
@@ -2873,18 +2873,13 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& displayDev
    const DisplayRenderArea renderArea(displayDevice);
    const auto hwcId = displayDevice->getHwcDisplayId();
    const bool hasClientComposition = getBE().mHwc->hasClientComposition(hwcId);
    const bool hasDeviceComposition = getBE().mHwc->hasDeviceComposition(hwcId);
    const bool skipClientColorTransform = getBE().mHwc->hasCapability(
        HWC2::Capability::SkipClientColorTransform);
    ATRACE_INT("hasClientComposition", hasClientComposition);

    mat4 oldColorMatrix;
    mat4 legacySrgbSaturationMatrix = mLegacySrgbSaturationMatrix;
    const bool applyColorMatrix = !hasDeviceComposition && !skipClientColorTransform;
    if (applyColorMatrix) {
        oldColorMatrix = getRenderEngine().setupColorTransform(mDrawingState.colorMatrix);
        legacySrgbSaturationMatrix = mDrawingState.colorMatrix * legacySrgbSaturationMatrix;
    }
    bool applyColorMatrix = false;
    bool applyLegacyColorMatrix = false;
    mat4 colorMatrix;
    mat4 legacyColorMatrix;
    const mat4* currentColorMatrix = nullptr;

    if (hasClientComposition) {
        ALOGV("hasClientComposition");
@@ -2897,6 +2892,24 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& displayDev
        getBE().mRenderEngine->setDisplayMaxLuminance(
                displayDevice->getHdrCapabilities().getDesiredMaxLuminance());

        const bool hasDeviceComposition = getBE().mHwc->hasDeviceComposition(hwcId);
        const bool skipClientColorTransform = getBE().mHwc->hasCapability(
            HWC2::Capability::SkipClientColorTransform);

        applyColorMatrix = !hasDeviceComposition && !skipClientColorTransform;
        if (applyColorMatrix) {
            colorMatrix = mDrawingState.colorMatrix;
        }

        applyLegacyColorMatrix = mDisplayColorSetting == DisplayColorSetting::ENHANCED;
        if (applyLegacyColorMatrix) {
            if (applyColorMatrix) {
                legacyColorMatrix = colorMatrix * mLegacySrgbSaturationMatrix;
            } else {
                legacyColorMatrix = mLegacySrgbSaturationMatrix;
            }
        }

        if (!displayDevice->makeCurrent()) {
            ALOGW("DisplayDevice::makeCurrent failed. Aborting surface composition for display %s",
                  displayDevice->getDisplayName().string());
@@ -2982,20 +2995,20 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& displayDev
                    break;
                }
                case HWC2::Composition::Client: {
                    // Only apply saturation matrix layer that is legacy SRGB dataspace
                    // when auto color mode is on.
                    bool restore = false;
                    mat4 savedMatrix;
                    if (mDisplayColorSetting == DisplayColorSetting::ENHANCED &&
                        layer->isLegacyDataSpace()) {
                        savedMatrix =
                            getRenderEngine().setupColorTransform(legacySrgbSaturationMatrix);
                        restore = true;
                    // switch color matrices lazily
                    if (layer->isLegacyDataSpace()) {
                        if (applyLegacyColorMatrix && currentColorMatrix != &legacyColorMatrix) {
                            getRenderEngine().setupColorTransform(legacyColorMatrix);
                            currentColorMatrix = &legacyColorMatrix;
                        }
                    } else {
                        if (applyColorMatrix && currentColorMatrix != &colorMatrix) {
                            getRenderEngine().setupColorTransform(colorMatrix);
                            currentColorMatrix = &colorMatrix;
                        }
                    layer->draw(renderArea, clip);
                    if (restore) {
                        getRenderEngine().setupColorTransform(savedMatrix);
                    }

                    layer->draw(renderArea, clip);
                    break;
                }
                default:
@@ -3007,8 +3020,8 @@ bool SurfaceFlinger::doComposeSurfaces(const sp<const DisplayDevice>& displayDev
        firstLayer = false;
    }

    if (applyColorMatrix) {
        getRenderEngine().setupColorTransform(oldColorMatrix);
    if (applyColorMatrix || applyLegacyColorMatrix) {
        getRenderEngine().setupColorTransform(mat4());
    }

    // disable scissor at the end of the frame
+1 −1
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ public:
    MOCK_METHOD1(setupLayerTexturing, void(const Texture&));
    MOCK_METHOD0(setupLayerBlackedOut, void());
    MOCK_METHOD4(setupFillWithColor, void(float, float, float, float));
    MOCK_METHOD1(setupColorTransform, mat4(const mat4&));
    MOCK_METHOD1(setupColorTransform, void(const mat4&));
    MOCK_METHOD0(disableTexturing, void());
    MOCK_METHOD0(disableBlending, void());
    MOCK_METHOD1(setSourceY410BT2020, void(bool));