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

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

[SurfaceFinger] Adds auto color mode support in SurfaceFlinger.

This patch adds auto color mode support in SurfaceFlinger. For Auto Awesome
Color milestone 1, we expect the hardware composer is capable of handling P3
layers, meaning if the hardware composer is given P3 layers, it will strech the
color from Display P3 to the pannel native color space. Hardware composer may
punt sRGB layers back to SurfaceFlinger, in this case, we fall back to
RenderEngine. We will set the destination data space to Display P3 when the
layers are mixed color spaces, and set the destination data space as SRGB if
they are all SRGB layers.

BUG: 73824924
BUG: 73825729
Test: Build
Change-Id: I577841b14de0cfe8c29f8aa30bee8621c5d72976
parent 61f77509
Loading
Loading
Loading
Loading
+20 −6
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ namespace android {
using namespace android::hardware::configstore;
using namespace android::hardware::configstore::V1_0;
using android::ui::ColorMode;
using android::ui::RenderIntent;

/*
 * Initialize the display to the specified values.
@@ -75,8 +76,8 @@ DisplayDevice::DisplayDevice(
        std::unique_ptr<RE::Surface> renderSurface,
        int displayWidth,
        int displayHeight,
        bool supportWideColor,
        bool supportHdr,
        bool hasWideColorGamut,
        bool hasHdr10,
        int initialPowerMode)
    : lastCompositionHadVisibleLayers(false),
      mFlinger(flinger),
@@ -98,8 +99,8 @@ DisplayDevice::DisplayDevice(
      mActiveConfig(0),
      mActiveColorMode(ColorMode::NATIVE),
      mColorTransform(HAL_COLOR_TRANSFORM_IDENTITY),
      mDisplayHasWideColor(supportWideColor),
      mDisplayHasHdr(supportHdr)
      mHasWideColorGamut(hasWideColorGamut),
      mHasHdr10(hasHdr10)
{
    // clang-format on

@@ -268,6 +269,14 @@ ColorMode DisplayDevice::getActiveColorMode() const {
    return mActiveColorMode;
}

RenderIntent DisplayDevice::getActiveRenderIntent() const {
    return mActiveRenderIntent;
}

void DisplayDevice::setActiveRenderIntent(RenderIntent renderIntent) {
    mActiveRenderIntent = renderIntent;
}

void DisplayDevice::setColorTransform(const mat4& transform) {
    const bool isIdentity = (transform == mat4());
    mColorTransform =
@@ -279,10 +288,15 @@ android_color_transform_t DisplayDevice::getColorTransform() const {
}

void DisplayDevice::setCompositionDataSpace(ui::Dataspace dataspace) {
    mCompositionDataSpace = dataspace;
    ANativeWindow* const window = mNativeWindow.get();
    native_window_set_buffers_data_space(window, static_cast<android_dataspace>(dataspace));
}

ui::Dataspace DisplayDevice::getCompositionDataSpace() const {
    return mCompositionDataSpace;
}

// ----------------------------------------------------------------------------

void DisplayDevice::setLayerStack(uint32_t stack) {
@@ -464,8 +478,8 @@ void DisplayDevice::dump(String8& result) const {
                        tr[0][1], tr[1][1], tr[2][1], tr[0][2], tr[1][2], tr[2][2]);
    auto const surface = static_cast<Surface*>(window);
    ui::Dataspace dataspace = surface->getBuffersDataSpace();
    result.appendFormat("   wideColor=%d, hdr=%d, colorMode=%s, dataspace: %s (%d)\n",
                        mDisplayHasWideColor, mDisplayHasHdr,
    result.appendFormat("   wideColorGamut=%d, hdr10=%d, colorMode=%s, dataspace: %s (%d)\n",
                        mHasWideColorGamut, mHasHdr10,
                        decodeColorMode(mActiveColorMode).c_str(),
                        dataspaceDetails(static_cast<android_dataspace>(dataspace)).c_str(), dataspace);

+15 −9
Original line number Diff line number Diff line
@@ -84,8 +84,8 @@ public:
            std::unique_ptr<RE::Surface> renderSurface,
            int displayWidth,
            int displayHeight,
            bool supportWideColor,
            bool supportHdr,
            bool hasWideColorGamut,
            bool hasHdr10,
            int initialPowerMode);
    // clang-format on

@@ -135,8 +135,8 @@ public:
    // machine happy without actually queueing a buffer if nothing has changed
    status_t beginFrame(bool mustRecompose) const;
    status_t prepareFrame(HWComposer& hwc);
    bool getWideColorSupport() const { return mDisplayHasWideColor; }
    bool getHdrSupport() const { return mDisplayHasHdr; }
    bool hasWideColorGamut() const { return mHasWideColorGamut; }
    bool hasHdr10() const { return mHasHdr10; }

    void swapBuffers(HWComposer& hwc) const;

@@ -165,9 +165,12 @@ public:

    ui::ColorMode getActiveColorMode() const;
    void setActiveColorMode(ui::ColorMode mode);
    ui::RenderIntent getActiveRenderIntent() const;
    void setActiveRenderIntent(ui::RenderIntent renderIntent);
    android_color_transform_t getColorTransform() const;
    void setColorTransform(const mat4& transform);
    void setCompositionDataSpace(ui::Dataspace dataspace);
    ui::Dataspace getCompositionDataSpace() const;

    /* ------------------------------------------------------------------------
     * Display active config management.
@@ -241,14 +244,17 @@ private:
    int mActiveConfig;
    // current active color mode
    ui::ColorMode mActiveColorMode;
    // Current active render intent.
    ui::RenderIntent mActiveRenderIntent;
    ui::Dataspace mCompositionDataSpace;
    // Current color transform
    android_color_transform_t mColorTransform;

    // Need to know if display is wide-color capable or not.
    // Initialized by SurfaceFlinger when the DisplayDevice is created.
    // Fed to RenderEngine during composition.
    bool mDisplayHasWideColor;
    bool mDisplayHasHdr;
    bool mHasWideColorGamut;
    bool mHasHdr10;
};

struct DisplayDeviceState {
@@ -290,9 +296,9 @@ public:
    bool isSecure() const override { return mDevice->isSecure(); }
    bool needsFiltering() const override { return mDevice->needsFiltering(); }
    Rect getSourceCrop() const override { return mSourceCrop; }
    bool getWideColorSupport() const override { return mDevice->getWideColorSupport(); }
    ui::ColorMode getActiveColorMode() const override {
        return mDevice->getActiveColorMode();
    bool getWideColorSupport() const override { return mDevice->hasWideColorGamut(); }
    ui::Dataspace getDataSpace() const override {
        return mDevice->getCompositionDataSpace();
    }

private:
+15 −0
Original line number Diff line number Diff line
@@ -1643,6 +1643,21 @@ bool Layer::detachChildren() {
    return true;
}

// Dataspace::UNKNOWN, Dataspace::SRGB, Dataspace::SRGB_LINEAR,
// Dataspace::V0_SRGB and Dataspace::V0_SRGB_LINEAR are considered legacy
// SRGB data space for now.
// Note that Dataspace::V0_SRGB and Dataspace::V0_SRGB_LINEAR are not legacy
// data space, however since framework doesn't distinguish them out of legacy
// SRGB, we have to treat them as the same for now.
bool Layer::isLegacySrgbDataSpace() const {
    // TODO(lpy) b/77652630, need to figure out when UNKNOWN can be treated as SRGB.
    return mDrawingState.dataSpace == ui::Dataspace::UNKNOWN ||
        mDrawingState.dataSpace == ui::Dataspace::SRGB ||
        mDrawingState.dataSpace == ui::Dataspace::SRGB_LINEAR ||
        mDrawingState.dataSpace == ui::Dataspace::V0_SRGB ||
        mDrawingState.dataSpace == ui::Dataspace::V0_SRGB_LINEAR;
}

void Layer::setParent(const sp<Layer>& layer) {
    mCurrentParent = layer;
}
+7 −0
Original line number Diff line number Diff line
@@ -297,6 +297,13 @@ public:
    bool reparent(const sp<IBinder>& newParentHandle);
    bool detachChildren();

    // Before color management is introduced, contents on Android have to be
    // desaturated in order to match what they appears like visually.
    // With color management, these contents will appear desaturated, thus
    // needed to be saturated so that they match what they are designed for
    // visually. When returns true, legacy SRGB data space is passed to HWC.
    bool isLegacySrgbDataSpace() const;

    // If we have received a new buffer this frame, we will pass its surface
    // damage down to hardware composer. Otherwise, we must send a region with
    // one empty rect.
+2 −3
Original line number Diff line number Diff line
@@ -25,15 +25,14 @@ public:
    virtual bool isSecure() const = 0;
    virtual bool needsFiltering() const = 0;
    virtual Rect getSourceCrop() const = 0;
    virtual bool getWideColorSupport() const = 0;
    virtual ui::Dataspace getDataSpace() const = 0;

    virtual void render(std::function<void()> drawLayers) { drawLayers(); }

    int getReqHeight() const { return mReqHeight; };
    int getReqWidth() const { return mReqWidth; };
    Transform::orientation_flags getRotationFlags() const { return mRotationFlags; };
    virtual bool getWideColorSupport() const = 0;
    virtual ui::ColorMode getActiveColorMode() const = 0;

    status_t updateDimensions();

private:
Loading