Merge "Dump offscreen layers in dumpsys and winscope trace"
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index ce1926e..79ee827 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -22,6 +22,7 @@
#include "Layer.h"
#include <android-base/stringprintf.h>
+#include <binder/IPCThreadState.h>
#include <compositionengine/Display.h>
#include <compositionengine/Layer.h>
#include <compositionengine/LayerFECompositionState.h>
@@ -122,7 +123,8 @@
mFrameTracker.setDisplayRefreshPeriod(compositorTiming.interval);
mSchedulerLayerHandle = mFlinger->mScheduler->registerLayer(mName.c_str(), mWindowType);
-
+ mCallingPid = args.callingPid;
+ mCallingUid = args.callingUid;
mFlinger->onLayerCreated();
}
@@ -136,6 +138,21 @@
mFlinger->onLayerDestroyed(this);
}
+LayerCreationArgs::LayerCreationArgs(SurfaceFlinger* flinger, const sp<Client>& client,
+ const String8& name, uint32_t w, uint32_t h, uint32_t flags,
+ LayerMetadata metadata)
+ : flinger(flinger),
+ client(client),
+ name(name),
+ w(w),
+ h(h),
+ flags(flags),
+ metadata(std::move(metadata)) {
+ IPCThreadState* ipc = IPCThreadState::self();
+ callingPid = ipc->getCallingPid();
+ callingUid = ipc->getCallingUid();
+}
+
// ---------------------------------------------------------------------------
// callbacks
// ---------------------------------------------------------------------------
@@ -1324,6 +1341,11 @@
mFrameEventHistory.dump(result);
}
+void Layer::dumpCallingUidPid(std::string& result) const {
+ StringAppendF(&result, "Layer %s (%s) pid:%d uid:%d\n", getName().string(), getType(),
+ mCallingPid, mCallingUid);
+}
+
void Layer::onDisconnect() {
Mutex::Autolock lock(mFrameEventHistoryMutex);
mFrameEventHistory.onDisconnect();
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 23763d2..32be980 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -80,9 +80,7 @@
struct LayerCreationArgs {
LayerCreationArgs(SurfaceFlinger* flinger, const sp<Client>& client, const String8& name,
- uint32_t w, uint32_t h, uint32_t flags, LayerMetadata metadata)
- : flinger(flinger), client(client), name(name), w(w), h(h), flags(flags),
- metadata(std::move(metadata)) {}
+ uint32_t w, uint32_t h, uint32_t flags, LayerMetadata metadata);
SurfaceFlinger* flinger;
const sp<Client>& client;
@@ -91,6 +89,8 @@
uint32_t h;
uint32_t flags;
LayerMetadata metadata;
+ pid_t callingPid;
+ uid_t callingUid;
};
class Layer : public virtual compositionengine::LayerFE {
@@ -608,6 +608,7 @@
void miniDump(std::string& result, const sp<DisplayDevice>& display) const;
void dumpFrameStats(std::string& result) const;
void dumpFrameEvents(std::string& result);
+ void dumpCallingUidPid(std::string& result) const;
void clearFrameStats();
void logFrameStats();
void getFrameStats(FrameStats* outStats) const;
@@ -932,6 +933,11 @@
bool mGetHandleCalled = false;
void removeRemoteSyncPoints();
+
+ // Tracks the process and user id of the caller when creating this layer
+ // to help debugging.
+ pid_t mCallingPid;
+ uid_t mCallingUid;
};
} // namespace android
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 7c9b99a..b7c2013 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -2729,32 +2729,31 @@
void SurfaceFlinger::commitTransaction()
{
- if (!mLayersPendingRemoval.isEmpty()) {
- // Notify removed layers now that they can't be drawn from
- for (const auto& l : mLayersPendingRemoval) {
- recordBufferingStats(l->getName().string(),
- l->getOccupancyHistory(true));
-
- // Ensure any buffers set to display on any children are released.
- if (l->isRemovedFromCurrentState()) {
- l->latchAndReleaseBuffer();
- }
-
- // If the layer has been removed and has no parent, then it will not be reachable
- // when traversing layers on screen. Add the layer to the offscreenLayers set to
- // ensure we can copy its current to drawing state.
- if (!l->getParent()) {
- mOffscreenLayers.emplace(l.get());
- }
- }
- mLayersPendingRemoval.clear();
- }
-
- // If this transaction is part of a window animation then the next frame
- // we composite should be considered an animation as well.
- mAnimCompositionPending = mAnimTransactionPending;
-
withTracingLock([&]() {
+ if (!mLayersPendingRemoval.isEmpty()) {
+ // Notify removed layers now that they can't be drawn from
+ for (const auto& l : mLayersPendingRemoval) {
+ recordBufferingStats(l->getName().string(), l->getOccupancyHistory(true));
+
+ // Ensure any buffers set to display on any children are released.
+ if (l->isRemovedFromCurrentState()) {
+ l->latchAndReleaseBuffer();
+ }
+
+ // If the layer has been removed and has no parent, then it will not be reachable
+ // when traversing layers on screen. Add the layer to the offscreenLayers set to
+ // ensure we can copy its current to drawing state.
+ if (!l->getParent()) {
+ mOffscreenLayers.emplace(l.get());
+ }
+ }
+ mLayersPendingRemoval.clear();
+ }
+
+ // If this transaction is part of a window animation then the next frame
+ // we composite should be considered an animation as well.
+ mAnimCompositionPending = mAnimTransactionPending;
+
mDrawingState = mCurrentState;
// clear the "changed" flags in current state
mCurrentState.colorMatrixChanged = false;
@@ -4123,9 +4122,11 @@
if (asProto) {
result.append(layersProto.SerializeAsString());
} else {
+ // Dump info that we need to access from the main thread
const auto layerTree = LayerProtoParser::generateLayerTree(layersProto);
result.append(LayerProtoParser::layerTreeToString(layerTree));
result.append("\n");
+ dumpOffscreenLayers(result);
}
}
}
@@ -4383,12 +4384,54 @@
return layersProto;
}
+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.
+ LayerProto* rootProto = layersProto.add_layers();
+ const int32_t offscreenRootLayerId = INT32_MAX - 2;
+ rootProto->set_id(offscreenRootLayerId);
+ rootProto->set_name("Offscreen Root");
+
+ for (Layer* offscreenLayer : mOffscreenLayers) {
+ // Add layer as child of the fake root
+ rootProto->add_children(offscreenLayer->sequence);
+
+ // Add layer
+ LayerProto* layerProto = layersProto.add_layers();
+ offscreenLayer->writeToProtoDrawingState(layerProto, traceFlags);
+ offscreenLayer->writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing,
+ traceFlags);
+ layerProto->set_parent(offscreenRootLayerId);
+
+ // Add children
+ offscreenLayer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
+ if (layer == offscreenLayer) {
+ return;
+ }
+ LayerProto* childProto = layersProto.add_layers();
+ layer->writeToProtoDrawingState(childProto, traceFlags);
+ layer->writeToProtoCommonState(childProto, LayerVector::StateSet::Drawing, traceFlags);
+ });
+ }
+}
+
LayersProto SurfaceFlinger::dumpProtoFromMainThread(uint32_t traceFlags) {
LayersProto layersProto;
postMessageSync(new LambdaMessage([&]() { layersProto = dumpDrawingStateProto(traceFlags); }));
return layersProto;
}
+void SurfaceFlinger::dumpOffscreenLayers(std::string& result) {
+ result.append("Offscreen Layers:\n");
+ postMessageSync(new LambdaMessage([&]() {
+ for (Layer* offscreenLayer : mOffscreenLayers) {
+ offscreenLayer->traverseInZOrder(LayerVector::StateSet::Drawing, [&](Layer* layer) {
+ layer->dumpCallingUidPid(result);
+ });
+ }
+ }));
+}
+
void SurfaceFlinger::dumpAllLocked(const DumpArgs& args, std::string& result) const {
const bool colorize = !args.empty() && args[0] == String16("--color");
Colorizer colorizer(colorize);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3b3d6e4..f6df33a 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -864,8 +864,11 @@
void dumpDisplayIdentificationData(std::string& result) const;
void dumpWideColorInfo(std::string& result) const;
LayersProto dumpDrawingStateProto(uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
+ void dumpOffscreenLayersProto(LayersProto& layersProto,
+ uint32_t traceFlags = SurfaceTracing::TRACE_ALL) const;
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 {
diff --git a/services/surfaceflinger/SurfaceTracing.cpp b/services/surfaceflinger/SurfaceTracing.cpp
index 9053f2c..eb26cd0 100644
--- a/services/surfaceflinger/SurfaceTracing.cpp
+++ b/services/surfaceflinger/SurfaceTracing.cpp
@@ -163,6 +163,7 @@
entry.set_elapsed_realtime_nanos(elapsedRealtimeNano());
entry.set_where(where);
LayersProto layers(mFlinger.dumpDrawingStateProto(mTraceFlags));
+ mFlinger.dumpOffscreenLayersProto(layers);
entry.mutable_layers()->Swap(&layers);
return entry;