Fix Choreographer affecting ASurfaceControlTest
Fixes `testSurfaceTransaction_setFrameTimeline_notPreferredIndex` case
on devices that do not have high refresh rates (e.g. max 60Hz). This
occurred because the transaction-ready logic in SF does not consider
transactions to be too early if the expected presentation time is over
100ms in the future, so the frame would just be deemed ready and
presented asap. Thus, no longer provide frame timelines that are far
into the future, which are not useful as well.
Test: atest ASurfaceControlTest
Test: atest ChoreographerTest
Test: atest ChoreographerNativeTest
Test: atest DisplayEventStructLayoutTest
Test: atest ParcelableVsyncEventData
Test: atest libsurfacefligner_unittest
Fixes: 270612751
Change-Id: Ic05717bc153a9b07409b8d7912a1c40e1e31a57e
diff --git a/libs/gui/VsyncEventData.cpp b/libs/gui/VsyncEventData.cpp
index 76c60c2..91fc9c0 100644
--- a/libs/gui/VsyncEventData.cpp
+++ b/libs/gui/VsyncEventData.cpp
@@ -46,11 +46,15 @@
SAFE_PARCEL(parcel->readInt64, &vsync.frameInterval);
- uint64_t uintPreferredFrameTimelineIndex;
- SAFE_PARCEL(parcel->readUint64, &uintPreferredFrameTimelineIndex);
+ uint32_t uintPreferredFrameTimelineIndex;
+ SAFE_PARCEL(parcel->readUint32, &uintPreferredFrameTimelineIndex);
vsync.preferredFrameTimelineIndex = static_cast<size_t>(uintPreferredFrameTimelineIndex);
- for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
+ uint32_t uintFrameTimelinesLength;
+ SAFE_PARCEL(parcel->readUint32, &uintFrameTimelinesLength);
+ vsync.frameTimelinesLength = static_cast<size_t>(uintFrameTimelinesLength);
+
+ for (size_t i = 0; i < vsync.frameTimelinesLength; i++) {
SAFE_PARCEL(parcel->readInt64, &vsync.frameTimelines[i].vsyncId);
SAFE_PARCEL(parcel->readInt64, &vsync.frameTimelines[i].deadlineTimestamp);
SAFE_PARCEL(parcel->readInt64, &vsync.frameTimelines[i].expectedPresentationTime);
@@ -60,8 +64,9 @@
}
status_t ParcelableVsyncEventData::writeToParcel(Parcel* parcel) const {
SAFE_PARCEL(parcel->writeInt64, vsync.frameInterval);
- SAFE_PARCEL(parcel->writeUint64, vsync.preferredFrameTimelineIndex);
- for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
+ SAFE_PARCEL(parcel->writeUint32, vsync.preferredFrameTimelineIndex);
+ SAFE_PARCEL(parcel->writeUint32, vsync.frameTimelinesLength);
+ for (size_t i = 0; i < vsync.frameTimelinesLength; i++) {
SAFE_PARCEL(parcel->writeInt64, vsync.frameTimelines[i].vsyncId);
SAFE_PARCEL(parcel->writeInt64, vsync.frameTimelines[i].deadlineTimestamp);
SAFE_PARCEL(parcel->writeInt64, vsync.frameTimelines[i].expectedPresentationTime);
diff --git a/libs/gui/include/gui/VsyncEventData.h b/libs/gui/include/gui/VsyncEventData.h
index dfdae21..9ddb7cd 100644
--- a/libs/gui/include/gui/VsyncEventData.h
+++ b/libs/gui/include/gui/VsyncEventData.h
@@ -24,7 +24,7 @@
// Plain Old Data (POD) vsync data structure. For example, it can be easily used in the
// DisplayEventReceiver::Event union.
struct VsyncEventData {
- // Max amount of frame timelines is arbitrarily set to be reasonable.
+ // Max capacity of frame timelines is arbitrarily set to be reasonable.
static constexpr int64_t kFrameTimelinesLength = 7;
// The current frame interval in ns when this frame was scheduled.
@@ -33,6 +33,9 @@
// Index into the frameTimelines that represents the platform's preferred frame timeline.
uint32_t preferredFrameTimelineIndex;
+ // Size of frame timelines provided by the platform; max is kFrameTimelinesLength.
+ uint32_t frameTimelinesLength;
+
struct alignas(8) FrameTimeline {
// The Vsync Id corresponsing to this vsync event. This will be used to
// populate ISurfaceComposer::setFrameTimelineVsync and
diff --git a/libs/gui/tests/DisplayEventStructLayout_test.cpp b/libs/gui/tests/DisplayEventStructLayout_test.cpp
index da88463..b7b4ab6 100644
--- a/libs/gui/tests/DisplayEventStructLayout_test.cpp
+++ b/libs/gui/tests/DisplayEventStructLayout_test.cpp
@@ -35,6 +35,7 @@
CHECK_OFFSET(DisplayEventReceiver::Event::VSync, count, 0);
CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameInterval, 8);
CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.preferredFrameTimelineIndex, 16);
+ CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameTimelinesLength, 20);
CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameTimelines, 24);
CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameTimelines[0].vsyncId, 24);
CHECK_OFFSET(DisplayEventReceiver::Event::VSync, vsyncData.frameTimelines[0].deadlineTimestamp,
diff --git a/libs/gui/tests/VsyncEventData_test.cpp b/libs/gui/tests/VsyncEventData_test.cpp
index f114522..6e039ee 100644
--- a/libs/gui/tests/VsyncEventData_test.cpp
+++ b/libs/gui/tests/VsyncEventData_test.cpp
@@ -36,6 +36,7 @@
FrameTimeline timeline1 = FrameTimeline{4, 5, 6};
data.vsync.frameTimelines[0] = timeline0;
data.vsync.frameTimelines[1] = timeline1;
+ data.vsync.frameTimelinesLength = 2;
Parcel p;
data.writeToParcel(&p);
@@ -45,6 +46,7 @@
data2.readFromParcel(&p);
ASSERT_EQ(data.vsync.frameInterval, data2.vsync.frameInterval);
ASSERT_EQ(data.vsync.preferredFrameTimelineIndex, data2.vsync.preferredFrameTimelineIndex);
+ ASSERT_EQ(data.vsync.frameTimelinesLength, data2.vsync.frameTimelinesLength);
for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
ASSERT_EQ(data.vsync.frameTimelines[i].vsyncId, data2.vsync.frameTimelines[i].vsyncId);
ASSERT_EQ(data.vsync.frameTimelines[i].deadlineTimestamp,