summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-08-16 23:26:16 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-08-16 23:26:16 +0000
commitd28a31b13d8ed11cab4bc8cea904631f36d1bb91 (patch)
tree78928a9390af28e237a3a67eb9c5140cb203c509
parent5bc5973ebb9497468412c670bdccad8f39db0b91 (diff)
parent820db998c871017e2715e3ed21b8be90ae0ad271 (diff)
downloadnative-d28a31b13d8ed11cab4bc8cea904631f36d1bb91.tar.gz
Snap for 8953730 from 820db998c871017e2715e3ed21b8be90ae0ad271 to tm-qpr1-release
Change-Id: Ib90b1776f7ed3f894ada7652f8d8c0c394a5fc82
-rw-r--r--services/inputflinger/UnwantedInteractionBlocker.cpp97
-rw-r--r--services/inputflinger/UnwantedInteractionBlocker.h27
-rw-r--r--services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp88
-rw-r--r--services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h3
-rw-r--r--services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp21
-rw-r--r--services/surfaceflinger/DisplayHardware/PowerAdvisor.h10
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp3
-rw-r--r--services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h3
8 files changed, 195 insertions, 57 deletions
diff --git a/services/inputflinger/UnwantedInteractionBlocker.cpp b/services/inputflinger/UnwantedInteractionBlocker.cpp
index 1c27a52d2e..ec41025e9d 100644
--- a/services/inputflinger/UnwantedInteractionBlocker.cpp
+++ b/services/inputflinger/UnwantedInteractionBlocker.cpp
@@ -77,8 +77,7 @@ static std::string toLower(std::string s) {
}
static bool isFromTouchscreen(int32_t source) {
- return isFromSource(source, AINPUT_SOURCE_TOUCHSCREEN) &&
- !isFromSource(source, AINPUT_SOURCE_STYLUS);
+ return isFromSource(source, AINPUT_SOURCE_TOUCHSCREEN);
}
static ::base::TimeTicks toChromeTimestamp(nsecs_t eventTime) {
@@ -142,23 +141,6 @@ static int32_t resolveActionForPointer(uint8_t pointerIndex, int32_t action) {
return AMOTION_EVENT_ACTION_MOVE;
}
-/**
- * Remove the data for the provided pointers from the args. The pointers are identified by their
- * pointerId, not by the index inside the array.
- * Return the new NotifyMotionArgs struct that has the remaining pointers.
- * The only fields that may be different in the returned args from the provided args are:
- * - action
- * - pointerCount
- * - pointerProperties
- * - pointerCoords
- * Action might change because it contains a pointer index. If another pointer is removed, the
- * active pointer index would be shifted.
- * Do not call this function for events with POINTER_UP or POINTER_DOWN events when removed pointer
- * id is the acting pointer id.
- *
- * @param args the args from which the pointers should be removed
- * @param pointerIds the pointer ids of the pointers that should be removed
- */
NotifyMotionArgs removePointerIds(const NotifyMotionArgs& args,
const std::set<int32_t>& pointerIds) {
const uint8_t actionIndex = MotionEvent::getActionIndex(args.action);
@@ -204,6 +186,26 @@ NotifyMotionArgs removePointerIds(const NotifyMotionArgs& args,
return newArgs;
}
+/**
+ * Remove stylus pointers from the provided NotifyMotionArgs.
+ *
+ * Return NotifyMotionArgs where the stylus pointers have been removed.
+ * If this results in removal of the active pointer, then return nullopt.
+ */
+static std::optional<NotifyMotionArgs> removeStylusPointerIds(const NotifyMotionArgs& args) {
+ std::set<int32_t> stylusPointerIds;
+ for (uint32_t i = 0; i < args.pointerCount; i++) {
+ if (args.pointerProperties[i].toolType == AMOTION_EVENT_TOOL_TYPE_STYLUS) {
+ stylusPointerIds.insert(args.pointerProperties[i].id);
+ }
+ }
+ NotifyMotionArgs withoutStylusPointers = removePointerIds(args, stylusPointerIds);
+ if (withoutStylusPointers.pointerCount == 0 || withoutStylusPointers.action == ACTION_UNKNOWN) {
+ return std::nullopt;
+ }
+ return withoutStylusPointers;
+}
+
std::optional<AndroidPalmFilterDeviceInfo> createPalmFilterDeviceInfo(
const InputDeviceInfo& deviceInfo) {
if (!isFromTouchscreen(deviceInfo.getSources())) {
@@ -616,23 +618,7 @@ std::vector<::ui::InProgressTouchEvdev> getTouches(const NotifyMotionArgs& args,
return touches;
}
-std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs& args) {
- if (mPalmDetectionFilter == nullptr) {
- return {args};
- }
- const bool skipThisEvent = args.action == AMOTION_EVENT_ACTION_HOVER_ENTER ||
- args.action == AMOTION_EVENT_ACTION_HOVER_MOVE ||
- args.action == AMOTION_EVENT_ACTION_HOVER_EXIT ||
- args.action == AMOTION_EVENT_ACTION_BUTTON_PRESS ||
- args.action == AMOTION_EVENT_ACTION_BUTTON_RELEASE ||
- args.action == AMOTION_EVENT_ACTION_SCROLL;
- if (skipThisEvent) {
- // Lets not process hover events, button events, or scroll for now.
- return {args};
- }
- if (args.action == AMOTION_EVENT_ACTION_DOWN) {
- mSuppressedPointerIds.clear();
- }
+std::set<int32_t> PalmRejector::detectPalmPointers(const NotifyMotionArgs& args) {
std::bitset<::ui::kNumTouchEvdevSlots> slotsToHold;
std::bitset<::ui::kNumTouchEvdevSlots> slotsToSuppress;
@@ -640,6 +626,7 @@ std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs
// the slots that have been removed due to the incoming event.
SlotState oldSlotState = mSlotState;
mSlotState.update(args);
+
std::vector<::ui::InProgressTouchEvdev> touches =
getTouches(args, mDeviceInfo, oldSlotState, mSlotState);
::base::TimeTicks chromeTimestamp = toChromeTimestamp(args.eventTime);
@@ -651,14 +638,14 @@ std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs
}
ALOGD("Filter: touches = %s", touchesStream.str().c_str());
}
+
mPalmDetectionFilter->Filter(touches, chromeTimestamp, &slotsToHold, &slotsToSuppress);
ALOGD_IF(DEBUG_MODEL, "Response: slotsToHold = %s, slotsToSuppress = %s",
slotsToHold.to_string().c_str(), slotsToSuppress.to_string().c_str());
// Now that we know which slots should be suppressed, let's convert those to pointer id's.
- std::set<int32_t> oldSuppressedIds;
- std::swap(oldSuppressedIds, mSuppressedPointerIds);
+ std::set<int32_t> newSuppressedIds;
for (size_t i = 0; i < args.pointerCount; i++) {
const int32_t pointerId = args.pointerProperties[i].id;
std::optional<size_t> slot = oldSlotState.getSlotForPointerId(pointerId);
@@ -667,9 +654,41 @@ std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs
LOG_ALWAYS_FATAL_IF(!slot, "Could not find slot for pointer id %" PRId32, pointerId);
}
if (slotsToSuppress.test(*slot)) {
- mSuppressedPointerIds.insert(pointerId);
+ newSuppressedIds.insert(pointerId);
}
}
+ return newSuppressedIds;
+}
+
+std::vector<NotifyMotionArgs> PalmRejector::processMotion(const NotifyMotionArgs& args) {
+ if (mPalmDetectionFilter == nullptr) {
+ return {args};
+ }
+ const bool skipThisEvent = args.action == AMOTION_EVENT_ACTION_HOVER_ENTER ||
+ args.action == AMOTION_EVENT_ACTION_HOVER_MOVE ||
+ args.action == AMOTION_EVENT_ACTION_HOVER_EXIT ||
+ args.action == AMOTION_EVENT_ACTION_BUTTON_PRESS ||
+ args.action == AMOTION_EVENT_ACTION_BUTTON_RELEASE ||
+ args.action == AMOTION_EVENT_ACTION_SCROLL;
+ if (skipThisEvent) {
+ // Lets not process hover events, button events, or scroll for now.
+ return {args};
+ }
+ if (args.action == AMOTION_EVENT_ACTION_DOWN) {
+ mSuppressedPointerIds.clear();
+ }
+
+ std::set<int32_t> oldSuppressedIds;
+ std::swap(oldSuppressedIds, mSuppressedPointerIds);
+
+ std::optional<NotifyMotionArgs> touchOnlyArgs = removeStylusPointerIds(args);
+ if (touchOnlyArgs) {
+ mSuppressedPointerIds = detectPalmPointers(*touchOnlyArgs);
+ } else {
+ // This is a stylus-only event.
+ // We can skip this event and just keep the suppressed pointer ids the same as before.
+ mSuppressedPointerIds = oldSuppressedIds;
+ }
std::vector<NotifyMotionArgs> argsWithoutUnwantedPointers =
cancelSuppressedPointers(args, oldSuppressedIds, mSuppressedPointerIds);
diff --git a/services/inputflinger/UnwantedInteractionBlocker.h b/services/inputflinger/UnwantedInteractionBlocker.h
index 1878849452..5d0dde8e64 100644
--- a/services/inputflinger/UnwantedInteractionBlocker.h
+++ b/services/inputflinger/UnwantedInteractionBlocker.h
@@ -43,6 +43,25 @@ std::optional<AndroidPalmFilterDeviceInfo> createPalmFilterDeviceInfo(
static constexpr int32_t ACTION_UNKNOWN = -1;
+/**
+ * Remove the data for the provided pointers from the args. The pointers are identified by their
+ * pointerId, not by the index inside the array.
+ * Return the new NotifyMotionArgs struct that has the remaining pointers.
+ * The only fields that may be different in the returned args from the provided args are:
+ * - action
+ * - pointerCount
+ * - pointerProperties
+ * - pointerCoords
+ * Action might change because it contains a pointer index. If another pointer is removed, the
+ * active pointer index would be shifted.
+ *
+ * If the active pointer id is removed (for example, for events like
+ * POINTER_UP or POINTER_DOWN), then the action is set to ACTION_UNKNOWN. It is up to the caller
+ * to set the action appropriately after the call.
+ *
+ * @param args the args from which the pointers should be removed
+ * @param pointerIds the pointer ids of the pointers that should be removed
+ */
NotifyMotionArgs removePointerIds(const NotifyMotionArgs& args,
const std::set<int32_t>& pointerIds);
@@ -154,6 +173,14 @@ private:
PalmRejector(const PalmRejector&) = delete;
PalmRejector& operator=(const PalmRejector&) = delete;
+ /**
+ * Update the slot state and send this event to the palm rejection model for palm detection.
+ * Return the pointer ids that should be suppressed.
+ *
+ * This function is not const because it has side-effects. It will update the slot state using
+ * the incoming args! Also, it will call Filter(..), which has side-effects.
+ */
+ std::set<int32_t> detectPalmPointers(const NotifyMotionArgs& args);
std::unique_ptr<::ui::SharedPalmDetectionFilterState> mSharedPalmState;
AndroidPalmFilterDeviceInfo mDeviceInfo;
std::unique_ptr<::ui::PalmDetectionFilter> mPalmDetectionFilter;
diff --git a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
index 9313a4500d..29fa001185 100644
--- a/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
+++ b/services/inputflinger/tests/UnwantedInteractionBlocker_test.cpp
@@ -66,6 +66,10 @@ MATCHER_P(WithAction, action, "MotionEvent with specified action") {
return result;
}
+MATCHER_P(WithFlags, flags, "MotionEvent with specified flags") {
+ return arg.flags == flags;
+}
+
static nsecs_t toNs(std::chrono::nanoseconds duration) {
return duration.count();
}
@@ -616,6 +620,90 @@ TEST_F(UnwantedInteractionBlockerTest, HeuristicFilterWorks) {
mTestListener.assertNotifyMotionWasCalled(WithAction(CANCEL));
}
+/**
+ * Send a stylus event that would have triggered the heuristic palm detector if it were a touch
+ * event. However, since it's a stylus event, it should propagate without being canceled through
+ * the blocker.
+ * This is similar to `HeuristicFilterWorks` test, but for stylus tool.
+ */
+TEST_F(UnwantedInteractionBlockerTest, StylusIsNotBlocked) {
+ InputDeviceInfo info = generateTestDeviceInfo();
+ info.addSource(AINPUT_SOURCE_STYLUS);
+ mBlocker->notifyInputDevicesChanged({info});
+ NotifyMotionArgs args1 = generateMotionArgs(0 /*downTime*/, 0 /*eventTime*/, DOWN, {{1, 2, 3}});
+ args1.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ mBlocker->notifyMotion(&args1);
+ mTestListener.assertNotifyMotionWasCalled(WithAction(DOWN));
+
+ // Move the stylus, setting large TOUCH_MAJOR/TOUCH_MINOR dimensions
+ NotifyMotionArgs args2 =
+ generateMotionArgs(0 /*downTime*/, RESAMPLE_PERIOD, MOVE, {{4, 5, 200}});
+ args2.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ mBlocker->notifyMotion(&args2);
+ mTestListener.assertNotifyMotionWasCalled(WithAction(MOVE));
+
+ // Lift up the stylus. If it were a touch event, this would force the model to decide on whether
+ // it's a palm.
+ NotifyMotionArgs args3 =
+ generateMotionArgs(0 /*downTime*/, 2 * RESAMPLE_PERIOD, UP, {{4, 5, 200}});
+ args3.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ mBlocker->notifyMotion(&args3);
+ mTestListener.assertNotifyMotionWasCalled(WithAction(UP));
+}
+
+/**
+ * Send a mixed touch and stylus event.
+ * The touch event goes first, and is a palm. The stylus event goes down after.
+ * Stylus event should continue to work even after touch is detected as a palm.
+ */
+TEST_F(UnwantedInteractionBlockerTest, TouchIsBlockedWhenMixedWithStylus) {
+ InputDeviceInfo info = generateTestDeviceInfo();
+ info.addSource(AINPUT_SOURCE_STYLUS);
+ mBlocker->notifyInputDevicesChanged({info});
+
+ // Touch down
+ NotifyMotionArgs args1 = generateMotionArgs(0 /*downTime*/, 0 /*eventTime*/, DOWN, {{1, 2, 3}});
+ mBlocker->notifyMotion(&args1);
+ mTestListener.assertNotifyMotionWasCalled(WithAction(DOWN));
+
+ // Stylus pointer down
+ NotifyMotionArgs args2 = generateMotionArgs(0 /*downTime*/, RESAMPLE_PERIOD, POINTER_1_DOWN,
+ {{1, 2, 3}, {10, 20, 30}});
+ args2.pointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ mBlocker->notifyMotion(&args2);
+ mTestListener.assertNotifyMotionWasCalled(WithAction(POINTER_1_DOWN));
+
+ // Large touch oval on the next finger move
+ NotifyMotionArgs args3 = generateMotionArgs(0 /*downTime*/, 2 * RESAMPLE_PERIOD, MOVE,
+ {{1, 2, 300}, {11, 21, 30}});
+ args3.pointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ mBlocker->notifyMotion(&args3);
+ mTestListener.assertNotifyMotionWasCalled(WithAction(MOVE));
+
+ // Lift up the finger pointer. It should be canceled due to the heuristic filter.
+ NotifyMotionArgs args4 = generateMotionArgs(0 /*downTime*/, 3 * RESAMPLE_PERIOD, POINTER_0_UP,
+ {{1, 2, 300}, {11, 21, 30}});
+ args4.pointerProperties[1].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ mBlocker->notifyMotion(&args4);
+ mTestListener.assertNotifyMotionWasCalled(
+ AllOf(WithAction(POINTER_0_UP), WithFlags(FLAG_CANCELED)));
+
+ NotifyMotionArgs args5 =
+ generateMotionArgs(0 /*downTime*/, 4 * RESAMPLE_PERIOD, MOVE, {{12, 22, 30}});
+ args5.pointerProperties[0].id = args4.pointerProperties[1].id;
+ args5.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ mBlocker->notifyMotion(&args5);
+ mTestListener.assertNotifyMotionWasCalled(WithAction(MOVE));
+
+ // Lift up the stylus pointer
+ NotifyMotionArgs args6 =
+ generateMotionArgs(0 /*downTime*/, 5 * RESAMPLE_PERIOD, UP, {{4, 5, 200}});
+ args6.pointerProperties[0].id = args4.pointerProperties[1].id;
+ args6.pointerProperties[0].toolType = AMOTION_EVENT_TOOL_TYPE_STYLUS;
+ mBlocker->notifyMotion(&args6);
+ mTestListener.assertNotifyMotionWasCalled(WithAction(UP));
+}
+
using UnwantedInteractionBlockerTestDeathTest = UnwantedInteractionBlockerTest;
/**
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
index 8c164edded..c8bd5e436c 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
@@ -55,7 +55,8 @@ public:
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 ae90dc1a97..4018c6b1af 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -315,7 +315,8 @@ void PowerAdvisor::setExpectedPresentTime(nsecs_t expectedPresentTime) {
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::setCommitStart(nsecs_t commitStartTime) {
}
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 @@ std::optional<nsecs_t> PowerAdvisor::estimateWorkDuration(bool earlyHint) {
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 @@ std::optional<nsecs_t> PowerAdvisor::estimateWorkDuration(bool earlyHint) {
}
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::optional<nsecs_t> PowerAdvisor::estimateWorkDuration(bool earlyHint) {
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);
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
index 98921b0861..71a1f8c03b 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
@@ -72,8 +72,8 @@ public:
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 @@ public:
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 @@ private:
// 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 @@ private:
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/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 83ec4ec213..fd824dc502 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2246,7 +2246,8 @@ void SurfaceFlinger::composite(nsecs_t frameTime, int64_t vsyncId)
// 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();
}
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
index d6dca45188..aede250db5 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
@@ -53,7 +53,8 @@ public:
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));