diff options
| -rw-r--r-- | services/surfaceflinger/RefreshRateOverlay.cpp | 20 | ||||
| -rw-r--r-- | services/surfaceflinger/RefreshRateOverlay.h | 26 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 94 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.h | 15 |
4 files changed, 95 insertions, 60 deletions
diff --git a/services/surfaceflinger/RefreshRateOverlay.cpp b/services/surfaceflinger/RefreshRateOverlay.cpp index 436a83b3a2..f602412930 100644 --- a/services/surfaceflinger/RefreshRateOverlay.cpp +++ b/services/surfaceflinger/RefreshRateOverlay.cpp @@ -200,26 +200,22 @@ void RefreshRateOverlay::primeCache() { } } -void RefreshRateOverlay::changeRefreshRate(const RefreshRate& refreshRate) { - const auto display = mFlinger.getDefaultDisplayDeviceLocked(); - if (!display) { - return; - } +void RefreshRateOverlay::setViewport(ui::Size viewport) { + Rect frame(viewport.width >> 3, viewport.height >> 5); + frame.offsetBy(viewport.width >> 5, viewport.height >> 4); + mLayer->setFrame(frame); - const int32_t left = display->getWidth() / 32; - const int32_t top = display->getHeight() / 16; - const int32_t right = left + display->getWidth() / 8; - const int32_t buttom = top + display->getHeight() / 32; + mFlinger.mTransactionFlags.fetch_or(eTransactionMask); +} +void RefreshRateOverlay::changeRefreshRate(const RefreshRate& refreshRate) { auto buffer = mBufferCache[refreshRate.getFps()]; mLayer->setBuffer(buffer, Fence::NO_FENCE, 0, 0, {}); - mLayer->setFrame(Rect(left, top, right, buttom)); - mFlinger.mTransactionFlags.fetch_or(eTransactionMask); } -}; // namespace android +} // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic pop // ignored "-Wconversion" diff --git a/services/surfaceflinger/RefreshRateOverlay.h b/services/surfaceflinger/RefreshRateOverlay.h index 6d34df220c..35c80201d7 100644 --- a/services/surfaceflinger/RefreshRateOverlay.h +++ b/services/surfaceflinger/RefreshRateOverlay.h @@ -13,19 +13,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #pragma once -#include "SurfaceFlinger.h" +#include <unordered_map> + +#include <math/vec4.h> +#include <ui/Rect.h> +#include <ui/Size.h> +#include <utils/StrongPointer.h> + +#include "Scheduler/RefreshRateConfigs.h" namespace android { +class Client; +class GraphicBuffer; +class IBinder; +class IGraphicBufferProducer; +class Layer; +class SurfaceFlinger; + using RefreshRate = scheduler::RefreshRateConfigs::RefreshRate; class RefreshRateOverlay { public: - RefreshRateOverlay(SurfaceFlinger& flinger); + explicit RefreshRateOverlay(SurfaceFlinger&); - void changeRefreshRate(const RefreshRate& refreshRate); + void setViewport(ui::Size); + void changeRefreshRate(const RefreshRate&); private: class SevenSegmentDrawer { @@ -56,7 +72,7 @@ private: void primeCache(); SurfaceFlinger& mFlinger; - sp<Client> mClient; + const sp<Client> mClient; sp<Layer> mLayer; sp<IBinder> mIBinder; sp<IGraphicBufferProducer> mGbp; @@ -68,4 +84,4 @@ private: const half3 HIGH_FPS_COLOR = half3(0.0f, 1.0f, 0.0f); }; -}; // namespace android +} // namespace android diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 87e73a0e7a..bc878871a0 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -582,14 +582,13 @@ void SurfaceFlinger::bootFinished() LOG_EVENT_LONG(LOGTAG_SF_STOP_BOOTANIM, ns2ms(systemTime(SYSTEM_TIME_MONOTONIC))); - static_cast<void>(schedule([this]() NO_THREAD_SAFETY_ANALYSIS { + static_cast<void>(schedule([this] { readPersistentProperties(); mPowerAdvisor.onBootFinished(); mBootStage = BootStage::FINISHED; if (property_get_bool("sf.debug.show_refresh_rate_overlay", false)) { - mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(*this); - mRefreshRateOverlay->changeRefreshRate(mRefreshRateConfigs->getCurrentRefreshRate()); + enableRefreshRateOverlay(true); } })); } @@ -934,9 +933,8 @@ int SurfaceFlinger::getActiveConfig(const sp<IBinder>& displayToken) { } if (isPrimary) { - std::lock_guard<std::mutex> lock(mActiveConfigLock); - if (mDesiredActiveConfigChanged) { - return mDesiredActiveConfig.configId.value(); + if (const auto config = getDesiredActiveConfig()) { + return config->configId.value(); } } @@ -1063,14 +1061,7 @@ void SurfaceFlinger::performSetActiveConfig() { ATRACE_CALL(); ALOGV("performSetActiveConfig"); // Store the local variable to release the lock. - const auto desiredActiveConfig = [&]() -> std::optional<ActiveConfigInfo> { - std::lock_guard<std::mutex> lock(mActiveConfigLock); - if (mDesiredActiveConfigChanged) { - return mDesiredActiveConfig; - } - return std::nullopt; - }(); - + const auto desiredActiveConfig = getDesiredActiveConfig(); if (!desiredActiveConfig) { // No desired active config pending to be applied return; @@ -1605,7 +1596,7 @@ void SurfaceFlinger::changeRefreshRateLocked(const RefreshRate& refreshRate, } void SurfaceFlinger::onHotplugReceived(int32_t sequenceId, hal::HWDisplayId hwcDisplayId, - hal::Connection connection) { + hal::Connection connection) NO_THREAD_SAFETY_ANALYSIS { ALOGV("%s(%d, %" PRIu64 ", %s)", __FUNCTION__, sequenceId, hwcDisplayId, connection == hal::Connection::CONNECTED ? "connected" : "disconnected"); @@ -2679,9 +2670,14 @@ void SurfaceFlinger::processDisplayChanged(const wp<IBinder>& displayToken, if (currentState.width != drawingState.width || currentState.height != drawingState.height) { display->setDisplaySize(currentState.width, currentState.height); + if (display->isPrimary()) { mScheduler->onPrimaryDisplayAreaChanged(currentState.width * currentState.height); } + + if (mRefreshRateOverlay) { + mRefreshRateOverlay->setViewport(display->getSize()); + } } } } @@ -5229,15 +5225,15 @@ status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* r return NO_ERROR; } case 1034: { - n = data.readInt32(); - if (n == 1 && !mRefreshRateOverlay) { - mRefreshRateOverlay = std::make_unique<RefreshRateOverlay>(*this); - auto& current = mRefreshRateConfigs->getCurrentRefreshRate(); - mRefreshRateOverlay->changeRefreshRate(current); - } else if (n == 0) { - mRefreshRateOverlay.reset(); - } else { - reply->writeBool(mRefreshRateOverlay != nullptr); + switch (n = data.readInt32()) { + case 0: + case 1: + enableRefreshRateOverlay(static_cast<bool>(n)); + break; + default: { + Mutex::Autolock lock(mStateLock); + reply->writeBool(mRefreshRateOverlay != nullptr); + } } return NO_ERROR; } @@ -5285,29 +5281,26 @@ void SurfaceFlinger::repaintEverythingForHWC() { void SurfaceFlinger::kernelTimerChanged(bool expired) { static bool updateOverlay = property_get_bool("debug.sf.kernel_idle_timer_update_overlay", true); - if (!updateOverlay || !mRefreshRateOverlay) return; + if (!updateOverlay) return; + if (Mutex::Autolock lock(mStateLock); !mRefreshRateOverlay) return; // Update the overlay on the main thread to avoid race conditions with // mRefreshRateConfigs->getCurrentRefreshRate() - static_cast<void>(schedule([=]() NO_THREAD_SAFETY_ANALYSIS { - if (mRefreshRateOverlay) { + static_cast<void>(schedule([=] { + const auto desiredActiveConfig = getDesiredActiveConfig(); + const auto& current = desiredActiveConfig + ? mRefreshRateConfigs->getRefreshRateFromConfigId(desiredActiveConfig->configId) + : mRefreshRateConfigs->getCurrentRefreshRate(); + const auto& min = mRefreshRateConfigs->getMinRefreshRate(); + + if (current != min) { const auto kernelTimerEnabled = property_get_bool(KERNEL_IDLE_TIMER_PROP, false); const bool timerExpired = kernelTimerEnabled && expired; - const auto& current = [this]() -> const RefreshRate& { - std::lock_guard<std::mutex> lock(mActiveConfigLock); - if (mDesiredActiveConfigChanged) { - return mRefreshRateConfigs->getRefreshRateFromConfigId( - mDesiredActiveConfig.configId); - } - - return mRefreshRateConfigs->getCurrentRefreshRate(); - }(); - const auto& min = mRefreshRateConfigs->getMinRefreshRate(); - if (current != min) { + if (Mutex::Autolock lock(mStateLock); mRefreshRateOverlay) { mRefreshRateOverlay->changeRefreshRate(timerExpired ? min : current); - mEventQueue->invalidate(); } + mEventQueue->invalidate(); } })); } @@ -6224,6 +6217,29 @@ void SurfaceFlinger::onFrameRateFlexibilityTokenReleased() { })); } +void SurfaceFlinger::enableRefreshRateOverlay(bool enable) { + static_cast<void>(schedule([=] { + std::unique_ptr<RefreshRateOverlay> overlay; + if (enable) { + overlay = std::make_unique<RefreshRateOverlay>(*this); + } + + { + 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(mRefreshRateConfigs->getCurrentRefreshRate()); + } + })); +} + } // namespace android #if defined(__gl_h_) diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h index f3984ed8d4..715d5f78ea 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -829,13 +829,13 @@ private: const DisplayDeviceState& state, const sp<compositionengine::DisplaySurface>& displaySurface, const sp<IGraphicBufferProducer>& producer); - void processDisplayChangesLocked(); + void processDisplayChangesLocked() REQUIRES(mStateLock); void processDisplayAdded(const wp<IBinder>& displayToken, const DisplayDeviceState& state); void processDisplayRemoved(const wp<IBinder>& displayToken); void processDisplayChanged(const wp<IBinder>& displayToken, const DisplayDeviceState& currentState, - const DisplayDeviceState& drawingState); - void processDisplayHotplugEventsLocked(); + const DisplayDeviceState& drawingState) REQUIRES(mStateLock); + void processDisplayHotplugEventsLocked() REQUIRES(mStateLock); void dispatchDisplayHotplugEvent(PhysicalDisplayId displayId, bool connected); @@ -1216,6 +1216,12 @@ private: * Misc */ + std::optional<ActiveConfigInfo> getDesiredActiveConfig() EXCLUDES(mActiveConfigLock) { + std::lock_guard<std::mutex> lock(mActiveConfigLock); + if (mDesiredActiveConfigChanged) return mDesiredActiveConfig; + return std::nullopt; + } + std::mutex mActiveConfigLock; // This bit is set once we start setting the config. We read from this bit during the // process. If at the end, this bit is different than mDesiredActiveConfig, we restart @@ -1258,7 +1264,8 @@ private: // This should only be accessed on the main thread. nsecs_t mFrameStartTime = 0; - std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay; + void enableRefreshRateOverlay(bool enable); + std::unique_ptr<RefreshRateOverlay> mRefreshRateOverlay GUARDED_BY(mStateLock); // Flag used to set override allowed display configs from backdoor bool mDebugDisplayConfigSetByBackdoor = false; |