SurfaceFlinger: Use a lockless stack for binder->tracing thread
Though the critical section is kept very small between the binder
and tracing threads, the tracing thread is not RT, and so we still
run the risk of it being descheduled and blocking one of our binder
threads excessively. In this thread we provide a simple lockless
stack implementation and use it to push pending transactions from
the binder thread to the main thread. We also looked up "layer IDs"
on the binder thread, which is no longer possible without the lock.
To work around this we store the pointer itself in the proto until
it reaches the tracing thread where we overwrite it with the mapped
value.
Bug: 200284593
Test: Existing tests pass
Change-Id: I408dc87ddfe088b68f65601455147a96b870627d
diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
index 1e5c3e7..c1112d2 100644
--- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
+++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
@@ -180,13 +180,13 @@
}
if (layer.what & layer_state_t::eReparent) {
- int32_t layerId = layer.parentSurfaceControlForChild
+ int64_t layerId = layer.parentSurfaceControlForChild
? mMapper->getLayerId(layer.parentSurfaceControlForChild->getHandle())
: -1;
proto.set_parent_id(layerId);
}
if (layer.what & layer_state_t::eRelativeLayerChanged) {
- int32_t layerId = layer.relativeLayerSurfaceControl
+ int64_t layerId = layer.relativeLayerSurfaceControl
? mMapper->getLayerId(layer.relativeLayerSurfaceControl->getHandle())
: -1;
proto.set_relative_parent_id(layerId);
@@ -342,13 +342,13 @@
outState.merge(state);
if (state.what & layer_state_t::eReparent) {
- outState.parentId = proto.parent_id();
+ outState.parentId = static_cast<int32_t>(proto.parent_id());
}
if (state.what & layer_state_t::eRelativeLayerChanged) {
- outState.relativeParentId = proto.relative_parent_id();
+ outState.relativeParentId = static_cast<int32_t>(proto.relative_parent_id());
}
if (state.what & layer_state_t::eInputInfoChanged) {
- outState.inputCropId = proto.window_info_handle().crop_layer_id();
+ outState.inputCropId = static_cast<int32_t>(proto.window_info_handle().crop_layer_id());
}
if (state.what & layer_state_t::eBufferChanged) {
const proto::LayerState_BufferData& bufferProto = proto.buffer_data();
@@ -364,7 +364,7 @@
}
void TransactionProtoParser::fromProto(const proto::LayerState& proto, layer_state_t& layer) {
- layer.layerId = proto.layer_id();
+ layer.layerId = (int32_t)proto.layer_id();
layer.what |= proto.what();
layer.surface = mMapper->getLayerHandle(layer.layerId);
@@ -450,23 +450,25 @@
}
if (proto.what() & layer_state_t::eReparent) {
- int32_t layerId = proto.parent_id();
+ int64_t layerId = proto.parent_id();
if (layerId == -1) {
layer.parentSurfaceControlForChild = nullptr;
} else {
layer.parentSurfaceControlForChild =
new SurfaceControl(SurfaceComposerClient::getDefault(),
- mMapper->getLayerHandle(layerId), nullptr, layerId);
+ mMapper->getLayerHandle(static_cast<int32_t>(layerId)),
+ nullptr, static_cast<int32_t>(layerId));
}
}
if (proto.what() & layer_state_t::eRelativeLayerChanged) {
- int32_t layerId = proto.relative_parent_id();
+ int64_t layerId = proto.relative_parent_id();
if (layerId == -1) {
layer.relativeLayerSurfaceControl = nullptr;
} else {
layer.relativeLayerSurfaceControl =
new SurfaceControl(SurfaceComposerClient::getDefault(),
- mMapper->getLayerHandle(layerId), nullptr, layerId);
+ mMapper->getLayerHandle(static_cast<int32_t>(layerId)),
+ nullptr, static_cast<int32_t>(layerId));
}
layer.z = proto.z();
}
@@ -493,8 +495,9 @@
inputInfo.transform.set(transformProto.tx(), transformProto.ty());
inputInfo.replaceTouchableRegionWithCrop =
windowInfoProto.replace_touchable_region_with_crop();
- int32_t layerId = windowInfoProto.crop_layer_id();
- inputInfo.touchableRegionCropHandle = mMapper->getLayerHandle(layerId);
+ int64_t layerId = windowInfoProto.crop_layer_id();
+ inputInfo.touchableRegionCropHandle =
+ mMapper->getLayerHandle(static_cast<int32_t>(layerId));
layer.windowInfoHandle = sp<gui::WindowInfoHandle>::make(inputInfo);
}
if (proto.what() & layer_state_t::eBackgroundColorChanged) {