Merge "Remove frame rate functions from buffer queue" into rvc-dev
diff --git a/services/inputflinger/BlockingQueue.h b/services/inputflinger/BlockingQueue.h
index db9f26e..b612ca7 100644
--- a/services/inputflinger/BlockingQueue.h
+++ b/services/inputflinger/BlockingQueue.h
@@ -45,10 +45,7 @@
T pop() {
std::unique_lock lock(mLock);
android::base::ScopedLockAssertion assumeLock(mLock);
- mHasElements.wait(lock, [this]{
- android::base::ScopedLockAssertion assumeLock(mLock);
- return !this->mQueue.empty();
- });
+ mHasElements.wait(lock, [this]() REQUIRES(mLock) { return !this->mQueue.empty(); });
T t = std::move(mQueue.front());
mQueue.erase(mQueue.begin());
return t;
diff --git a/services/inputflinger/InputClassifier.cpp b/services/inputflinger/InputClassifier.cpp
index ae9a348..e5e83d7 100644
--- a/services/inputflinger/InputClassifier.cpp
+++ b/services/inputflinger/InputClassifier.cpp
@@ -250,7 +250,7 @@
case ClassifierEventType::DEVICE_RESET: {
const int32_t deviceId = *(event.getDeviceId());
halResponseOk = mService->resetDevice(deviceId).isOk();
- setClassification(deviceId, MotionClassification::NONE);
+ clearDeviceState(deviceId);
break;
}
case ClassifierEventType::HAL_RESET: {
@@ -321,6 +321,12 @@
mClassifications[deviceId] = MotionClassification::NONE;
}
+void MotionClassifier::clearDeviceState(int32_t deviceId) {
+ std::scoped_lock lock(mLock);
+ mClassifications.erase(deviceId);
+ mLastDownTimes.erase(deviceId);
+}
+
MotionClassification MotionClassifier::classify(const NotifyMotionArgs& args) {
if ((args.action & AMOTION_EVENT_ACTION_MASK) == AMOTION_EVENT_ACTION_DOWN) {
updateLastDownTime(args.deviceId, args.downTime);
@@ -455,6 +461,7 @@
void InputClassifier::dump(std::string& dump) {
std::scoped_lock lock(mLock);
dump += "Input Classifier State:\n";
+ dump += StringPrintf(INDENT1 "Deep press: %s\n", deepPressEnabled() ? "enabled" : "disabled");
dump += INDENT1 "Motion Classifier:\n";
if (mMotionClassifier) {
diff --git a/services/inputflinger/InputClassifier.h b/services/inputflinger/InputClassifier.h
index 47e20db..9692352 100644
--- a/services/inputflinger/InputClassifier.h
+++ b/services/inputflinger/InputClassifier.h
@@ -212,6 +212,8 @@
void updateLastDownTime(int32_t deviceId, nsecs_t downTime);
+ void clearDeviceState(int32_t deviceId);
+
/**
* Exit the InputClassifier HAL thread.
* Useful for tests to ensure proper cleanup.
diff --git a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
index 550ec61..06e0cbb 100644
--- a/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
+++ b/services/surfaceflinger/DisplayHardware/PowerAdvisor.cpp
@@ -124,24 +124,20 @@
static std::unique_ptr<HalWrapper> connect() {
// Power HAL 1.3 is not guaranteed to be available, thus we need to query
// Power HAL 1.0 first and try to cast it to Power HAL 1.3.
- // Power HAL 1.0 is always available, thus if we fail to query it, it means
- // Power HAL is not available temporarily and we should retry later. However,
- // if Power HAL 1.0 is available and we can't cast it to Power HAL 1.3,
- // it means Power HAL 1.3 is not available at all, so we should stop trying.
sp<V1_3::IPower> powerHal = nullptr;
- if (sHasPowerHal_1_3) {
- sp<V1_0::IPower> powerHal_1_0 = V1_0::IPower::getService();
- if (powerHal_1_0 != nullptr) {
- // Try to cast to Power HAL 1.3
- powerHal = V1_3::IPower::castFrom(powerHal_1_0);
- if (powerHal == nullptr) {
- ALOGW("No Power HAL 1.3 service in system");
- sHasPowerHal_1_3 = false;
- } else {
- ALOGI("Loaded Power HAL 1.3 service");
- }
+ sp<V1_0::IPower> powerHal_1_0 = V1_0::IPower::getService();
+ if (powerHal_1_0 != nullptr) {
+ // Try to cast to Power HAL 1.3
+ powerHal = V1_3::IPower::castFrom(powerHal_1_0);
+ if (powerHal == nullptr) {
+ ALOGW("No Power HAL 1.3 service in system, disabling PowerAdvisor");
+ } else {
+ ALOGI("Loaded Power HAL 1.3 service");
}
+ } else {
+ ALOGW("No Power HAL found, disabling PowerAdvisor");
}
+
if (powerHal == nullptr) {
return nullptr;
}
@@ -162,12 +158,9 @@
}
private:
- static bool sHasPowerHal_1_3;
const sp<V1_3::IPower> mPowerHal = nullptr;
};
-bool HidlPowerHalWrapper::sHasPowerHal_1_3 = true;
-
class AidlPowerHalWrapper : public PowerAdvisor::HalWrapper {
public:
AidlPowerHalWrapper(sp<IPower> powerHal) : mPowerHal(std::move(powerHal)) {
@@ -226,7 +219,13 @@
PowerAdvisor::HalWrapper* PowerAdvisor::getPowerHal() {
static std::unique_ptr<HalWrapper> sHalWrapper = nullptr;
+ static bool sHasHal = true;
+ if (!sHasHal) {
+ return nullptr;
+ }
+
+ // If we used to have a HAL, but it stopped responding, attempt to reconnect
if (mReconnectPowerHal) {
sHalWrapper = nullptr;
mReconnectPowerHal = false;
@@ -244,6 +243,12 @@
sHalWrapper = HidlPowerHalWrapper::connect();
}
+ // If we make it to this point and still don't have a HAL, it's unlikely we
+ // will, so stop trying
+ if (sHalWrapper == nullptr) {
+ sHasHal = false;
+ }
+
return sHalWrapper.get();
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 766871e..64cfb3d 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -719,9 +719,14 @@
Hwc2::IComposerClient::Composition Layer::getCompositionType(
const sp<const DisplayDevice>& display) const {
const auto outputLayer = findOutputLayerForDisplay(display);
- LOG_FATAL_IF(!outputLayer);
- return outputLayer->getState().hwc ? (*outputLayer->getState().hwc).hwcCompositionType
- : Hwc2::IComposerClient::Composition::CLIENT;
+ if (outputLayer == nullptr) {
+ return Hwc2::IComposerClient::Composition::INVALID;
+ }
+ if (outputLayer->getState().hwc) {
+ return (*outputLayer->getState().hwc).hwcCompositionType;
+ } else {
+ return Hwc2::IComposerClient::Composition::CLIENT;
+ }
}
bool Layer::getClearClientTarget(const sp<const DisplayDevice>& display) const {
@@ -2052,13 +2057,20 @@
setTransactionFlags(eTransactionNeeded);
}
-LayerProto* Layer::writeToProto(LayersProto& layersProto, uint32_t traceFlags) const {
+LayerProto* Layer::writeToProto(LayersProto& layersProto, uint32_t traceFlags,
+ const sp<const DisplayDevice>& device) const {
LayerProto* layerProto = layersProto.add_layers();
writeToProtoDrawingState(layerProto, traceFlags);
writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing, traceFlags);
+ // Only populate for the primary display.
+ if (device) {
+ const Hwc2::IComposerClient::Composition compositionType = getCompositionType(device);
+ layerProto->set_hwc_composition_type(static_cast<HwcCompositionType>(compositionType));
+ }
+
for (const sp<Layer>& layer : mDrawingChildren) {
- layer->writeToProto(layersProto, traceFlags);
+ layer->writeToProto(layersProto, traceFlags, device);
}
return layerProto;
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 5d2144a..20d7232 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -506,7 +506,8 @@
bool isRemovedFromCurrentState() const;
LayerProto* writeToProto(LayersProto& layersProto,
- uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
+ uint32_t traceFlags = SurfaceTracing::TRACE_ALL,
+ const sp<const DisplayDevice>& device = nullptr) const;
// Write states that are modified by the main thread. This includes drawing
// state as well as buffer data. This should be called in the main or tracing
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.cpp b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
index 949ba4c..8987dcd 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.cpp
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.cpp
@@ -19,8 +19,10 @@
#define LOG_TAG "VSyncReactor"
//#define LOG_NDEBUG 0
#include "VSyncReactor.h"
+#include <cutils/properties.h>
#include <log/log.h>
#include <utils/Trace.h>
+#include "../TracedOrdinal.h"
#include "TimeKeeper.h"
#include "VSyncDispatch.h"
#include "VSyncTracker.h"
@@ -32,12 +34,35 @@
return systemTime(SYSTEM_TIME_MONOTONIC);
}
+class PredictedVsyncTracer {
+public:
+ PredictedVsyncTracer(VSyncDispatch& dispatch)
+ : mRegistration(dispatch,
+ std::bind(&PredictedVsyncTracer::callback, this, std::placeholders::_1,
+ std::placeholders::_2),
+ "PredictedVsyncTracer") {
+ mRegistration.schedule(0, 0);
+ }
+
+private:
+ TracedOrdinal<bool> mParity = {"VSYNC-predicted", 0};
+ VSyncCallbackRegistration mRegistration;
+
+ void callback(nsecs_t /*vsyncTime*/, nsecs_t /*targetWakeupTim*/) {
+ mParity = !mParity;
+ mRegistration.schedule(0, 0);
+ }
+};
+
VSyncReactor::VSyncReactor(std::unique_ptr<Clock> clock, std::unique_ptr<VSyncDispatch> dispatch,
std::unique_ptr<VSyncTracker> tracker, size_t pendingFenceLimit)
: mClock(std::move(clock)),
mTracker(std::move(tracker)),
mDispatch(std::move(dispatch)),
- mPendingLimit(pendingFenceLimit) {}
+ mPendingLimit(pendingFenceLimit),
+ mPredictedVsyncTracer(property_get_bool("debug.sf.show_predicted_vsync", false)
+ ? std::make_unique<PredictedVsyncTracer>(*mDispatch)
+ : nullptr) {}
VSyncReactor::~VSyncReactor() = default;
@@ -287,7 +312,7 @@
auto it = mCallbacks.find(callback);
if (it == mCallbacks.end()) {
// TODO (b/146557561): resolve lastCallbackTime semantics in DispSync i/f.
- static auto constexpr maxListeners = 3;
+ static auto constexpr maxListeners = 4;
if (mCallbacks.size() >= maxListeners) {
ALOGE("callback %s not added, exceeded callback limit of %i (currently %zu)", name,
maxListeners, mCallbacks.size());
diff --git a/services/surfaceflinger/Scheduler/VSyncReactor.h b/services/surfaceflinger/Scheduler/VSyncReactor.h
index aa8a38d..7d8a8e3 100644
--- a/services/surfaceflinger/Scheduler/VSyncReactor.h
+++ b/services/surfaceflinger/Scheduler/VSyncReactor.h
@@ -30,6 +30,7 @@
class VSyncDispatch;
class VSyncTracker;
class CallbackRepeater;
+class PredictedVsyncTracer;
// TODO (b/145217110): consider renaming.
class VSyncReactor : public android::DispSync {
@@ -86,6 +87,8 @@
std::unordered_map<DispSync::Callback*, std::unique_ptr<CallbackRepeater>> mCallbacks
GUARDED_BY(mMutex);
+
+ const std::unique_ptr<PredictedVsyncTracer> mPredictedVsyncTracer;
};
class SystemClock : public Clock {
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 1d00624..27bd53c 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -906,15 +906,24 @@
auto refreshRate = mRefreshRateConfigs->getRefreshRateFromConfigId(info.configId);
ALOGV("setDesiredActiveConfig(%s)", refreshRate.name.c_str());
- // Don't check against the current mode yet. Worst case we set the desired
- // config twice. However event generation config might have changed so we need to update it
- // accordingly
std::lock_guard<std::mutex> lock(mActiveConfigLock);
- const Scheduler::ConfigEvent prevConfig = mDesiredActiveConfig.event;
- mDesiredActiveConfig = info;
- mDesiredActiveConfig.event = mDesiredActiveConfig.event | prevConfig;
+ if (mDesiredActiveConfigChanged) {
+ // If a config change is pending, just cache the latest request in
+ // mDesiredActiveConfig
+ const Scheduler::ConfigEvent prevConfig = mDesiredActiveConfig.event;
+ mDesiredActiveConfig = info;
+ mDesiredActiveConfig.event = mDesiredActiveConfig.event | prevConfig;
+ } else {
+ // Check is we are already at the desired config
+ const auto display = getDefaultDisplayDeviceLocked();
+ if (!display || display->getActiveConfig() == refreshRate.configId) {
+ return;
+ }
- if (!mDesiredActiveConfigChanged) {
+ // Initiate a config change.
+ mDesiredActiveConfigChanged = true;
+ mDesiredActiveConfig = info;
+
// This will trigger HWC refresh without resetting the idle timer.
repaintEverythingForHWC();
// Start receiving vsync samples now, so that we can detect a period
@@ -927,7 +936,6 @@
mPhaseConfiguration->setRefreshRateFps(refreshRate.fps);
mVSyncModulator->setPhaseOffsets(mPhaseConfiguration->getCurrentOffsets());
}
- mDesiredActiveConfigChanged = true;
if (mRefreshRateOverlay) {
mRefreshRateOverlay->changeRefreshRate(refreshRate);
@@ -4450,13 +4458,20 @@
}
LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {
+ Mutex::Autolock _l(mStateLock);
+ const auto device = getDefaultDisplayDeviceLocked();
LayersProto layersProto;
for (const sp<Layer>& layer : mDrawingState.layersSortedByZ) {
- layer->writeToProto(layersProto, traceFlags);
+ layer->writeToProto(layersProto, traceFlags, device);
}
+
return layersProto;
}
+void SurfaceFlinger::dumpHwc(std::string& result) const {
+ getHwComposer().dump(result);
+}
+
void SurfaceFlinger::dumpOffscreenLayersProto(LayersProto& layersProto, uint32_t traceFlags) const {
// Add a fake invisible root layer to the proto output and parent all the offscreen layers to
// it.
@@ -4471,7 +4486,8 @@
rootProto->add_children(offscreenLayer->sequence);
// Add layer
- LayerProto* layerProto = offscreenLayer->writeToProto(layersProto, traceFlags);
+ LayerProto* layerProto =
+ offscreenLayer->writeToProto(layersProto, traceFlags, nullptr /*device*/);
layerProto->set_parent(offscreenRootLayerId);
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 477d7a5..83f0131 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -921,6 +921,8 @@
LayersProto dumpDrawingStateProto(uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
void dumpOffscreenLayersProto(LayersProto& layersProto,
uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
+ // Dumps state from HW Composer
+ void dumpHwc(std::string& result) const;
LayersProto dumpProtoFromMainThread(uint32_t traceFlags = SurfaceTracing::TRACE_ALL)
EXCLUDES(mStateLock);
void dumpOffscreenLayers(std::string& result) EXCLUDES(mStateLock);
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index eb5c7de..c5556ec 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -170,6 +170,12 @@
mFlinger.dumpOffscreenLayersProto(layers);
entry.mutable_layers()->Swap(&layers);
+ if (mTraceFlags & SurfaceTracing::TRACE_HWC) {
+ std::string hwcDump;
+ mFlinger.dumpHwc(hwcDump);
+ entry.set_hwc_blob(hwcDump);
+ }
+
return entry;
}
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index 18524f0..3c24881 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -56,6 +56,7 @@
TRACE_CRITICAL = 1 << 0,
TRACE_INPUT = 1 << 1,
TRACE_EXTRA = 1 << 2,
+ TRACE_HWC = 1 << 3,
TRACE_ALL = 0xffffffff
};
void setTraceFlags(uint32_t flags);
diff --git a/services/surfaceflinger/layerproto/layers.proto b/services/surfaceflinger/layerproto/layers.proto
index 8afe503..7f1f542 100644
--- a/services/surfaceflinger/layerproto/layers.proto
+++ b/services/surfaceflinger/layerproto/layers.proto
@@ -9,6 +9,23 @@
repeated LayerProto layers = 1;
}
+// Must match definition in the IComposerClient HAL
+enum HwcCompositionType {
+ // Invalid composition type
+ INVALID = 0;
+ // Layer was composited by the client into the client target buffer
+ CLIENT = 1;
+ // Layer was composited by the device through hardware overlays
+ DEVICE = 2;
+ // Layer was composited by the device using a color
+ SOLID_COLOR = 3;
+ // Similar to DEVICE, but the layer position may have been asynchronously set
+ // through setCursorPosition
+ CURSOR = 4;
+ // Layer was composited by the device via a sideband stream.
+ SIDEBAND = 5;
+}
+
// Information about each layer.
message LayerProto {
// unique id per layer.
@@ -73,7 +90,7 @@
int32 window_type = 33 [deprecated=true];
int32 app_id = 34 [deprecated=true];
// The layer's composition type
- int32 hwc_composition_type = 35;
+ HwcCompositionType hwc_composition_type = 35;
// If it's a buffer layer, indicate if the content is protected
bool is_protected = 36;
// Current frame number being rendered.
@@ -190,4 +207,4 @@
message ColorTransformProto {
// This will be a 4x4 matrix of float values
repeated float val = 1;
-}
\ No newline at end of file
+}
diff --git a/services/surfaceflinger/layerproto/layerstrace.proto b/services/surfaceflinger/layerproto/layerstrace.proto
index bee17d2..ac33a0e 100644
--- a/services/surfaceflinger/layerproto/layerstrace.proto
+++ b/services/surfaceflinger/layerproto/layerstrace.proto
@@ -48,4 +48,7 @@
optional string where = 2;
optional LayersProto layers = 3;
+
+ // Blob for the current HWC information for all layers, reported by dumpsys.
+ optional string hwc_blob = 4;
}