SurfaceFlinger: Add DISPLAY_EVENT_FRAME_RATE_OVERRIDE
Add a new event to DisplayEventReceiver that conveys a list
of apps whose frame rates have been overriden.
This event is processed by the DisplayManager to advertise the
new frame rate to the overridden app.
Change-Id: I89fce8b5b4d9db65ec5db7dd2393c384c0fcfd82
Bug: 169271059
Bug: 169271062
Bug: 170503758
Test: manual test using SF backdoor
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index bf5be47..b63e8c8 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -45,6 +45,9 @@
#include "FrameTimeline.h"
#include "HwcStrongTypes.h"
+#undef LOG_TAG
+#define LOG_TAG "EventThread"
+
using namespace std::chrono_literals;
namespace android {
@@ -123,14 +126,36 @@
return event;
}
+DisplayEventReceiver::Event makeFrameRateOverrideEvent(PhysicalDisplayId displayId,
+ FrameRateOverride frameRateOverride) {
+ return DisplayEventReceiver::Event{
+ .header =
+ DisplayEventReceiver::Event::Header{
+ .type = DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE,
+ .displayId = displayId,
+ .timestamp = systemTime(),
+ },
+ .frameRateOverride = frameRateOverride,
+ };
+}
+
+DisplayEventReceiver::Event makeFrameRateOverrideFlushEvent(PhysicalDisplayId displayId) {
+ return DisplayEventReceiver::Event{
+ .header = DisplayEventReceiver::Event::Header{
+ .type = DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH,
+ .displayId = displayId,
+ .timestamp = systemTime(),
+ }};
+}
+
} // namespace
-EventThreadConnection::EventThreadConnection(EventThread* eventThread, uid_t callingUid,
- ResyncCallback resyncCallback,
- ISurfaceComposer::ConfigChanged configChanged)
+EventThreadConnection::EventThreadConnection(
+ EventThread* eventThread, uid_t callingUid, ResyncCallback resyncCallback,
+ ISurfaceComposer::EventRegistrationFlags eventRegistration)
: resyncCallback(std::move(resyncCallback)),
- mConfigChanged(configChanged),
mOwnerUid(callingUid),
+ mEventRegistration(eventRegistration),
mEventThread(eventThread),
mChannel(gui::BitTube::DefaultSize) {}
@@ -161,8 +186,25 @@
}
status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
- ssize_t size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
- return size < 0 ? status_t(size) : status_t(NO_ERROR);
+ constexpr auto toStatus = [](ssize_t size) {
+ return size < 0 ? status_t(size) : status_t(NO_ERROR);
+ };
+
+ if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE ||
+ event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH) {
+ mPendingEvents.emplace_back(event);
+ if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE) {
+ return status_t(NO_ERROR);
+ }
+
+ auto size = DisplayEventReceiver::sendEvents(&mChannel, mPendingEvents.data(),
+ mPendingEvents.size());
+ mPendingEvents.clear();
+ return toStatus(size);
+ }
+
+ auto size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
+ return toStatus(size);
}
// ---------------------------------------------------------------------------
@@ -220,10 +262,11 @@
}
sp<EventThreadConnection> EventThread::createEventConnection(
- ResyncCallback resyncCallback, ISurfaceComposer::ConfigChanged configChanged) const {
+ ResyncCallback resyncCallback,
+ ISurfaceComposer::EventRegistrationFlags eventRegistration) const {
return new EventThreadConnection(const_cast<EventThread*>(this),
IPCThreadState::self()->getCallingUid(),
- std::move(resyncCallback), configChanged);
+ std::move(resyncCallback), eventRegistration);
}
status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
@@ -333,6 +376,18 @@
mCondition.notify_all();
}
+void EventThread::onFrameRateOverridesChanged(PhysicalDisplayId displayId,
+ std::vector<FrameRateOverride> overrides) {
+ std::lock_guard<std::mutex> lock(mMutex);
+
+ for (auto frameRateOverride : overrides) {
+ mPendingEvents.push_back(makeFrameRateOverrideEvent(displayId, frameRateOverride));
+ }
+ mPendingEvents.push_back(makeFrameRateOverrideFlushEvent(displayId));
+
+ mCondition.notify_all();
+}
+
size_t EventThread::getEventThreadConnectionCount() {
std::lock_guard<std::mutex> lock(mMutex);
return mDisplayEventConnections.size();
@@ -459,7 +514,8 @@
return true;
case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED: {
- return connection->mConfigChanged == ISurfaceComposer::eConfigChangedDispatch;
+ return connection->mEventRegistration.test(
+ ISurfaceComposer::EventRegistration::configChanged);
}
case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
@@ -488,6 +544,12 @@
return event.vsync.count % vsyncPeriod(connection->vsyncRequest) == 0;
}
+ case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE:
+ [[fallthrough]];
+ case DisplayEventReceiver::DISPLAY_EVENT_FRAME_RATE_OVERRIDE_FLUSH:
+ return connection->mEventRegistration.test(
+ ISurfaceComposer::EventRegistration::frameRateOverride);
+
default:
return false;
}