Loading services/surfaceflinger/DisplayDevice.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -468,6 +468,12 @@ bool DisplayDevice::onKernelTimerChanged(std::optional<DisplayModeId> desiredMod return false; } void DisplayDevice::onVrrIdle(bool idle) { if (mRefreshRateOverlay) { mRefreshRateOverlay->onVrrIdle(idle); } } void DisplayDevice::animateOverlay() { if (mRefreshRateOverlay) { mRefreshRateOverlay->animate(); Loading services/surfaceflinger/DisplayDevice.h +1 −0 Original line number Diff line number Diff line Loading @@ -196,6 +196,7 @@ public: bool isRefreshRateOverlayEnabled() const { return mRefreshRateOverlay != nullptr; } void animateOverlay(); bool onKernelTimerChanged(std::optional<DisplayModeId>, bool timerExpired); void onVrrIdle(bool idle); // Enables an overlay to be display with the hdr/sdr ratio void enableHdrSdrRatioOverlay(bool enable) REQUIRES(kMainThreadContext); Loading services/surfaceflinger/RefreshRateOverlay.cpp +38 −12 Original line number Diff line number Diff line Loading @@ -28,10 +28,11 @@ namespace android { auto RefreshRateOverlay::draw(int refreshRate, int renderFps, SkColor color, auto RefreshRateOverlay::draw(int refreshRate, int renderFps, bool idle, SkColor color, ui::Transform::RotationFlags rotation, ftl::Flags<Features> features) -> Buffers { const size_t loopCount = features.test(Features::Spinner) ? 6 : 1; const bool isSetByHwc = features.test(Features::SetByHwc); Buffers buffers; buffers.reserve(loopCount); Loading Loading @@ -71,7 +72,11 @@ auto RefreshRateOverlay::draw(int refreshRate, int renderFps, SkColor color, canvas->setMatrix(canvasTransform); int left = 0; if (idle && !isSetByHwc) { drawDash(left, *canvas); } else { drawNumber(refreshRate, left, color, *canvas); } left += 3 * (kDigitWidth + kDigitSpace); if (features.test(Features::Spinner)) { switch (i) { Loading Loading @@ -104,8 +109,12 @@ auto RefreshRateOverlay::draw(int refreshRate, int renderFps, SkColor color, left += kDigitWidth + kDigitSpace; if (features.test(Features::RenderRate)) { if (idle) { drawDash(left, *canvas); } else { drawNumber(renderFps, left, color, *canvas); } } left += 3 * (kDigitWidth + kDigitSpace); void* pixels = nullptr; Loading Loading @@ -138,6 +147,14 @@ void RefreshRateOverlay::drawNumber(int number, int left, SkColor color, SkCanva SegmentDrawer::drawDigit(number % 10, left, color, canvas); } void RefreshRateOverlay::drawDash(int left, SkCanvas& canvas) { left += kDigitWidth + kDigitSpace; SegmentDrawer::drawSegment(SegmentDrawer::Segment::Middle, left, SK_ColorRED, canvas); left += kDigitWidth + kDigitSpace; SegmentDrawer::drawSegment(SegmentDrawer::Segment::Middle, left, SK_ColorRED, canvas); } std::unique_ptr<RefreshRateOverlay> RefreshRateOverlay::create(FpsRange range, ftl::Flags<Features> features) { std::unique_ptr<RefreshRateOverlay> overlay = Loading Loading @@ -171,7 +188,8 @@ bool RefreshRateOverlay::initCheck() const { return mSurfaceControl != nullptr; } auto RefreshRateOverlay::getOrCreateBuffers(Fps refreshRate, Fps renderFps) -> const Buffers& { auto RefreshRateOverlay::getOrCreateBuffers(Fps refreshRate, Fps renderFps, bool idle) -> const Buffers& { static const Buffers kNoBuffers; if (!mSurfaceControl) return kNoBuffers; Loading @@ -197,8 +215,8 @@ auto RefreshRateOverlay::getOrCreateBuffers(Fps refreshRate, Fps renderFps) -> c createTransaction().setTransform(mSurfaceControl->get(), transform).apply(); BufferCache::const_iterator it = mBufferCache.find({refreshRate.getIntValue(), renderFps.getIntValue(), transformHint}); BufferCache::const_iterator it = mBufferCache.find( {refreshRate.getIntValue(), renderFps.getIntValue(), transformHint, idle}); if (it == mBufferCache.end()) { const int maxFps = mFpsRange.max.getIntValue(); Loading @@ -222,10 +240,10 @@ auto RefreshRateOverlay::getOrCreateBuffers(Fps refreshRate, Fps renderFps) -> c const SkColor color = colorBase.toSkColor(); auto buffers = draw(refreshIntFps, renderIntFps, color, transformHint, mFeatures); auto buffers = draw(refreshIntFps, renderIntFps, idle, color, transformHint, mFeatures); it = mBufferCache .try_emplace({refreshIntFps, renderIntFps, transformHint}, std::move(buffers)) .first; .try_emplace({refreshIntFps, renderIntFps, transformHint, idle}, std::move(buffers)).first; } return it->second; Loading Loading @@ -257,7 +275,15 @@ void RefreshRateOverlay::setLayerStack(ui::LayerStack stack) { void RefreshRateOverlay::changeRefreshRate(Fps refreshRate, Fps renderFps) { mRefreshRate = refreshRate; mRenderFps = renderFps; const auto buffer = getOrCreateBuffers(refreshRate, renderFps)[mFrame]; const auto buffer = getOrCreateBuffers(refreshRate, renderFps, mIsVrrIdle)[mFrame]; createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply(); } void RefreshRateOverlay::onVrrIdle(bool idle) { mIsVrrIdle = idle; if (!mRefreshRate || !mRenderFps) return; const auto buffer = getOrCreateBuffers(*mRefreshRate, *mRenderFps, mIsVrrIdle)[mFrame]; createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply(); } Loading @@ -265,7 +291,7 @@ void RefreshRateOverlay::changeRenderRate(Fps renderFps) { if (mFeatures.test(Features::RenderRate) && mRefreshRate && FlagManager::getInstance().misc1()) { mRenderFps = renderFps; const auto buffer = getOrCreateBuffers(*mRefreshRate, renderFps)[mFrame]; const auto buffer = getOrCreateBuffers(*mRefreshRate, renderFps, mIsVrrIdle)[mFrame]; createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply(); } } Loading @@ -273,7 +299,7 @@ void RefreshRateOverlay::changeRenderRate(Fps renderFps) { void RefreshRateOverlay::animate() { if (!mFeatures.test(Features::Spinner) || !mRefreshRate) return; const auto& buffers = getOrCreateBuffers(*mRefreshRate, *mRenderFps); const auto& buffers = getOrCreateBuffers(*mRefreshRate, *mRenderFps, mIsVrrIdle); mFrame = (mFrame + 1) % buffers.size(); const auto buffer = buffers[mFrame]; createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply(); Loading services/surfaceflinger/RefreshRateOverlay.h +8 −4 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ public: void changeRenderRate(Fps); void animate(); bool isSetByHwc() const { return mFeatures.test(RefreshRateOverlay::Features::SetByHwc); } void onVrrIdle(bool idle); RefreshRateOverlay(ConstructorTag, FpsRange, ftl::Flags<Features>); Loading @@ -65,11 +66,12 @@ private: using Buffers = std::vector<sp<GraphicBuffer>>; static Buffers draw(int refreshRate, int renderFps, SkColor, ui::Transform::RotationFlags, ftl::Flags<Features>); static Buffers draw(int refreshRate, int renderFps, bool idle, SkColor, ui::Transform::RotationFlags, ftl::Flags<Features>); static void drawNumber(int number, int left, SkColor, SkCanvas&); static void drawDash(int left, SkCanvas&); const Buffers& getOrCreateBuffers(Fps, Fps); const Buffers& getOrCreateBuffers(Fps, Fps, bool); SurfaceComposerClient::Transaction createTransaction() const; Loading @@ -77,10 +79,11 @@ private: int refreshRate; int renderFps; ui::Transform::RotationFlags flags; bool idle; bool operator==(Key other) const { return refreshRate == other.refreshRate && renderFps == other.renderFps && flags == other.flags; flags == other.flags && idle == other.idle; } }; Loading @@ -89,6 +92,7 @@ private: std::optional<Fps> mRefreshRate; std::optional<Fps> mRenderFps; bool mIsVrrIdle = false; size_t mFrame = 0; const FpsRange mFpsRange; // For color interpolation. Loading services/surfaceflinger/Scheduler/ISchedulerCallback.h +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct ISchedulerCallback { virtual void onExpectedPresentTimePosted(TimePoint, ftl::NonNull<DisplayModePtr>, Fps renderRate) = 0; virtual void onCommitNotComposited(PhysicalDisplayId pacesetterDisplayId) = 0; virtual void vrrDisplayIdle(bool idle) = 0; protected: ~ISchedulerCallback() = default; Loading Loading
services/surfaceflinger/DisplayDevice.cpp +6 −0 Original line number Diff line number Diff line Loading @@ -468,6 +468,12 @@ bool DisplayDevice::onKernelTimerChanged(std::optional<DisplayModeId> desiredMod return false; } void DisplayDevice::onVrrIdle(bool idle) { if (mRefreshRateOverlay) { mRefreshRateOverlay->onVrrIdle(idle); } } void DisplayDevice::animateOverlay() { if (mRefreshRateOverlay) { mRefreshRateOverlay->animate(); Loading
services/surfaceflinger/DisplayDevice.h +1 −0 Original line number Diff line number Diff line Loading @@ -196,6 +196,7 @@ public: bool isRefreshRateOverlayEnabled() const { return mRefreshRateOverlay != nullptr; } void animateOverlay(); bool onKernelTimerChanged(std::optional<DisplayModeId>, bool timerExpired); void onVrrIdle(bool idle); // Enables an overlay to be display with the hdr/sdr ratio void enableHdrSdrRatioOverlay(bool enable) REQUIRES(kMainThreadContext); Loading
services/surfaceflinger/RefreshRateOverlay.cpp +38 −12 Original line number Diff line number Diff line Loading @@ -28,10 +28,11 @@ namespace android { auto RefreshRateOverlay::draw(int refreshRate, int renderFps, SkColor color, auto RefreshRateOverlay::draw(int refreshRate, int renderFps, bool idle, SkColor color, ui::Transform::RotationFlags rotation, ftl::Flags<Features> features) -> Buffers { const size_t loopCount = features.test(Features::Spinner) ? 6 : 1; const bool isSetByHwc = features.test(Features::SetByHwc); Buffers buffers; buffers.reserve(loopCount); Loading Loading @@ -71,7 +72,11 @@ auto RefreshRateOverlay::draw(int refreshRate, int renderFps, SkColor color, canvas->setMatrix(canvasTransform); int left = 0; if (idle && !isSetByHwc) { drawDash(left, *canvas); } else { drawNumber(refreshRate, left, color, *canvas); } left += 3 * (kDigitWidth + kDigitSpace); if (features.test(Features::Spinner)) { switch (i) { Loading Loading @@ -104,8 +109,12 @@ auto RefreshRateOverlay::draw(int refreshRate, int renderFps, SkColor color, left += kDigitWidth + kDigitSpace; if (features.test(Features::RenderRate)) { if (idle) { drawDash(left, *canvas); } else { drawNumber(renderFps, left, color, *canvas); } } left += 3 * (kDigitWidth + kDigitSpace); void* pixels = nullptr; Loading Loading @@ -138,6 +147,14 @@ void RefreshRateOverlay::drawNumber(int number, int left, SkColor color, SkCanva SegmentDrawer::drawDigit(number % 10, left, color, canvas); } void RefreshRateOverlay::drawDash(int left, SkCanvas& canvas) { left += kDigitWidth + kDigitSpace; SegmentDrawer::drawSegment(SegmentDrawer::Segment::Middle, left, SK_ColorRED, canvas); left += kDigitWidth + kDigitSpace; SegmentDrawer::drawSegment(SegmentDrawer::Segment::Middle, left, SK_ColorRED, canvas); } std::unique_ptr<RefreshRateOverlay> RefreshRateOverlay::create(FpsRange range, ftl::Flags<Features> features) { std::unique_ptr<RefreshRateOverlay> overlay = Loading Loading @@ -171,7 +188,8 @@ bool RefreshRateOverlay::initCheck() const { return mSurfaceControl != nullptr; } auto RefreshRateOverlay::getOrCreateBuffers(Fps refreshRate, Fps renderFps) -> const Buffers& { auto RefreshRateOverlay::getOrCreateBuffers(Fps refreshRate, Fps renderFps, bool idle) -> const Buffers& { static const Buffers kNoBuffers; if (!mSurfaceControl) return kNoBuffers; Loading @@ -197,8 +215,8 @@ auto RefreshRateOverlay::getOrCreateBuffers(Fps refreshRate, Fps renderFps) -> c createTransaction().setTransform(mSurfaceControl->get(), transform).apply(); BufferCache::const_iterator it = mBufferCache.find({refreshRate.getIntValue(), renderFps.getIntValue(), transformHint}); BufferCache::const_iterator it = mBufferCache.find( {refreshRate.getIntValue(), renderFps.getIntValue(), transformHint, idle}); if (it == mBufferCache.end()) { const int maxFps = mFpsRange.max.getIntValue(); Loading @@ -222,10 +240,10 @@ auto RefreshRateOverlay::getOrCreateBuffers(Fps refreshRate, Fps renderFps) -> c const SkColor color = colorBase.toSkColor(); auto buffers = draw(refreshIntFps, renderIntFps, color, transformHint, mFeatures); auto buffers = draw(refreshIntFps, renderIntFps, idle, color, transformHint, mFeatures); it = mBufferCache .try_emplace({refreshIntFps, renderIntFps, transformHint}, std::move(buffers)) .first; .try_emplace({refreshIntFps, renderIntFps, transformHint, idle}, std::move(buffers)).first; } return it->second; Loading Loading @@ -257,7 +275,15 @@ void RefreshRateOverlay::setLayerStack(ui::LayerStack stack) { void RefreshRateOverlay::changeRefreshRate(Fps refreshRate, Fps renderFps) { mRefreshRate = refreshRate; mRenderFps = renderFps; const auto buffer = getOrCreateBuffers(refreshRate, renderFps)[mFrame]; const auto buffer = getOrCreateBuffers(refreshRate, renderFps, mIsVrrIdle)[mFrame]; createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply(); } void RefreshRateOverlay::onVrrIdle(bool idle) { mIsVrrIdle = idle; if (!mRefreshRate || !mRenderFps) return; const auto buffer = getOrCreateBuffers(*mRefreshRate, *mRenderFps, mIsVrrIdle)[mFrame]; createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply(); } Loading @@ -265,7 +291,7 @@ void RefreshRateOverlay::changeRenderRate(Fps renderFps) { if (mFeatures.test(Features::RenderRate) && mRefreshRate && FlagManager::getInstance().misc1()) { mRenderFps = renderFps; const auto buffer = getOrCreateBuffers(*mRefreshRate, renderFps)[mFrame]; const auto buffer = getOrCreateBuffers(*mRefreshRate, renderFps, mIsVrrIdle)[mFrame]; createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply(); } } Loading @@ -273,7 +299,7 @@ void RefreshRateOverlay::changeRenderRate(Fps renderFps) { void RefreshRateOverlay::animate() { if (!mFeatures.test(Features::Spinner) || !mRefreshRate) return; const auto& buffers = getOrCreateBuffers(*mRefreshRate, *mRenderFps); const auto& buffers = getOrCreateBuffers(*mRefreshRate, *mRenderFps, mIsVrrIdle); mFrame = (mFrame + 1) % buffers.size(); const auto buffer = buffers[mFrame]; createTransaction().setBuffer(mSurfaceControl->get(), buffer).apply(); Loading
services/surfaceflinger/RefreshRateOverlay.h +8 −4 Original line number Diff line number Diff line Loading @@ -57,6 +57,7 @@ public: void changeRenderRate(Fps); void animate(); bool isSetByHwc() const { return mFeatures.test(RefreshRateOverlay::Features::SetByHwc); } void onVrrIdle(bool idle); RefreshRateOverlay(ConstructorTag, FpsRange, ftl::Flags<Features>); Loading @@ -65,11 +66,12 @@ private: using Buffers = std::vector<sp<GraphicBuffer>>; static Buffers draw(int refreshRate, int renderFps, SkColor, ui::Transform::RotationFlags, ftl::Flags<Features>); static Buffers draw(int refreshRate, int renderFps, bool idle, SkColor, ui::Transform::RotationFlags, ftl::Flags<Features>); static void drawNumber(int number, int left, SkColor, SkCanvas&); static void drawDash(int left, SkCanvas&); const Buffers& getOrCreateBuffers(Fps, Fps); const Buffers& getOrCreateBuffers(Fps, Fps, bool); SurfaceComposerClient::Transaction createTransaction() const; Loading @@ -77,10 +79,11 @@ private: int refreshRate; int renderFps; ui::Transform::RotationFlags flags; bool idle; bool operator==(Key other) const { return refreshRate == other.refreshRate && renderFps == other.renderFps && flags == other.flags; flags == other.flags && idle == other.idle; } }; Loading @@ -89,6 +92,7 @@ private: std::optional<Fps> mRefreshRate; std::optional<Fps> mRenderFps; bool mIsVrrIdle = false; size_t mFrame = 0; const FpsRange mFpsRange; // For color interpolation. Loading
services/surfaceflinger/Scheduler/ISchedulerCallback.h +1 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,7 @@ struct ISchedulerCallback { virtual void onExpectedPresentTimePosted(TimePoint, ftl::NonNull<DisplayModePtr>, Fps renderRate) = 0; virtual void onCommitNotComposited(PhysicalDisplayId pacesetterDisplayId) = 0; virtual void vrrDisplayIdle(bool idle) = 0; protected: ~ISchedulerCallback() = default; Loading