summaryrefslogtreecommitdiff
path: root/services/surfaceflinger/Scheduler/EventThread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/surfaceflinger/Scheduler/EventThread.cpp')
-rw-r--r--services/surfaceflinger/Scheduler/EventThread.cpp243
1 files changed, 77 insertions, 166 deletions
diff --git a/services/surfaceflinger/Scheduler/EventThread.cpp b/services/surfaceflinger/Scheduler/EventThread.cpp
index 2321e2d082..cee36a121f 100644
--- a/services/surfaceflinger/Scheduler/EventThread.cpp
+++ b/services/surfaceflinger/Scheduler/EventThread.cpp
@@ -31,8 +31,6 @@
#include <android-base/stringprintf.h>
-#include <binder/IPCThreadState.h>
-
#include <cutils/compiler.h>
#include <cutils/sched_policy.h>
@@ -41,13 +39,8 @@
#include <utils/Errors.h>
#include <utils/Trace.h>
-#include "DisplayHardware/DisplayMode.h"
-#include "FrameTimeline.h"
-
#include "EventThread.h"
-
-#undef LOG_TAG
-#define LOG_TAG "EventThread"
+#include "HwcStrongTypes.h"
using namespace std::chrono_literals;
@@ -68,8 +61,6 @@ std::string toString(VSyncRequest request) {
return "VSyncRequest::None";
case VSyncRequest::Single:
return "VSyncRequest::Single";
- case VSyncRequest::SingleSuppressCallback:
- return "VSyncRequest::SingleSuppressCallback";
default:
return StringPrintf("VSyncRequest::Periodic{period=%d}", vsyncPeriod(request));
}
@@ -83,16 +74,18 @@ std::string toString(const EventThreadConnection& connection) {
std::string toString(const DisplayEventReceiver::Event& event) {
switch (event.header.type) {
case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
- return StringPrintf("Hotplug{displayId=%s, %s}",
- to_string(event.header.displayId).c_str(),
+ return StringPrintf("Hotplug{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", %s}",
+ event.header.displayId,
event.hotplug.connected ? "connected" : "disconnected");
case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
- return StringPrintf("VSync{displayId=%s, count=%u, expectedVSyncTimestamp=%" PRId64 "}",
- to_string(event.header.displayId).c_str(), event.vsync.count,
+ return StringPrintf("VSync{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT
+ ", count=%u, expectedVSyncTimestamp=%" PRId64 "}",
+ event.header.displayId, event.vsync.count,
event.vsync.expectedVSyncTimestamp);
- case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE:
- return StringPrintf("ModeChanged{displayId=%s, modeId=%u}",
- to_string(event.header.displayId).c_str(), event.modeChange.modeId);
+ case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED:
+ return StringPrintf("ConfigChanged{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT
+ ", configId=%u}",
+ event.header.displayId, event.config.configId);
default:
return "Event{}";
}
@@ -107,56 +100,30 @@ DisplayEventReceiver::Event makeHotplug(PhysicalDisplayId displayId, nsecs_t tim
}
DisplayEventReceiver::Event makeVSync(PhysicalDisplayId displayId, nsecs_t timestamp,
- uint32_t count, nsecs_t expectedVSyncTimestamp,
- nsecs_t deadlineTimestamp, int64_t vsyncId) {
+ uint32_t count, nsecs_t expectedVSyncTimestamp) {
DisplayEventReceiver::Event event;
event.header = {DisplayEventReceiver::DISPLAY_EVENT_VSYNC, displayId, timestamp};
event.vsync.count = count;
event.vsync.expectedVSyncTimestamp = expectedVSyncTimestamp;
- event.vsync.deadlineTimestamp = deadlineTimestamp;
- event.vsync.vsyncId = vsyncId;
return event;
}
-DisplayEventReceiver::Event makeModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId,
- nsecs_t vsyncPeriod) {
+DisplayEventReceiver::Event makeConfigChanged(PhysicalDisplayId displayId,
+ HwcConfigIndexType configId, nsecs_t vsyncPeriod) {
DisplayEventReceiver::Event event;
- event.header = {DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE, displayId, systemTime()};
- event.modeChange.modeId = modeId.value();
- event.modeChange.vsyncPeriod = vsyncPeriod;
+ event.header = {DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED, displayId, systemTime()};
+ event.config.configId = configId.value();
+ event.config.vsyncPeriod = vsyncPeriod;
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::EventRegistrationFlags eventRegistration)
+EventThreadConnection::EventThreadConnection(EventThread* eventThread,
+ ResyncCallback resyncCallback,
+ ISurfaceComposer::ConfigChanged configChanged)
: resyncCallback(std::move(resyncCallback)),
- mOwnerUid(callingUid),
- mEventRegistration(eventRegistration),
+ mConfigChanged(configChanged),
mEventThread(eventThread),
mChannel(gui::BitTube::DefaultSize) {}
@@ -172,7 +139,6 @@ void EventThreadConnection::onFirstRef() {
status_t EventThreadConnection::stealReceiveChannel(gui::BitTube* outChannel) {
outChannel->setReceiveFd(mChannel.moveReceiveFd());
- outChannel->setSendFd(base::unique_fd(dup(mChannel.getSendFd())));
return NO_ERROR;
}
@@ -186,26 +152,14 @@ void EventThreadConnection::requestNextVsync() {
mEventThread->requestNextVsync(this);
}
-status_t EventThreadConnection::postEvent(const DisplayEventReceiver::Event& event) {
- 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);
- }
+void EventThreadConnection::requestLatestConfig() {
+ ATRACE_NAME("requestLatestConfig");
+ mEventThread->requestLatestConfig(this);
+}
- auto size = DisplayEventReceiver::sendEvents(&mChannel, &event, 1);
- return toStatus(size);
+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);
}
// ---------------------------------------------------------------------------
@@ -215,20 +169,10 @@ EventThread::~EventThread() = default;
namespace impl {
EventThread::EventThread(std::unique_ptr<VSyncSource> vsyncSource,
- android::frametimeline::TokenManager* tokenManager,
- InterceptVSyncsCallback interceptVSyncsCallback,
- ThrottleVsyncCallback throttleVsyncCallback,
- GetVsyncPeriodFunction getVsyncPeriodFunction)
+ InterceptVSyncsCallback interceptVSyncsCallback)
: mVSyncSource(std::move(vsyncSource)),
- mTokenManager(tokenManager),
mInterceptVSyncsCallback(std::move(interceptVSyncsCallback)),
- mThrottleVsyncCallback(std::move(throttleVsyncCallback)),
- mGetVsyncPeriodFunction(std::move(getVsyncPeriodFunction)),
mThreadName(mVSyncSource->getName()) {
-
- LOG_ALWAYS_FATAL_IF(getVsyncPeriodFunction == nullptr,
- "getVsyncPeriodFunction must not be null");
-
mVSyncSource->setCallback(this);
mThread = std::thread([this]() NO_THREAD_SAFETY_ANALYSIS {
@@ -262,18 +206,15 @@ EventThread::~EventThread() {
mThread.join();
}
-void EventThread::setDuration(std::chrono::nanoseconds workDuration,
- std::chrono::nanoseconds readyDuration) {
+void EventThread::setPhaseOffset(nsecs_t phaseOffset) {
std::lock_guard<std::mutex> lock(mMutex);
- mVSyncSource->setDuration(workDuration, readyDuration);
+ mVSyncSource->setPhaseOffset(phaseOffset);
}
sp<EventThreadConnection> EventThread::createEventConnection(
- ResyncCallback resyncCallback,
- ISurfaceComposer::EventRegistrationFlags eventRegistration) const {
- return new EventThreadConnection(const_cast<EventThread*>(this),
- IPCThreadState::self()->getCallingUid(),
- std::move(resyncCallback), eventRegistration);
+ ResyncCallback resyncCallback, ISurfaceComposer::ConfigChanged configChanged) const {
+ return new EventThreadConnection(const_cast<EventThread*>(this), std::move(resyncCallback),
+ configChanged);
}
status_t EventThread::registerDisplayEventConnection(const sp<EventThreadConnection>& connection) {
@@ -325,11 +266,31 @@ void EventThread::requestNextVsync(const sp<EventThreadConnection>& connection)
if (connection->vsyncRequest == VSyncRequest::None) {
connection->vsyncRequest = VSyncRequest::Single;
mCondition.notify_all();
- } else if (connection->vsyncRequest == VSyncRequest::SingleSuppressCallback) {
- connection->vsyncRequest = VSyncRequest::Single;
}
}
+void EventThread::requestLatestConfig(const sp<EventThreadConnection>& connection) {
+ std::lock_guard<std::mutex> lock(mMutex);
+ if (connection->mForcedConfigChangeDispatch) {
+ return;
+ }
+ connection->mForcedConfigChangeDispatch = true;
+ auto pendingConfigChange =
+ std::find_if(std::begin(mPendingEvents), std::end(mPendingEvents),
+ [&](const DisplayEventReceiver::Event& event) {
+ return event.header.type ==
+ DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED;
+ });
+
+ // If we didn't find a pending config change event, then push out the
+ // latest one we've ever seen.
+ if (pendingConfigChange == std::end(mPendingEvents)) {
+ mPendingEvents.push_back(mLastConfigChangeEvent);
+ }
+
+ mCondition.notify_all();
+}
+
void EventThread::onScreenReleased() {
std::lock_guard<std::mutex> lock(mMutex);
if (!mVSyncState || mVSyncState->synthetic) {
@@ -350,21 +311,12 @@ void EventThread::onScreenAcquired() {
mCondition.notify_all();
}
-void EventThread::onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp,
- nsecs_t deadlineTimestamp) {
+void EventThread::onVSyncEvent(nsecs_t timestamp, nsecs_t expectedVSyncTimestamp) {
std::lock_guard<std::mutex> lock(mMutex);
LOG_FATAL_IF(!mVSyncState);
- const int64_t vsyncId = [&] {
- if (mTokenManager != nullptr) {
- return mTokenManager->generateTokenForPredictions(
- {timestamp, deadlineTimestamp, expectedVSyncTimestamp});
- }
- return FrameTimelineInfo::INVALID_VSYNC_ID;
- }();
-
mPendingEvents.push_back(makeVSync(mVSyncState->displayId, timestamp, ++mVSyncState->count,
- expectedVSyncTimestamp, deadlineTimestamp, vsyncId));
+ expectedVSyncTimestamp));
mCondition.notify_all();
}
@@ -375,23 +327,11 @@ void EventThread::onHotplugReceived(PhysicalDisplayId displayId, bool connected)
mCondition.notify_all();
}
-void EventThread::onModeChanged(PhysicalDisplayId displayId, DisplayModeId modeId,
- nsecs_t vsyncPeriod) {
+void EventThread::onConfigChanged(PhysicalDisplayId displayId, HwcConfigIndexType configId,
+ nsecs_t vsyncPeriod) {
std::lock_guard<std::mutex> lock(mMutex);
- mPendingEvents.push_back(makeModeChanged(displayId, modeId, vsyncPeriod));
- 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));
-
+ mPendingEvents.push_back(makeConfigChanged(displayId, configId, vsyncPeriod));
mCondition.notify_all();
}
@@ -426,6 +366,9 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
mInterceptVSyncsCallback(event->header.timestamp);
}
break;
+ case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED:
+ mLastConfigChangeEvent = *event;
+ break;
}
}
@@ -438,6 +381,10 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
vsyncRequested |= connection->vsyncRequest != VSyncRequest::None;
if (event && shouldConsumeEvent(*event, connection)) {
+ if (event->header.type == DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED &&
+ connection->mForcedConfigChangeDispatch) {
+ connection->mForcedConfigChangeDispatch = false;
+ }
consumers.push_back(connection);
}
@@ -498,18 +445,9 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
LOG_FATAL_IF(!mVSyncState);
const auto now = systemTime(SYSTEM_TIME_MONOTONIC);
- const auto deadlineTimestamp = now + timeout.count();
- const auto expectedVSyncTime = deadlineTimestamp + timeout.count();
- const int64_t vsyncId = [&] {
- if (mTokenManager != nullptr) {
- return mTokenManager->generateTokenForPredictions(
- {now, deadlineTimestamp, expectedVSyncTime});
- }
- return FrameTimelineInfo::INVALID_VSYNC_ID;
- }();
+ const auto expectedVSyncTime = now + timeout.count();
mPendingEvents.push_back(makeVSync(mVSyncState->displayId, now,
- ++mVSyncState->count, expectedVSyncTime,
- deadlineTimestamp, vsyncId));
+ ++mVSyncState->count, expectedVSyncTime));
}
}
}
@@ -517,52 +455,29 @@ void EventThread::threadMain(std::unique_lock<std::mutex>& lock) {
bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event,
const sp<EventThreadConnection>& connection) const {
- const auto throttleVsync = [&] {
- return mThrottleVsyncCallback &&
- mThrottleVsyncCallback(event.vsync.expectedVSyncTimestamp, connection->mOwnerUid);
- };
-
switch (event.header.type) {
case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
return true;
- case DisplayEventReceiver::DISPLAY_EVENT_MODE_CHANGE: {
- return connection->mEventRegistration.test(
- ISurfaceComposer::EventRegistration::modeChanged);
+ case DisplayEventReceiver::DISPLAY_EVENT_CONFIG_CHANGED: {
+ const bool oneTimeDispatch = connection->mForcedConfigChangeDispatch;
+ return oneTimeDispatch ||
+ connection->mConfigChanged == ISurfaceComposer::eConfigChangedDispatch;
}
case DisplayEventReceiver::DISPLAY_EVENT_VSYNC:
switch (connection->vsyncRequest) {
case VSyncRequest::None:
return false;
- case VSyncRequest::SingleSuppressCallback:
+ case VSyncRequest::Single:
connection->vsyncRequest = VSyncRequest::None;
- return false;
- case VSyncRequest::Single: {
- if (throttleVsync()) {
- return false;
- }
- connection->vsyncRequest = VSyncRequest::SingleSuppressCallback;
return true;
- }
case VSyncRequest::Periodic:
- if (throttleVsync()) {
- return false;
- }
return true;
default:
- // We don't throttle vsync if the app set a vsync request rate
- // since there is no easy way to do that and this is a very
- // rare case
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;
}
@@ -571,11 +486,7 @@ bool EventThread::shouldConsumeEvent(const DisplayEventReceiver::Event& event,
void EventThread::dispatchEvent(const DisplayEventReceiver::Event& event,
const DisplayEventConsumers& consumers) {
for (const auto& consumer : consumers) {
- DisplayEventReceiver::Event copy = event;
- if (event.header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
- copy.vsync.frameInterval = mGetVsyncPeriodFunction(consumer->mOwnerUid);
- }
- switch (consumer->postEvent(copy)) {
+ switch (consumer->postEvent(event)) {
case NO_ERROR:
break;
@@ -597,8 +508,8 @@ void EventThread::dump(std::string& result) const {
StringAppendF(&result, "%s: state=%s VSyncState=", mThreadName, toCString(mState));
if (mVSyncState) {
- StringAppendF(&result, "{displayId=%s, count=%u%s}\n",
- to_string(mVSyncState->displayId).c_str(), mVSyncState->count,
+ StringAppendF(&result, "{displayId=%" ANDROID_PHYSICAL_DISPLAY_ID_FORMAT ", count=%u%s}\n",
+ mVSyncState->displayId, mVSyncState->count,
mVSyncState->synthetic ? ", synthetic" : "");
} else {
StringAppendF(&result, "none\n");