Revert "Revert "Send multiple scheduler frame timelines.""
This reverts commit caaa47d60b83670206dcd3c34382719b1f247ab5.
Reason for revert: Fix the reverted CL in 2nd CL.
Bug: 198192508
Bug: 204941507
Test: See 2nd CL.
Change-Id: I15c693c2e0a82ef81a490319da11871bd74298b3
diff --git a/libs/gui/DisplayEventDispatcher.cpp b/libs/gui/DisplayEventDispatcher.cpp
index 6f1a7ae..c986b82 100644
--- a/libs/gui/DisplayEventDispatcher.cpp
+++ b/libs/gui/DisplayEventDispatcher.cpp
@@ -130,6 +130,19 @@
return 1; // keep the callback
}
+void DisplayEventDispatcher::populateFrameTimelines(const DisplayEventReceiver::Event& event,
+ VsyncEventData* outVsyncEventData) const {
+ for (size_t i = 0; i < DisplayEventReceiver::kFrameTimelinesLength; i++) {
+ DisplayEventReceiver::Event::VSync::FrameTimeline receiverTimeline =
+ event.vsync.frameTimelines[i];
+ outVsyncEventData->frameTimelines[i] = {.id = receiverTimeline.vsyncId,
+ .deadlineTimestamp =
+ receiverTimeline.deadlineTimestamp,
+ .expectedPresentTime =
+ receiverTimeline.expectedVSyncTimestamp};
+ }
+}
+
bool DisplayEventDispatcher::processPendingEvents(nsecs_t* outTimestamp,
PhysicalDisplayId* outDisplayId,
uint32_t* outCount,
@@ -154,6 +167,9 @@
outVsyncEventData->deadlineTimestamp = ev.vsync.deadlineTimestamp;
outVsyncEventData->frameInterval = ev.vsync.frameInterval;
outVsyncEventData->expectedPresentTime = ev.vsync.expectedVSyncTimestamp;
+ outVsyncEventData->preferredFrameTimelineIndex =
+ ev.vsync.preferredFrameTimelineIndex;
+ populateFrameTimelines(ev, outVsyncEventData);
break;
case DisplayEventReceiver::DISPLAY_EVENT_HOTPLUG:
dispatchHotplug(ev.header.timestamp, ev.header.displayId, ev.hotplug.connected);
diff --git a/libs/gui/include/gui/DisplayEventDispatcher.h b/libs/gui/include/gui/DisplayEventDispatcher.h
index f3bd139..92c89b8 100644
--- a/libs/gui/include/gui/DisplayEventDispatcher.h
+++ b/libs/gui/include/gui/DisplayEventDispatcher.h
@@ -17,6 +17,7 @@
#include <gui/DisplayEventReceiver.h>
#include <utils/Log.h>
#include <utils/Looper.h>
+#include <array>
namespace android {
using FrameRateOverride = DisplayEventReceiver::Event::FrameRateOverride;
@@ -36,6 +37,26 @@
// The anticipated Vsync present time.
int64_t expectedPresentTime = 0;
+
+ struct FrameTimeline {
+ // The Vsync Id corresponsing to this vsync event. This will be used to
+ // populate ISurfaceComposer::setFrameTimelineVsync and
+ // SurfaceComposerClient::setFrameTimelineVsync
+ int64_t id = FrameTimelineInfo::INVALID_VSYNC_ID;
+
+ // The deadline in CLOCK_MONOTONIC that the app needs to complete its
+ // frame by (both on the CPU and the GPU)
+ int64_t deadlineTimestamp = std::numeric_limits<int64_t>::max();
+
+ // The anticipated Vsync present time.
+ int64_t expectedPresentTime = 0;
+ };
+
+ // Sorted possible frame timelines.
+ std::array<FrameTimeline, DisplayEventReceiver::kFrameTimelinesLength> frameTimelines;
+
+ // Index into the frameTimelines that represents the platform's preferred frame timeline.
+ size_t preferredFrameTimelineIndex = std::numeric_limits<size_t>::max();
};
class DisplayEventDispatcher : public LooperCallback {
@@ -77,5 +98,8 @@
bool processPendingEvents(nsecs_t* outTimestamp, PhysicalDisplayId* outDisplayId,
uint32_t* outCount, VsyncEventData* outVsyncEventData);
+
+ void populateFrameTimelines(const DisplayEventReceiver::Event& event,
+ VsyncEventData* outVsyncEventData) const;
};
} // namespace android
diff --git a/libs/gui/include/gui/DisplayEventReceiver.h b/libs/gui/include/gui/DisplayEventReceiver.h
index 0dffbde..ca36843 100644
--- a/libs/gui/include/gui/DisplayEventReceiver.h
+++ b/libs/gui/include/gui/DisplayEventReceiver.h
@@ -49,6 +49,9 @@
// ----------------------------------------------------------------------------
class DisplayEventReceiver {
public:
+ // Max amount of frame timelines is arbitrarily set to be reasonable.
+ static constexpr int64_t kFrameTimelinesLength = 7;
+
enum {
DISPLAY_EVENT_VSYNC = fourcc('v', 's', 'y', 'n'),
DISPLAY_EVENT_HOTPLUG = fourcc('p', 'l', 'u', 'g'),
@@ -77,6 +80,12 @@
nsecs_t deadlineTimestamp __attribute__((aligned(8)));
nsecs_t frameInterval __attribute__((aligned(8)));
int64_t vsyncId;
+ size_t preferredFrameTimelineIndex __attribute__((aligned(8)));
+ struct FrameTimeline {
+ nsecs_t expectedVSyncTimestamp __attribute__((aligned(8)));
+ nsecs_t deadlineTimestamp __attribute__((aligned(8)));
+ int64_t vsyncId;
+ } frameTimelines[kFrameTimelinesLength];
};
struct Hotplug {
diff --git a/libs/nativedisplay/AChoreographer.cpp b/libs/nativedisplay/AChoreographer.cpp
index 79d9b93..fc9680b 100644
--- a/libs/nativedisplay/AChoreographer.cpp
+++ b/libs/nativedisplay/AChoreographer.cpp
@@ -100,17 +100,10 @@
* Implementation of AChoreographerFrameCallbackData.
*/
struct ChoreographerFrameCallbackDataImpl {
- struct FrameTimeline {
- int64_t vsyncId{0};
- int64_t expectedPresentTimeNanos{0};
- int64_t deadlineNanos{0};
- };
-
int64_t frameTimeNanos{0};
- size_t frameTimelinesLength;
-
- std::vector<FrameTimeline> frameTimelines;
+ std::array<VsyncEventData::FrameTimeline, DisplayEventReceiver::kFrameTimelinesLength>
+ frameTimelines;
size_t preferredFrameTimelineIndex;
@@ -456,14 +449,9 @@
}
ChoreographerFrameCallbackDataImpl Choreographer::createFrameCallbackData(nsecs_t timestamp) const {
- std::vector<ChoreographerFrameCallbackDataImpl::FrameTimeline> frameTimelines;
- frameTimelines.push_back({.vsyncId = mLastVsyncEventData.id,
- .expectedPresentTimeNanos = mLastVsyncEventData.expectedPresentTime,
- .deadlineNanos = mLastVsyncEventData.deadlineTimestamp});
return {.frameTimeNanos = timestamp,
- .frameTimelinesLength = 1,
- .preferredFrameTimelineIndex = 0,
- .frameTimelines = frameTimelines,
+ .preferredFrameTimelineIndex = mLastVsyncEventData.preferredFrameTimelineIndex,
+ .frameTimelines = mLastVsyncEventData.frameTimelines,
.choreographer = this};
}
@@ -646,7 +634,7 @@
AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
"Data is only valid in callback");
- return frameCallbackData->frameTimelinesLength;
+ return frameCallbackData->frameTimelines.size();
}
size_t AChoreographerFrameCallbackData_getPreferredFrameTimelineIndex(
const AChoreographerFrameCallbackData* data) {
@@ -662,8 +650,8 @@
AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
"Data is only valid in callback");
- LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelinesLength, "Index out of bounds");
- return frameCallbackData->frameTimelines[index].vsyncId;
+ LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelines.size(), "Index out of bounds");
+ return frameCallbackData->frameTimelines[index].id;
}
int64_t AChoreographerFrameCallbackData_getFrameTimelineExpectedPresentTime(
const AChoreographerFrameCallbackData* data, size_t index) {
@@ -671,8 +659,8 @@
AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
"Data is only valid in callback");
- LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelinesLength, "Index out of bounds");
- return frameCallbackData->frameTimelines[index].expectedPresentTimeNanos;
+ LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelines.size(), "Index out of bounds");
+ return frameCallbackData->frameTimelines[index].expectedPresentTime;
}
int64_t AChoreographerFrameCallbackData_getFrameTimelineDeadline(
const AChoreographerFrameCallbackData* data, size_t index) {
@@ -680,8 +668,8 @@
AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
"Data is only valid in callback");
- LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelinesLength, "Index out of bounds");
- return frameCallbackData->frameTimelines[index].deadlineNanos;
+ LOG_ALWAYS_FATAL_IF(index >= frameCallbackData->frameTimelines.size(), "Index out of bounds");
+ return frameCallbackData->frameTimelines[index].deadlineTimestamp;
}
AChoreographer* AChoreographer_create() {