diff options
| -rw-r--r-- | libs/arect/Android.bp | 7 | ||||
| -rw-r--r-- | libs/gui/aidl/android/gui/ISurfaceComposer.aidl | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/Scheduler/OneShotTimer.cpp | 23 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 1 | ||||
| -rw-r--r-- | services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp | 34 |
5 files changed, 57 insertions, 13 deletions
diff --git a/libs/arect/Android.bp b/libs/arect/Android.bp index 41b34605f7..76e3e66749 100644 --- a/libs/arect/Android.bp +++ b/libs/arect/Android.bp @@ -39,9 +39,16 @@ ndk_headers { cc_library_headers { name: "libarect_headers", + vendor_available: true, + min_sdk_version: "29", // TODO(b/153609531): remove when no longer needed. native_bridge_supported: true, export_include_dirs: ["include"], + apex_available: [ + "//apex_available:platform", + "com.android.media", + "com.android.media.swcodec", + ], } cc_library_static { diff --git a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl index a9977b0f45..b31b37bada 100644 --- a/libs/gui/aidl/android/gui/ISurfaceComposer.aidl +++ b/libs/gui/aidl/android/gui/ISurfaceComposer.aidl @@ -54,10 +54,11 @@ interface ISurfaceComposer { */ void setPowerMode(IBinder display, int mode); - /* returns display statistics for a given display + /** + * Returns display statistics for a given display * intended to be used by the media framework to properly schedule * video frames */ - DisplayStatInfo getDisplayStats(IBinder display); + DisplayStatInfo getDisplayStats(@nullable IBinder display); /** * Get transactional state of given display. diff --git a/services/surfaceflinger/Scheduler/OneShotTimer.cpp b/services/surfaceflinger/Scheduler/OneShotTimer.cpp index 9c6e56dfa8..3c8dc64f10 100644 --- a/services/surfaceflinger/Scheduler/OneShotTimer.cpp +++ b/services/surfaceflinger/Scheduler/OneShotTimer.cpp @@ -118,16 +118,17 @@ void OneShotTimer::loop() { auto triggerTime = mClock->now() + mInterval; state = TimerState::WAITING; while (true) { - mWaiting = true; - constexpr auto zero = std::chrono::steady_clock::duration::zero(); - // Wait for mInterval time to check if we need to reset or drop into the idle state. - struct timespec ts; - calculateTimeoutTime(std::chrono::nanoseconds(mInterval), &ts); - int result = sem_clockwait(&mSemaphore, CLOCK_MONOTONIC, &ts); - if (result && errno != ETIMEDOUT && errno != EINTR) { - std::stringstream ss; - ss << "sem_clockwait failed (" << errno << ")"; - LOG_ALWAYS_FATAL("%s", ss.str().c_str()); + // Wait until triggerTime time to check if we need to reset or drop into the idle state. + if (const auto triggerInterval = triggerTime - mClock->now(); triggerInterval > 0ns) { + mWaiting = true; + struct timespec ts; + calculateTimeoutTime(triggerInterval, &ts); + int result = sem_clockwait(&mSemaphore, CLOCK_MONOTONIC, &ts); + if (result && errno != ETIMEDOUT && errno != EINTR) { + std::stringstream ss; + ss << "sem_clockwait failed (" << errno << ")"; + LOG_ALWAYS_FATAL("%s", ss.str().c_str()); + } } mWaiting = false; @@ -136,7 +137,7 @@ void OneShotTimer::loop() { break; } - if (state == TimerState::WAITING && (triggerTime - mClock->now()) <= zero) { + if (state == TimerState::WAITING && (triggerTime - mClock->now()) <= 0ns) { triggerTimeout = true; state = TimerState::IDLE; break; diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp index 97d8aef88a..6a17cd8881 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -6747,6 +6747,7 @@ ftl::SharedFuture<FenceResult> SurfaceFlinger::renderScreenImpl( clientCompositionDisplay.orientation = rotation; clientCompositionDisplay.outputDataspace = dataspace; + clientCompositionDisplay.currentLuminanceNits = displayBrightnessNits; clientCompositionDisplay.maxLuminance = DisplayDevice::sDefaultMaxLumiance; clientCompositionDisplay.renderIntent = static_cast<aidl::android::hardware::graphics::composer3::RenderIntent>(renderIntent); diff --git a/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp b/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp index 597e5e71a2..aafc323a9b 100644 --- a/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp +++ b/services/surfaceflinger/tests/unittests/OneShotTimerTest.cpp @@ -130,6 +130,40 @@ TEST_F(OneShotTimerTest, DISABLED_resetBackToBackTest) { EXPECT_FALSE(mResetTimerCallback.waitForUnexpectedCall().has_value()); } +// TODO(b/186417847) This test is new and passes locally, but may be flaky +TEST_F(OneShotTimerTest, DISABLED_resetBackToBackSlowAdvanceTest) { + fake::FakeClock* clock = new fake::FakeClock(); + mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms, + mResetTimerCallback.getInvocable(), + mExpiredTimerCallback.getInvocable(), + std::unique_ptr<fake::FakeClock>(clock)); + mIdleTimer->start(); + EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value()); + + mIdleTimer->reset(); + EXPECT_FALSE(mResetTimerCallback.waitForUnexpectedCall().has_value()); + EXPECT_FALSE(mExpiredTimerCallback.waitForUnexpectedCall().has_value()); + + clock->advanceTime(200us); + mIdleTimer->reset(); + + // Normally we would check that the timer callbacks weren't invoked here + // after resetting the timer, but we need to precisely control the timing of + // this test, and checking that callbacks weren't invoked requires non-zero + // time. + + clock->advanceTime(1500us); + EXPECT_TRUE(mExpiredTimerCallback.waitForCall(1100us).has_value()); + mIdleTimer->reset(); + EXPECT_TRUE(mResetTimerCallback.waitForCall().has_value()); + + mIdleTimer->stop(); + clock->advanceTime(2ms); + // Final quick check that no more callback were observed. + EXPECT_FALSE(mExpiredTimerCallback.waitForUnexpectedCall().has_value()); + EXPECT_FALSE(mResetTimerCallback.waitForUnexpectedCall().has_value()); +} + TEST_F(OneShotTimerTest, startNotCalledTest) { fake::FakeClock* clock = new fake::FakeClock(); mIdleTimer = std::make_unique<scheduler::OneShotTimer>("TestTimer", 1ms, |