Fix a long standing locking issue with tracing thread
If winscope tracing is enabled, the tracing thread will read the drawing
state if the visible region changes and writes the state it to a proto.
This has a few issues: layer drawing state was being committed without
holding the tracing lock, layers could be destroyed when
finalizePendingOutputLayers (without holding the tracing lock) making
access to offscreenlayers invalid, finally we could get miss a trace
entry or have invalid entries.
This fix takes the tracing lock while committing the layer drawing
states and removes accessing the drawing states which are modified
later. It also identifies any missed entries.
In S, we will look at simplifying the tracing model to store a delta
of changes per layer.
Fixes: b/152010382, b/144918813, b/140854698
Test: w/ hwasan build and winscope enabled atest SurfaceFlinger_test libgui_test
Test: w/ hwasan build and winscope enabled go/wm-tests
Change-Id: I71c7b8e6567767ef97d82c5ea2e06a82ecc3c17a
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index 3d67a6b..5039761 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -2134,10 +2134,12 @@
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));
+ if (traceFlags & SurfaceTracing::TRACE_COMPOSITION) {
+ // 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) {
@@ -2180,8 +2182,10 @@
LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(),
[&]() { return layerInfo->mutable_position(); });
LayerProtoHelper::writeToProto(mBounds, [&]() { return layerInfo->mutable_bounds(); });
- LayerProtoHelper::writeToProto(debugGetVisibleRegionOnDefaultDisplay(),
- [&]() { return layerInfo->mutable_visible_region(); });
+ if (traceFlags & SurfaceTracing::TRACE_COMPOSITION) {
+ LayerProtoHelper::writeToProto(debugGetVisibleRegionOnDefaultDisplay(),
+ [&]() { return layerInfo->mutable_visible_region(); });
+ }
LayerProtoHelper::writeToProto(surfaceDamageRegion,
[&]() { return layerInfo->mutable_damage_region(); });
@@ -2191,15 +2195,13 @@
}
}
- if (traceFlags & SurfaceTracing::TRACE_EXTRA) {
- LayerProtoHelper::writeToProto(mSourceBounds,
- [&]() { return layerInfo->mutable_source_bounds(); });
- LayerProtoHelper::writeToProto(mScreenBounds,
- [&]() { return layerInfo->mutable_screen_bounds(); });
- LayerProtoHelper::writeToProto(getRoundedCornerState().cropRect,
- [&]() { return layerInfo->mutable_corner_radius_crop(); });
- layerInfo->set_shadow_radius(mEffectiveShadowRadius);
- }
+ LayerProtoHelper::writeToProto(mSourceBounds,
+ [&]() { return layerInfo->mutable_source_bounds(); });
+ LayerProtoHelper::writeToProto(mScreenBounds,
+ [&]() { return layerInfo->mutable_screen_bounds(); });
+ LayerProtoHelper::writeToProto(getRoundedCornerState().cropRect,
+ [&]() { return layerInfo->mutable_corner_radius_crop(); });
+ layerInfo->set_shadow_radius(mEffectiveShadowRadius);
}
void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet stateSet,