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

Commit a784d5b9 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "SF: add a spinner to refresh rate overlay"

parents 27283751 29d0da35
Loading
Loading
Loading
Loading
+70 −28
Original line number Diff line number Diff line
@@ -106,14 +106,17 @@ void RefreshRateOverlay::SevenSegmentDrawer::drawDigit(int digit, int left, cons
        drawSegment(Segment::Buttom, left, color, buffer, pixels);
}

sp<GraphicBuffer> RefreshRateOverlay::SevenSegmentDrawer::drawNumber(int number,
                                                                     const half4& color) {
    if (number < 0 || number > 1000) return nullptr;
std::vector<sp<GraphicBuffer>> RefreshRateOverlay::SevenSegmentDrawer::drawNumber(
        int number, const half4& color, bool showSpinner) {
    if (number < 0 || number > 1000) return {};

    const auto hundreds = number / 100;
    const auto tens = (number / 10) % 10;
    const auto ones = number % 10;

    std::vector<sp<GraphicBuffer>> buffers;
    const auto loopCount = showSpinner ? 6 : 1;
    for (int i = 0; i < loopCount; i++) {
        sp<GraphicBuffer> buffer =
                new GraphicBuffer(BUFFER_WIDTH, BUFFER_HEIGHT, HAL_PIXEL_FORMAT_RGBA_8888, 1,
                                  GRALLOC_USAGE_SW_WRITE_RARELY | GRALLOC_USAGE_HW_COMPOSER |
@@ -126,21 +129,48 @@ sp<GraphicBuffer> RefreshRateOverlay::SevenSegmentDrawer::drawNumber(int number,
        int left = 0;
        if (hundreds != 0) {
            drawDigit(hundreds, left, color, buffer, pixels);
        left += DIGIT_WIDTH + DIGIT_SPACE;
        }
        left += DIGIT_WIDTH + DIGIT_SPACE;

        if (tens != 0) {
            drawDigit(tens, left, color, buffer, pixels);
        left += DIGIT_WIDTH + DIGIT_SPACE;
        }
        left += DIGIT_WIDTH + DIGIT_SPACE;

        drawDigit(ones, left, color, buffer, pixels);
        left += DIGIT_WIDTH + DIGIT_SPACE;

        if (showSpinner) {
            switch (i) {
                case 0:
                    drawSegment(Segment::Upper, left, color, buffer, pixels);
                    break;
                case 1:
                    drawSegment(Segment::UpperRight, left, color, buffer, pixels);
                    break;
                case 2:
                    drawSegment(Segment::LowerRight, left, color, buffer, pixels);
                    break;
                case 3:
                    drawSegment(Segment::Buttom, left, color, buffer, pixels);
                    break;
                case 4:
                    drawSegment(Segment::LowerLeft, left, color, buffer, pixels);
                    break;
                case 5:
                    drawSegment(Segment::UpperLeft, left, color, buffer, pixels);
                    break;
            }
        }

        buffer->unlock();
    return buffer;
        buffers.emplace_back(buffer);
    }
    return buffers;
}

RefreshRateOverlay::RefreshRateOverlay(SurfaceFlinger& flinger)
      : mFlinger(flinger), mClient(new Client(&mFlinger)) {
RefreshRateOverlay::RefreshRateOverlay(SurfaceFlinger& flinger, bool showSpinner)
      : mFlinger(flinger), mClient(new Client(&mFlinger)), mShowSpinner(showSpinner) {
    createLayer();
    primeCache();
}
@@ -176,7 +206,7 @@ void RefreshRateOverlay::primeCache() {
    if (allRefreshRates.size() == 1) {
        auto fps = allRefreshRates.begin()->second->getFps();
        half4 color = {LOW_FPS_COLOR, ALPHA};
        mBufferCache.emplace(fps, SevenSegmentDrawer::drawNumber(fps, color));
        mBufferCache.emplace(fps, SevenSegmentDrawer::drawNumber(fps, color, mShowSpinner));
        return;
    }

@@ -196,12 +226,12 @@ void RefreshRateOverlay::primeCache() {
        color.g = HIGH_FPS_COLOR.g * fpsScale + LOW_FPS_COLOR.g * (1 - fpsScale);
        color.b = HIGH_FPS_COLOR.b * fpsScale + LOW_FPS_COLOR.b * (1 - fpsScale);
        color.a = ALPHA;
        mBufferCache.emplace(fps, SevenSegmentDrawer::drawNumber(fps, color));
        mBufferCache.emplace(fps, SevenSegmentDrawer::drawNumber(fps, color, mShowSpinner));
    }
}

void RefreshRateOverlay::setViewport(ui::Size viewport) {
    Rect frame(viewport.width >> 3, viewport.height >> 5);
    Rect frame((3 * viewport.width) >> 4, viewport.height >> 5);
    frame.offsetBy(viewport.width >> 5, viewport.height >> 4);
    mLayer->setFrame(frame);

@@ -209,7 +239,19 @@ void RefreshRateOverlay::setViewport(ui::Size viewport) {
}

void RefreshRateOverlay::changeRefreshRate(const RefreshRate& refreshRate) {
    auto buffer = mBufferCache[refreshRate.getFps()];
    mCurrentFps = refreshRate.getFps();
    auto buffer = mBufferCache[*mCurrentFps][mFrame];
    mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, {});

    mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
}

void RefreshRateOverlay::onInvalidate() {
    if (!mCurrentFps.has_value()) return;

    const auto& buffers = mBufferCache[*mCurrentFps];
    mFrame = (mFrame + 1) % buffers.size();
    auto buffer = buffers[mFrame];
    mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, {});

    mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
+10 −5
Original line number Diff line number Diff line
@@ -38,15 +38,17 @@ using RefreshRate = scheduler::RefreshRateConfigs::RefreshRate;

class RefreshRateOverlay {
public:
    explicit RefreshRateOverlay(SurfaceFlinger&);
    RefreshRateOverlay(SurfaceFlinger&, bool showSpinner);

    void setViewport(ui::Size);
    void changeRefreshRate(const RefreshRate&);
    void onInvalidate();

private:
    class SevenSegmentDrawer {
    public:
        static sp<GraphicBuffer> drawNumber(int number, const half4& color);
        static std::vector<sp<GraphicBuffer>> drawNumber(int number, const half4& color,
                                                         bool showSpinner);
        static uint32_t getHeight() { return BUFFER_HEIGHT; }
        static uint32_t getWidth() { return BUFFER_WIDTH; }

@@ -65,7 +67,7 @@ private:
        static constexpr uint32_t DIGIT_SPACE = 16;
        static constexpr uint32_t BUFFER_HEIGHT = DIGIT_HEIGHT;
        static constexpr uint32_t BUFFER_WIDTH =
                3 * DIGIT_WIDTH + 2 * DIGIT_SPACE; // Digit|Space|Digit|Space|Digit
                4 * DIGIT_WIDTH + 3 * DIGIT_SPACE; // Digit|Space|Digit|Space|Digit|Space|Spinner
    };

    bool createLayer();
@@ -77,11 +79,14 @@ private:
    sp<IBinder> mIBinder;
    sp<IGraphicBufferProducer> mGbp;

    std::unordered_map<int, sp<GraphicBuffer>> mBufferCache;

    std::unordered_map<int, std::vector<sp<GraphicBuffer>>> mBufferCache;
    std::optional<int> mCurrentFps;
    int mFrame = 0;
    static constexpr float ALPHA = 0.8f;
    const half3 LOW_FPS_COLOR = half3(1.0f, 0.0f, 0.0f);
    const half3 HIGH_FPS_COLOR = half3(0.0f, 1.0f, 0.0f);

    const bool mShowSpinner;
};

} // namespace android
+9 −1
Original line number Diff line number Diff line
@@ -470,6 +470,8 @@ SurfaceFlinger::SurfaceFlinger(Factory& factory) : SurfaceFlinger(factory, SkipI

    mKernelIdleTimerEnabled = mSupportKernelIdleTimer = sysprop::support_kernel_idle_timer(false);
    base::SetProperty(KERNEL_IDLE_TIMER_PROP, mKernelIdleTimerEnabled ? "true" : "false");

    mRefreshRateOverlaySpinner = property_get_bool("sf.debug.show_refresh_rate_overlay_spinner", 0);
}

SurfaceFlinger::~SurfaceFlinger() = default;
@@ -1965,6 +1967,12 @@ void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) {
        mTracingEnabledChanged = false;
    }

    if (mRefreshRateOverlaySpinner) {
        if (Mutex::Autolock lock(mStateLock); mRefreshRateOverlay) {
            mRefreshRateOverlay->onInvalidate();
        }
    }

    bool refreshNeeded;
    {
        ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
@@ -6259,7 +6267,7 @@ void SurfaceFlinger::enableRefreshRateOverlay(bool enable) {
    static_cast<void>(schedule([=] {
        std::unique_ptr<RefreshRateOverlay> overlay;
        if (enable) {
            overlay = std::make_unique<RefreshRateOverlay>(*this);
            overlay = std::make_unique<RefreshRateOverlay>(*this, mRefreshRateOverlaySpinner);
        }

        {
+2 −0
Original line number Diff line number Diff line
@@ -547,6 +547,8 @@ private:
    bool mKernelIdleTimerEnabled = false;
    // Keeps track of whether the kernel timer is supported on the SF side.
    bool mSupportKernelIdleTimer = false;
    // Show spinner with refresh rate overlay
    bool mRefreshRateOverlaySpinner = false;
    /* ------------------------------------------------------------------------
     * Message handling
     */