Merge "Camera NDK: Add android.control.zoomRatio control" into rvc-dev
diff --git a/include/input/InputTransport.h b/include/input/InputTransport.h
index 8ca178c..7ca9031 100644
--- a/include/input/InputTransport.h
+++ b/include/input/InputTransport.h
@@ -404,6 +404,13 @@
*/
bool hasPendingBatch() const;
+ /* Returns the source of first pending batch if exist.
+ *
+ * Should be called after calling consume() with consumeBatches == false to determine
+ * whether consume() should be called again later on with consumeBatches == true.
+ */
+ int32_t getPendingBatchSource() const;
+
private:
// True if touch resampling is enabled.
const bool mResampleTouch;
diff --git a/libs/dumputils/dump_utils.cpp b/libs/dumputils/dump_utils.cpp
index 5b65c95..b2b74dc 100644
--- a/libs/dumputils/dump_utils.cpp
+++ b/libs/dumputils/dump_utils.cpp
@@ -75,6 +75,7 @@
"android.hardware.automotive.audiocontrol@1.0::IAudioControl",
"android.hardware.automotive.vehicle@2.0::IVehicle",
"android.hardware.automotive.evs@1.0::IEvsCamera",
+ "android.hardware.neuralnetworks@1.0::IDevice",
NULL,
};
diff --git a/libs/input/InputTransport.cpp b/libs/input/InputTransport.cpp
index 7335b30..ef7cc7d 100644
--- a/libs/input/InputTransport.cpp
+++ b/libs/input/InputTransport.cpp
@@ -1130,6 +1130,16 @@
return !mBatches.isEmpty();
}
+int32_t InputConsumer::getPendingBatchSource() const {
+ if (mBatches.isEmpty()) {
+ return AINPUT_SOURCE_CLASS_NONE;
+ }
+
+ const Batch& batch = mBatches.itemAt(0);
+ const InputMessage& head = batch.samples.itemAt(0);
+ return head.body.motion.source;
+}
+
ssize_t InputConsumer::findBatch(int32_t deviceId, int32_t source) const {
for (size_t i = 0; i < mBatches.size(); i++) {
const Batch& batch = mBatches.itemAt(i);
diff --git a/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp b/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp
index acaaf4e..2d9f01b 100644
--- a/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp
+++ b/services/surfaceflinger/CompositionEngine/src/ClientCompositionRequestCache.cpp
@@ -35,7 +35,8 @@
return lhs.geometry == rhs.geometry && lhs.alpha == rhs.alpha &&
lhs.sourceDataspace == rhs.sourceDataspace &&
lhs.colorTransform == rhs.colorTransform &&
- lhs.disableBlending == rhs.disableBlending && lhs.shadow == rhs.shadow;
+ lhs.disableBlending == rhs.disableBlending && lhs.shadow == rhs.shadow &&
+ lhs.backgroundBlurRadius == rhs.backgroundBlurRadius;
}
inline bool equalIgnoringBuffer(const renderengine::Buffer& lhs, const renderengine::Buffer& rhs) {
diff --git a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
index e740b13..b738096 100644
--- a/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
+++ b/services/surfaceflinger/CompositionEngine/tests/MockPowerAdvisor.h
@@ -29,6 +29,7 @@
PowerAdvisor();
~PowerAdvisor() override;
+ MOCK_METHOD0(onBootFinished, void());
MOCK_METHOD2(setExpensiveRenderingExpected, void(DisplayId displayId, bool expected));
MOCK_METHOD0(notifyDisplayUpdateImminent, void());
};
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index 06e0cbb..1d8179c 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -72,6 +72,10 @@
}
}
+void PowerAdvisor::onBootFinished() {
+ mBootFinished.store(true);
+}
+
void PowerAdvisor::setExpensiveRenderingExpected(DisplayId displayId, bool expected) {
if (expected) {
mExpensiveDisplays.insert(displayId);
@@ -97,6 +101,12 @@
}
void PowerAdvisor::notifyDisplayUpdateImminent() {
+ // Only start sending this notification once the system has booted so we don't introduce an
+ // early-boot dependency on Power HAL
+ if (!mBootFinished.load()) {
+ return;
+ }
+
if (mSendUpdateImminent.load()) {
HalWrapper* const halWrapper = getPowerHal();
if (halWrapper == nullptr) {
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
index 957d289..4a90acb 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.h
@@ -35,6 +35,7 @@
public:
virtual ~PowerAdvisor();
+ virtual void onBootFinished() = 0;
virtual void setExpensiveRenderingExpected(DisplayId displayId, bool expected) = 0;
virtual void notifyDisplayUpdateImminent() = 0;
};
@@ -56,12 +57,14 @@
PowerAdvisor();
~PowerAdvisor() override;
+ void onBootFinished() override;
void setExpensiveRenderingExpected(DisplayId displayId, bool expected) override;
void notifyDisplayUpdateImminent() override;
private:
HalWrapper* getPowerHal();
+ std::atomic_bool mBootFinished = false;
bool mReconnectPowerHal = false;
std::unordered_set<DisplayId> mExpensiveDisplays;
diff --git a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
index c04447d..7941cda 100644
--- a/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
+++ b/services/surfaceflinger/Scheduler/PhaseOffsets.cpp
@@ -71,15 +71,20 @@
std::unordered_map<float, Offsets> offsets;
for (const auto& [ignored, refreshRate] : refreshRateConfigs.getAllRefreshRates()) {
- if (refreshRate->fps > 65.0f) {
- offsets.emplace(refreshRate->fps, getHighFpsOffsets(refreshRate->vsyncPeriod));
- } else {
- offsets.emplace(refreshRate->fps, getDefaultOffsets(refreshRate->vsyncPeriod));
- }
+ const float fps = refreshRate->fps;
+ offsets.emplace(fps, getPhaseOffsets(fps, refreshRate->vsyncPeriod));
}
return offsets;
}
+PhaseOffsets::Offsets PhaseOffsets::getPhaseOffsets(float fps, nsecs_t vsyncPeriod) const {
+ if (fps > 65.0f) {
+ return getHighFpsOffsets(vsyncPeriod);
+ } else {
+ return getDefaultOffsets(vsyncPeriod);
+ }
+}
+
PhaseOffsets::Offsets PhaseOffsets::getDefaultOffsets(nsecs_t vsyncDuration) const {
const int64_t vsyncPhaseOffsetNs = sysprop::vsync_event_phase_offset_ns(1000000);
const int64_t sfVsyncPhaseOffsetNs = sysprop::vsync_sf_event_phase_offset_ns(1000000);
@@ -159,8 +164,15 @@
[&fps](const std::pair<float, Offsets>& candidateFps) {
return fpsEqualsWithMargin(fps, candidateFps.first);
});
- LOG_ALWAYS_FATAL_IF(iter == mOffsets.end());
- return iter->second;
+
+ if (iter != mOffsets.end()) {
+ return iter->second;
+ }
+
+ // Unknown refresh rate. This might happen if we get a hotplug event for an external display.
+ // In this case just construct the offset.
+ ALOGW("Can't find offset for %.2f fps", fps);
+ return getPhaseOffsets(fps, static_cast<nsecs_t>(1e9f / fps));
}
static void validateSysprops() {
@@ -288,8 +300,7 @@
return iter->second;
}
- // Unknown refresh rate. This might happen if we get a hotplug event for the default display.
- // This happens only during tests and not during regular device operation.
+ // Unknown refresh rate. This might happen if we get a hotplug event for an external display.
// In this case just construct the offset.
ALOGW("Can't find offset for %.2f fps", fps);
return constructOffsets(static_cast<nsecs_t>(1e9f / fps));
diff --git a/services/surfaceflinger/Scheduler/PhaseOffsets.h b/services/surfaceflinger/Scheduler/PhaseOffsets.h
index b7d4eae..208f06b 100644
--- a/services/surfaceflinger/Scheduler/PhaseOffsets.h
+++ b/services/surfaceflinger/Scheduler/PhaseOffsets.h
@@ -69,8 +69,9 @@
private:
std::unordered_map<float, Offsets> initializeOffsets(
const scheduler::RefreshRateConfigs&) const;
- Offsets getDefaultOffsets(nsecs_t vsyncDuration) const;
- Offsets getHighFpsOffsets(nsecs_t vsyncDuration) const;
+ Offsets getDefaultOffsets(nsecs_t vsyncPeriod) const;
+ Offsets getHighFpsOffsets(nsecs_t vsyncPeriod) const;
+ Offsets getPhaseOffsets(float fps, nsecs_t vsyncPeriod) const;
const nsecs_t mThresholdForNextVsync;
const std::unordered_map<float, Offsets> mOffsets;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index cfaabfc..2da92b3 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -567,6 +567,7 @@
postMessageAsync(new LambdaMessage([this]() NO_THREAD_SAFETY_ANALYSIS {
readPersistentProperties();
+ mPowerAdvisor.onBootFinished();
mBootStage = BootStage::FINISHED;
if (property_get_bool("sf.debug.show_refresh_rate_overlay", false)) {
@@ -1028,7 +1029,7 @@
ATRACE_CALL();
ALOGV("performSetActiveConfig");
if (mCheckPendingFence) {
- if (previousFrameMissed()) {
+ if (previousFramePending()) {
// fence has not signaled yet. wait for the next invalidate
mEventQueue->invalidate();
return true;
@@ -1775,13 +1776,17 @@
setTransactionFlags(eDisplayTransactionNeeded);
}
-bool SurfaceFlinger::previousFrameMissed(int graceTimeMs) NO_THREAD_SAFETY_ANALYSIS {
- ATRACE_CALL();
+sp<Fence> SurfaceFlinger::previousFrameFence() NO_THREAD_SAFETY_ANALYSIS {
// We are storing the last 2 present fences. If sf's phase offset is to be
// woken up before the actual vsync but targeting the next vsync, we need to check
// fence N-2
- const sp<Fence>& fence = mVSyncModulator->getOffsets().sf > 0 ? mPreviousPresentFences[0]
- : mPreviousPresentFences[1];
+ return mVSyncModulator->getOffsets().sf > 0 ? mPreviousPresentFences[0]
+ : mPreviousPresentFences[1];
+}
+
+bool SurfaceFlinger::previousFramePending(int graceTimeMs) NO_THREAD_SAFETY_ANALYSIS {
+ ATRACE_CALL();
+ const sp<Fence>& fence = previousFrameFence();
if (fence == Fence::NO_FENCE) {
return false;
@@ -1794,6 +1799,16 @@
return (fence->getStatus() == Fence::Status::Unsignaled);
}
+nsecs_t SurfaceFlinger::previousFramePresentTime() NO_THREAD_SAFETY_ANALYSIS {
+ const sp<Fence>& fence = previousFrameFence();
+
+ if (fence == Fence::NO_FENCE) {
+ return Fence::SIGNAL_TIME_INVALID;
+ }
+
+ return fence->getSignalTime();
+}
+
void SurfaceFlinger::populateExpectedPresentTime() {
DisplayStatInfo stats;
mScheduler->getDisplayStatInfo(&stats);
@@ -1811,6 +1826,7 @@
// calculate the expected present time once and use the cached
// value throughout this frame to make sure all layers are
// seeing this same value.
+ const nsecs_t lastExpectedPresentTime = mExpectedPresentTime.load();
populateExpectedPresentTime();
// When Backpressure propagation is enabled we want to give a small grace period
@@ -1821,12 +1837,32 @@
(mPropagateBackpressureClientComposition || !mHadClientComposition))
? 1
: 0;
- const TracedOrdinal<bool> frameMissed = {"FrameMissed",
- previousFrameMissed(
- graceTimeForPresentFenceMs)};
- const TracedOrdinal<bool> hwcFrameMissed = {"HwcFrameMissed",
+
+ // Pending frames may trigger backpressure propagation.
+ const TracedOrdinal<bool> framePending = {"PrevFramePending",
+ previousFramePending(
+ graceTimeForPresentFenceMs)};
+
+ // Frame missed counts for metrics tracking.
+ // A frame is missed if the prior frame is still pending. If no longer pending,
+ // then we still count the frame as missed if the predicted present time
+ // was further in the past than when the fence actually fired.
+
+ // Add some slop to correct for drift. This should generally be
+ // smaller than a typical frame duration, but should not be so small
+ // that it reports reasonable drift as a missed frame.
+ DisplayStatInfo stats;
+ mScheduler->getDisplayStatInfo(&stats);
+ const nsecs_t frameMissedSlop = stats.vsyncPeriod / 2;
+ const nsecs_t previousPresentTime = previousFramePresentTime();
+ const TracedOrdinal<bool> frameMissed =
+ {"PrevFrameMissed",
+ framePending ||
+ (previousPresentTime >= 0 &&
+ (lastExpectedPresentTime < previousPresentTime - frameMissedSlop))};
+ const TracedOrdinal<bool> hwcFrameMissed = {"PrevHwcFrameMissed",
mHadDeviceComposition && frameMissed};
- const TracedOrdinal<bool> gpuFrameMissed = {"GpuFrameMissed",
+ const TracedOrdinal<bool> gpuFrameMissed = {"PrevGpuFrameMissed",
mHadClientComposition && frameMissed};
if (frameMissed) {
@@ -1846,7 +1882,7 @@
mGpuFrameMissedCount++;
}
- if (frameMissed && mPropagateBackpressure) {
+ if (framePending && mPropagateBackpressure) {
if ((hwcFrameMissed && !gpuFrameMissed) ||
mPropagateBackpressureClientComposition) {
signalLayerUpdate();
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 44e18a7..6ab1fcf 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -844,7 +844,21 @@
bool isDisplayConfigAllowed(HwcConfigIndexType configId) const REQUIRES(mStateLock);
- bool previousFrameMissed(int graceTimeMs = 0);
+ // Gets the fence for the previous frame.
+ // Must be called on the main thread.
+ sp<Fence> previousFrameFence();
+
+ // Whether the previous frame has not yet been presented to the display.
+ // If graceTimeMs is positive, this method waits for at most the provided
+ // grace period before reporting if the frame missed.
+ // Must be called on the main thread.
+ bool previousFramePending(int graceTimeMs = 0);
+
+ // Returns the previous time that the frame was presented. If the frame has
+ // not been presented yet, then returns Fence::SIGNAL_TIME_PENDING. If there
+ // is no pending frame, then returns Fence::SIGNAL_TIME_INVALID.
+ // Must be called on the main thread.
+ nsecs_t previousFramePresentTime();
// Populates the expected present time for this frame. For negative offsets, performs a
// correction using the predicted vsync for the next frame instead.
diff --git a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
index fe57c98..e22d0cf 100644
--- a/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
+++ b/services/surfaceflinger/tests/unittests/mock/DisplayHardware/MockPowerAdvisor.h
@@ -29,6 +29,7 @@
PowerAdvisor();
~PowerAdvisor() override;
+ MOCK_METHOD0(onBootFinished, void());
MOCK_METHOD2(setExpensiveRenderingExpected, void(DisplayId displayId, bool expected));
MOCK_METHOD0(notifyDisplayUpdateImminent, void());
};