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

Commit 1b11bc66 authored by Ady Abraham's avatar Ady Abraham
Browse files

SF: move RefreshRateOverlay to DisplayDevice

Test: SF unit tests
Test: refresh rate overlay is visible on all displays
Bug: 187539899
Change-Id: I3bfa3749dcd5bbd7d6238a60332b98bba954ca53
parent 3efa3942
Loading
Loading
Loading
Loading
+46 −1
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@

#include "DisplayDevice.h"
#include "Layer.h"
#include "RefreshRateOverlay.h"
#include "SurfaceFlinger.h"

namespace android {
@@ -159,6 +160,9 @@ void DisplayDevice::setActiveMode(DisplayModeId id) {
    if (mRefreshRateConfigs) {
        mRefreshRateConfigs->setCurrentModeId(mActiveMode->getId());
    }
    if (mRefreshRateOverlay) {
        mRefreshRateOverlay->changeRefreshRate(mActiveMode->getFps());
    }
}

status_t DisplayDevice::initiateModeChange(DisplayModeId modeId,
@@ -222,6 +226,9 @@ ui::Dataspace DisplayDevice::getCompositionDataSpace() const {

void DisplayDevice::setLayerStack(ui::LayerStack stack) {
    mCompositionDisplay->setLayerStackFilter(stack, isInternal());
    if (mRefreshRateOverlay) {
        mRefreshRateOverlay->setLayerStack(stack);
    }
}

void DisplayDevice::setFlags(uint32_t flags) {
@@ -230,7 +237,11 @@ void DisplayDevice::setFlags(uint32_t flags) {

void DisplayDevice::setDisplaySize(int width, int height) {
    LOG_FATAL_IF(!isVirtual(), "Changing the display size is supported only for virtual displays.");
    mCompositionDisplay->setDisplaySize(ui::Size(width, height));
    const auto size = ui::Size(width, height);
    mCompositionDisplay->setDisplaySize(size);
    if (mRefreshRateOverlay) {
        mRefreshRateOverlay->setViewport(size);
    }
}

void DisplayDevice::setProjection(ui::Rotation orientation, Rect layerStackSpaceRect,
@@ -390,6 +401,40 @@ HdrCapabilities DisplayDevice::getHdrCapabilities() const {
                           capabilities.getDesiredMinLuminance());
}

void DisplayDevice::enableRefreshRateOverlay(bool enable, bool showSpinnner) {
    if (!enable) {
        mRefreshRateOverlay.reset();
        return;
    }

    const auto [lowFps, highFps] = mRefreshRateConfigs->getSupportedRefreshRateRange();
    mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(*mFlinger, lowFps.getIntValue(),
                                                               highFps.getIntValue(), showSpinnner);
    mRefreshRateOverlay->setLayerStack(getLayerStack());
    mRefreshRateOverlay->setViewport(getSize());
    mRefreshRateOverlay->changeRefreshRate(getActiveMode()->getFps());
}

bool DisplayDevice::onKernelTimerChanged(std::optional<DisplayModeId> desiredModeId,
                                         bool timerExpired) {
    if (mRefreshRateConfigs && mRefreshRateOverlay) {
        const auto newRefreshRate =
                mRefreshRateConfigs->onKernelTimerChanged(desiredModeId, timerExpired);
        if (newRefreshRate) {
            mRefreshRateOverlay->changeRefreshRate(*newRefreshRate);
            return true;
        }
    }

    return false;
}

void DisplayDevice::onInvalidate() {
    if (mRefreshRateOverlay) {
        mRefreshRateOverlay->onInvalidate();
    }
}

std::atomic<int32_t> DisplayDeviceState::sNextSequenceId(1);

}  // namespace android
+8 −0
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ class Fence;
class HWComposer;
class IGraphicBufferProducer;
class Layer;
class RefreshRateOverlay;
class SurfaceFlinger;

struct CompositionInfo;
@@ -205,6 +206,12 @@ public:
        return mRefreshRateConfigs;
    }

    // Enables an overlay to be displayed with the current refresh rate
    void enableRefreshRateOverlay(bool enable, bool showSpinner);
    bool isRefreshRateOverlayEnabled() const { return mRefreshRateOverlay != nullptr; }
    bool onKernelTimerChanged(std::optional<DisplayModeId>, bool timerExpired);
    void onInvalidate();

    void onVsync(nsecs_t timestamp);
    nsecs_t getVsyncPeriodFromHWC() const;
    nsecs_t getRefreshTimestamp() const;
@@ -252,6 +259,7 @@ private:
    std::vector<ui::Hdr> mOverrideHdrTypes;

    std::shared_ptr<scheduler::RefreshRateConfigs> mRefreshRateConfigs;
    std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay;
};

struct DisplayDeviceState {
+12 −20
Original line number Diff line number Diff line
@@ -175,10 +175,14 @@ std::vector<sp<GraphicBuffer>> RefreshRateOverlay::SevenSegmentDrawer::drawNumbe
    return buffers;
}

RefreshRateOverlay::RefreshRateOverlay(SurfaceFlinger& flinger, bool showSpinner)
      : mFlinger(flinger), mClient(new Client(&mFlinger)), mShowSpinner(showSpinner) {
RefreshRateOverlay::RefreshRateOverlay(SurfaceFlinger& flinger, uint32_t lowFps, uint32_t highFps,
                                       bool showSpinner)
      : mFlinger(flinger),
        mClient(new Client(&mFlinger)),
        mShowSpinner(showSpinner),
        mLowFps(lowFps),
        mHighFps(highFps) {
    createLayer();
    reset();
}

bool RefreshRateOverlay::createLayer() {
@@ -194,7 +198,6 @@ bool RefreshRateOverlay::createLayer() {
        return false;
    }

    Mutex::Autolock _l(mFlinger.mStateLock);
    mLayer = mClient->getLayerUser(mIBinder);
    mLayer->setFrameRate(Layer::FrameRate(Fps(0.0f), Layer::FrameRateCompatibility::NoVote));

@@ -256,6 +259,11 @@ void RefreshRateOverlay::setViewport(ui::Size viewport) {
    mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
}

void RefreshRateOverlay::setLayerStack(uint32_t stack) {
    mLayer->setLayerStack(stack);
    mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
}

void RefreshRateOverlay::changeRefreshRate(const Fps& fps) {
    mCurrentFps = fps.getIntValue();
    auto buffer = getOrCreateBuffers(*mCurrentFps)[mFrame];
@@ -281,22 +289,6 @@ void RefreshRateOverlay::onInvalidate() {
    mFlinger.mTransactionFlags.fetch_or(eTransactionMask);
}

void RefreshRateOverlay::reset() {
    mBufferCache.clear();
    // TODO: this is a temp hack that would be removed in the next CL
    const auto range = [&]() NO_THREAD_SAFETY_ANALYSIS {
        constexpr auto defaultFps = Fps(60);
        const auto display = mFlinger.getDefaultDisplayDeviceLocked();
        if (display) {
            return display->refreshRateConfigs().getSupportedRefreshRateRange();
        }
        ALOGW("%s: default display is null", __func__);
        return scheduler::RefreshRateConfigs::FpsRange{defaultFps, defaultFps};
    }();
    mLowFps = range.min.getIntValue();
    mHighFps = range.max.getIntValue();
}

} // namespace android

// TODO(b/129481165): remove the #pragma below and fix conversion issues
+4 −4
Original line number Diff line number Diff line
@@ -37,12 +37,12 @@ class SurfaceFlinger;

class RefreshRateOverlay {
public:
    RefreshRateOverlay(SurfaceFlinger&, bool showSpinner);
    RefreshRateOverlay(SurfaceFlinger&, uint32_t lowFps, uint32_t highFps, bool showSpinner);

    void setLayerStack(uint32_t stack);
    void setViewport(ui::Size);
    void changeRefreshRate(const Fps&);
    void onInvalidate();
    void reset();

private:
    class SevenSegmentDrawer {
@@ -91,8 +91,8 @@ private:
    const bool mShowSpinner;

    // Interpolate the colors between these values.
    uint32_t mLowFps;
    uint32_t mHighFps;
    const uint32_t mLowFps;
    const uint32_t mHighFps;
};

} // namespace android
+24 −52
Original line number Diff line number Diff line
@@ -726,7 +726,7 @@ void SurfaceFlinger::bootFinished() {
        mBootStage = BootStage::FINISHED;

        if (property_get_bool("sf.debug.show_refresh_rate_overlay", false)) {
            enableRefreshRateOverlay(true);
            ON_MAIN_THREAD(enableRefreshRateOverlay(true));
        }
    }));
}
@@ -1192,10 +1192,6 @@ void SurfaceFlinger::setActiveModeInternal() {
    updatePhaseConfiguration(refreshRate);
    ATRACE_INT("ActiveConfigFPS", refreshRate.getValue());

    if (mRefreshRateOverlay) {
        mRefreshRateOverlay->changeRefreshRate(upcomingMode->getFps());
    }

    if (mUpcomingActiveMode.event != Scheduler::ModeEvent::None) {
        const nsecs_t vsyncPeriod = refreshRate.getPeriodNsecs();
        const auto physicalId = display->getPhysicalId();
@@ -1969,8 +1965,13 @@ void SurfaceFlinger::onMessageInvalidate(int64_t vsyncId, nsecs_t expectedVSyncT
    }

    if (mRefreshRateOverlaySpinner) {
        if (Mutex::Autolock lock(mStateLock); mRefreshRateOverlay) {
            mRefreshRateOverlay->onInvalidate();
        if (Mutex::Autolock lock(mStateLock);
            const auto display = getDefaultDisplayDeviceLocked()) {
            if (display) {
                display->onInvalidate();
            } else {
                ALOGW("%s: default display is null", __func__);
            }
        }
    }

@@ -2890,10 +2891,6 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken,
            if (isDisplayActiveLocked(display)) {
                onActiveDisplaySizeChanged(display);
            }

            if (mRefreshRateOverlay) {
                mRefreshRateOverlay->setViewport(display->getSize());
            }
        }
    }
}
@@ -2902,9 +2899,6 @@ void SurfaceFlinger::updateInternalDisplayVsyncLocked(const sp<DisplayDevice>& a
    const Fps refreshRate = activeDisplay->refreshRateConfigs().getCurrentRefreshRate().getFps();
    updatePhaseConfiguration(refreshRate);
    mRefreshRateStats->setRefreshRate(refreshRate);
    if (mRefreshRateOverlay) {
        mRefreshRateOverlay->reset();
    }
}

void SurfaceFlinger::processDisplayChangesLocked() {
@@ -5659,16 +5653,17 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r
                return NO_ERROR;
            }
            case 1034: {
                schedule([&] {
                    switch (n = data.readInt32()) {
                        case 0:
                        case 1:
                        enableRefreshRateOverlay(static_cast<bool>(n));
                            ON_MAIN_THREAD(enableRefreshRateOverlay(static_cast<bool>(n)));
                            break;
                        default: {
                        Mutex::Autolock lock(mStateLock);
                        reply->writeBool(mRefreshRateOverlay != nullptr);
                            reply->writeBool(ON_MAIN_THREAD(isRefreshRateOverlayEnabled()));
                        }
                    }
                }).get();
                return NO_ERROR;
            }
            case 1035: {
@@ -5814,7 +5809,7 @@ void SurfaceFlinger::kernelTimerChanged(bool expired) {
    static bool updateOverlay =
            property_get_bool("debug.sf.kernel_idle_timer_update_overlay", true);
    if (!updateOverlay) return;
    if (Mutex::Autolock lock(mStateLock); !mRefreshRateOverlay) return;
    if (Mutex::Autolock lock(mStateLock); !isRefreshRateOverlayEnabled()) return;

    // Update the overlay on the main thread to avoid race conditions with
    // mRefreshRateConfigs->getCurrentRefreshRate()
@@ -5829,12 +5824,7 @@ void SurfaceFlinger::kernelTimerChanged(bool expired) {
            ALOGW("%s: default display is null", __func__);
            return;
        }
        const auto newRefreshRate =
                display->refreshRateConfigs().onKernelTimerChanged(desiredModeId, timerExpired);
        if (newRefreshRate) {
            if (Mutex::Autolock lock(mStateLock); mRefreshRateOverlay) {
                mRefreshRateOverlay->changeRefreshRate(*newRefreshRate);
            }
        if (display->onKernelTimerChanged(desiredModeId, timerExpired)) {
            mEventQueue->invalidate();
        }
    }));
@@ -6816,25 +6806,11 @@ status_t SurfaceFlinger::setFrameTimelineInfo(const sp<IGraphicBufferProducer>&
}

void SurfaceFlinger::enableRefreshRateOverlay(bool enable) {
    static_cast<void>(schedule([=] {
        std::unique_ptr<RefreshRateOverlay> overlay;
        if (enable) {
            overlay = std::make_unique<RefreshRateOverlay>(*this, mRefreshRateOverlaySpinner);
        }

        {
            Mutex::Autolock lock(mStateLock);

            // Destroy the layer of the current overlay, if any, outside the lock.
            mRefreshRateOverlay.swap(overlay);
            if (!mRefreshRateOverlay) return;

            if (const auto display = getDefaultDisplayDeviceLocked()) {
                mRefreshRateOverlay->setViewport(display->getSize());
                mRefreshRateOverlay->changeRefreshRate(display->getActiveMode()->getFps());
    for (const auto& [ignored, display] : mDisplays) {
        if (display->isInternal()) {
            display->enableRefreshRateOverlay(enable, mRefreshRateOverlaySpinner);
        }
    }
    }));
}

status_t SurfaceFlinger::addTransactionTraceListener(
@@ -7018,10 +6994,6 @@ void SurfaceFlinger::onActiveDisplayChangedLocked(const sp<DisplayDevice>& activ
    updateInternalDisplayVsyncLocked(activeDisplay);
    mScheduler->setRefreshRateConfigs(activeDisplay->holdRefreshRateConfigs());
    onActiveDisplaySizeChanged(activeDisplay);
    if (mRefreshRateOverlay) {
        mRefreshRateOverlay->setViewport(activeDisplay->getSize());
        mRefreshRateOverlay->changeRefreshRate(activeDisplay->getActiveMode()->getFps());
    }
}

} // namespace android
Loading