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

Commit fd501b8b authored by Ram Indani's avatar Ram Indani Committed by Android (Google) Code Review
Browse files

Merge "Update FrameInterval using next vsync generated" into main

parents 2f8ab0ea 0491e646
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -545,6 +545,7 @@ status_t HWComposer::getDeviceCompositionChanges(
        }
        }
    }
    }


    ATRACE_FORMAT("NextFrameInterval %d_Hz", frameInterval.getIntValue());
    if (canSkipValidate) {
    if (canSkipValidate) {
        sp<Fence> outPresentFence = Fence::NO_FENCE;
        sp<Fence> outPresentFence = Fence::NO_FENCE;
        uint32_t state = UINT32_MAX;
        uint32_t state = UINT32_MAX;
+18 −0
Original line number Original line Diff line number Diff line
@@ -579,6 +579,24 @@ void Scheduler::setRenderRate(PhysicalDisplayId id, Fps renderFrameRate) {
    display.schedulePtr->getTracker().setRenderRate(renderFrameRate);
    display.schedulePtr->getTracker().setRenderRate(renderFrameRate);
}
}


Fps Scheduler::getNextFrameInterval(PhysicalDisplayId id,
                                    TimePoint currentExpectedPresentTime) const {
    std::scoped_lock lock(mDisplayLock);
    ftl::FakeGuard guard(kMainThreadContext);

    const auto displayOpt = mDisplays.get(id);
    if (!displayOpt) {
        ALOGW("%s: Invalid display %s!", __func__, to_string(id).c_str());
        return Fps{};
    }
    const Display& display = *displayOpt;
    const nsecs_t threshold =
            display.selectorPtr->getActiveMode().modePtr->getVsyncRate().getPeriodNsecs() / 2;
    const nsecs_t nextVsyncTime = display.schedulePtr->getTracker().nextAnticipatedVSyncTimeFrom(
            currentExpectedPresentTime.ns() + threshold);
    return Fps::fromPeriodNsecs(nextVsyncTime - currentExpectedPresentTime.ns());
}

void Scheduler::resync() {
void Scheduler::resync() {
    static constexpr nsecs_t kIgnoreDelay = ms2ns(750);
    static constexpr nsecs_t kIgnoreDelay = ms2ns(750);


+3 −0
Original line number Original line Diff line number Diff line
@@ -313,6 +313,9 @@ public:
        return pacesetterSelectorPtr()->getActiveMode().fps;
        return pacesetterSelectorPtr()->getActiveMode().fps;
    }
    }


    Fps getNextFrameInterval(PhysicalDisplayId, TimePoint currentExpectedPresentTime) const
            EXCLUDES(mDisplayLock);

    // Returns the framerate of the layer with the given sequence ID
    // Returns the framerate of the layer with the given sequence ID
    float getLayerFramerate(nsecs_t now, int32_t id) const {
    float getLayerFramerate(nsecs_t now, int32_t id) const {
        return mLayerHistory.getLayerFramerate(now, id);
        return mLayerHistory.getLayerFramerate(now, id);
+4 −5
Original line number Original line Diff line number Diff line
@@ -2619,10 +2619,6 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
                refreshArgs.outputs.push_back(display->getCompositionDisplay());
                refreshArgs.outputs.push_back(display->getCompositionDisplay());
            }
            }
        }
        }
        if (display->getId() == pacesetterId) {
            // TODO(b/255601557) Update frameInterval per display
            refreshArgs.frameInterval = display->refreshRateSelector().getActiveMode().fps;
        }
    }
    }
    mPowerAdvisor->setDisplays(displayIds);
    mPowerAdvisor->setDisplays(displayIds);


@@ -2687,8 +2683,11 @@ CompositeResultsPerDisplay SurfaceFlinger::composite(
                pacesetterTarget.previousFrameVsyncTime(minFramePeriod) - hwcMinWorkDuration;
                pacesetterTarget.previousFrameVsyncTime(minFramePeriod) - hwcMinWorkDuration;
    }
    }


    const TimePoint expectedPresentTime = pacesetterTarget.expectedPresentTime();
    // TODO(b/255601557) Update frameInterval per display
    refreshArgs.frameInterval = mScheduler->getNextFrameInterval(pacesetterId, expectedPresentTime);
    refreshArgs.scheduledFrameTime = mScheduler->getScheduledFrameTime();
    refreshArgs.scheduledFrameTime = mScheduler->getScheduledFrameTime();
    refreshArgs.expectedPresentTime = pacesetterTarget.expectedPresentTime().ns();
    refreshArgs.expectedPresentTime = expectedPresentTime.ns();
    refreshArgs.hasTrustedPresentationListener = mNumTrustedPresentationListeners > 0;
    refreshArgs.hasTrustedPresentationListener = mNumTrustedPresentationListeners > 0;


    // Store the present time just before calling to the composition engine so we could notify
    // Store the present time just before calling to the composition engine so we could notify
