SF: Remove display lookup in SurfaceTracing
Remove the strong reference to prevent a removed display from being
destroyed off the main thread. This is also a step in adding thread
annotations to display state accessors.
Also, clean up SurfaceTracing usage in the SurfaceFlinger class.
Bug: 123715322
Test: Tracing still works.
Change-Id: Iad174e7b42fbde96a46155c740838f6cd3966365
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index cd78c1a..b4ae8ed 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -169,19 +169,22 @@
#pragma clang diagnostic pop
-class ConditionalLock {
-public:
- ConditionalLock(Mutex& mutex, bool lock) : mMutex(mutex), mLocked(lock) {
- if (lock) {
- mMutex.lock();
- }
+template <typename Mutex>
+struct ConditionalLockGuard {
+ ConditionalLockGuard(Mutex& mutex, bool lock) : mutex(mutex), lock(lock) {
+ if (lock) mutex.lock();
}
- ~ConditionalLock() { if (mLocked) mMutex.unlock(); }
-private:
- Mutex& mMutex;
- bool mLocked;
+
+ ~ConditionalLockGuard() {
+ if (lock) mutex.unlock();
+ }
+
+ Mutex& mutex;
+ const bool lock;
};
+using ConditionalLock = ConditionalLockGuard<Mutex>;
+
// TODO(b/141333600): Consolidate with HWC2::Display::Config::Builder::getDefaultDensity.
constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV / 160.f;
@@ -1948,8 +1951,15 @@
// potentially trigger a display handoff.
updateVrFlinger();
+ if (mTracingEnabledChanged) {
+ mTracingEnabled = mTracing.isEnabled();
+ mTracingEnabledChanged = false;
+ }
+
bool refreshNeeded;
- withTracingLock([&]() {
+ {
+ ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
+
refreshNeeded = handleMessageTransaction();
refreshNeeded |= handleMessageInvalidate();
if (mTracingEnabled) {
@@ -1959,7 +1969,7 @@
mTracing.notifyLocked("visibleRegionsDirty");
}
}
- });
+ }
// Layers need to get updated (in the previous line) before we can use them for
// choosing the refresh rate.
@@ -3034,26 +3044,6 @@
mDrawingState.traverse([&](Layer* layer) { layer->updateMirrorInfo(); });
}
-void SurfaceFlinger::withTracingLock(std::function<void()> lockedOperation) {
- if (mTracingEnabledChanged) {
- mTracingEnabled = mTracing.isEnabled();
- mTracingEnabledChanged = false;
- }
-
- // Synchronize with Tracing thread
- std::unique_lock<std::mutex> lock;
- if (mTracingEnabled) {
- lock = std::unique_lock<std::mutex>(mDrawingStateLock);
- }
-
- lockedOperation();
-
- // Synchronize with Tracing thread
- if (mTracingEnabled) {
- lock.unlock();
- }
-}
-
void SurfaceFlinger::commitOffscreenLayers() {
for (Layer* offscreenLayer : mOffscreenLayers) {
offscreenLayer->traverse(LayerVector::StateSet::Drawing, [](Layer* layer) {
@@ -4560,11 +4550,13 @@
result.append("\n");
}
-LayersProto SurfaceFlinger::dumpDrawingStateProto(
- uint32_t traceFlags, const sp<const DisplayDevice>& displayDevice) const {
+LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {
+ // If context is SurfaceTracing thread, mTracingLock blocks display transactions on main thread.
+ const auto display = getDefaultDisplayDeviceLocked();
+
LayersProto layersProto;
for (const sp<Layer>& layer : mDrawingState.layersSortedByZ) {
- layer->writeToProto(layersProto, traceFlags, displayDevice);
+ layer->writeToProto(layersProto, traceFlags, display);
}
return layersProto;
@@ -4596,10 +4588,7 @@
LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) {
LayersProto layersProto;
- postMessageSync(new LambdaMessage([&]() {
- const auto& displayDevice = getDefaultDisplayDeviceLocked();
- layersProto = dumpDrawingStateProto(traceFlags, displayDevice);
- }));
+ postMessageSync(new LambdaMessage([&] { layersProto = dumpDrawingStateProto(traceFlags); }));
return layersProto;
}
@@ -5126,20 +5115,12 @@
n = data.readInt32();
if (n) {
ALOGD("LayerTracing enabled");
- Mutex::Autolock lock(mStateLock);
- mTracingEnabledChanged = true;
- mTracing.enable();
+ mTracingEnabledChanged = mTracing.enable();
reply->writeInt32(NO_ERROR);
} else {
ALOGD("LayerTracing disabled");
- bool writeFile = false;
- {
- Mutex::Autolock lock(mStateLock);
- mTracingEnabledChanged = true;
- writeFile = mTracing.disable();
- }
-
- if (writeFile) {
+ mTracingEnabledChanged = mTracing.disable();
+ if (mTracingEnabledChanged) {
reply->writeInt32(mTracing.writeToFile());
} else {
reply->writeInt32(NO_ERROR);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 72d1ffe..35212e5 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -931,8 +931,7 @@
void dumpDisplayIdentificationData(std::string& result) const;
void dumpRawDisplayIdentificationData(const DumpArgs&, std::string& result) const;
void dumpWideColorInfo(std::string& result) const;
- LayersProto dumpDrawingStateProto(uint32_t traceFlags = SurfaceTracing::TRACE_ALL,
- const sp<const DisplayDevice>& displayDevice = nullptr) const;
+ LayersProto dumpDrawingStateProto(uint32_t traceFlags) const;
void dumpOffscreenLayersProto(LayersProto& layersProto,
uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
// Dumps state from HW Composer
@@ -940,7 +939,6 @@
LayersProto dumpProtoFromMainThread(uint32_t traceFlags = SurfaceTracing::TRACE_ALL)
EXCLUDES(mStateLock);
void dumpOffscreenLayers(std::string& result) EXCLUDES(mStateLock);
- void withTracingLock(std::function<void()> operation) REQUIRES(mStateLock);
bool isLayerTripleBufferingDisabled() const {
return this->mLayerTripleBufferingDisabled;
@@ -982,9 +980,6 @@
SortedVector<sp<Layer>> mLayersPendingRemoval;
bool mTraversalNeededMainThread = false;
- // guards access to the mDrawing state if tracing is enabled.
- mutable std::mutex mDrawingStateLock;
-
// global color transform states
Daltonizer mDaltonizer;
float mGlobalSaturationFactor = 1.0f;
@@ -1059,10 +1054,13 @@
bool mPropagateBackpressure = true;
bool mPropagateBackpressureClientComposition = false;
std::unique_ptr<SurfaceInterceptor> mInterceptor;
+
SurfaceTracing mTracing{*this};
+ std::mutex mTracingLock;
bool mTracingEnabled = false;
bool mAddCompositionStateToTrace = false;
- bool mTracingEnabledChanged GUARDED_BY(mStateLock) = false;
+ std::atomic<bool> mTracingEnabledChanged = false;
+
const std::shared_ptr<TimeStats> mTimeStats;
const std::unique_ptr<FrameTracer> mFrameTracer;
bool mUseHwcVirtualDisplays = false;
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index f0b895d..d84ce69 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -33,7 +33,7 @@
namespace android {
SurfaceTracing::SurfaceTracing(SurfaceFlinger& flinger)
- : mFlinger(flinger), mSfLock(flinger.mDrawingStateLock) {}
+ : mFlinger(flinger), mSfLock(flinger.mTracingLock) {}
void SurfaceTracing::mainLoop() {
bool enabled = addFirstEntry();
@@ -44,21 +44,19 @@
}
bool SurfaceTracing::addFirstEntry() {
- const auto displayDevice = mFlinger.getDefaultDisplayDevice();
LayersTraceProto entry;
{
std::scoped_lock lock(mSfLock);
- entry = traceLayersLocked("tracing.enable", displayDevice);
+ entry = traceLayersLocked("tracing.enable");
}
return addTraceToBuffer(entry);
}
LayersTraceProto SurfaceTracing::traceWhenNotified() {
- const auto displayDevice = mFlinger.getDefaultDisplayDevice();
std::unique_lock<std::mutex> lock(mSfLock);
mCanStartTrace.wait(lock);
android::base::ScopedLockAssertion assumeLock(mSfLock);
- LayersTraceProto entry = traceLayersLocked(mWhere, displayDevice);
+ LayersTraceProto entry = traceLayersLocked(mWhere);
mTracingInProgress = false;
mMissedTraceEntries = 0;
lock.unlock();
@@ -126,15 +124,17 @@
}
}
-void SurfaceTracing::enable() {
+bool SurfaceTracing::enable() {
std::scoped_lock lock(mTraceLock);
if (mEnabled) {
- return;
+ return false;
}
+
mBuffer.reset(mBufferSize);
mEnabled = true;
mThread = std::thread(&SurfaceTracing::mainLoop, this);
+ return true;
}
status_t SurfaceTracing::writeToFile() {
@@ -176,14 +176,13 @@
mTraceFlags = flags;
}
-LayersTraceProto SurfaceTracing::traceLayersLocked(const char* where,
- const sp<const DisplayDevice>& displayDevice) {
+LayersTraceProto SurfaceTracing::traceLayersLocked(const char* where) {
ATRACE_CALL();
LayersTraceProto entry;
entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
entry.set_where(where);
- LayersProto layers(mFlinger.dumpDrawingStateProto(mTraceFlags, displayDevice));
+ LayersProto layers(mFlinger.dumpDrawingStateProto(mTraceFlags));
if (flagIsSetLocked(SurfaceTracing::TRACE_EXTRA)) {
mFlinger.dumpOffscreenLayersProto(layers);
diff --git a/services/surfaceflinger/SurfaceTracing.h b/services/surfaceflinger/SurfaceTracing.h
index e90fc4d..f208eb8 100644
--- a/services/surfaceflinger/SurfaceTracing.h
+++ b/services/surfaceflinger/SurfaceTracing.h
@@ -27,8 +27,6 @@
#include <queue>
#include <thread>
-#include "DisplayDevice.h"
-
using namespace android::surfaceflinger;
namespace android {
@@ -44,7 +42,7 @@
class SurfaceTracing {
public:
explicit SurfaceTracing(SurfaceFlinger& flinger);
- void enable();
+ bool enable();
bool disable();
status_t writeToFile();
bool isEnabled() const;
@@ -92,9 +90,7 @@
void mainLoop();
bool addFirstEntry();
LayersTraceProto traceWhenNotified();
- LayersTraceProto traceLayersLocked(const char* where,
- const sp<const DisplayDevice>& displayDevice)
- REQUIRES(mSfLock);
+ LayersTraceProto traceLayersLocked(const char* where) REQUIRES(mSfLock);
// Returns true if trace is enabled.
bool addTraceToBuffer(LayersTraceProto& entry);