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

Commit dda07d9b authored by Alec Mouri's avatar Alec Mouri
Browse files

Allow SurfaceFlinger to treat 170M as sRGB.

Introduce a debug sysprop, defaulted to false, to allow for rewriting
the transfer function to sRGB when set to true.

This is due to several considerations:

1. SurfaceFlinger has not color managed SMPTE 170M properly ever since
   color management was introduced in Android O, and was only fixed in
   Android 13. This means that some camera -> encoding -> storage ->
   playback flows may be incorrectly calibrated on some devices since
   SMPTE 170M was reinterpreted as sRGB for a long time.
2. BT. 1886 recommends a reference EOTF of gamma 2.4 with tuneable
   parameters to approximate a CRT on a non-CRT display. Because the
   framework doesn't support BT. 1886 and it's too late to add support,
   casting as sRGB is probably okay for now and matches old behavior.
3. Typical Rec. 709 content is graded assuming a dim surround, but phone
   displays are used in a wide range of viewing environments, which
   means that viewing Rec. 709 content in a bright environment may
   appear to have lower contrast. Decoding as sRGB will push the dark
   codes into lower luminance levels, which will improve contrast in
   those scenarios. Note that it's better to adjust contrast based on
   the ambient viewing environment, but again it's too late for Android
   13 to improve the color pipeline in the GPU.

Bug: 229442032
Test: Photos playback after recording a video
Change-Id: I64fc8f2ea77f8e595333de36fb9da2979d8316ca
parent f18ac6ca
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -267,6 +267,9 @@ public:
    // Enables predicting composition strategy to run client composition earlier
    virtual void setPredictCompositionStrategy(bool) = 0;

    // Enables overriding the 170M trasnfer function as sRGB
    virtual void setTreat170mAsSrgb(bool) = 0;

protected:
    virtual void setDisplayColorProfile(std::unique_ptr<DisplayColorProfile>) = 0;
    virtual void setRenderSurface(std::unique_ptr<RenderSurface>) = 0;
+1 −0
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ public:
    void cacheClientCompositionRequests(uint32_t) override;
    bool canPredictCompositionStrategy(const CompositionRefreshArgs&) override;
    void setPredictCompositionStrategy(bool) override;
    void setTreat170mAsSrgb(bool) override;

    // Testing
    const ReleasedLayers& getReleasedLayersForTest() const;
+2 −0
Original line number Diff line number Diff line
@@ -162,6 +162,8 @@ struct OutputCompositionState {
    CompositionStrategyPredictionState strategyPrediction =
            CompositionStrategyPredictionState::DISABLED;

    bool treat170mAsSrgb = false;

    // Debugging
    void dump(std::string& result) const;
};
+1 −0
Original line number Diff line number Diff line
@@ -132,6 +132,7 @@ public:
    MOCK_METHOD1(cacheClientCompositionRequests, void(uint32_t));
    MOCK_METHOD1(canPredictCompositionStrategy, bool(const CompositionRefreshArgs&));
    MOCK_METHOD1(setPredictCompositionStrategy, void(bool));
    MOCK_METHOD1(setTreat170mAsSrgb, void(bool));
};

} // namespace android::compositionengine::mock
+4 −0
Original line number Diff line number Diff line
@@ -1488,6 +1488,10 @@ void Output::setPredictCompositionStrategy(bool predict) {
    }
}

void Output::setTreat170mAsSrgb(bool enable) {
    editState().treat170mAsSrgb = enable;
}

bool Output::canPredictCompositionStrategy(const CompositionRefreshArgs& refreshArgs) {
    if (!getState().isEnabled || !mHwComposerAsyncWorker) {
        ALOGV("canPredictCompositionStrategy disabled");
Loading