Merge "SF: prioritize auto latch unsignlaled"
diff --git a/libs/gui/SurfaceComposerClient.cpp b/libs/gui/SurfaceComposerClient.cpp
index c793523..d16ddb9 100644
--- a/libs/gui/SurfaceComposerClient.cpp
+++ b/libs/gui/SurfaceComposerClient.cpp
@@ -1269,6 +1269,12 @@
mStatus = BAD_INDEX;
return *this;
}
+ if (alpha < 0.0f || alpha > 1.0f) {
+ ALOGE("SurfaceComposerClient::Transaction::setAlpha: invalid alpha %f", alpha);
+ mStatus = BAD_VALUE;
+ return *this;
+
+ }
s->what |= layer_state_t::eAlphaChanged;
s->alpha = alpha;
diff --git a/libs/gui/include/gui/JankInfo.h b/libs/gui/include/gui/JankInfo.h
index ce9716f..1dddeba 100644
--- a/libs/gui/include/gui/JankInfo.h
+++ b/libs/gui/include/gui/JankInfo.h
@@ -24,9 +24,9 @@
None = 0x0,
// Jank that occurs in the layers below SurfaceFlinger
DisplayHAL = 0x1,
- // SF took too long on the CPU
+ // SF took too long on the CPU; deadline missed during HWC
SurfaceFlingerCpuDeadlineMissed = 0x2,
- // SF took too long on the GPU
+ // SF took too long on the GPU; deadline missed during GPU composition
SurfaceFlingerGpuDeadlineMissed = 0x4,
// Either App or GPU took too long on the frame
AppDeadlineMissed = 0x8,
diff --git a/libs/gui/include/gui/TraceUtils.h b/libs/gui/include/gui/TraceUtils.h
index 0009615..4c01683 100644
--- a/libs/gui/include/gui/TraceUtils.h
+++ b/libs/gui/include/gui/TraceUtils.h
@@ -21,13 +21,14 @@
#include <cutils/trace.h>
#include <utils/Trace.h>
-#define ATRACE_FORMAT(fmt, ...) \
- TraceUtils::TraceEnder __traceEnder = \
- (TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__), TraceUtils::TraceEnder())
+#define ATRACE_FORMAT(fmt, ...) \
+ TraceUtils::TraceEnder traceEnder = \
+ (CC_UNLIKELY(ATRACE_ENABLED()) && \
+ (TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__), true), \
+ TraceUtils::TraceEnder())
-#define ATRACE_FORMAT_BEGIN(fmt, ...) TraceUtils::atraceFormatBegin(fmt, ##__VA_ARGS__)
-
-#define ATRACE_FORMAT_INSTANT(fmt, ...) TraceUtils::intantFormat(fmt, ##__VA_ARGS__)
+#define ATRACE_FORMAT_INSTANT(fmt, ...) \
+ (CC_UNLIKELY(ATRACE_ENABLED()) && (TraceUtils::instantFormat(fmt, ##__VA_ARGS__), true))
namespace android {
@@ -39,8 +40,6 @@
};
static void atraceFormatBegin(const char* fmt, ...) {
- if (CC_LIKELY(!ATRACE_ENABLED())) return;
-
const int BUFFER_SIZE = 256;
va_list ap;
char buf[BUFFER_SIZE];
@@ -52,9 +51,7 @@
ATRACE_BEGIN(buf);
}
- static void intantFormat(const char* fmt, ...) {
- if (CC_LIKELY(!ATRACE_ENABLED())) return;
-
+ static void instantFormat(const char* fmt, ...) {
const int BUFFER_SIZE = 256;
va_list ap;
char buf[BUFFER_SIZE];
@@ -65,7 +62,6 @@
ATRACE_INSTANT(buf);
}
+};
-}; // class TraceUtils
-
-} /* namespace android */
+} // namespace android
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
index 8c164ed..c8bd5e4 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
@@ -55,7 +55,8 @@
MOCK_METHOD(void, setRequiresClientComposition,
(DisplayId displayId, bool requiresClientComposition), (override));
MOCK_METHOD(void, setExpectedPresentTime, (nsecs_t expectedPresentTime), (override));
- MOCK_METHOD(void, setPresentFenceTime, (nsecs_t presentFenceTime), (override));
+ MOCK_METHOD(void, setSfPresentTiming, (nsecs_t presentFenceTime, nsecs_t presentEndTime),
+ (override));
MOCK_METHOD(void, setHwcPresentDelayedTime,
(DisplayId displayId,
std::chrono::steady_clock::time_point earliestFrameStartTime));
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index 62078ba..ea71a32 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -315,7 +315,8 @@
mExpectedPresentTimes.append(expectedPresentTime);
}
-void PowerAdvisor::setPresentFenceTime(nsecs_t presentFenceTime) {
+void PowerAdvisor::setSfPresentTiming(nsecs_t presentFenceTime, nsecs_t presentEndTime) {
+ mLastSfPresentEndTime = presentEndTime;
mLastPresentFenceTime = presentFenceTime;
}
@@ -334,13 +335,7 @@
}
void PowerAdvisor::setCompositeEnd(nsecs_t compositeEnd) {
- mLastCompositeEndTime = compositeEnd;
- // calculate the postcomp time here as well
- std::vector<DisplayId>&& displays = getOrderedDisplayIds(&DisplayTimingData::hwcPresentEndTime);
- DisplayTimingData& timingData = mDisplayTimingData[displays.back()];
- mLastPostcompDuration = compositeEnd -
- (timingData.skippedValidate ? *timingData.hwcValidateEndTime
- : *timingData.hwcPresentEndTime);
+ mLastPostcompDuration = compositeEnd - mLastSfPresentEndTime;
}
void PowerAdvisor::setDisplays(std::vector<DisplayId>& displayIds) {
@@ -399,7 +394,7 @@
getOrderedDisplayIds(&DisplayTimingData::hwcPresentStartTime);
DisplayTimeline referenceTiming, estimatedTiming;
- // Iterate over the displays in the same order they are presented
+ // Iterate over the displays that use hwc in the same order they are presented
for (DisplayId displayId : displayIds) {
if (mDisplayTimingData.count(displayId) == 0) {
continue;
@@ -451,8 +446,11 @@
}
ATRACE_INT64("Idle duration", idleDuration);
+ nsecs_t estimatedFlingerEndTime = earlyHint ? estimatedEndTime : mLastSfPresentEndTime;
+
// Don't count time spent idly waiting in the estimate as we could do more work in that time
estimatedEndTime -= idleDuration;
+ estimatedFlingerEndTime -= idleDuration;
// We finish the frame when both present and the gpu are done, so wait for the later of the two
// Also add the frame delay duration since the target did not move while we were delayed
@@ -460,7 +458,10 @@
std::max(estimatedEndTime, estimatedGpuEndTime.value_or(0)) - mCommitStartTimes[0];
// We finish SurfaceFlinger when post-composition finishes, so add that in here
- nsecs_t flingerDuration = estimatedEndTime + mLastPostcompDuration - mCommitStartTimes[0];
+ nsecs_t flingerDuration =
+ estimatedFlingerEndTime + mLastPostcompDuration - mCommitStartTimes[0];
+
+ // Combine the two timings into a single normalized one
nsecs_t combinedDuration = combineTimingEstimates(totalDuration, flingerDuration);
return std::make_optional(combinedDuration);
@@ -640,9 +641,7 @@
mSupportsPowerHint = checkPowerHintSessionSupported();
- mAllowedActualDeviation =
- base::GetIntProperty<nsecs_t>("debug.sf.allowed_actual_deviation",
- std::chrono::nanoseconds(250us).count());
+ mAllowedActualDeviation = base::GetIntProperty<nsecs_t>("debug.sf.allowed_actual_deviation", 0);
}
AidlPowerHalWrapper::~AidlPowerHalWrapper() {
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
index a93744f..859cf3d 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
@@ -72,8 +72,8 @@
nsecs_t presentEndTime) = 0;
// Reports the expected time that the current frame will present to the display
virtual void setExpectedPresentTime(nsecs_t expectedPresentTime) = 0;
- // Reports the most recent present fence time once it's known at the end of the frame
- virtual void setPresentFenceTime(nsecs_t presentFenceTime) = 0;
+ // Reports the most recent present fence time and end time once known
+ virtual void setSfPresentTiming(nsecs_t presentFenceTime, nsecs_t presentEndTime) = 0;
// Reports whether a display used client composition this frame
virtual void setRequiresClientComposition(DisplayId displayId,
bool requiresClientComposition) = 0;
@@ -142,7 +142,7 @@
void setSkippedValidate(DisplayId displayId, bool skipped) override;
void setRequiresClientComposition(DisplayId displayId, bool requiresClientComposition) override;
void setExpectedPresentTime(nsecs_t expectedPresentTime) override;
- void setPresentFenceTime(nsecs_t presentFenceTime) override;
+ void setSfPresentTiming(nsecs_t presentFenceTime, nsecs_t presentEndTime) override;
void setHwcPresentDelayedTime(
DisplayId displayId,
std::chrono::steady_clock::time_point earliestFrameStartTime) override;
@@ -245,8 +245,6 @@
// Current frame's delay
nsecs_t mFrameDelayDuration = 0;
- // Last frame's composite end time
- nsecs_t mLastCompositeEndTime = -1;
// Last frame's post-composition duration
nsecs_t mLastPostcompDuration = 0;
// Buffer of recent commit start times
@@ -255,6 +253,8 @@
RingBuffer<nsecs_t, 2> mExpectedPresentTimes;
// Most recent present fence time, set at the end of the frame once known
nsecs_t mLastPresentFenceTime = -1;
+ // Most recent present fence time, set at the end of the frame once known
+ nsecs_t mLastSfPresentEndTime = -1;
// Target for the entire pipeline including gpu
std::optional<nsecs_t> mTotalFrameTargetDuration;
// Updated list of display IDs
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index 3e69b5c..c73a75c 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -109,11 +109,11 @@
jankType &= ~JankType::DisplayHAL;
}
if (jankType & JankType::SurfaceFlingerCpuDeadlineMissed) {
- janks.emplace_back("SurfaceFlinger CPU Deadline Missed");
+ janks.emplace_back("SurfaceFlinger deadline missed (while in HWC)");
jankType &= ~JankType::SurfaceFlingerCpuDeadlineMissed;
}
if (jankType & JankType::SurfaceFlingerGpuDeadlineMissed) {
- janks.emplace_back("SurfaceFlinger GPU Deadline Missed");
+ janks.emplace_back("SurfaceFlinger deadline missed (while in GPU comp)");
jankType &= ~JankType::SurfaceFlingerGpuDeadlineMissed;
}
if (jankType & JankType::AppDeadlineMissed) {
@@ -986,11 +986,8 @@
mJankClassificationThresholds.presentThreshold) {
// Classify CPU vs GPU if SF wasn't stuffed or if SF was stuffed but this frame
// was presented more than a vsync late.
- if (mGpuFence != FenceTime::NO_FENCE &&
- mSurfaceFlingerActuals.endTime - mSurfaceFlingerActuals.startTime <
- mRefreshRate.getPeriodNsecs()) {
- // If SF was in GPU composition and the CPU work finished before the vsync
- // period, classify it as GPU deadline missed.
+ if (mGpuFence != FenceTime::NO_FENCE) {
+ // If SF was in GPU composition, classify it as GPU deadline missed.
mJankType = JankType::SurfaceFlingerGpuDeadlineMissed;
} else {
mJankType = JankType::SurfaceFlingerCpuDeadlineMissed;
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.cpp b/services/surfaceflinger/Scheduler/MessageQueue.cpp
index e90e387..e1ac301 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.cpp
+++ b/services/surfaceflinger/Scheduler/MessageQueue.cpp
@@ -30,7 +30,7 @@
namespace android::impl {
-void MessageQueue::Handler::dispatchFrame(int64_t vsyncId, nsecs_t expectedVsyncTime) {
+void MessageQueue::Handler::dispatchFrame(VsyncId vsyncId, TimePoint expectedVsyncTime) {
if (!mFramePending.exchange(true)) {
mVsyncId = vsyncId;
mExpectedVsyncTime = expectedVsyncTime;
@@ -44,16 +44,7 @@
void MessageQueue::Handler::handleMessage(const Message&) {
mFramePending.store(false);
-
- const nsecs_t frameTime = systemTime();
- auto& compositor = mQueue.mCompositor;
-
- if (!compositor.commit(frameTime, mVsyncId, mExpectedVsyncTime)) {
- return;
- }
-
- compositor.composite(frameTime, mVsyncId);
- compositor.sample();
+ mQueue.onFrameSignal(mQueue.mCompositor, mVsyncId, mExpectedVsyncTime);
}
MessageQueue::MessageQueue(ICompositor& compositor)
@@ -102,16 +93,17 @@
// Trace VSYNC-sf
mVsync.value = (mVsync.value + 1) % 2;
+ const auto expectedVsyncTime = TimePoint::fromNs(vsyncTime);
{
std::lock_guard lock(mVsync.mutex);
- mVsync.lastCallbackTime = std::chrono::nanoseconds(vsyncTime);
+ mVsync.lastCallbackTime = expectedVsyncTime;
mVsync.scheduledFrameTime.reset();
}
- const auto vsyncId = mVsync.tokenManager->generateTokenForPredictions(
- {targetWakeupTime, readyTime, vsyncTime});
+ const auto vsyncId = VsyncId{mVsync.tokenManager->generateTokenForPredictions(
+ {targetWakeupTime, readyTime, vsyncTime})};
- mHandler->dispatchFrame(vsyncId, vsyncTime);
+ mHandler->dispatchFrame(vsyncId, expectedVsyncTime);
}
void MessageQueue::initVsync(scheduler::VSyncDispatch& dispatch,
@@ -133,9 +125,10 @@
std::lock_guard lock(mVsync.mutex);
mVsync.workDuration = workDuration;
if (mVsync.scheduledFrameTime) {
- mVsync.scheduledFrameTime = mVsync.registration->schedule(
- {mVsync.workDuration.get().count(),
- /*readyDuration=*/0, mVsync.lastCallbackTime.count()});
+ mVsync.scheduledFrameTime =
+ mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
+ .readyDuration = 0,
+ .earliestVsync = mVsync.lastCallbackTime.ns()});
}
}
@@ -171,7 +164,7 @@
{
std::lock_guard lock(mInjector.mutex);
if (CC_UNLIKELY(mInjector.connection)) {
- ALOGD("%s while injecting VSYNC", __FUNCTION__);
+ ALOGD("%s while injecting VSYNC", __func__);
mInjector.connection->requestNextVsync();
return;
}
@@ -181,7 +174,7 @@
mVsync.scheduledFrameTime =
mVsync.registration->schedule({.workDuration = mVsync.workDuration.get().count(),
.readyDuration = 0,
- .earliestVsync = mVsync.lastCallbackTime.count()});
+ .earliestVsync = mVsync.lastCallbackTime.ns()});
}
void MessageQueue::injectorCallback() {
@@ -190,9 +183,10 @@
while ((n = DisplayEventReceiver::getEvents(&mInjector.tube, buffer, 8)) > 0) {
for (int i = 0; i < n; i++) {
if (buffer[i].header.type == DisplayEventReceiver::DISPLAY_EVENT_VSYNC) {
- auto& vsync = buffer[i].vsync;
- mHandler->dispatchFrame(vsync.vsyncData.preferredVsyncId(),
- vsync.vsyncData.preferredExpectedPresentationTime());
+ auto& vsync = buffer[i].vsync.vsyncData;
+ mHandler->dispatchFrame(VsyncId{vsync.preferredVsyncId()},
+ TimePoint::fromNs(
+ vsync.preferredExpectedPresentationTime()));
break;
}
}
diff --git a/services/surfaceflinger/Scheduler/MessageQueue.h b/services/surfaceflinger/Scheduler/MessageQueue.h
index 9dde82b..506f27b 100644
--- a/services/surfaceflinger/Scheduler/MessageQueue.h
+++ b/services/surfaceflinger/Scheduler/MessageQueue.h
@@ -28,6 +28,9 @@
#include <utils/StrongPointer.h>
#include <utils/Timers.h>
+#include <scheduler/Time.h>
+#include <scheduler/VsyncId.h>
+
#include "EventThread.h"
#include "TracedOrdinal.h"
#include "VSyncDispatch.h"
@@ -35,8 +38,8 @@
namespace android {
struct ICompositor {
- virtual bool commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime) = 0;
- virtual void composite(nsecs_t frameTime, int64_t vsyncId) = 0;
+ virtual bool commit(TimePoint frameTime, VsyncId, TimePoint expectedVsyncTime) = 0;
+ virtual void composite(TimePoint frameTime, VsyncId) = 0;
virtual void sample() = 0;
protected:
@@ -88,8 +91,9 @@
class Handler : public MessageHandler {
MessageQueue& mQueue;
std::atomic_bool mFramePending = false;
- std::atomic<int64_t> mVsyncId = 0;
- std::atomic<nsecs_t> mExpectedVsyncTime = 0;
+
+ std::atomic<VsyncId> mVsyncId;
+ std::atomic<TimePoint> mExpectedVsyncTime;
public:
explicit Handler(MessageQueue& queue) : mQueue(queue) {}
@@ -97,7 +101,7 @@
bool isFramePending() const;
- virtual void dispatchFrame(int64_t vsyncId, nsecs_t expectedVsyncTime);
+ virtual void dispatchFrame(VsyncId, TimePoint expectedVsyncTime);
};
friend class Handler;
@@ -108,6 +112,8 @@
void vsyncCallback(nsecs_t vsyncTime, nsecs_t targetWakeupTime, nsecs_t readyTime);
private:
+ virtual void onFrameSignal(ICompositor&, VsyncId, TimePoint expectedVsyncTime) = 0;
+
ICompositor& mCompositor;
const sp<Looper> mLooper;
const sp<Handler> mHandler;
@@ -119,7 +125,7 @@
mutable std::mutex mutex;
TracedOrdinal<std::chrono::nanoseconds> workDuration
GUARDED_BY(mutex) = {"VsyncWorkDuration-sf", std::chrono::nanoseconds(0)};
- std::chrono::nanoseconds lastCallbackTime GUARDED_BY(mutex) = std::chrono::nanoseconds{0};
+ TimePoint lastCallbackTime GUARDED_BY(mutex);
std::optional<nsecs_t> scheduledFrameTime GUARDED_BY(mutex);
TracedOrdinal<int> value = {"VSYNC-sf", 0};
};
diff --git a/services/surfaceflinger/Scheduler/Scheduler.cpp b/services/surfaceflinger/Scheduler/Scheduler.cpp
index a3d4e8d..55ae013 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.cpp
+++ b/services/surfaceflinger/Scheduler/Scheduler.cpp
@@ -131,6 +131,18 @@
}
}
+void Scheduler::onFrameSignal(ICompositor& compositor, VsyncId vsyncId,
+ TimePoint expectedVsyncTime) {
+ const TimePoint frameTime = SchedulerClock::now();
+
+ if (!compositor.commit(frameTime, vsyncId, expectedVsyncTime)) {
+ return;
+ }
+
+ compositor.composite(frameTime, vsyncId);
+ compositor.sample();
+}
+
void Scheduler::createVsyncSchedule(FeatureFlags features) {
mVsyncSchedule.emplace(features);
}
@@ -151,20 +163,20 @@
.getFrameRateOverrideForUid(uid, supportsFrameRateOverrideByContent);
}
-bool Scheduler::isVsyncValid(nsecs_t expectedVsyncTimestamp, uid_t uid) const {
+bool Scheduler::isVsyncValid(TimePoint expectedVsyncTimestamp, uid_t uid) const {
const auto frameRate = getFrameRateOverride(uid);
if (!frameRate.has_value()) {
return true;
}
- return mVsyncSchedule->getTracker().isVSyncInPhase(expectedVsyncTimestamp, *frameRate);
+ return mVsyncSchedule->getTracker().isVSyncInPhase(expectedVsyncTimestamp.ns(), *frameRate);
}
impl::EventThread::ThrottleVsyncCallback Scheduler::makeThrottleVsyncCallback() const {
std::scoped_lock lock(mRefreshRateConfigsLock);
return [this](nsecs_t expectedVsyncTimestamp, uid_t uid) {
- return !isVsyncValid(expectedVsyncTimestamp, uid);
+ return !isVsyncValid(TimePoint::fromNs(expectedVsyncTimestamp), uid);
};
}
diff --git a/services/surfaceflinger/Scheduler/Scheduler.h b/services/surfaceflinger/Scheduler/Scheduler.h
index f800eeb..4730493 100644
--- a/services/surfaceflinger/Scheduler/Scheduler.h
+++ b/services/surfaceflinger/Scheduler/Scheduler.h
@@ -192,7 +192,7 @@
// Returns true if a given vsync timestamp is considered valid vsync
// for a given uid
- bool isVsyncValid(nsecs_t expectedVsyncTimestamp, uid_t uid) const;
+ bool isVsyncValid(TimePoint expectedVsyncTimestamp, uid_t uid) const;
void dump(std::string&) const;
void dump(ConnectionHandle, std::string&) const;
@@ -243,6 +243,9 @@
enum class TimerState { Reset, Expired };
enum class TouchState { Inactive, Active };
+ // impl::MessageQueue overrides:
+ void onFrameSignal(ICompositor&, VsyncId, TimePoint expectedVsyncTime) override;
+
// Create a connection on the given EventThread.
ConnectionHandle createConnection(std::unique_ptr<EventThread>);
sp<EventThreadConnection> createConnectionInternal(
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/Time.h b/services/surfaceflinger/Scheduler/include/scheduler/Time.h
index 487709b..f00d456 100644
--- a/services/surfaceflinger/Scheduler/include/scheduler/Time.h
+++ b/services/surfaceflinger/Scheduler/include/scheduler/Time.h
@@ -46,7 +46,8 @@
struct Duration : TimePoint::duration {
// Implicit conversion from std::chrono counterpart.
- constexpr Duration(TimePoint::duration d) : TimePoint::duration(d) {}
+ template <typename R, typename P>
+ constexpr Duration(std::chrono::duration<R, P> d) : TimePoint::duration(d) {}
static constexpr Duration fromNs(nsecs_t ns) { return {std::chrono::nanoseconds(ns)}; }
@@ -65,4 +66,15 @@
return Duration(time_since_epoch()).ns();
}
+// Shorthand to convert the tick count of a Duration to Period and Rep. For example:
+//
+// const auto i = ticks<std::ratio<1>>(d); // Integer seconds.
+// const auto f = ticks<std::milli, float>(d); // Floating-point milliseconds.
+//
+template <typename Period, typename Rep = Duration::rep>
+constexpr Rep ticks(Duration d) {
+ using D = std::chrono::duration<Rep, Period>;
+ return std::chrono::duration_cast<D>(d).count();
+}
+
} // namespace android
diff --git a/services/surfaceflinger/Scheduler/include/scheduler/VsyncId.h b/services/surfaceflinger/Scheduler/include/scheduler/VsyncId.h
new file mode 100644
index 0000000..c64a3cd
--- /dev/null
+++ b/services/surfaceflinger/Scheduler/include/scheduler/VsyncId.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdint>
+
+namespace android {
+
+// TODO(b/185536303): Import StrongTyping.h into FTL so it can be used here.
+
+// Sequential frame identifier, also known as FrameTimeline token.
+struct VsyncId {
+ int64_t value = -1;
+};
+
+inline bool operator==(VsyncId lhs, VsyncId rhs) {
+ return lhs.value == rhs.value;
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index e3d1d92..744cb46 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -158,6 +158,7 @@
namespace android {
+using namespace std::chrono_literals;
using namespace std::string_literals;
using namespace hardware::configstore;
@@ -1555,7 +1556,7 @@
status_t SurfaceFlinger::injectVSync(nsecs_t when) {
Mutex::Autolock lock(mStateLock);
- const nsecs_t expectedPresentTime = calculateExpectedPresentTime(when).ns();
+ const nsecs_t expectedPresentTime = calculateExpectedPresentTime(TimePoint::fromNs(when)).ns();
const nsecs_t deadlineTimestamp = expectedPresentTime;
return mScheduler->injectVSync(when, expectedPresentTime, deadlineTimestamp) ? NO_ERROR
: BAD_VALUE;
@@ -1930,9 +1931,9 @@
}));
}
-auto SurfaceFlinger::getPreviousPresentFence(nsecs_t frameTime, Period vsyncPeriod)
+auto SurfaceFlinger::getPreviousPresentFence(TimePoint frameTime, Period vsyncPeriod)
-> const FenceTimePtr& {
- const bool isTwoVsyncsAhead = mExpectedPresentTime - frameTime > vsyncPeriod.ns();
+ const bool isTwoVsyncsAhead = mExpectedPresentTime - frameTime > vsyncPeriod;
const size_t i = static_cast<size_t>(isTwoVsyncsAhead);
return mPreviousPresentFences[i].fenceTime;
}
@@ -1949,10 +1950,10 @@
return status == -ETIME;
}
-TimePoint SurfaceFlinger::calculateExpectedPresentTime(nsecs_t frameTime) const {
+TimePoint SurfaceFlinger::calculateExpectedPresentTime(TimePoint frameTime) const {
const auto& schedule = mScheduler->getVsyncSchedule();
- const TimePoint vsyncDeadline = schedule.vsyncDeadlineAfter(TimePoint::fromNs(frameTime));
+ const TimePoint vsyncDeadline = schedule.vsyncDeadlineAfter(frameTime);
if (mVsyncModulator->getVsyncConfig().sfOffset > 0) {
return vsyncDeadline;
}
@@ -1961,25 +1962,21 @@
return vsyncDeadline + schedule.period();
}
-bool SurfaceFlinger::commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime)
+bool SurfaceFlinger::commit(TimePoint frameTime, VsyncId vsyncId, TimePoint expectedVsyncTime)
FTL_FAKE_GUARD(kMainThreadContext) {
// The expectedVsyncTime, which was predicted when this frame was scheduled, is normally in the
// future relative to frameTime, but may not be for delayed frames. Adjust mExpectedPresentTime
// accordingly, but not mScheduledPresentTime.
- const nsecs_t lastScheduledPresentTime = mScheduledPresentTime;
+ const TimePoint lastScheduledPresentTime = mScheduledPresentTime;
mScheduledPresentTime = expectedVsyncTime;
// Calculate the expected present time once and use the cached value throughout this frame to
// make sure all layers are seeing this same value.
- mExpectedPresentTime = expectedVsyncTime >= frameTime
- ? expectedVsyncTime
- : calculateExpectedPresentTime(frameTime).ns();
+ mExpectedPresentTime = expectedVsyncTime >= frameTime ? expectedVsyncTime
+ : calculateExpectedPresentTime(frameTime);
- const auto vsyncIn = [&] {
- if (!ATRACE_ENABLED()) return 0.f;
- return (mExpectedPresentTime - systemTime()) / 1e6f;
- }();
- ATRACE_FORMAT("%s %" PRId64 " vsyncIn %.2fms%s", __func__, vsyncId, vsyncIn,
+ ATRACE_FORMAT("%s %" PRId64 " vsyncIn %.2fms%s", __func__, vsyncId.value,
+ ticks<std::milli, float>(mExpectedPresentTime - scheduler::SchedulerClock::now()),
mExpectedPresentTime == expectedVsyncTime ? "" : " (adjusted)");
const Period vsyncPeriod = mScheduler->getVsyncSchedule().period();
@@ -2009,7 +2006,7 @@
const TracedOrdinal<bool> frameMissed = {"PrevFrameMissed",
framePending ||
(previousPresentTime >= 0 &&
- (lastScheduledPresentTime <
+ (lastScheduledPresentTime.ns() <
previousPresentTime - frameMissedSlop))};
const TracedOrdinal<bool> hwcFrameMissed = {"PrevHwcFrameMissed",
mHadDeviceComposition && frameMissed};
@@ -2066,15 +2063,16 @@
activeDisplay->getPowerMode() == hal::PowerMode::ON;
if (mPowerHintSessionEnabled) {
const auto& display = FTL_FAKE_GUARD(mStateLock, getDefaultDisplayDeviceLocked()).get();
- // get stable vsync period from display mode
const nsecs_t vsyncPeriod = display->getActiveMode()->getVsyncPeriod();
- mPowerAdvisor->setCommitStart(frameTime);
- mPowerAdvisor->setExpectedPresentTime(mExpectedPresentTime);
- const nsecs_t idealSfWorkDuration =
- mVsyncModulator->getVsyncConfig().sfWorkDuration.count();
- // Frame delay is how long we should have minus how long we actually have
- mPowerAdvisor->setFrameDelay(idealSfWorkDuration - (mExpectedPresentTime - frameTime));
- mPowerAdvisor->setTotalFrameTargetWorkDuration(idealSfWorkDuration);
+ mPowerAdvisor->setCommitStart(frameTime.ns());
+ mPowerAdvisor->setExpectedPresentTime(mExpectedPresentTime.ns());
+
+ // Frame delay is how long we should have minus how long we actually have.
+ const Duration idealSfWorkDuration = mVsyncModulator->getVsyncConfig().sfWorkDuration;
+ const Duration frameDelay = idealSfWorkDuration - (mExpectedPresentTime - frameTime);
+
+ mPowerAdvisor->setFrameDelay(frameDelay.ns());
+ mPowerAdvisor->setTotalFrameTargetWorkDuration(idealSfWorkDuration.ns());
mPowerAdvisor->setTargetWorkDuration(vsyncPeriod);
// Send early hint here to make sure there's not another frame pending
@@ -2094,7 +2092,8 @@
// Composite if transactions were committed, or if requested by HWC.
bool mustComposite = mMustComposite.exchange(false);
{
- mFrameTimeline->setSfWakeUp(vsyncId, frameTime, Fps::fromPeriodNsecs(vsyncPeriod.ns()));
+ mFrameTimeline->setSfWakeUp(vsyncId.value, frameTime.ns(),
+ Fps::fromPeriodNsecs(vsyncPeriod.ns()));
bool needsTraversal = false;
if (clearTransactionFlags(eTransactionFlushNeeded)) {
@@ -2144,7 +2143,7 @@
if (mLayerTracingEnabled && !mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) {
// This will block and tracing should only be enabled for debugging.
- mLayerTracing.notify(mVisibleRegionsDirty, frameTime, vsyncId);
+ mLayerTracing.notify(mVisibleRegionsDirty, frameTime.ns(), vsyncId.value);
}
mLastCommittedVsyncId = vsyncId;
@@ -2153,9 +2152,9 @@
return mustComposite && CC_LIKELY(mBootStage != BootStage::BOOTLOADER);
}
-void SurfaceFlinger::composite(nsecs_t frameTime, int64_t vsyncId)
+void SurfaceFlinger::composite(TimePoint frameTime, VsyncId vsyncId)
FTL_FAKE_GUARD(kMainThreadContext) {
- ATRACE_FORMAT("%s %" PRId64, __func__, vsyncId);
+ ATRACE_FORMAT("%s %" PRId64, __func__, vsyncId.value);
compositionengine::CompositionRefreshArgs refreshArgs;
const auto& displays = FTL_FAKE_GUARD(mStateLock, mDisplays);
@@ -2215,15 +2214,13 @@
refreshArgs.devOptFlashDirtyRegionsDelay = std::chrono::milliseconds(mDebugFlashDelay);
}
- const auto expectedPresentTime = mExpectedPresentTime.load();
- const auto prevVsyncTime =
- TimePoint::fromNs(expectedPresentTime) - mScheduler->getVsyncSchedule().period();
-
+ const auto prevVsyncTime = mExpectedPresentTime - mScheduler->getVsyncSchedule().period();
const auto hwcMinWorkDuration = mVsyncConfiguration->getCurrentConfigs().hwcMinWorkDuration;
+
refreshArgs.earliestPresentTime = prevVsyncTime - hwcMinWorkDuration;
refreshArgs.previousPresentFence = mPreviousPresentFences[0].fenceTime;
refreshArgs.scheduledFrameTime = mScheduler->getScheduledFrameTime();
- refreshArgs.expectedPresentTime = expectedPresentTime;
+ refreshArgs.expectedPresentTime = mExpectedPresentTime.ns();
// Store the present time just before calling to the composition engine so we could notify
// the scheduler.
@@ -2231,11 +2228,12 @@
mCompositionEngine->present(refreshArgs);
- mTimeStats->recordFrameDuration(frameTime, systemTime());
+ mTimeStats->recordFrameDuration(frameTime.ns(), systemTime());
// Send a power hint hint after presentation is finished
if (mPowerHintSessionEnabled) {
- mPowerAdvisor->setPresentFenceTime(mPreviousPresentFences[0].fenceTime->getSignalTime());
+ mPowerAdvisor->setSfPresentTiming(mPreviousPresentFences[0].fenceTime->getSignalTime(),
+ systemTime());
if (mPowerHintSessionMode.late) {
mPowerAdvisor->sendActualWorkDuration();
}
@@ -2274,7 +2272,7 @@
mLayersWithQueuedFrames.clear();
if (mLayerTracingEnabled && mLayerTracing.flagIsSet(LayerTracing::TRACE_COMPOSITION)) {
// This will block and should only be used for debugging.
- mLayerTracing.notify(mVisibleRegionsDirty, frameTime, vsyncId);
+ mLayerTracing.notify(mVisibleRegionsDirty, frameTime.ns(), vsyncId.value);
}
mVisibleRegionsWereDirtyThisFrame = mVisibleRegionsDirty; // Cache value for use in post-comp
@@ -3630,13 +3628,12 @@
auto& transaction = transactionQueue.front();
const auto ready =
- transactionIsReadyToBeApplied(transaction,
- transaction.frameTimelineInfo,
- transaction.isAutoTimestamp,
- transaction.desiredPresentTime,
- transaction.originUid, transaction.states,
- bufferLayersReadyToPresent, transactions.size(),
- tryApplyUnsignaled);
+ transactionIsReadyToBeApplied(transaction, transaction.frameTimelineInfo,
+ transaction.isAutoTimestamp,
+ TimePoint::fromNs(transaction.desiredPresentTime),
+ transaction.originUid, transaction.states,
+ bufferLayersReadyToPresent, transactions.size(),
+ tryApplyUnsignaled);
ATRACE_INT("TransactionReadiness", static_cast<int>(ready));
if (ready == TransactionReadiness::NotReady) {
setTransactionFlags(eTransactionFlushNeeded);
@@ -3678,7 +3675,7 @@
return transactionsPendingBarrier;
}
-bool SurfaceFlinger::flushTransactionQueues(int64_t vsyncId) {
+bool SurfaceFlinger::flushTransactionQueues(VsyncId vsyncId) {
// to prevent onHandleDestroyed from being called while the lock is held,
// we must keep a copy of the transactions (specifically the composer
// states) around outside the scope of the lock
@@ -3730,7 +3727,7 @@
}
bool SurfaceFlinger::applyTransactions(std::vector<TransactionState>& transactions,
- int64_t vsyncId) {
+ VsyncId vsyncId) {
bool needsTraversal = false;
// Now apply all transactions.
for (auto& transaction : transactions) {
@@ -3750,7 +3747,7 @@
}
if (mTransactionTracing) {
- mTransactionTracing->addCommittedTransactions(transactions, vsyncId);
+ mTransactionTracing->addCommittedTransactions(transactions, vsyncId.value);
}
return needsTraversal;
}
@@ -3759,27 +3756,28 @@
return !mPendingTransactionQueues.empty() || !mLocklessTransactionQueue.isEmpty();
}
-bool SurfaceFlinger::frameIsEarly(nsecs_t expectedPresentTime, int64_t vsyncId) const {
- // The amount of time SF can delay a frame if it is considered early based
- // on the VsyncModulator::VsyncConfig::appWorkDuration
- constexpr std::chrono::nanoseconds kEarlyLatchMaxThreshold = 100ms;
-
- const nsecs_t currentVsyncPeriod = mScheduler->getVsyncSchedule().period().ns();
- const nsecs_t earlyLatchVsyncThreshold = currentVsyncPeriod / 2;
-
- const auto prediction = mFrameTimeline->getTokenManager()->getPredictionsForToken(vsyncId);
- if (!prediction.has_value()) {
+bool SurfaceFlinger::frameIsEarly(TimePoint expectedPresentTime, VsyncId vsyncId) const {
+ const auto prediction =
+ mFrameTimeline->getTokenManager()->getPredictionsForToken(vsyncId.value);
+ if (!prediction) {
return false;
}
- if (std::abs(prediction->presentTime - expectedPresentTime) >=
- kEarlyLatchMaxThreshold.count()) {
+ const auto predictedPresentTime = TimePoint::fromNs(prediction->presentTime);
+
+ // The duration for which SF can delay a frame if it is considered early based on the
+ // VsyncModulator::VsyncConfig::appWorkDuration.
+ if (constexpr std::chrono::nanoseconds kEarlyLatchMaxThreshold = 100ms;
+ std::chrono::abs(predictedPresentTime - expectedPresentTime) >= kEarlyLatchMaxThreshold) {
return false;
}
- return prediction->presentTime >= expectedPresentTime &&
- prediction->presentTime - expectedPresentTime >= earlyLatchVsyncThreshold;
+ const Duration earlyLatchVsyncThreshold = mScheduler->getVsyncSchedule().period() / 2;
+
+ return predictedPresentTime >= expectedPresentTime &&
+ predictedPresentTime - expectedPresentTime >= earlyLatchVsyncThreshold;
}
+
bool SurfaceFlinger::shouldLatchUnsignaled(const sp<Layer>& layer, const layer_state_t& state,
size_t numStates, size_t totalTXapplied) const {
if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::Disabled) {
@@ -3826,30 +3824,29 @@
return true;
}
-auto SurfaceFlinger::transactionIsReadyToBeApplied(TransactionState& transaction,
- const FrameTimelineInfo& info, bool isAutoTimestamp, int64_t desiredPresentTime,
- uid_t originUid, const Vector<ComposerState>& states,
- const std::unordered_map<
- sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent,
+auto SurfaceFlinger::transactionIsReadyToBeApplied(
+ TransactionState& transaction, const FrameTimelineInfo& info, bool isAutoTimestamp,
+ TimePoint desiredPresentTime, uid_t originUid, const Vector<ComposerState>& states,
+ const std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>&
+ bufferLayersReadyToPresent,
size_t totalTXapplied, bool tryApplyUnsignaled) const -> TransactionReadiness {
ATRACE_FORMAT("transactionIsReadyToBeApplied vsyncId: %" PRId64, info.vsyncId);
- const nsecs_t expectedPresentTime = mExpectedPresentTime.load();
// Do not present if the desiredPresentTime has not passed unless it is more than one second
// in the future. We ignore timestamps more than 1 second in the future for stability reasons.
- if (!isAutoTimestamp && desiredPresentTime >= expectedPresentTime &&
- desiredPresentTime < expectedPresentTime + s2ns(1)) {
+ if (!isAutoTimestamp && desiredPresentTime >= mExpectedPresentTime &&
+ desiredPresentTime < mExpectedPresentTime + 1s) {
ATRACE_NAME("not current");
return TransactionReadiness::NotReady;
}
- if (!mScheduler->isVsyncValid(expectedPresentTime, originUid)) {
+ if (!mScheduler->isVsyncValid(mExpectedPresentTime, originUid)) {
ATRACE_NAME("!isVsyncValid");
return TransactionReadiness::NotReady;
}
// If the client didn't specify desiredPresentTime, use the vsyncId to determine the expected
// present time of this transaction.
- if (isAutoTimestamp && frameIsEarly(expectedPresentTime, info.vsyncId)) {
+ if (isAutoTimestamp && frameIsEarly(mExpectedPresentTime, VsyncId{info.vsyncId})) {
ATRACE_NAME("frameIsEarly");
return TransactionReadiness::NotReady;
}
@@ -4945,8 +4942,6 @@
}
void SurfaceFlinger::logFrameStats(TimePoint now) {
- using namespace std::chrono_literals;
-
static TimePoint sTimestamp = now;
if (now - sTimestamp < 30min) return;
sTimestamp = now;
@@ -5679,7 +5674,7 @@
mScheduler
->schedule([&]() FTL_FAKE_GUARD(mStateLock) {
mLayerTracing.notify(true /* visibleRegionDirty */,
- startingTime, mLastCommittedVsyncId);
+ startingTime, mLastCommittedVsyncId.value);
})
.wait();
}
@@ -6978,7 +6973,7 @@
return calculateMaxAcquiredBufferCount(refreshRate, presentLatency);
}
-void SurfaceFlinger::handleLayerCreatedLocked(const LayerCreatedState& state, int64_t vsyncId) {
+void SurfaceFlinger::handleLayerCreatedLocked(const LayerCreatedState& state, VsyncId vsyncId) {
sp<Layer> layer = state.layer.promote();
if (!layer) {
ALOGD("Layer was destroyed soon after creation %p", state.layer.unsafe_get());
@@ -7009,7 +7004,7 @@
layer->updateTransformHint(mActiveDisplayTransformHint);
if (mTransactionTracing) {
- mTransactionTracing->onLayerAddedToDrawingState(layer->getSequence(), vsyncId);
+ mTransactionTracing->onLayerAddedToDrawingState(layer->getSequence(), vsyncId.value);
}
mInterceptor->saveSurfaceCreation(layer);
}
@@ -7094,7 +7089,7 @@
return buffer;
}
-bool SurfaceFlinger::commitMirrorDisplays(int64_t vsyncId) {
+bool SurfaceFlinger::commitMirrorDisplays(VsyncId vsyncId) {
std::vector<MirrorDisplayState> mirrorDisplays;
{
std::scoped_lock<std::mutex> lock(mMirrorDisplayLock);
@@ -7125,7 +7120,7 @@
childMirror->setClonedChild(layer->createClone());
if (mTransactionTracing) {
mTransactionTracing->onLayerAddedToDrawingState(childMirror->getSequence(),
- vsyncId);
+ vsyncId.value);
}
childMirror->reparent(mirrorDisplay.rootHandle);
}
@@ -7133,7 +7128,7 @@
return true;
}
-bool SurfaceFlinger::commitCreatedLayers(int64_t vsyncId) {
+bool SurfaceFlinger::commitCreatedLayers(VsyncId vsyncId) {
std::vector<LayerCreatedState> createdLayers;
{
std::scoped_lock<std::mutex> lock(mCreatedLayersLock);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 361fa2e..d005337 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -623,11 +623,11 @@
// Commits transactions for layers and displays. Returns whether any state has been invalidated,
// i.e. whether a frame should be composited for each display.
- bool commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVsyncTime) override;
+ bool commit(TimePoint frameTime, VsyncId, TimePoint expectedVsyncTime) override;
// Composites a frame for each display. CompositionEngine performs GPU and/or HAL composition
// via RenderEngine and the Composer HAL, respectively.
- void composite(nsecs_t frameTime, int64_t vsyncId) override;
+ void composite(TimePoint frameTime, VsyncId) override;
// Samples the composited frame via RegionSamplingThread.
void sample() override;
@@ -719,15 +719,15 @@
const std::vector<ListenerCallbacks>& listenerCallbacks,
int originPid, int originUid, uint64_t transactionId)
REQUIRES(mStateLock);
- // flush pending transaction that was presented after desiredPresentTime.
- bool flushTransactionQueues(int64_t vsyncId);
+ // Flush pending transactions that were presented after desiredPresentTime.
+ bool flushTransactionQueues(VsyncId) REQUIRES(kMainThreadContext);
// Returns true if there is at least one transaction that needs to be flushed
bool transactionFlushNeeded();
int flushPendingTransactionQueues(
std::vector<TransactionState>& transactions,
std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent,
- bool tryApplyUnsignaled) REQUIRES(mStateLock);
+ bool tryApplyUnsignaled) REQUIRES(mStateLock) REQUIRES(kMainThreadContext);
uint32_t setClientStateLocked(const FrameTimelineInfo&, ComposerState&,
int64_t desiredPresentTime, bool isAutoTimestamp,
@@ -751,21 +751,24 @@
Ready,
ReadyUnsignaled,
};
- TransactionReadiness transactionIsReadyToBeApplied(TransactionState& state,
- const FrameTimelineInfo& info, bool isAutoTimestamp, int64_t desiredPresentTime,
- uid_t originUid, const Vector<ComposerState>& states,
- const std::unordered_map<
- sp<IBinder>, uint64_t, SpHash<IBinder>>& bufferLayersReadyToPresent,
- size_t totalTXapplied, bool tryApplyUnsignaled) const REQUIRES(mStateLock);
+ TransactionReadiness transactionIsReadyToBeApplied(
+ TransactionState&, const FrameTimelineInfo&, bool isAutoTimestamp,
+ TimePoint desiredPresentTime, uid_t originUid, const Vector<ComposerState>&,
+ const std::unordered_map<sp<IBinder>, uint64_t, SpHash<IBinder>>&
+ bufferLayersReadyToPresent,
+ size_t totalTXapplied, bool tryApplyUnsignaled) const REQUIRES(mStateLock)
+ REQUIRES(kMainThreadContext);
+
static LatchUnsignaledConfig getLatchUnsignaledConfig();
bool shouldLatchUnsignaled(const sp<Layer>& layer, const layer_state_t&, size_t numStates,
size_t totalTXapplied) const;
- bool applyTransactions(std::vector<TransactionState>& transactions, int64_t vsyncId)
+ bool applyTransactions(std::vector<TransactionState>& transactions, VsyncId)
REQUIRES(mStateLock);
uint32_t setDisplayStateLocked(const DisplayState& s) REQUIRES(mStateLock);
uint32_t addInputWindowCommands(const InputWindowCommands& inputWindowCommands)
REQUIRES(mStateLock);
- bool frameIsEarly(nsecs_t expectedPresentTime, int64_t vsyncId) const;
+ bool frameIsEarly(TimePoint expectedPresentTime, VsyncId) const;
+
/*
* Layer management
*/
@@ -945,7 +948,7 @@
using FenceTimePtr = std::shared_ptr<FenceTime>;
- const FenceTimePtr& getPreviousPresentFence(nsecs_t frameTime, Period)
+ const FenceTimePtr& getPreviousPresentFence(TimePoint frameTime, Period)
REQUIRES(kMainThreadContext);
// Blocks the thread waiting for up to graceTimeMs in case the fence is about to signal.
@@ -953,7 +956,7 @@
// Calculates the expected present time for this frame. For negative offsets, performs a
// correction using the predicted vsync for the next frame instead.
- TimePoint calculateExpectedPresentTime(nsecs_t frameTime) const;
+ TimePoint calculateExpectedPresentTime(TimePoint frameTime) const;
/*
* Display identification
@@ -1189,7 +1192,7 @@
const std::unique_ptr<FrameTracer> mFrameTracer;
const std::unique_ptr<frametimeline::FrameTimeline> mFrameTimeline;
- int64_t mLastCommittedVsyncId = -1;
+ VsyncId mLastCommittedVsyncId;
// If blurs should be enabled on this device.
bool mSupportsBlur = false;
@@ -1278,8 +1281,9 @@
};
std::array<FenceWithFenceTime, 2> mPreviousPresentFences;
- std::atomic<nsecs_t> mExpectedPresentTime = 0;
- nsecs_t mScheduledPresentTime = 0;
+ TimePoint mScheduledPresentTime GUARDED_BY(kMainThreadContext);
+ TimePoint mExpectedPresentTime GUARDED_BY(kMainThreadContext);
+
hal::Vsync mHWCVsyncPendingState = hal::Vsync::DISABLE;
hal::Vsync mLastHWCVsyncState = hal::Vsync::DISABLE;
@@ -1333,9 +1337,8 @@
// A temporay pool that store the created layers and will be added to current state in main
// thread.
std::vector<LayerCreatedState> mCreatedLayers GUARDED_BY(mCreatedLayersLock);
- bool commitCreatedLayers(int64_t vsyncId);
- void handleLayerCreatedLocked(const LayerCreatedState& state, int64_t vsyncId)
- REQUIRES(mStateLock);
+ bool commitCreatedLayers(VsyncId);
+ void handleLayerCreatedLocked(const LayerCreatedState&, VsyncId) REQUIRES(mStateLock);
mutable std::mutex mMirrorDisplayLock;
struct MirrorDisplayState {
@@ -1348,7 +1351,7 @@
const sp<Client> client;
};
std::vector<MirrorDisplayState> mMirrorDisplays GUARDED_BY(mMirrorDisplayLock);
- bool commitMirrorDisplays(int64_t vsyncId);
+ bool commitMirrorDisplays(VsyncId);
std::atomic<ui::Transform::RotationFlags> mActiveDisplayTransformHint;
diff --git a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
index ca642fb..312d4ab 100644
--- a/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
+++ b/services/surfaceflinger/Tracing/tools/LayerTraceGenerator.cpp
@@ -201,8 +201,6 @@
TraceGenFlingerDataMapper* dataMapper = mapper.get();
TransactionProtoParser parser(std::move(mapper));
- nsecs_t frameTime;
- int64_t vsyncId;
ALOGD("Generating %d transactions...", traceFile.entry_size());
for (int i = 0; i < traceFile.entry_size(); i++) {
proto::TransactionTraceEntry entry = traceFile.entry(i);
@@ -256,8 +254,8 @@
transaction.listenerCallbacks, transaction.id);
}
- frameTime = entry.elapsed_realtime_nanos();
- vsyncId = entry.vsync_id();
+ const auto frameTime = TimePoint::fromNs(entry.elapsed_realtime_nanos());
+ const auto vsyncId = VsyncId{entry.vsync_id()};
mFlinger.commit(frameTime, vsyncId);
for (int j = 0; j < entry.removed_layer_handles_size(); j++) {
@@ -271,4 +269,4 @@
return true;
}
-} // namespace android
\ No newline at end of file
+} // namespace android
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp
index cf4cd80..28b875a 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzer.cpp
@@ -244,7 +244,6 @@
setDisplayStateLocked();
setTransactionState();
- mTestableFlinger.flushTransactionQueues();
onTransact(data, size);
}
diff --git a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
index 86b7a7a..b25d959 100644
--- a/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
+++ b/services/surfaceflinger/fuzzer/surfaceflinger_fuzzers_utils.h
@@ -153,14 +153,22 @@
ui::PixelFormat::YCBCR_P010,
ui::PixelFormat::HSV_888};
-FloatRect getFuzzedFloatRect(FuzzedDataProvider *fdp) {
+inline VsyncId getFuzzedVsyncId(FuzzedDataProvider& fdp) {
+ return VsyncId{fdp.ConsumeIntegral<int64_t>()};
+}
+
+inline TimePoint getFuzzedTimePoint(FuzzedDataProvider& fdp) {
+ return TimePoint::fromNs(fdp.ConsumeIntegral<nsecs_t>());
+}
+
+inline FloatRect getFuzzedFloatRect(FuzzedDataProvider* fdp) {
return FloatRect(fdp->ConsumeFloatingPoint<float>() /*left*/,
fdp->ConsumeFloatingPoint<float>() /*right*/,
fdp->ConsumeFloatingPoint<float>() /*top*/,
fdp->ConsumeFloatingPoint<float>() /*bottom*/);
}
-HdrMetadata getFuzzedHdrMetadata(FuzzedDataProvider *fdp) {
+inline HdrMetadata getFuzzedHdrMetadata(FuzzedDataProvider* fdp) {
HdrMetadata hdrMetadata;
if (fdp->ConsumeBool()) {
hdrMetadata.cta8613.maxContentLightLevel = fdp->ConsumeFloatingPoint<float>();
@@ -270,8 +278,8 @@
private:
// ICompositor overrides:
- bool commit(nsecs_t, int64_t, nsecs_t) override { return false; }
- void composite(nsecs_t, int64_t) override {}
+ bool commit(TimePoint, VsyncId, TimePoint) override { return false; }
+ void composite(TimePoint, VsyncId) override {}
void sample() override {}
// MessageQueue overrides:
@@ -284,13 +292,18 @@
namespace surfaceflinger::test {
class Factory final : public surfaceflinger::Factory {
+ struct NoOpMessageQueue : android::impl::MessageQueue {
+ using android::impl::MessageQueue::MessageQueue;
+ void onFrameSignal(ICompositor&, VsyncId, TimePoint) override {}
+ };
+
public:
~Factory() = default;
- std::unique_ptr<HWComposer> createHWComposer(const std::string &) override { return nullptr; }
+ std::unique_ptr<HWComposer> createHWComposer(const std::string&) override { return nullptr; }
- std::unique_ptr<MessageQueue> createMessageQueue(ICompositor &compositor) {
- return std::make_unique<android::impl::MessageQueue>(compositor);
+ std::unique_ptr<MessageQueue> createMessageQueue(ICompositor& compositor) {
+ return std::make_unique<NoOpMessageQueue>(compositor);
}
std::unique_ptr<scheduler::VsyncConfiguration> createVsyncConfiguration(
@@ -595,13 +608,14 @@
setVsyncConfig(&mFdp);
- mFlinger->flushTransactionQueues(0);
+ FTL_FAKE_GUARD(kMainThreadContext,
+ mFlinger->flushTransactionQueues(getFuzzedVsyncId(mFdp)));
mFlinger->setTransactionFlags(mFdp.ConsumeIntegral<uint32_t>());
mFlinger->clearTransactionFlags(mFdp.ConsumeIntegral<uint32_t>());
mFlinger->commitOffscreenLayers();
- mFlinger->frameIsEarly(mFdp.ConsumeIntegral<nsecs_t>(), mFdp.ConsumeIntegral<int64_t>());
+ mFlinger->frameIsEarly(getFuzzedTimePoint(mFdp), getFuzzedVsyncId(mFdp));
mFlinger->computeLayerBounds();
mFlinger->startBootAnim();
@@ -736,8 +750,6 @@
listenerCallbacks, transactionId);
}
- auto flushTransactionQueues() { return mFlinger->flushTransactionQueues(0); };
-
auto onTransact(uint32_t code, const Parcel &data, Parcel *reply, uint32_t flags) {
return mFlinger->onTransact(code, data, reply, flags);
}
diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
index 756db8a..874fa7c 100644
--- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
@@ -1680,7 +1680,7 @@
EXPECT_EQ(displayFrame0->getActuals().presentTime, 52);
EXPECT_EQ(displayFrame0->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
EXPECT_EQ(displayFrame0->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
- EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
+ EXPECT_EQ(displayFrame0->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
// case 3 - cpu time = 86 - 82 = 4, vsync period = 30
mFrameTimeline->setSfWakeUp(sfToken3, 106, Fps::fromPeriodNsecs(30));
@@ -2184,6 +2184,50 @@
EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
}
+TEST_F(FrameTimelineTest, jankClassification_displayFrameLateFinishLatePresent_GpuAndCpuMiss) {
+ auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+ auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+ auto gpuFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
+ int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 60});
+
+ // Case 1: cpu time = 33 - 12 = 21, vsync period = 11
+ mFrameTimeline->setSfWakeUp(sfToken1, 12, Fps::fromPeriodNsecs(11));
+ mFrameTimeline->setSfPresent(33, presentFence1, gpuFence1);
+ auto displayFrame = getDisplayFrame(0);
+ gpuFence1->signalForTest(36);
+ presentFence1->signalForTest(52);
+
+ // Fences haven't been flushed yet, so it should be 0
+ EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
+
+ addEmptyDisplayFrame();
+ displayFrame = getDisplayFrame(0);
+
+ // Fences have flushed, so the present timestamps should be updated
+ EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
+ EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
+ EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
+ EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerGpuDeadlineMissed);
+
+ // Case 2: No GPU fence so it will not use GPU composition.
+ mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(30));
+ mFrameTimeline->setSfPresent(66, presentFence2);
+ auto displayFrame2 = getDisplayFrame(2); // 2 because of previous empty frame
+ presentFence2->signalForTest(90);
+
+ // Fences for the frame haven't been flushed yet, so it should be 0
+ EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
+
+ addEmptyDisplayFrame();
+
+ // Fences have flushed, so the present timestamps should be updated
+ EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
+ EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
+ EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
+ EXPECT_EQ(displayFrame2->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
+}
+
TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
}
diff --git a/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp b/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp
index e0aa0b1..f20b9f9 100644
--- a/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp
+++ b/services/surfaceflinger/tests/unittests/MessageQueueTest.cpp
@@ -32,8 +32,8 @@
using CallbackToken = scheduler::VSyncDispatch::CallbackToken;
struct NoOpCompositor final : ICompositor {
- bool commit(nsecs_t, int64_t, nsecs_t) override { return false; }
- void composite(nsecs_t, int64_t) override {}
+ bool commit(TimePoint, VsyncId, TimePoint) override { return false; }
+ void composite(TimePoint, VsyncId) override {}
void sample() override {}
} gNoOpCompositor;
@@ -41,12 +41,15 @@
struct MockHandler : MessageQueue::Handler {
using MessageQueue::Handler::Handler;
- MOCK_METHOD(void, dispatchFrame, (int64_t, nsecs_t), (override));
+ MOCK_METHOD(void, dispatchFrame, (VsyncId, TimePoint), (override));
};
explicit TestableMessageQueue(sp<MockHandler> handler)
: impl::MessageQueue(gNoOpCompositor, handler), mHandler(std::move(handler)) {}
+ // impl::MessageQueue overrides:
+ void onFrameSignal(ICompositor&, VsyncId, TimePoint) override {}
+
public:
TestableMessageQueue() : TestableMessageQueue(sp<MockHandler>::make(*this)) {}
@@ -71,7 +74,7 @@
struct MessageQueueTest : testing::Test {
void SetUp() override {
EXPECT_CALL(mVSyncDispatch, registerCallback(_, "sf")).WillOnce(Return(mCallbackToken));
- EXPECT_NO_FATAL_FAILURE(mEventQueue.initVsync(mVSyncDispatch, mTokenManager, mDuration));
+ EXPECT_NO_FATAL_FAILURE(mEventQueue.initVsync(mVSyncDispatch, mTokenManager, kDuration));
EXPECT_CALL(mVSyncDispatch, unregisterCallback(mCallbackToken)).Times(1);
}
@@ -80,16 +83,15 @@
TestableMessageQueue mEventQueue;
const CallbackToken mCallbackToken{5};
- constexpr static auto mDuration = std::chrono::nanoseconds(100ms);
- constexpr static auto mDifferentDuration = std::chrono::nanoseconds(250ms);
+
+ static constexpr Duration kDuration = 100ms;
+ static constexpr Duration kDifferentDuration = 250ms;
};
namespace {
-/* ------------------------------------------------------------------------
- * Test cases
- */
+
TEST_F(MessageQueueTest, commit) {
- const auto timing = scheduler::VSyncDispatch::ScheduleTiming{.workDuration = mDuration.count(),
+ const auto timing = scheduler::VSyncDispatch::ScheduleTiming{.workDuration = kDuration.ns(),
.readyDuration = 0,
.earliestVsync = 0};
EXPECT_FALSE(mEventQueue.getScheduledFrameTime());
@@ -103,7 +105,7 @@
TEST_F(MessageQueueTest, commitTwice) {
InSequence s;
- const auto timing = scheduler::VSyncDispatch::ScheduleTiming{.workDuration = mDuration.count(),
+ const auto timing = scheduler::VSyncDispatch::ScheduleTiming{.workDuration = kDuration.ns(),
.readyDuration = 0,
.earliestVsync = 0};
@@ -122,7 +124,7 @@
TEST_F(MessageQueueTest, commitTwiceWithCallback) {
InSequence s;
- const auto timing = scheduler::VSyncDispatch::ScheduleTiming{.workDuration = mDuration.count(),
+ const auto timing = scheduler::VSyncDispatch::ScheduleTiming{.workDuration = kDuration.ns(),
.readyDuration = 0,
.earliestVsync = 0};
@@ -132,33 +134,36 @@
ASSERT_TRUE(mEventQueue.getScheduledFrameTime());
EXPECT_EQ(1234, mEventQueue.getScheduledFrameTime()->time_since_epoch().count());
- const auto startTime = 100;
- const auto endTime = startTime + mDuration.count();
- const auto presentTime = 500;
- const auto vsyncId = 42;
+ constexpr TimePoint kStartTime = TimePoint::fromNs(100);
+ constexpr TimePoint kEndTime = kStartTime + kDuration;
+ constexpr TimePoint kPresentTime = TimePoint::fromNs(500);
+ constexpr VsyncId vsyncId{42};
+
EXPECT_CALL(mTokenManager,
- generateTokenForPredictions(
- frametimeline::TimelineItem(startTime, endTime, presentTime)))
- .WillOnce(Return(vsyncId));
- EXPECT_CALL(*mEventQueue.mHandler, dispatchFrame(vsyncId, presentTime)).Times(1);
- EXPECT_NO_FATAL_FAILURE(mEventQueue.vsyncCallback(presentTime, startTime, endTime));
+ generateTokenForPredictions(frametimeline::TimelineItem(kStartTime.ns(),
+ kEndTime.ns(),
+ kPresentTime.ns())))
+ .WillOnce(Return(vsyncId.value));
+ EXPECT_CALL(*mEventQueue.mHandler, dispatchFrame(vsyncId, kPresentTime)).Times(1);
+ EXPECT_NO_FATAL_FAILURE(
+ mEventQueue.vsyncCallback(kPresentTime.ns(), kStartTime.ns(), kEndTime.ns()));
EXPECT_FALSE(mEventQueue.getScheduledFrameTime());
const auto timingAfterCallback =
- scheduler::VSyncDispatch::ScheduleTiming{.workDuration = mDuration.count(),
+ scheduler::VSyncDispatch::ScheduleTiming{.workDuration = kDuration.ns(),
.readyDuration = 0,
- .earliestVsync = presentTime};
+ .earliestVsync = kPresentTime.ns()};
EXPECT_CALL(mVSyncDispatch, schedule(mCallbackToken, timingAfterCallback)).WillOnce(Return(0));
EXPECT_NO_FATAL_FAILURE(mEventQueue.scheduleFrame());
}
TEST_F(MessageQueueTest, commitWithDurationChange) {
- EXPECT_NO_FATAL_FAILURE(mEventQueue.setDuration(mDifferentDuration));
+ EXPECT_NO_FATAL_FAILURE(mEventQueue.setDuration(kDifferentDuration));
const auto timing =
- scheduler::VSyncDispatch::ScheduleTiming{.workDuration = mDifferentDuration.count(),
+ scheduler::VSyncDispatch::ScheduleTiming{.workDuration = kDifferentDuration.ns(),
.readyDuration = 0,
.earliestVsync = 0};
diff --git a/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp b/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
index 18e0a1c..e256d2c 100644
--- a/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
+++ b/services/surfaceflinger/tests/unittests/SurfaceFlinger_PowerHintTest.cpp
@@ -133,22 +133,20 @@
TEST_F(SurfaceFlingerPowerHintTest, sendDurationsIncludingHwcWaitTime) {
ON_CALL(*mPowerAdvisor, usePowerHintSession()).WillByDefault(Return(true));
- const std::chrono::nanoseconds mockVsyncPeriod = 15ms;
EXPECT_CALL(*mPowerAdvisor, setTargetWorkDuration(_)).Times(1);
-
- const nsecs_t now = systemTime();
- const std::chrono::nanoseconds mockHwcRunTime = 20ms;
EXPECT_CALL(*mDisplaySurface,
prepareFrame(compositionengine::DisplaySurface::CompositionType::Hwc))
.Times(1);
- EXPECT_CALL(*mComposer, presentOrValidateDisplay(HWC_DISPLAY, _, _, _, _, _))
- .WillOnce([mockHwcRunTime] {
- std::this_thread::sleep_for(mockHwcRunTime);
- return hardware::graphics::composer::V2_1::Error::NONE;
- });
+ EXPECT_CALL(*mComposer, presentOrValidateDisplay(HWC_DISPLAY, _, _, _, _, _)).WillOnce([] {
+ constexpr Duration kMockHwcRunTime = 20ms;
+ std::this_thread::sleep_for(kMockHwcRunTime);
+ return hardware::graphics::composer::V2_1::Error::NONE;
+ });
EXPECT_CALL(*mPowerAdvisor, sendActualWorkDuration()).Times(1);
- static constexpr bool kVsyncId = 123; // arbitrary
- mFlinger.commitAndComposite(now, kVsyncId, now + mockVsyncPeriod.count());
+
+ const TimePoint frameTime = scheduler::SchedulerClock::now();
+ constexpr Period kMockVsyncPeriod = 15ms;
+ mFlinger.commitAndComposite(frameTime, VsyncId{123}, frameTime + kMockVsyncPeriod);
}
TEST_F(SurfaceFlingerPowerHintTest, inactiveOnDisplayDoze) {
@@ -156,22 +154,20 @@
mDisplay->setPowerMode(hal::PowerMode::DOZE);
- const std::chrono::nanoseconds mockVsyncPeriod = 15ms;
EXPECT_CALL(*mPowerAdvisor, setTargetWorkDuration(_)).Times(0);
-
- const nsecs_t now = systemTime();
- const std::chrono::nanoseconds mockHwcRunTime = 20ms;
EXPECT_CALL(*mDisplaySurface,
prepareFrame(compositionengine::DisplaySurface::CompositionType::Hwc))
.Times(1);
- EXPECT_CALL(*mComposer, presentOrValidateDisplay(HWC_DISPLAY, _, _, _, _, _))
- .WillOnce([mockHwcRunTime] {
- std::this_thread::sleep_for(mockHwcRunTime);
- return hardware::graphics::composer::V2_1::Error::NONE;
- });
+ EXPECT_CALL(*mComposer, presentOrValidateDisplay(HWC_DISPLAY, _, _, _, _, _)).WillOnce([] {
+ constexpr Duration kMockHwcRunTime = 20ms;
+ std::this_thread::sleep_for(kMockHwcRunTime);
+ return hardware::graphics::composer::V2_1::Error::NONE;
+ });
EXPECT_CALL(*mPowerAdvisor, sendActualWorkDuration()).Times(0);
- static constexpr bool kVsyncId = 123; // arbitrary
- mFlinger.commitAndComposite(now, kVsyncId, now + mockVsyncPeriod.count());
+
+ const TimePoint frameTime = scheduler::SchedulerClock::now();
+ constexpr Period kMockVsyncPeriod = 15ms;
+ mFlinger.commitAndComposite(frameTime, VsyncId{123}, frameTime + kMockVsyncPeriod);
}
} // namespace
diff --git a/services/surfaceflinger/tests/unittests/TestableScheduler.h b/services/surfaceflinger/tests/unittests/TestableScheduler.h
index 4708572..66cdfd7 100644
--- a/services/surfaceflinger/tests/unittests/TestableScheduler.h
+++ b/services/surfaceflinger/tests/unittests/TestableScheduler.h
@@ -109,8 +109,8 @@
private:
// ICompositor overrides:
- bool commit(nsecs_t, int64_t, nsecs_t) override { return false; }
- void composite(nsecs_t, int64_t) override {}
+ bool commit(TimePoint, VsyncId, TimePoint) override { return false; }
+ void composite(TimePoint, VsyncId) override {}
void sample() override {}
};
diff --git a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
index 66eb186..407706d 100644
--- a/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
+++ b/services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h
@@ -27,6 +27,7 @@
#include <compositionengine/impl/Display.h>
#include <compositionengine/impl/OutputLayerCompositionState.h>
#include <compositionengine/mock/DisplaySurface.h>
+#include <ftl/fake_guard.h>
#include <gui/ScreenCaptureResults.h>
#include "BufferStateLayer.h"
@@ -316,25 +317,22 @@
* Forwarding for functions being tested
*/
- nsecs_t commit(nsecs_t frameTime, int64_t vsyncId, nsecs_t expectedVSyncTime) {
+ TimePoint commit(TimePoint frameTime, VsyncId vsyncId, TimePoint expectedVSyncTime) {
mFlinger->commit(frameTime, vsyncId, expectedVSyncTime);
return frameTime;
}
- nsecs_t commit(nsecs_t frameTime, int64_t vsyncId) {
- std::chrono::nanoseconds period = 10ms;
- return commit(frameTime, vsyncId, frameTime + period.count());
+ TimePoint commit(TimePoint frameTime, VsyncId vsyncId) {
+ return commit(frameTime, vsyncId, frameTime + Period(10ms));
}
- nsecs_t commit() {
- const nsecs_t now = systemTime();
- const nsecs_t expectedVsyncTime = now + 10'000'000;
- return commit(now, kVsyncId, expectedVsyncTime);
+ TimePoint commit() {
+ const TimePoint frameTime = scheduler::SchedulerClock::now();
+ return commit(frameTime, kVsyncId);
}
- void commitAndComposite(const nsecs_t frameTime, const int64_t vsyncId,
- const nsecs_t expectedVsyncTime) {
- mFlinger->composite(commit(frameTime, vsyncId, expectedVsyncTime), kVsyncId);
+ void commitAndComposite(TimePoint frameTime, VsyncId vsyncId, TimePoint expectedVsyncTime) {
+ mFlinger->composite(commit(frameTime, vsyncId, expectedVsyncTime), vsyncId);
}
void commitAndComposite() { mFlinger->composite(commit(), kVsyncId); }
@@ -432,7 +430,9 @@
listenerCallbacks, transactionId);
}
- auto flushTransactionQueues() { return mFlinger->flushTransactionQueues(0); };
+ auto flushTransactionQueues() {
+ return FTL_FAKE_GUARD(kMainThreadContext, mFlinger->flushTransactionQueues(kVsyncId));
+ }
auto onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
return mFlinger->onTransact(code, data, reply, flags);
@@ -870,7 +870,7 @@
};
private:
- constexpr static int64_t kVsyncId = 123;
+ static constexpr VsyncId kVsyncId{123};
surfaceflinger::test::Factory mFactory;
sp<SurfaceFlinger> mFlinger;
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
index d6dca45..aede250 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
@@ -53,7 +53,8 @@
MOCK_METHOD(void, setRequiresClientComposition,
(DisplayId displayId, bool requiresClientComposition), (override));
MOCK_METHOD(void, setExpectedPresentTime, (nsecs_t expectedPresentTime), (override));
- MOCK_METHOD(void, setPresentFenceTime, (nsecs_t presentFenceTime), (override));
+ MOCK_METHOD(void, setSfPresentTiming, (nsecs_t presentFenceTime, nsecs_t presentEndTime),
+ (override));
MOCK_METHOD(void, setHwcPresentDelayedTime,
(DisplayId displayId,
std::chrono::steady_clock::time_point earliestFrameStartTime));