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

Commit 88ce0fa5 authored by Marin Shalamanov's avatar Marin Shalamanov Committed by Android (Google) Code Review
Browse files

Merge changes I8cb45020,I8787dcca

* changes:
  SF: Remove display config functions from HWC2
  SF: Clean up Scheduler::registerLayer
parents 2416f131 3ea1d605
Loading
Loading
Loading
Loading
+5 −8
Original line number Diff line number Diff line
@@ -87,20 +87,17 @@ public:
    MOCK_METHOD2(setVsyncEnabled, void(PhysicalDisplayId, hal::Vsync));
    MOCK_CONST_METHOD1(getRefreshTimestamp, nsecs_t(PhysicalDisplayId));
    MOCK_CONST_METHOD1(isConnected, bool(PhysicalDisplayId));
    MOCK_CONST_METHOD1(
            getConfigs,
            std::vector<std::shared_ptr<const HWC2::Display::Config>>(PhysicalDisplayId));
    MOCK_CONST_METHOD1(getActiveConfig,
                       std::shared_ptr<const HWC2::Display::Config>(PhysicalDisplayId));
    MOCK_CONST_METHOD1(getActiveConfigIndex, int(PhysicalDisplayId));
    MOCK_CONST_METHOD1(getModes, DisplayModes(PhysicalDisplayId));
    MOCK_CONST_METHOD1(getActiveMode, DisplayModePtr(PhysicalDisplayId));
    MOCK_CONST_METHOD1(getColorModes, std::vector<ui::ColorMode>(PhysicalDisplayId));
    MOCK_METHOD3(setActiveColorMode, status_t(PhysicalDisplayId, ui::ColorMode, ui::RenderIntent));
    MOCK_CONST_METHOD0(isUsingVrComposer, bool());
    MOCK_CONST_METHOD1(getDisplayConnectionType, DisplayConnectionType(PhysicalDisplayId));
    MOCK_CONST_METHOD1(isVsyncPeriodSwitchSupported, bool(PhysicalDisplayId));
    MOCK_CONST_METHOD1(getDisplayVsyncPeriod, nsecs_t(PhysicalDisplayId));
    MOCK_METHOD4(setActiveConfigWithConstraints,
                 status_t(PhysicalDisplayId, size_t, const hal::VsyncPeriodChangeConstraints&,
    MOCK_METHOD4(setActiveModeWithConstraints,
                 status_t(PhysicalDisplayId, HwcConfigIndexType,
                          const hal::VsyncPeriodChangeConstraints&,
                          hal::VsyncPeriodChangeTimeline*));
    MOCK_METHOD2(setAutoLowLatencyMode, status_t(PhysicalDisplayId, bool));
    MOCK_METHOD2(getSupportedContentTypes,
+1 −1
Original line number Diff line number Diff line
@@ -210,7 +210,7 @@ void DisplayDevice::dump(std::string& result) const {
    result.append("   ");
    StringAppendF(&result, "powerMode=%s (%d), ", to_string(mPowerMode).c_str(),
                  static_cast<int32_t>(mPowerMode));
    StringAppendF(&result, "activeConfig=%d, ", mActiveConfig.value());
    StringAppendF(&result, "activeConfig=%zu, ", mActiveConfig.value());
    StringAppendF(&result, "deviceProductInfo=");
    if (mDeviceProductInfo) {
        mDeviceProductInfo->dump(result);
+131 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include "DisplayHardware/Hal.h"
#include "Scheduler/HwcStrongTypes.h"

#include <android/configuration.h>
#include <utils/Timers.h>

#include <memory>
#include <vector>

namespace android {

namespace hal = android::hardware::graphics::composer::hal;

class DisplayMode;
using DisplayModePtr = std::shared_ptr<const DisplayMode>;
using DisplayModes = std::vector<DisplayModePtr>;

class DisplayMode {
public:
    class Builder {
    public:
        explicit Builder(hal::HWConfigId id) : mDisplayMode(new DisplayMode(id)) {}

        DisplayModePtr build() {
            return std::const_pointer_cast<const DisplayMode>(std::move(mDisplayMode));
        }

        Builder& setId(HwcConfigIndexType id) {
            mDisplayMode->mId = id;
            return *this;
        }

        Builder& setWidth(int32_t width) {
            mDisplayMode->mWidth = width;
            return *this;
        }

        Builder& setHeight(int32_t height) {
            mDisplayMode->mHeight = height;
            return *this;
        }

        Builder& setVsyncPeriod(int32_t vsyncPeriod) {
            mDisplayMode->mVsyncPeriod = vsyncPeriod;
            return *this;
        }

        Builder& setDpiX(int32_t dpiX) {
            if (dpiX == -1) {
                mDisplayMode->mDpiX = getDefaultDensity();
            } else {
                mDisplayMode->mDpiX = dpiX / 1000.0f;
            }
            return *this;
        }

        Builder& setDpiY(int32_t dpiY) {
            if (dpiY == -1) {
                mDisplayMode->mDpiY = getDefaultDensity();
            } else {
                mDisplayMode->mDpiY = dpiY / 1000.0f;
            }
            return *this;
        }

        Builder& setConfigGroup(int32_t configGroup) {
            mDisplayMode->mConfigGroup = configGroup;
            return *this;
        }

    private:
        float getDefaultDensity() {
            // Default density is based on TVs: 1080p displays get XHIGH density, lower-
            // resolution displays get TV density. Maybe eventually we'll need to update
            // it for 4k displays, though hopefully those will just report accurate DPI
            // information to begin with. This is also used for virtual displays and
            // older HWC implementations, so be careful about orientation.

            auto longDimension = std::max(mDisplayMode->mWidth, mDisplayMode->mHeight);
            if (longDimension >= 1080) {
                return ACONFIGURATION_DENSITY_XHIGH;
            } else {
                return ACONFIGURATION_DENSITY_TV;
            }
        }
        std::shared_ptr<DisplayMode> mDisplayMode;
    };

    HwcConfigIndexType getId() const { return mId; }
    hal::HWConfigId getHwcId() const { return mHwcId; }

    int32_t getWidth() const { return mWidth; }
    int32_t getHeight() const { return mHeight; }
    nsecs_t getVsyncPeriod() const { return mVsyncPeriod; }
    float getDpiX() const { return mDpiX; }
    float getDpiY() const { return mDpiY; }
    int32_t getConfigGroup() const { return mConfigGroup; }

private:
    explicit DisplayMode(hal::HWConfigId id) : mHwcId(id) {}

    hal::HWConfigId mHwcId;
    HwcConfigIndexType mId;

    int32_t mWidth = -1;
    int32_t mHeight = -1;
    nsecs_t mVsyncPeriod = -1;
    float mDpiX = -1;
    float mDpiY = -1;
    int32_t mConfigGroup = -1;
};

} // namespace android
 No newline at end of file
+2 −3
Original line number Diff line number Diff line
@@ -77,9 +77,8 @@ FramebufferSurface::FramebufferSurface(HWComposer& hwc, PhysicalDisplayId displa
    mConsumer->setConsumerUsageBits(GRALLOC_USAGE_HW_FB |
                                       GRALLOC_USAGE_HW_RENDER |
                                       GRALLOC_USAGE_HW_COMPOSER);
    const auto& activeConfig = mHwc.getActiveConfig(displayId);
    ui::Size limitedSize =
            limitFramebufferSize(activeConfig->getWidth(), activeConfig->getHeight());
    const auto& activeMode = mHwc.getActiveMode(displayId);
    ui::Size limitedSize = limitFramebufferSize(activeMode->getWidth(), activeMode->getHeight());
    mConsumer->setDefaultBufferSize(limitedSize.width, limitedSize.height);
    mConsumer->setMaxAcquiredBufferCount(
            SurfaceFlinger::maxFrameBufferAcquiredBuffers - 1);
+6 −190
Original line number Diff line number Diff line
@@ -68,33 +68,6 @@ inline bool hasMetadataKey(const std::set<Hwc2::PerFrameMetadataKey>& keys,
// Display methods
Display::~Display() = default;

Display::Config::Config(Display& display, HWConfigId id)
      : mDisplay(display),
        mId(id),
        mWidth(-1),
        mHeight(-1),
        mVsyncPeriod(-1),
        mDpiX(-1),
        mDpiY(-1) {}

Display::Config::Builder::Builder(Display& display, HWConfigId id)
      : mConfig(new Config(display, id)) {}

float Display::Config::Builder::getDefaultDensity() {
    // Default density is based on TVs: 1080p displays get XHIGH density, lower-
    // resolution displays get TV density. Maybe eventually we'll need to update
    // it for 4k displays, though hopefully those will just report accurate DPI
    // information to begin with. This is also used for virtual displays and
    // older HWC implementations, so be careful about orientation.

    auto longDimension = std::max(mConfig->mWidth, mConfig->mHeight);
    if (longDimension >= 1080) {
        return ACONFIGURATION_DENSITY_XHIGH;
    } else {
        return ACONFIGURATION_DENSITY_TV;
    }
}

namespace impl {

Display::Display(android::Hwc2::Composer& composer,
@@ -162,93 +135,12 @@ Error Display::destroyLayer(HWC2::Layer* layer) {
    return Error::NONE;
}

Error Display::getActiveConfig(
        std::shared_ptr<const Display::Config>* outConfig) const
{
    ALOGV("[%" PRIu64 "] getActiveConfig", mId);
    HWConfigId configId = 0;
    auto intError = mComposer.getActiveConfig(mId, &configId);
    auto error = static_cast<Error>(intError);

    if (error != Error::NONE) {
        ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
        *outConfig = nullptr;
        return error;
    }

    if (mConfigs.count(configId) != 0) {
        *outConfig = mConfigs.at(configId);
    } else {
        ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId,
                configId);
        // Return no error, but the caller needs to check for a null pointer to
        // detect this case
        *outConfig = nullptr;
    }

    return Error::NONE;
}

bool Display::isVsyncPeriodSwitchSupported() const {
    ALOGV("[%" PRIu64 "] isVsyncPeriodSwitchSupported()", mId);

    return mComposer.isVsyncPeriodSwitchSupported();
}

Error Display::getDisplayVsyncPeriod(nsecs_t* outVsyncPeriod) const {
    ALOGV("[%" PRIu64 "] getDisplayVsyncPeriod", mId);

    Error error;

    if (isVsyncPeriodSwitchSupported()) {
        Hwc2::VsyncPeriodNanos vsyncPeriodNanos = 0;
        auto intError = mComposer.getDisplayVsyncPeriod(mId, &vsyncPeriodNanos);
        error = static_cast<Error>(intError);
        *outVsyncPeriod = static_cast<nsecs_t>(vsyncPeriodNanos);
    } else {
        // Get the default vsync period
        std::shared_ptr<const Display::Config> config;
        error = getActiveConfig(&config);
        if (error != Error::NONE) {
            return error;
        }
        if (!config) {
            // HWC has updated the display modes and hasn't notified us yet.
            return Error::BAD_CONFIG;
        }

        *outVsyncPeriod = config->getVsyncPeriod();
    }

    return error;
}

Error Display::getActiveConfigIndex(int* outIndex) const {
    ALOGV("[%" PRIu64 "] getActiveConfigIndex", mId);
    HWConfigId configId = 0;
    auto intError = mComposer.getActiveConfig(mId, &configId);
    auto error = static_cast<Error>(intError);

    if (error != Error::NONE) {
        ALOGE("Unable to get active config for mId:[%" PRIu64 "]", mId);
        *outIndex = -1;
        return error;
    }

    auto pos = mConfigs.find(configId);
    if (pos != mConfigs.end()) {
        *outIndex = std::distance(mConfigs.begin(), pos);
        ALOGV("[%" PRIu64 "] index = %d", mId, *outIndex);
    } else {
        ALOGE("[%" PRIu64 "] getActiveConfig returned unknown config %u", mId, configId);
        // Return no error, but the caller needs to check for a negative index
        // to detect this case
        *outIndex = -1;
    }

    return Error::NONE;
}

Error Display::getChangedCompositionTypes(std::unordered_map<HWC2::Layer*, Composition>* outTypes) {
    std::vector<Hwc2::Layer> layerIds;
    std::vector<Hwc2::IComposerClient::Composition> types;
@@ -335,15 +227,6 @@ Error Display::getDataspaceSaturationMatrix(Dataspace dataspace, android::mat4*
    return static_cast<Error>(intError);
}

std::vector<std::shared_ptr<const Display::Config>> Display::getConfigs() const
{
    std::vector<std::shared_ptr<const Config>> configs;
    for (const auto& element : mConfigs) {
        configs.emplace_back(element.second);
    }
    return configs;
}

Error Display::getName(std::string* outName) const
{
    auto intError = mComposer.getDisplayName(mId, outName);
@@ -486,16 +369,10 @@ Error Display::present(sp<Fence>* outPresentFence)
    return Error::NONE;
}

Error Display::setActiveConfigWithConstraints(
        const std::shared_ptr<const HWC2::Display::Config>& config,
        const VsyncPeriodChangeConstraints& constraints, VsyncPeriodChangeTimeline* outTimeline) {
Error Display::setActiveConfigWithConstraints(hal::HWConfigId configId,
                                              const VsyncPeriodChangeConstraints& constraints,
                                              VsyncPeriodChangeTimeline* outTimeline) {
    ALOGV("[%" PRIu64 "] setActiveConfigWithConstraints", mId);
    if (config->getDisplayId() != mId) {
        ALOGE("setActiveConfigWithConstraints received config %u for the wrong display %" PRIu64
              " (expected %" PRIu64 ")",
              config->getId(), config->getDisplayId(), mId);
        return Error::BAD_CONFIG;
    }

    if (isVsyncPeriodSwitchSupported()) {
        Hwc2::IComposerClient::VsyncPeriodChangeConstraints hwc2Constraints;
@@ -503,8 +380,7 @@ Error Display::setActiveConfigWithConstraints(
        hwc2Constraints.seamlessRequired = constraints.seamlessRequired;

        Hwc2::VsyncPeriodChangeTimeline vsyncPeriodChangeTimeline = {};
        auto intError =
                mComposer.setActiveConfigWithConstraints(mId, config->getId(), hwc2Constraints,
        auto intError = mComposer.setActiveConfigWithConstraints(mId, configId, hwc2Constraints,
                                                                 &vsyncPeriodChangeTimeline);
        outTimeline->newVsyncAppliedTimeNanos = vsyncPeriodChangeTimeline.newVsyncAppliedTimeNanos;
        outTimeline->refreshRequired = vsyncPeriodChangeTimeline.refreshRequired;
@@ -519,25 +395,13 @@ Error Display::setActiveConfigWithConstraints(
        ALOGE("setActiveConfigWithConstraints received constraints that can't be satisfied");
    }

    auto intError_2_4 = mComposer.setActiveConfig(mId, config->getId());
    auto intError_2_4 = mComposer.setActiveConfig(mId, configId);
    outTimeline->newVsyncAppliedTimeNanos = std::max(now, constraints.desiredTimeNanos);
    outTimeline->refreshRequired = true;
    outTimeline->refreshTimeNanos = now;
    return static_cast<Error>(intError_2_4);
}

Error Display::setActiveConfig(const std::shared_ptr<const Config>& config)
{
    if (config->getDisplayId() != mId) {
        ALOGE("setActiveConfig received config %u for the wrong display %"
                PRIu64 " (expected %" PRIu64 ")", config->getId(),
                config->getDisplayId(), mId);
        return Error::BAD_CONFIG;
    }
    auto intError = mComposer.setActiveConfig(mId, config->getId());
    return static_cast<Error>(intError);
}

Error Display::setClientTarget(uint32_t slot, const sp<GraphicBuffer>& target,
        const sp<Fence>& acquireFence, Dataspace dataspace)
{
@@ -681,58 +545,10 @@ Error Display::getClientTargetProperty(ClientTargetProperty* outClientTargetProp
void Display::setConnected(bool connected) {
    if (!mIsConnected && connected) {
        mComposer.setClientTargetSlotCount(mId);
        if (mType == DisplayType::PHYSICAL) {
            loadConfigs();
        }
    }
    mIsConnected = connected;
}

int32_t Display::getAttribute(HWConfigId configId, Attribute attribute) {
    int32_t value = 0;
    auto intError = mComposer.getDisplayAttribute(mId, configId, attribute, &value);
    auto error = static_cast<Error>(intError);
    if (error != Error::NONE) {
        ALOGE("getDisplayAttribute(%" PRIu64 ", %u, %s) failed: %s (%d)", mId,
                configId, to_string(attribute).c_str(),
                to_string(error).c_str(), intError);
        return -1;
    }
    return value;
}

void Display::loadConfig(HWConfigId configId) {
    ALOGV("[%" PRIu64 "] loadConfig(%u)", mId, configId);

    auto config = Config::Builder(*this, configId)
                          .setWidth(getAttribute(configId, hal::Attribute::WIDTH))
                          .setHeight(getAttribute(configId, hal::Attribute::HEIGHT))
                          .setVsyncPeriod(getAttribute(configId, hal::Attribute::VSYNC_PERIOD))
                          .setDpiX(getAttribute(configId, hal::Attribute::DPI_X))
                          .setDpiY(getAttribute(configId, hal::Attribute::DPI_Y))
                          .setConfigGroup(getAttribute(configId, hal::Attribute::CONFIG_GROUP))
                          .build();
    mConfigs.emplace(configId, std::move(config));
}

void Display::loadConfigs()
{
    ALOGV("[%" PRIu64 "] loadConfigs", mId);

    std::vector<HWConfigId> configIds;
    auto intError = mComposer.getDisplayConfigs(mId, &configIds);
    auto error = static_cast<Error>(intError);
    if (error != Error::NONE) {
        ALOGE("[%" PRIu64 "] getDisplayConfigs [2] failed: %s (%d)", mId,
                to_string(error).c_str(), intError);
        return;
    }

    for (auto configId : configIds) {
        loadConfig(configId);
    }
}

// Other Display methods

HWC2::Layer* Display::getLayerById(HWLayerId id) const {
Loading