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

Commit b0054a26 authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

SF: Unify data types for display modes

Remove the RefreshRateConfigs::RefreshRate wrapper around DisplayMode.
Store DisplayModes as a SmallMap, so that RefreshRateConfigs uses the
same data structure for lookup by ID. Use iterators into that map for
all bookkeeping in RefreshRateConfigs.

Bug: 182939859
Bug: 185535769
Test: libsurfaceflinger_unittest
Change-Id: I7708fa997089802c45d906b17b7a073f5c82105e
parent 6c7b36e8
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -404,7 +404,7 @@ void BufferLayer::onPostComposition(const DisplayDevice* display,
    }

    if (display) {
        const Fps refreshRate = display->refreshRateConfigs().getCurrentRefreshRate().getFps();
        const Fps refreshRate = display->refreshRateConfigs().getActiveMode()->getFps();
        const std::optional<Fps> renderRate =
                mFlinger->mScheduler->getFrameRateOverride(getOwnerUid());

+9 −14
Original line number Diff line number Diff line
@@ -196,7 +196,7 @@ void DisplayDevice::setActiveMode(DisplayModeId id) {
    ATRACE_INT(mActiveModeFPSTrace.c_str(), mode->getFps().getIntValue());
    mActiveMode = mode;
    if (mRefreshRateConfigs) {
        mRefreshRateConfigs->setCurrentModeId(mActiveMode->getId());
        mRefreshRateConfigs->setActiveModeId(mActiveMode->getId());
    }
    if (mRefreshRateOverlay) {
        mRefreshRateOverlay->changeRefreshRate(mActiveMode->getFps());
@@ -227,21 +227,16 @@ const DisplayModes& DisplayDevice::getSupportedModes() const {
}

DisplayModePtr DisplayDevice::getMode(DisplayModeId modeId) const {
    const auto it =
            std::find_if(mSupportedModes.begin(), mSupportedModes.end(),
                         [&](const DisplayModePtr& mode) { return mode->getId() == modeId; });
    if (it != mSupportedModes.end()) {
        return *it;
    }
    return nullptr;
    const DisplayModePtr nullMode;
    return mSupportedModes.get(modeId).value_or(std::cref(nullMode));
}

std::optional<DisplayModeId> DisplayDevice::translateModeId(hal::HWConfigId hwcId) const {
    const auto it =
            std::find_if(mSupportedModes.begin(), mSupportedModes.end(),
                         [&](const DisplayModePtr& mode) { return mode->getHwcId() == hwcId; });
                         [hwcId](const auto& pair) { return pair.second->getHwcId() == hwcId; });
    if (it != mSupportedModes.end()) {
        return (*it)->getId();
        return it->second->getId();
    }
    return {};
}
@@ -366,12 +361,12 @@ void DisplayDevice::dump(std::string& result) const {
                  activeMode ? to_string(*activeMode).c_str() : "none");

    result.append("   supportedModes=\n");

    for (const auto& mode : mSupportedModes) {
    for (const auto& [id, mode] : mSupportedModes) {
        result.append("      ");
        result.append(to_string(*mode));
        result.append("\n");
        result.push_back('\n');
    }

    StringAppendF(&result, "   deviceProductInfo=");
    if (mDeviceProductInfo) {
        mDeviceProductInfo->dump(result);
+58 −37
Original line number Diff line number Diff line
@@ -18,10 +18,10 @@

#include <cstddef>
#include <memory>
#include <vector>

#include <android-base/stringprintf.h>
#include <android/configuration.h>
#include <ftl/small_map.h>
#include <ui/DisplayId.h>
#include <ui/DisplayMode.h>
#include <ui/Size.h>
@@ -38,8 +38,17 @@ namespace hal = android::hardware::graphics::composer::hal;

class DisplayMode;
using DisplayModePtr = std::shared_ptr<const DisplayMode>;
using DisplayModes = std::vector<DisplayModePtr>;
using DisplayModeId = StrongTyping<ui::DisplayModeId, struct DisplayModeIdTag, Compare, Hash>;

// Prevent confusion with fps_approx_ops on the underlying Fps.
bool operator<(const DisplayModePtr&, const DisplayModePtr&) = delete;
bool operator>(const DisplayModePtr&, const DisplayModePtr&) = delete;
bool operator<=(const DisplayModePtr&, const DisplayModePtr&) = delete;
bool operator>=(const DisplayModePtr&, const DisplayModePtr&) = delete;

using DisplayModeId = StrongTyping<ui::DisplayModeId, struct DisplayModeIdTag, Compare>;

using DisplayModes = ftl::SmallMap<DisplayModeId, DisplayModePtr, 3>;
using DisplayModeIterator = DisplayModes::const_iterator;

class DisplayMode {
public:
@@ -61,35 +70,30 @@ public:
            return *this;
        }

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

        Builder& setHeight(int32_t height) {
            mDisplayMode->mHeight = height;
        Builder& setResolution(ui::Size resolution) {
            mDisplayMode->mResolution = resolution;
            return *this;
        }

        Builder& setVsyncPeriod(int32_t vsyncPeriod) {
        Builder& setVsyncPeriod(nsecs_t vsyncPeriod) {
            mDisplayMode->mFps = Fps::fromPeriodNsecs(vsyncPeriod);
            return *this;
        }

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

        Builder& setDpiY(int32_t dpiY) {
            if (dpiY == -1) {
                mDisplayMode->mDpiY = getDefaultDensity();
                mDisplayMode->mDpi.y = getDefaultDensity();
            } else {
                mDisplayMode->mDpiY = dpiY / 1000.0f;
                mDisplayMode->mDpi.y = dpiY / 1000.f;
            }
            return *this;
        }
@@ -107,59 +111,76 @@ public:
            // 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) {
            if (std::max(mDisplayMode->getWidth(), mDisplayMode->getHeight()) >= 1080) {
                return ACONFIGURATION_DENSITY_XHIGH;
            } else {
                return ACONFIGURATION_DENSITY_TV;
            }
        }

        std::shared_ptr<DisplayMode> mDisplayMode;
    };

    DisplayModeId getId() const { return mId; }

    hal::HWConfigId getHwcId() const { return mHwcId; }
    PhysicalDisplayId getPhysicalDisplayId() const { return mPhysicalDisplayId; }

    int32_t getWidth() const { return mWidth; }
    int32_t getHeight() const { return mHeight; }
    ui::Size getSize() const { return {mWidth, mHeight}; }
    ui::Size getResolution() const { return mResolution; }
    int32_t getWidth() const { return mResolution.getWidth(); }
    int32_t getHeight() const { return mResolution.getHeight(); }

    Fps getFps() const { return mFps; }
    nsecs_t getVsyncPeriod() const { return mFps.getPeriodNsecs(); }
    float getDpiX() const { return mDpiX; }
    float getDpiY() const { return mDpiY; }

    struct Dpi {
        float x = -1;
        float y = -1;

        bool operator==(Dpi other) const { return x == other.x && y == other.y; }
    };

    Dpi getDpi() const { return mDpi; }

    // Switches between modes in the same group are seamless, i.e.
    // without visual interruptions such as a black screen.
    int32_t getGroup() const { return mGroup; }

    bool equalsExceptDisplayModeId(const DisplayModePtr& other) const {
        return mHwcId == other->mHwcId && mWidth == other->mWidth && mHeight == other->mHeight &&
                getVsyncPeriod() == other->getVsyncPeriod() && mDpiX == other->mDpiX &&
                mDpiY == other->mDpiY && mGroup == other->mGroup;
    }

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

    hal::HWConfigId mHwcId;
    const hal::HWConfigId mHwcId;
    DisplayModeId mId;

    PhysicalDisplayId mPhysicalDisplayId;

    int32_t mWidth = -1;
    int32_t mHeight = -1;
    ui::Size mResolution;
    Fps mFps;
    float mDpiX = -1;
    float mDpiY = -1;
    Dpi mDpi;
    int32_t mGroup = -1;
};

inline bool equalsExceptDisplayModeId(const DisplayMode& lhs, const DisplayMode& rhs) {
    return lhs.getHwcId() == rhs.getHwcId() && lhs.getResolution() == rhs.getResolution() &&
            lhs.getVsyncPeriod() == rhs.getVsyncPeriod() && lhs.getDpi() == rhs.getDpi() &&
            lhs.getGroup() == rhs.getGroup();
}

inline std::string to_string(const DisplayMode& mode) {
    return base::StringPrintf("{id=%d, hwcId=%d, width=%d, height=%d, refreshRate=%s, "
                              "dpiX=%.2f, dpiY=%.2f, group=%d}",
    return base::StringPrintf("{id=%d, hwcId=%d, resolution=%dx%d, refreshRate=%s, "
                              "dpi=%.2fx%.2f, group=%d}",
                              mode.getId().value(), mode.getHwcId(), mode.getWidth(),
                              mode.getHeight(), to_string(mode.getFps()).c_str(), mode.getDpiX(),
                              mode.getDpiY(), mode.getGroup());
                              mode.getHeight(), to_string(mode.getFps()).c_str(), mode.getDpi().x,
                              mode.getDpi().y, mode.getGroup());
}

template <typename... DisplayModePtrs>
inline DisplayModes makeModes(const DisplayModePtrs&... modePtrs) {
    DisplayModes modes;
    // Note: The omission of std::move(modePtrs) is intentional, because order of evaluation for
    // arguments is unspecified.
    (modes.try_emplace(modePtrs->getId(), modePtrs), ...);
    return modes;
}

} // namespace android
Loading