+60 −0
Original line number Original line Diff line number Diff line
@@ -14,6 +14,7 @@
 * limitations under the License.
 * limitations under the License.
 */
 */


#include <common/test/FlagUtils.h>
#include <ftl/fake_guard.h>
#include <ftl/fake_guard.h>
#include <gmock/gmock.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <gtest/gtest.h>
@@ -23,6 +24,7 @@


#include "Scheduler/EventThread.h"
#include "Scheduler/EventThread.h"
#include "Scheduler/RefreshRateSelector.h"
#include "Scheduler/RefreshRateSelector.h"
#include "Scheduler/VSyncPredictor.h"
#include "TestableScheduler.h"
#include "TestableScheduler.h"
#include "TestableSurfaceFlinger.h"
#include "TestableSurfaceFlinger.h"
#include "mock/DisplayHardware/MockDisplayMode.h"
#include "mock/DisplayHardware/MockDisplayMode.h"
@@ -32,11 +34,15 @@


#include <FrontEnd/LayerHierarchy.h>
#include <FrontEnd/LayerHierarchy.h>


#include <com_android_graphics_surfaceflinger_flags.h>
#include "FpsOps.h"
#include "FpsOps.h"


using namespace com::android::graphics::surfaceflinger;

namespace android::scheduler {
namespace android::scheduler {


using android::mock::createDisplayMode;
using android::mock::createDisplayMode;
using android::mock::createVrrDisplayMode;


using testing::_;
using testing::_;
using testing::Return;
using testing::Return;
@@ -548,6 +554,60 @@ TEST_F(SchedulerTest, onFrameSignalMultipleDisplays) {
    EXPECT_EQ(makeVsyncIds(VsyncId(44), true), compositor.vsyncIds.composite);
    EXPECT_EQ(makeVsyncIds(VsyncId(44), true), compositor.vsyncIds.composite);
}
}


TEST_F(SchedulerTest, nextFrameIntervalTest) {
    SET_FLAG_FOR_TEST(flags::vrr_config, true);

    static constexpr size_t kHistorySize = 10;
    static constexpr size_t kMinimumSamplesForPrediction = 6;
    static constexpr size_t kOutlierTolerancePercent = 25;
    const auto refreshRate = Fps::fromPeriodNsecs(500);
    auto frameRate = Fps::fromPeriodNsecs(1000);

    const ftl::NonNull<DisplayModePtr> kMode = ftl::as_non_null(
            createVrrDisplayMode(DisplayModeId(0), refreshRate,
                                 hal::VrrConfig{.minFrameIntervalNs = static_cast<int32_t>(
                                                        frameRate.getPeriodNsecs())}));
    std::shared_ptr<VSyncPredictor> vrrTracker =
            std::make_shared<VSyncPredictor>(kMode, kHistorySize, kMinimumSamplesForPrediction,
                                             kOutlierTolerancePercent, mVsyncTrackerCallback);
    std::shared_ptr<RefreshRateSelector> vrrSelectorPtr =
            std::make_shared<RefreshRateSelector>(makeModes(kMode), kMode->getId());
    TestableScheduler scheduler{std::make_unique<android::mock::VsyncController>(),
                                vrrTracker,
                                vrrSelectorPtr,
                                sp<VsyncModulator>::make(VsyncConfigSet{}),
                                mSchedulerCallback,
                                mVsyncTrackerCallback};

    scheduler.registerDisplay(kMode->getPhysicalDisplayId(), vrrSelectorPtr, vrrTracker);
    vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
    scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate);
    vrrTracker->addVsyncTimestamp(0);

    // Next frame at refresh rate as no previous frame
    EXPECT_EQ(refreshRate,
              scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(), TimePoint::fromNs(0)));

    EXPECT_EQ(Fps::fromPeriodNsecs(1000),
              scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
                                             TimePoint::fromNs(500)));
    EXPECT_EQ(Fps::fromPeriodNsecs(1000),
              scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
                                             TimePoint::fromNs(1500)));

    // Change render rate
    frameRate = Fps::fromPeriodNsecs(2000);
    vrrSelectorPtr->setActiveMode(kMode->getId(), frameRate);
    scheduler.setRenderRate(kMode->getPhysicalDisplayId(), frameRate);

    EXPECT_EQ(Fps::fromPeriodNsecs(2000),
              scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
                                             TimePoint::fromNs(2500)));
    EXPECT_EQ(Fps::fromPeriodNsecs(2000),
              scheduler.getNextFrameInterval(kMode->getPhysicalDisplayId(),
                                             TimePoint::fromNs(4500)));
}

class AttachedChoreographerTest : public SchedulerTest {
class AttachedChoreographerTest : public SchedulerTest {
protected:
protected:
    void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps,
    void frameRateTestScenario(Fps layerFps, int8_t frameRateCompatibility, Fps displayFps,
Loading