Loading libs/gui/include/gui/FrameTimestamps.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -131,6 +131,7 @@ public: // Public for testing. // Public for testing. static nsecs_t snapToNextTick( static nsecs_t snapToNextTick( nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval); nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval); nsecs_t getReportedCompositeDeadline() const { return mCompositorTiming.deadline; }; nsecs_t getNextCompositeDeadline(const nsecs_t now) const; nsecs_t getNextCompositeDeadline(const nsecs_t now) const; nsecs_t getCompositeInterval() const { return mCompositorTiming.interval; } nsecs_t getCompositeInterval() const { return mCompositorTiming.interval; } Loading libs/gui/tests/BLASTBufferQueue_test.cpp +27 −0 Original line number Original line Diff line number Diff line Loading @@ -1109,4 +1109,31 @@ TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) { adapter.waitForCallbacks(); adapter.waitForCallbacks(); } } TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) { BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight); sp<IGraphicBufferProducer> igbProducer; ProducerFrameEventHistory history; setUpProducer(adapter, igbProducer); IGraphicBufferProducer::QueueBufferOutput qbOutput; nsecs_t requestedPresentTimeA = 0; nsecs_t postedTimeA = 0; adapter.setTransactionCompleteCallback(1); setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true); history.applyDelta(qbOutput.frameTimestamps); adapter.waitForCallback(1); // queue another buffer so we query for frame event deltas nsecs_t requestedPresentTimeB = 0; nsecs_t postedTimeB = 0; setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true); history.applyDelta(qbOutput.frameTimestamps); // check for a valid compositor deadline ASSERT_NE(0, history.getReportedCompositeDeadline()); // wait for any callbacks that have not been received adapter.waitForCallbacks(); } } // namespace android } // namespace android services/surfaceflinger/SurfaceFlinger.cpp +8 −9 Original line number Original line Diff line number Diff line Loading @@ -2231,18 +2231,15 @@ void SurfaceFlinger::postComposition() { getBE().mDisplayTimeline.push(mPreviousPresentFences[0].fenceTime); getBE().mDisplayTimeline.push(mPreviousPresentFences[0].fenceTime); nsecs_t now = systemTime(); // Set presentation information before calling Layer::releasePendingBuffer, such that jank // Set presentation information before calling Layer::releasePendingBuffer, such that jank // information from previous' frame classification is already available when sending jank info // information from previous' frame classification is already available when sending jank info // to clients, so they get jank classification as early as possible. // to clients, so they get jank classification as early as possible. mFrameTimeline->setSfPresent(systemTime(), mPreviousPresentFences[0].fenceTime, mFrameTimeline->setSfPresent(/* sfPresentTime */ now, mPreviousPresentFences[0].fenceTime, glCompositionDoneFenceTime); glCompositionDoneFenceTime); nsecs_t dequeueReadyTime = systemTime(); const DisplayStatInfo stats = mScheduler->getDisplayStatInfo(now); for (const auto& layer : mLayersWithQueuedFrames) { layer->releasePendingBuffer(dequeueReadyTime); } const DisplayStatInfo stats = mScheduler->getDisplayStatInfo(systemTime()); // We use the CompositionEngine::getLastFrameRefreshTimestamp() which might // We use the CompositionEngine::getLastFrameRefreshTimestamp() which might // be sampled a little later than when we started doing work for this frame, // be sampled a little later than when we started doing work for this frame, Loading @@ -2259,6 +2256,7 @@ void SurfaceFlinger::postComposition() { const bool frameLatched = const bool frameLatched = layer->onPostComposition(display, glCompositionDoneFenceTime, layer->onPostComposition(display, glCompositionDoneFenceTime, mPreviousPresentFences[0].fenceTime, compositorTiming); mPreviousPresentFences[0].fenceTime, compositorTiming); layer->releasePendingBuffer(/*dequeueReadyTime*/ now); if (frameLatched) { if (frameLatched) { recordBufferingStats(layer->getName(), layer->getOccupancyHistory(false)); recordBufferingStats(layer->getName(), layer->getOccupancyHistory(false)); } } Loading Loading @@ -4473,10 +4471,11 @@ void SurfaceFlinger::onInitializeDisplays() { d.height = 0; d.height = 0; displays.add(d); displays.add(d); nsecs_t now = systemTime(); // It should be on the main thread, apply it directly. // It should be on the main thread, apply it directly. applyTransactionState(FrameTimelineInfo{}, state, displays, 0, mInputWindowCommands, applyTransactionState(FrameTimelineInfo{}, state, displays, 0, mInputWindowCommands, systemTime(), true, {}, systemTime(), true, false, {}, getpid(), getuid(), /* desiredPresentTime */ now, true, {}, /* postTime */ now, true, false, 0 /* Undefined transactionId */); {}, getpid(), getuid(), 0 /* Undefined transactionId */); setPowerModeInternal(display, hal::PowerMode::ON); setPowerModeInternal(display, hal::PowerMode::ON); const nsecs_t vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod(); const nsecs_t vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod(); Loading Loading
libs/gui/include/gui/FrameTimestamps.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -131,6 +131,7 @@ public: // Public for testing. // Public for testing. static nsecs_t snapToNextTick( static nsecs_t snapToNextTick( nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval); nsecs_t timestamp, nsecs_t tickPhase, nsecs_t tickInterval); nsecs_t getReportedCompositeDeadline() const { return mCompositorTiming.deadline; }; nsecs_t getNextCompositeDeadline(const nsecs_t now) const; nsecs_t getNextCompositeDeadline(const nsecs_t now) const; nsecs_t getCompositeInterval() const { return mCompositorTiming.interval; } nsecs_t getCompositeInterval() const { return mCompositorTiming.interval; } Loading
libs/gui/tests/BLASTBufferQueue_test.cpp +27 −0 Original line number Original line Diff line number Diff line Loading @@ -1109,4 +1109,31 @@ TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_DroppedFrame) { adapter.waitForCallbacks(); adapter.waitForCallbacks(); } } TEST_F(BLASTFrameEventHistoryTest, FrameEventHistory_CompositorTimings) { BLASTBufferQueueHelper adapter(mSurfaceControl, mDisplayWidth, mDisplayHeight); sp<IGraphicBufferProducer> igbProducer; ProducerFrameEventHistory history; setUpProducer(adapter, igbProducer); IGraphicBufferProducer::QueueBufferOutput qbOutput; nsecs_t requestedPresentTimeA = 0; nsecs_t postedTimeA = 0; adapter.setTransactionCompleteCallback(1); setUpAndQueueBuffer(igbProducer, &requestedPresentTimeA, &postedTimeA, &qbOutput, true); history.applyDelta(qbOutput.frameTimestamps); adapter.waitForCallback(1); // queue another buffer so we query for frame event deltas nsecs_t requestedPresentTimeB = 0; nsecs_t postedTimeB = 0; setUpAndQueueBuffer(igbProducer, &requestedPresentTimeB, &postedTimeB, &qbOutput, true); history.applyDelta(qbOutput.frameTimestamps); // check for a valid compositor deadline ASSERT_NE(0, history.getReportedCompositeDeadline()); // wait for any callbacks that have not been received adapter.waitForCallbacks(); } } // namespace android } // namespace android
services/surfaceflinger/SurfaceFlinger.cpp +8 −9 Original line number Original line Diff line number Diff line Loading @@ -2231,18 +2231,15 @@ void SurfaceFlinger::postComposition() { getBE().mDisplayTimeline.push(mPreviousPresentFences[0].fenceTime); getBE().mDisplayTimeline.push(mPreviousPresentFences[0].fenceTime); nsecs_t now = systemTime(); // Set presentation information before calling Layer::releasePendingBuffer, such that jank // Set presentation information before calling Layer::releasePendingBuffer, such that jank // information from previous' frame classification is already available when sending jank info // information from previous' frame classification is already available when sending jank info // to clients, so they get jank classification as early as possible. // to clients, so they get jank classification as early as possible. mFrameTimeline->setSfPresent(systemTime(), mPreviousPresentFences[0].fenceTime, mFrameTimeline->setSfPresent(/* sfPresentTime */ now, mPreviousPresentFences[0].fenceTime, glCompositionDoneFenceTime); glCompositionDoneFenceTime); nsecs_t dequeueReadyTime = systemTime(); const DisplayStatInfo stats = mScheduler->getDisplayStatInfo(now); for (const auto& layer : mLayersWithQueuedFrames) { layer->releasePendingBuffer(dequeueReadyTime); } const DisplayStatInfo stats = mScheduler->getDisplayStatInfo(systemTime()); // We use the CompositionEngine::getLastFrameRefreshTimestamp() which might // We use the CompositionEngine::getLastFrameRefreshTimestamp() which might // be sampled a little later than when we started doing work for this frame, // be sampled a little later than when we started doing work for this frame, Loading @@ -2259,6 +2256,7 @@ void SurfaceFlinger::postComposition() { const bool frameLatched = const bool frameLatched = layer->onPostComposition(display, glCompositionDoneFenceTime, layer->onPostComposition(display, glCompositionDoneFenceTime, mPreviousPresentFences[0].fenceTime, compositorTiming); mPreviousPresentFences[0].fenceTime, compositorTiming); layer->releasePendingBuffer(/*dequeueReadyTime*/ now); if (frameLatched) { if (frameLatched) { recordBufferingStats(layer->getName(), layer->getOccupancyHistory(false)); recordBufferingStats(layer->getName(), layer->getOccupancyHistory(false)); } } Loading Loading @@ -4473,10 +4471,11 @@ void SurfaceFlinger::onInitializeDisplays() { d.height = 0; d.height = 0; displays.add(d); displays.add(d); nsecs_t now = systemTime(); // It should be on the main thread, apply it directly. // It should be on the main thread, apply it directly. applyTransactionState(FrameTimelineInfo{}, state, displays, 0, mInputWindowCommands, applyTransactionState(FrameTimelineInfo{}, state, displays, 0, mInputWindowCommands, systemTime(), true, {}, systemTime(), true, false, {}, getpid(), getuid(), /* desiredPresentTime */ now, true, {}, /* postTime */ now, true, false, 0 /* Undefined transactionId */); {}, getpid(), getuid(), 0 /* Undefined transactionId */); setPowerModeInternal(display, hal::PowerMode::ON); setPowerModeInternal(display, hal::PowerMode::ON); const nsecs_t vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod(); const nsecs_t vsyncPeriod = mRefreshRateConfigs->getCurrentRefreshRate().getVsyncPeriod(); Loading