Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0655a915 authored by Rachel Lee's avatar Rachel Lee
Browse files

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
parent a8827e9c
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -46,11 +46,15 @@ status_t ParcelableVsyncEventData::readFromParcel(const Parcel* parcel) {

    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::readFromParcel(const Parcel* parcel) {
}
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);
+4 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ namespace android::gui {
// 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 @@ struct VsyncEventData {
    // 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
+1 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ TEST(DisplayEventStructLayoutTest, TestEventAlignment) {
    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,
+2 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ TEST(ParcelableVsyncEventData, Parcelling) {
    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 @@ TEST(ParcelableVsyncEventData, Parcelling) {
    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,
+1 −1
Original line number Diff line number Diff line
@@ -197,7 +197,7 @@ size_t AChoreographerFrameCallbackData_getFrameTimelinesLength(
            AChoreographerFrameCallbackData_to_ChoreographerFrameCallbackDataImpl(data);
    LOG_ALWAYS_FATAL_IF(!frameCallbackData->choreographer->inCallback(),
                        "Data is only valid in callback");
    return VsyncEventData::kFrameTimelinesLength;
    return frameCallbackData->vsyncEventData.frameTimelinesLength;
}
size_t AChoreographerFrameCallbackData_getPreferredFrameTimelineIndex(
        const AChoreographerFrameCallbackData* data) {
Loading