Loading include/gui/FrameTimestamps.h +1 −1 Original line number Diff line number Diff line Loading @@ -105,7 +105,7 @@ struct FrameEvents { struct CompositorTiming { nsecs_t deadline{0}; nsecs_t interval{16666667}; nsecs_t presentLatency{0}; nsecs_t presentLatency{16666667}; }; // A short history of frames that are synchronized between the consumer and Loading libs/gui/tests/Surface_test.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ protected: mComposerClient = new SurfaceComposerClient; ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); // TODO(brianderson): The following sometimes fails and is a source of // test flakiness. mSurfaceControl = mComposerClient->createSurface( String8("Test Surface"), 32, 32, PIXEL_FORMAT_RGBA_8888, 0); Loading Loading @@ -526,7 +528,7 @@ public: }; class GetFrameTimestampsTest : public SurfaceTest { class GetFrameTimestampsTest : public ::testing::Test { protected: struct FenceAndFenceTime { explicit FenceAndFenceTime(FenceToFenceTimeMap& fenceMap) Loading Loading @@ -616,11 +618,9 @@ protected: RefreshEvents mRefreshes[3]; }; GetFrameTimestampsTest() : SurfaceTest() {} GetFrameTimestampsTest() {} virtual void SetUp() { SurfaceTest::SetUp(); BufferQueue::createBufferQueue(&mProducer, &mConsumer); mFakeConsumer = new FakeConsumer; mCfeh = &mFakeConsumer->mFrameEventHistory; Loading services/surfaceflinger/SurfaceFlinger.cpp +29 −20 Original line number Diff line number Diff line Loading @@ -1129,7 +1129,7 @@ void SurfaceFlinger::onVSyncReceived(HWComposer* composer, int32_t type, } void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) { std::lock_guard<std::mutex> lock(mCompositeTimingLock); std::lock_guard<std::mutex> lock(mCompositorTimingLock); *compositorTiming = mCompositorTiming; } Loading Loading @@ -1426,35 +1426,40 @@ void SurfaceFlinger::updateCompositorTiming( mCompositePresentTimes.pop(); } setCompositorTimingSnapped( vsyncPhase, vsyncInterval, compositeToPresentLatency); } void SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) { // Integer division and modulo round toward 0 not -inf, so we need to // treat negative and positive offsets differently. nsecs_t idealLatency = (sfVsyncPhaseOffsetNs >= 0) ? nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ? (vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) : ((-sfVsyncPhaseOffsetNs) % vsyncInterval); // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval. if (idealLatency <= 0) { idealLatency = vsyncInterval; } // Snap the latency to a value that removes scheduling jitter from the // composition and present times, which often have >1ms of jitter. // Reducing jitter is important if an app attempts to extrapolate // something (such as user input) to an accurate diasplay time. // Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs // with (presentLatency % interval). nsecs_t snappedCompositeToPresentLatency = -1; if (compositeToPresentLatency >= 0) { nsecs_t bias = vsyncInterval / 2; int64_t extraVsyncs = (compositeToPresentLatency - idealLatency + bias) / vsyncInterval; nsecs_t extraLatency = extraVsyncs * vsyncInterval; snappedCompositeToPresentLatency = idealLatency + extraLatency; } (compositeToPresentLatency - idealLatency + bias) / vsyncInterval; nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ? idealLatency + (extraVsyncs * vsyncInterval) : idealLatency; std::lock_guard<std::mutex> lock(mCompositeTimingLock); std::lock_guard<std::mutex> lock(mCompositorTimingLock); mCompositorTiming.deadline = vsyncPhase - idealLatency; mCompositorTiming.interval = vsyncInterval; if (snappedCompositeToPresentLatency >= 0) { mCompositorTiming.presentLatency = snappedCompositeToPresentLatency; } } void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) { Loading Loading @@ -1500,10 +1505,15 @@ void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) // since updateCompositorTiming has snapping logic. updateCompositorTiming( vsyncPhase, vsyncInterval, refreshStartTime, displayFenceTime); CompositorTiming compositorTiming; { std::lock_guard<std::mutex> lock(mCompositorTimingLock); compositorTiming = mCompositorTiming; } mDrawingState.traverseInZOrder([&](Layer* layer) { bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime, *presentFenceTime, *retireFenceTime, mCompositorTiming); *presentFenceTime, *retireFenceTime, compositorTiming); if (frameLatched) { recordBufferingStats(layer->getName().string(), layer->getOccupancyHistory(false)); Loading Loading @@ -2982,10 +2992,9 @@ void SurfaceFlinger::onInitializeDisplays() { const nsecs_t period = activeConfig->getVsyncPeriod(); mAnimFrameTracker.setDisplayRefreshPeriod(period); { std::lock_guard<std::mutex> lock(mCompositeTimingLock); mCompositorTiming.interval = period; } // Use phase of 0 since phase is not known. // Use latency of 0, which will snap to the ideal latency. setCompositorTimingSnapped(0, period, 0); } void SurfaceFlinger::initializeDisplays() { Loading services/surfaceflinger/SurfaceFlinger.h +4 −1 Original line number Diff line number Diff line Loading @@ -466,6 +466,9 @@ private: void updateCompositorTiming( nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime, std::shared_ptr<FenceTime>& presentFenceTime); void setCompositorTimingSnapped( nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency); void rebuildLayerStacks(); void setUpHWComposer(); void doComposition(); Loading Loading @@ -636,7 +639,7 @@ private: bool mHWVsyncAvailable; // protected by mCompositorTimingLock; mutable std::mutex mCompositeTimingLock; mutable std::mutex mCompositorTimingLock; CompositorTiming mCompositorTiming; // Only accessed from the main thread. Loading services/surfaceflinger/SurfaceFlinger_hwc1.cpp +30 −16 Original line number Diff line number Diff line Loading @@ -1048,7 +1048,7 @@ void SurfaceFlinger::onVSyncReceived(HWComposer* /*composer*/, int type, } void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) { std::lock_guard<std::mutex> lock(mCompositeTimingLock); std::lock_guard<std::mutex> lock(mCompositorTimingLock); *compositorTiming = mCompositorTiming; } Loading Loading @@ -1211,35 +1211,40 @@ void SurfaceFlinger::updateCompositorTiming( mCompositePresentTimes.pop(); } setCompositorTimingSnapped( vsyncPhase, vsyncInterval, compositeToPresentLatency); } void SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) { // Integer division and modulo round toward 0 not -inf, so we need to // treat negative and positive offsets differently. nsecs_t idealLatency = (sfVsyncPhaseOffsetNs >= 0) ? nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ? (vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) : ((-sfVsyncPhaseOffsetNs) % vsyncInterval); // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval. if (idealLatency <= 0) { idealLatency = vsyncInterval; } // Snap the latency to a value that removes scheduling jitter from the // composition and present times, which often have >1ms of jitter. // Reducing jitter is important if an app attempts to extrapolate // something (such as user input) to an accurate diasplay time. // Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs // with (presentLatency % interval). nsecs_t snappedCompositeToPresentLatency = -1; if (compositeToPresentLatency >= 0) { nsecs_t bias = vsyncInterval / 2; int64_t extraVsyncs = (compositeToPresentLatency - idealLatency + bias) / vsyncInterval; nsecs_t extraLatency = extraVsyncs * vsyncInterval; snappedCompositeToPresentLatency = idealLatency + extraLatency; } (compositeToPresentLatency - idealLatency + bias) / vsyncInterval; nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ? idealLatency + (extraVsyncs * vsyncInterval) : idealLatency; std::lock_guard<std::mutex> lock(mCompositeTimingLock); std::lock_guard<std::mutex> lock(mCompositorTimingLock); mCompositorTiming.deadline = vsyncPhase - idealLatency; mCompositorTiming.interval = vsyncInterval; if (snappedCompositeToPresentLatency >= 0) { mCompositorTiming.presentLatency = snappedCompositeToPresentLatency; } } void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) { Loading Loading @@ -1270,10 +1275,15 @@ void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) // since updateCompositorTiming has snapping logic. updateCompositorTiming( vsyncPhase, vsyncInterval, refreshStartTime, retireFenceTime); CompositorTiming compositorTiming; { std::lock_guard<std::mutex> lock(mCompositorTimingLock); compositorTiming = mCompositorTiming; } mDrawingState.traverseInZOrder([&](Layer* layer) { bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime, presentFenceTime, retireFenceTime, mCompositorTiming); presentFenceTime, retireFenceTime, compositorTiming); if (frameLatched) { recordBufferingStats(layer->getName().string(), layer->getOccupancyHistory(false)); Loading Loading @@ -2758,6 +2768,10 @@ void SurfaceFlinger::onInitializeDisplays() { const nsecs_t period = getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); mAnimFrameTracker.setDisplayRefreshPeriod(period); // Use phase of 0 since phase is not known. // Use latency of 0, which will snap to the ideal latency. setCompositorTimingSnapped(0, period, 0); } void SurfaceFlinger::initializeDisplays() { Loading Loading
include/gui/FrameTimestamps.h +1 −1 Original line number Diff line number Diff line Loading @@ -105,7 +105,7 @@ struct FrameEvents { struct CompositorTiming { nsecs_t deadline{0}; nsecs_t interval{16666667}; nsecs_t presentLatency{0}; nsecs_t presentLatency{16666667}; }; // A short history of frames that are synchronized between the consumer and Loading
libs/gui/tests/Surface_test.cpp +4 −4 Original line number Diff line number Diff line Loading @@ -52,6 +52,8 @@ protected: mComposerClient = new SurfaceComposerClient; ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); // TODO(brianderson): The following sometimes fails and is a source of // test flakiness. mSurfaceControl = mComposerClient->createSurface( String8("Test Surface"), 32, 32, PIXEL_FORMAT_RGBA_8888, 0); Loading Loading @@ -526,7 +528,7 @@ public: }; class GetFrameTimestampsTest : public SurfaceTest { class GetFrameTimestampsTest : public ::testing::Test { protected: struct FenceAndFenceTime { explicit FenceAndFenceTime(FenceToFenceTimeMap& fenceMap) Loading Loading @@ -616,11 +618,9 @@ protected: RefreshEvents mRefreshes[3]; }; GetFrameTimestampsTest() : SurfaceTest() {} GetFrameTimestampsTest() {} virtual void SetUp() { SurfaceTest::SetUp(); BufferQueue::createBufferQueue(&mProducer, &mConsumer); mFakeConsumer = new FakeConsumer; mCfeh = &mFakeConsumer->mFrameEventHistory; Loading
services/surfaceflinger/SurfaceFlinger.cpp +29 −20 Original line number Diff line number Diff line Loading @@ -1129,7 +1129,7 @@ void SurfaceFlinger::onVSyncReceived(HWComposer* composer, int32_t type, } void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) { std::lock_guard<std::mutex> lock(mCompositeTimingLock); std::lock_guard<std::mutex> lock(mCompositorTimingLock); *compositorTiming = mCompositorTiming; } Loading Loading @@ -1426,35 +1426,40 @@ void SurfaceFlinger::updateCompositorTiming( mCompositePresentTimes.pop(); } setCompositorTimingSnapped( vsyncPhase, vsyncInterval, compositeToPresentLatency); } void SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) { // Integer division and modulo round toward 0 not -inf, so we need to // treat negative and positive offsets differently. nsecs_t idealLatency = (sfVsyncPhaseOffsetNs >= 0) ? nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ? (vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) : ((-sfVsyncPhaseOffsetNs) % vsyncInterval); // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval. if (idealLatency <= 0) { idealLatency = vsyncInterval; } // Snap the latency to a value that removes scheduling jitter from the // composition and present times, which often have >1ms of jitter. // Reducing jitter is important if an app attempts to extrapolate // something (such as user input) to an accurate diasplay time. // Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs // with (presentLatency % interval). nsecs_t snappedCompositeToPresentLatency = -1; if (compositeToPresentLatency >= 0) { nsecs_t bias = vsyncInterval / 2; int64_t extraVsyncs = (compositeToPresentLatency - idealLatency + bias) / vsyncInterval; nsecs_t extraLatency = extraVsyncs * vsyncInterval; snappedCompositeToPresentLatency = idealLatency + extraLatency; } (compositeToPresentLatency - idealLatency + bias) / vsyncInterval; nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ? idealLatency + (extraVsyncs * vsyncInterval) : idealLatency; std::lock_guard<std::mutex> lock(mCompositeTimingLock); std::lock_guard<std::mutex> lock(mCompositorTimingLock); mCompositorTiming.deadline = vsyncPhase - idealLatency; mCompositorTiming.interval = vsyncInterval; if (snappedCompositeToPresentLatency >= 0) { mCompositorTiming.presentLatency = snappedCompositeToPresentLatency; } } void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) { Loading Loading @@ -1500,10 +1505,15 @@ void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) // since updateCompositorTiming has snapping logic. updateCompositorTiming( vsyncPhase, vsyncInterval, refreshStartTime, displayFenceTime); CompositorTiming compositorTiming; { std::lock_guard<std::mutex> lock(mCompositorTimingLock); compositorTiming = mCompositorTiming; } mDrawingState.traverseInZOrder([&](Layer* layer) { bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime, *presentFenceTime, *retireFenceTime, mCompositorTiming); *presentFenceTime, *retireFenceTime, compositorTiming); if (frameLatched) { recordBufferingStats(layer->getName().string(), layer->getOccupancyHistory(false)); Loading Loading @@ -2982,10 +2992,9 @@ void SurfaceFlinger::onInitializeDisplays() { const nsecs_t period = activeConfig->getVsyncPeriod(); mAnimFrameTracker.setDisplayRefreshPeriod(period); { std::lock_guard<std::mutex> lock(mCompositeTimingLock); mCompositorTiming.interval = period; } // Use phase of 0 since phase is not known. // Use latency of 0, which will snap to the ideal latency. setCompositorTimingSnapped(0, period, 0); } void SurfaceFlinger::initializeDisplays() { Loading
services/surfaceflinger/SurfaceFlinger.h +4 −1 Original line number Diff line number Diff line Loading @@ -466,6 +466,9 @@ private: void updateCompositorTiming( nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeTime, std::shared_ptr<FenceTime>& presentFenceTime); void setCompositorTimingSnapped( nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency); void rebuildLayerStacks(); void setUpHWComposer(); void doComposition(); Loading Loading @@ -636,7 +639,7 @@ private: bool mHWVsyncAvailable; // protected by mCompositorTimingLock; mutable std::mutex mCompositeTimingLock; mutable std::mutex mCompositorTimingLock; CompositorTiming mCompositorTiming; // Only accessed from the main thread. Loading
services/surfaceflinger/SurfaceFlinger_hwc1.cpp +30 −16 Original line number Diff line number Diff line Loading @@ -1048,7 +1048,7 @@ void SurfaceFlinger::onVSyncReceived(HWComposer* /*composer*/, int type, } void SurfaceFlinger::getCompositorTiming(CompositorTiming* compositorTiming) { std::lock_guard<std::mutex> lock(mCompositeTimingLock); std::lock_guard<std::mutex> lock(mCompositorTimingLock); *compositorTiming = mCompositorTiming; } Loading Loading @@ -1211,35 +1211,40 @@ void SurfaceFlinger::updateCompositorTiming( mCompositePresentTimes.pop(); } setCompositorTimingSnapped( vsyncPhase, vsyncInterval, compositeToPresentLatency); } void SurfaceFlinger::setCompositorTimingSnapped(nsecs_t vsyncPhase, nsecs_t vsyncInterval, nsecs_t compositeToPresentLatency) { // Integer division and modulo round toward 0 not -inf, so we need to // treat negative and positive offsets differently. nsecs_t idealLatency = (sfVsyncPhaseOffsetNs >= 0) ? nsecs_t idealLatency = (sfVsyncPhaseOffsetNs > 0) ? (vsyncInterval - (sfVsyncPhaseOffsetNs % vsyncInterval)) : ((-sfVsyncPhaseOffsetNs) % vsyncInterval); // Just in case sfVsyncPhaseOffsetNs == -vsyncInterval. if (idealLatency <= 0) { idealLatency = vsyncInterval; } // Snap the latency to a value that removes scheduling jitter from the // composition and present times, which often have >1ms of jitter. // Reducing jitter is important if an app attempts to extrapolate // something (such as user input) to an accurate diasplay time. // Snapping also allows an app to precisely calculate sfVsyncPhaseOffsetNs // with (presentLatency % interval). nsecs_t snappedCompositeToPresentLatency = -1; if (compositeToPresentLatency >= 0) { nsecs_t bias = vsyncInterval / 2; int64_t extraVsyncs = (compositeToPresentLatency - idealLatency + bias) / vsyncInterval; nsecs_t extraLatency = extraVsyncs * vsyncInterval; snappedCompositeToPresentLatency = idealLatency + extraLatency; } (compositeToPresentLatency - idealLatency + bias) / vsyncInterval; nsecs_t snappedCompositeToPresentLatency = (extraVsyncs > 0) ? idealLatency + (extraVsyncs * vsyncInterval) : idealLatency; std::lock_guard<std::mutex> lock(mCompositeTimingLock); std::lock_guard<std::mutex> lock(mCompositorTimingLock); mCompositorTiming.deadline = vsyncPhase - idealLatency; mCompositorTiming.interval = vsyncInterval; if (snappedCompositeToPresentLatency >= 0) { mCompositorTiming.presentLatency = snappedCompositeToPresentLatency; } } void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) { Loading Loading @@ -1270,10 +1275,15 @@ void SurfaceFlinger::postComposition(nsecs_t refreshStartTime) // since updateCompositorTiming has snapping logic. updateCompositorTiming( vsyncPhase, vsyncInterval, refreshStartTime, retireFenceTime); CompositorTiming compositorTiming; { std::lock_guard<std::mutex> lock(mCompositorTimingLock); compositorTiming = mCompositorTiming; } mDrawingState.traverseInZOrder([&](Layer* layer) { bool frameLatched = layer->onPostComposition(glCompositionDoneFenceTime, presentFenceTime, retireFenceTime, mCompositorTiming); presentFenceTime, retireFenceTime, compositorTiming); if (frameLatched) { recordBufferingStats(layer->getName().string(), layer->getOccupancyHistory(false)); Loading Loading @@ -2758,6 +2768,10 @@ void SurfaceFlinger::onInitializeDisplays() { const nsecs_t period = getHwComposer().getRefreshPeriod(HWC_DISPLAY_PRIMARY); mAnimFrameTracker.setDisplayRefreshPeriod(period); // Use phase of 0 since phase is not known. // Use latency of 0, which will snap to the ideal latency. setCompositorTimingSnapped(0, period, 0); } void SurfaceFlinger::initializeDisplays() { Loading