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

Commit ed531a30 authored by Peiyong Lin's avatar Peiyong Lin
Browse files

[SurfaceFlinger] Query per display SkipClientColorTransform.

Previously the ability of SkipClientColorTransform is a global capability.
However, some hardwares can't apply it for all displays. Thus we introduced per
display capability. This patch plumbs it in SurfaceFlinger.

BUG: 69911676
Test: Build, flash and boot, verify with color blindness
Change-Id: Ibde2c5fe16b090bb07594702dd450ab863414589
parent 75cc36e4
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -1050,6 +1050,23 @@ Error Composer::getDisplayedContentSamplingAttributes(Display display, PixelForm
    return error;
}

Error Composer::getDisplayCapabilities(Display display,
                                       std::vector<DisplayCapability>* outCapabilities) {
    if (!mClient_2_3) {
        return Error::UNSUPPORTED;
    }
    Error error = kDefaultError;
    mClient_2_3->getDisplayCapabilities(display,
                                        [&](const auto& tmpError, const auto& tmpCapabilities) {
                                            error = tmpError;
                                            if (error != Error::NONE) {
                                                return;
                                            }
                                            *outCapabilities = tmpCapabilities;
                                        });
    return error;
}

CommandReader::~CommandReader()
{
    resetData();
+5 −5
Original line number Diff line number Diff line
@@ -48,24 +48,20 @@ namespace V2_3 = hardware::graphics::composer::V2_3;
using types::V1_0::ColorTransform;
using types::V1_0::Hdr;
using types::V1_0::Transform;

using types::V1_1::PixelFormat;
using types::V1_1::RenderIntent;
using types::V1_2::ColorMode;
using types::V1_2::Dataspace;

using V2_1::Config;
using V2_1::Display;
using V2_1::Error;
using V2_1::IComposerCallback;
using V2_1::Layer;

using V2_3::CommandReaderBase;
using V2_3::CommandWriterBase;

using V2_3::IComposer;
using V2_3::IComposerClient;

using DisplayCapability = IComposerClient::DisplayCapability;
using PerFrameMetadata = IComposerClient::PerFrameMetadata;
using PerFrameMetadataKey = IComposerClient::PerFrameMetadataKey;

@@ -196,6 +192,8 @@ public:
    virtual Error getDisplayedContentSamplingAttributes(Display display, PixelFormat* outFormat,
                                                        Dataspace* outDataspace,
                                                        uint8_t* outComponentMask) = 0;
    virtual Error getDisplayCapabilities(Display display,
                                         std::vector<DisplayCapability>* outCapabilities) = 0;
};

namespace impl {
@@ -398,6 +396,8 @@ public:
    Error getDisplayedContentSamplingAttributes(Display display, PixelFormat* outFormat,
                                                Dataspace* outDataspace,
                                                uint8_t* outComponentMask) override;
    Error getDisplayCapabilities(Display display,
                                 std::vector<DisplayCapability>* outCapabilities) override;

private:
    class CommandWriter : public CommandWriterBase {
+18 −9
Original line number Diff line number Diff line
@@ -234,6 +234,22 @@ Display::Display(android::Hwc2::Composer& composer, android::Hwc2::PowerAdvisor&
        mId(id),
        mIsConnected(false),
        mType(type) {
    std::vector<Hwc2::DisplayCapability> tmpCapabilities;
    auto error = static_cast<Error>(mComposer.getDisplayCapabilities(mId, &tmpCapabilities));
    if (error == Error::None) {
        for (auto capability : tmpCapabilities) {
            mDisplayCapabilities.emplace(static_cast<DisplayCapability>(capability));
        }
    } else if (error == Error::Unsupported) {
        if (capabilities.count(Capability::SkipClientColorTransform)) {
            mDisplayCapabilities.emplace(DisplayCapability::SkipClientColorTransform);
        }
        bool dozeSupport = false;
        error = static_cast<Error>(mComposer.getDozeSupport(mId, &dozeSupport));
        if (error == Error::None && dozeSupport) {
            mDisplayCapabilities.emplace(DisplayCapability::Doze);
        }
    }
    ALOGV("Created display %" PRIu64, id);
}

@@ -507,15 +523,8 @@ Error Display::getType(DisplayType* outType) const
    return Error::None;
}

Error Display::supportsDoze(bool* outSupport) const
{
    bool intSupport = false;
    auto intError = mComposer.getDozeSupport(mId, &intSupport);
    auto error = static_cast<Error>(intError);
    if (error != Error::None) {
        return error;
    }
    *outSupport = static_cast<bool>(intSupport);
Error Display::supportsDoze(bool* outSupport) const {
    *outSupport = mDisplayCapabilities.count(DisplayCapability::Doze) > 0;
    return Error::None;
}

+4 −0
Original line number Diff line number Diff line
@@ -272,6 +272,9 @@ public:
    hwc2_display_t getId() const { return mId; }
    bool isConnected() const { return mIsConnected; }
    void setConnected(bool connected);  // For use by Device only
    const std::unordered_set<DisplayCapability>& getCapabilities() const {
        return mDisplayCapabilities;
    };

private:
    int32_t getAttribute(hwc2_config_t configId, Attribute attribute);
@@ -298,6 +301,7 @@ private:
    DisplayType mType;
    std::unordered_map<hwc2_layer_t, std::unique_ptr<Layer>> mLayers;
    std::unordered_map<hwc2_config_t, std::shared_ptr<const Config>> mConfigs;
    std::unordered_set<DisplayCapability> mDisplayCapabilities;
};

// Convenience C++ class to access hwc2_device_t Layer functions directly.
+9 −0
Original line number Diff line number Diff line
@@ -95,6 +95,15 @@ bool HWComposer::hasCapability(HWC2::Capability capability) const
    return mHwcDevice->getCapabilities().count(capability) > 0;
}

bool HWComposer::hasDisplayCapability(const std::optional<DisplayId>& displayId,
                                      HWC2::DisplayCapability capability) const {
    if (!displayId) {
        return false;
    }
    RETURN_IF_INVALID_DISPLAY(*displayId, false);
    return mDisplayData.at(*displayId).hwcDisplay->getCapabilities().count(capability) > 0;
}

void HWComposer::validateChange(HWC2::Composition from, HWC2::Composition to) {
    bool valid = true;
    switch (from) {
Loading