Merge changes I6987329c,I830048a5
* changes:
SF: Save proto traces to a specific path
TransactionTracing: Introduce FlingerDataMapper
diff --git a/libs/gui/LayerState.cpp b/libs/gui/LayerState.cpp
index eec4a87..9022e7d 100644
--- a/libs/gui/LayerState.cpp
+++ b/libs/gui/LayerState.cpp
@@ -35,7 +35,9 @@
using gui::WindowInfoHandle;
layer_state_t::layer_state_t()
- : what(0),
+ : surface(nullptr),
+ layerId(-1),
+ what(0),
x(0),
y(0),
z(0),
@@ -153,8 +155,12 @@
SAFE_PARCEL(output.writeBool, isTrustedOverlay);
SAFE_PARCEL(output.writeUint32, static_cast<uint32_t>(dropInputMode));
- SAFE_PARCEL(output.writeNullableParcelable,
- bufferData ? std::make_optional<BufferData>(*bufferData) : std::nullopt);
+
+ const bool hasBufferData = (bufferData != nullptr);
+ SAFE_PARCEL(output.writeBool, hasBufferData);
+ if (hasBufferData) {
+ SAFE_PARCEL(output.writeParcelable, *bufferData);
+ }
return NO_ERROR;
}
@@ -264,9 +270,15 @@
uint32_t mode;
SAFE_PARCEL(input.readUint32, &mode);
dropInputMode = static_cast<gui::DropInputMode>(mode);
- std::optional<BufferData> tmpBufferData;
- SAFE_PARCEL(input.readParcelable, &tmpBufferData);
- bufferData = tmpBufferData ? std::make_shared<BufferData>(*tmpBufferData) : nullptr;
+
+ bool hasBufferData;
+ SAFE_PARCEL(input.readBool, &hasBufferData);
+ if (hasBufferData) {
+ bufferData = std::make_shared<BufferData>();
+ SAFE_PARCEL(input.readParcelable, bufferData.get());
+ } else {
+ bufferData = nullptr;
+ }
return NO_ERROR;
}
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index a039250..973029c 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1993,29 +1993,31 @@
setTransactionFlags(eTransactionNeeded);
}
-LayerProto* Layer::writeToProto(LayersProto& layersProto, uint32_t traceFlags,
- const DisplayDevice* display) {
+LayerProto* Layer::writeToProto(LayersProto& layersProto, uint32_t traceFlags) {
LayerProto* layerProto = layersProto.add_layers();
- writeToProtoDrawingState(layerProto, traceFlags, display);
+ writeToProtoDrawingState(layerProto);
writeToProtoCommonState(layerProto, LayerVector::StateSet::Drawing, traceFlags);
if (traceFlags & LayerTracing::TRACE_COMPOSITION) {
// Only populate for the primary display.
+ UnnecessaryLock assumeLocked(mFlinger->mStateLock); // called from the main thread.
+ const auto display = mFlinger->getDefaultDisplayDeviceLocked();
if (display) {
const auto compositionType = getCompositionType(*display);
layerProto->set_hwc_composition_type(static_cast<HwcCompositionType>(compositionType));
+ LayerProtoHelper::writeToProto(getVisibleRegion(display.get()),
+ [&]() { return layerProto->mutable_visible_region(); });
}
}
for (const sp<Layer>& layer : mDrawingChildren) {
- layer->writeToProto(layersProto, traceFlags, display);
+ layer->writeToProto(layersProto, traceFlags);
}
return layerProto;
}
-void Layer::writeToProtoDrawingState(LayerProto* layerInfo, uint32_t traceFlags,
- const DisplayDevice* display) {
+void Layer::writeToProtoDrawingState(LayerProto* layerInfo) {
const ui::Transform transform = getTransform();
auto buffer = getExternalTexture();
if (buffer != nullptr) {
@@ -2039,10 +2041,6 @@
LayerProtoHelper::writePositionToProto(transform.tx(), transform.ty(),
[&]() { return layerInfo->mutable_position(); });
LayerProtoHelper::writeToProto(mBounds, [&]() { return layerInfo->mutable_bounds(); });
- if (traceFlags & LayerTracing::TRACE_COMPOSITION) {
- LayerProtoHelper::writeToProto(getVisibleRegion(display),
- [&]() { return layerInfo->mutable_visible_region(); });
- }
LayerProtoHelper::writeToProto(surfaceDamageRegion,
[&]() { return layerInfo->mutable_damage_region(); });
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index e51af1e..21dd5f4 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -686,12 +686,12 @@
bool isRemovedFromCurrentState() const;
- LayerProto* writeToProto(LayersProto& layersProto, uint32_t traceFlags, const DisplayDevice*);
+ LayerProto* writeToProto(LayersProto& layersProto, uint32_t traceFlags);
// 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
// thread.
- void writeToProtoDrawingState(LayerProto* layerInfo, uint32_t traceFlags, const DisplayDevice*);
+ void writeToProtoDrawingState(LayerProto* layerInfo);
// Write drawing or current state. If writing current state, the caller should hold the
// external mStateLock. If writing drawing state, this function should be called on the
// main or tracing thread.
diff --git a/services/surfaceflinger/LayerProtoHelper.cpp b/services/surfaceflinger/LayerProtoHelper.cpp
index 015caa6..3bd0643 100644
--- a/services/surfaceflinger/LayerProtoHelper.cpp
+++ b/services/surfaceflinger/LayerProtoHelper.cpp
@@ -156,14 +156,14 @@
void LayerProtoHelper::writeToProto(const renderengine::ExternalTexture& buffer,
std::function<ActiveBufferProto*()> getActiveBufferProto) {
- if (buffer.getBuffer()->getWidth() != 0 || buffer.getBuffer()->getHeight() != 0 ||
- buffer.getBuffer()->getUsage() != 0 || buffer.getBuffer()->getPixelFormat() != 0) {
+ if (buffer.getWidth() != 0 || buffer.getHeight() != 0 || buffer.getUsage() != 0 ||
+ buffer.getPixelFormat() != 0) {
// Use a lambda do avoid writing the object header when the object is empty
ActiveBufferProto* activeBufferProto = getActiveBufferProto();
- activeBufferProto->set_width(buffer.getBuffer()->getWidth());
- activeBufferProto->set_height(buffer.getBuffer()->getHeight());
- activeBufferProto->set_format(buffer.getBuffer()->getPixelFormat());
- activeBufferProto->set_usage(buffer.getBuffer()->getUsage());
+ activeBufferProto->set_width(buffer.getWidth());
+ activeBufferProto->set_height(buffer.getHeight());
+ activeBufferProto->set_stride(buffer.getUsage());
+ activeBufferProto->set_format(buffer.getPixelFormat());
}
}
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 980d1dc..5991b86 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -250,11 +250,6 @@
const status_t status;
};
-struct SCOPED_CAPABILITY UnnecessaryLock {
- explicit UnnecessaryLock(Mutex& mutex) ACQUIRE(mutex) {}
- ~UnnecessaryLock() RELEASE() {}
-};
-
// TODO(b/141333600): Consolidate with DisplayMode::Builder::getDefaultDensity.
constexpr float FALLBACK_DENSITY = ACONFIGURATION_DENSITY_TV;
@@ -5102,11 +5097,9 @@
}
LayersProto SurfaceFlinger::dumpDrawingStateProto(uint32_t traceFlags) const {
- const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
-
LayersProto layersProto;
for (const sp<Layer>& layer : mDrawingState.layersSortedByZ) {
- layer->writeToProto(layersProto, traceFlags, display.get());
+ layer->writeToProto(layersProto, traceFlags);
}
return layersProto;
@@ -5147,8 +5140,7 @@
rootProto->add_children(offscreenLayer->sequence);
// Add layer
- LayerProto* layerProto =
- offscreenLayer->writeToProto(layersProto, traceFlags, nullptr /*device*/);
+ LayerProto* layerProto = offscreenLayer->writeToProto(layersProto, traceFlags);
layerProto->set_parent(offscreenRootLayerId);
}
}
@@ -5743,9 +5735,9 @@
}
case 1025: { // Set layer tracing
n = data.readInt32();
- int64_t fixedStartingTime = data.readInt64();
bool tracingEnabledChanged;
- if (n) {
+ if (n == 1) {
+ int64_t fixedStartingTime = data.readInt64();
ALOGD("LayerTracing enabled");
tracingEnabledChanged = mLayerTracing.enable();
if (tracingEnabledChanged) {
@@ -5757,6 +5749,10 @@
})
.wait();
}
+ } else if (n == 2) {
+ std::string filename = std::string(data.readCString());
+ ALOGD("LayerTracing disabled. Trace wrote to %s", filename.c_str());
+ tracingEnabledChanged = mLayerTracing.disable(filename.c_str());
} else {
ALOGD("LayerTracing disabled");
tracingEnabledChanged = mLayerTracing.disable();
@@ -6009,9 +6005,9 @@
mTransactionTracing->setBufferSize(
TransactionTracing::ACTIVE_TRACING_BUFFER_SIZE);
} else {
+ mTransactionTracing->writeToFile();
mTransactionTracing->setBufferSize(
TransactionTracing::CONTINUOUS_TRACING_BUFFER_SIZE);
- mTransactionTracing->writeToFile();
}
}
reply->writeInt32(NO_ERROR);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 9525573..02d5f1e 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -177,6 +177,11 @@
std::atomic<nsecs_t> mLastSwapTime = 0;
};
+struct SCOPED_CAPABILITY UnnecessaryLock {
+ explicit UnnecessaryLock(Mutex& mutex) ACQUIRE(mutex) {}
+ ~UnnecessaryLock() RELEASE() {}
+};
+
class SurfaceFlinger : public BnSurfaceComposer,
public PriorityDumper,
private IBinder::DeathRecipient,
diff --git a/services/surfaceflinger/Tracing/LayerTracing.cpp b/services/surfaceflinger/Tracing/LayerTracing.cpp
index 006efdf..49554c7 100644
--- a/services/surfaceflinger/Tracing/LayerTracing.cpp
+++ b/services/surfaceflinger/Tracing/LayerTracing.cpp
@@ -45,14 +45,14 @@
return true;
}
-bool LayerTracing::disable() {
+bool LayerTracing::disable(std::string filename) {
std::scoped_lock lock(mTraceLock);
if (!mEnabled) {
return false;
}
mEnabled = false;
LayersTraceFileProto fileProto = createTraceFileProto();
- mBuffer->writeToFile(fileProto, FILE_NAME);
+ mBuffer->writeToFile(fileProto, filename);
mBuffer->reset();
return true;
}
diff --git a/services/surfaceflinger/Tracing/LayerTracing.h b/services/surfaceflinger/Tracing/LayerTracing.h
index bd448c9..88a19ec 100644
--- a/services/surfaceflinger/Tracing/LayerTracing.h
+++ b/services/surfaceflinger/Tracing/LayerTracing.h
@@ -43,7 +43,7 @@
LayerTracing(SurfaceFlinger& flinger);
~LayerTracing();
bool enable();
- bool disable();
+ bool disable(std::string filename = FILE_NAME);
bool isEnabled() const;
status_t writeToFile();
LayersTraceFileProto createTraceFileProto() const;
diff --git a/services/surfaceflinger/Tracing/RingBuffer.h b/services/surfaceflinger/Tracing/RingBuffer.h
index 3b2626d..7e38c55 100644
--- a/services/surfaceflinger/Tracing/RingBuffer.h
+++ b/services/surfaceflinger/Tracing/RingBuffer.h
@@ -67,7 +67,7 @@
// -rw-r--r--
const mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
if (!android::base::WriteStringToFile(output, filename, mode, getuid(), getgid(), true)) {
- ALOGE("Could not save the proto file.");
+ ALOGE("Could not save the proto file %s", filename.c_str());
return PERMISSION_DENIED;
}
return NO_ERROR;
diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
index a91698f..fb5a6b3 100644
--- a/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
+++ b/services/surfaceflinger/Tracing/TransactionProtoParser.cpp
@@ -22,9 +22,7 @@
namespace android::surfaceflinger {
-proto::TransactionState TransactionProtoParser::toProto(const TransactionState& t,
- LayerHandleToIdFn getLayerId,
- DisplayHandleToIdFn getDisplayId) {
+proto::TransactionState TransactionProtoParser::toProto(const TransactionState& t) {
proto::TransactionState proto;
proto.set_pid(t.originPid);
proto.set_uid(t.originUid);
@@ -33,12 +31,14 @@
proto.set_post_time(t.postTime);
proto.set_transaction_id(t.id);
+ proto.mutable_layer_changes()->Reserve(static_cast<int32_t>(t.states.size()));
for (auto& layerState : t.states) {
- proto.mutable_layer_changes()->Add(std::move(toProto(layerState.state, getLayerId)));
+ proto.mutable_layer_changes()->Add(std::move(toProto(layerState.state)));
}
+ proto.mutable_display_changes()->Reserve(static_cast<int32_t>(t.displays.size()));
for (auto& displayState : t.displays) {
- proto.mutable_display_changes()->Add(std::move(toProto(displayState, getDisplayId)));
+ proto.mutable_display_changes()->Add(std::move(toProto(displayState)));
}
return proto;
}
@@ -46,8 +46,9 @@
proto::TransactionState TransactionProtoParser::toProto(
const std::map<int32_t /* layerId */, TracingLayerState>& states) {
proto::TransactionState proto;
+ proto.mutable_layer_changes()->Reserve(static_cast<int32_t>(states.size()));
for (auto& [layerId, state] : states) {
- proto::LayerState layerProto = toProto(state, nullptr);
+ proto::LayerState layerProto = toProto(state);
if (layerProto.has_buffer_data()) {
proto::LayerState_BufferData* bufferProto = layerProto.mutable_buffer_data();
bufferProto->set_buffer_id(state.bufferId);
@@ -69,11 +70,10 @@
return proto;
}
-proto::LayerState TransactionProtoParser::toProto(const layer_state_t& layer,
- LayerHandleToIdFn getLayerId) {
+proto::LayerState TransactionProtoParser::toProto(const layer_state_t& layer) {
proto::LayerState proto;
- if (getLayerId != nullptr) {
- proto.set_layer_id(getLayerId(layer.surface));
+ if (layer.surface) {
+ proto.set_layer_id(mMapper->getLayerId(layer.surface));
} else {
proto.set_layer_id(layer.layerId);
}
@@ -136,13 +136,27 @@
}
if (layer.what & layer_state_t::eBufferChanged) {
proto::LayerState_BufferData* bufferProto = proto.mutable_buffer_data();
- if (layer.bufferData->buffer) {
+ if (layer.bufferData->hasBuffer()) {
bufferProto->set_buffer_id(layer.bufferData->getId());
bufferProto->set_width(layer.bufferData->getWidth());
bufferProto->set_height(layer.bufferData->getHeight());
bufferProto->set_pixel_format(static_cast<proto::LayerState_BufferData_PixelFormat>(
layer.bufferData->getPixelFormat()));
bufferProto->set_usage(layer.bufferData->getUsage());
+ } else {
+ uint64_t bufferId;
+ uint32_t width;
+ uint32_t height;
+ int32_t pixelFormat;
+ uint64_t usage;
+ mMapper->getGraphicBufferPropertiesFromCache(layer.bufferData->cachedBuffer, &bufferId,
+ &width, &height, &pixelFormat, &usage);
+ bufferProto->set_buffer_id(bufferId);
+ bufferProto->set_width(width);
+ bufferProto->set_height(height);
+ bufferProto->set_pixel_format(
+ static_cast<proto::LayerState_BufferData_PixelFormat>(pixelFormat));
+ bufferProto->set_usage(usage);
}
bufferProto->set_frame_number(layer.bufferData->frameNumber);
bufferProto->set_flags(layer.bufferData->flags.get());
@@ -165,15 +179,15 @@
}
}
- if ((layer.what & layer_state_t::eReparent) && getLayerId != nullptr) {
+ if (layer.what & layer_state_t::eReparent) {
int32_t layerId = layer.parentSurfaceControlForChild
- ? getLayerId(layer.parentSurfaceControlForChild->getHandle())
+ ? mMapper->getLayerId(layer.parentSurfaceControlForChild->getHandle())
: -1;
proto.set_parent_id(layerId);
}
- if ((layer.what & layer_state_t::eRelativeLayerChanged) && getLayerId != nullptr) {
+ if (layer.what & layer_state_t::eRelativeLayerChanged) {
int32_t layerId = layer.relativeLayerSurfaceControl
- ? getLayerId(layer.relativeLayerSurfaceControl->getHandle())
+ ? mMapper->getLayerId(layer.relativeLayerSurfaceControl->getHandle())
: -1;
proto.set_relative_parent_id(layerId);
proto.set_z(layer.z);
@@ -200,12 +214,8 @@
transformProto->set_ty(inputInfo->transform.ty());
windowInfoProto->set_replace_touchable_region_with_crop(
inputInfo->replaceTouchableRegionWithCrop);
- if (getLayerId != nullptr) {
- windowInfoProto->set_crop_layer_id(
- getLayerId(inputInfo->touchableRegionCropHandle.promote()));
- } else {
- windowInfoProto->set_crop_layer_id(-1);
- }
+ windowInfoProto->set_crop_layer_id(
+ mMapper->getLayerId(inputInfo->touchableRegionCropHandle.promote()));
}
}
if (layer.what & layer_state_t::eBackgroundColorChanged) {
@@ -252,13 +262,10 @@
return proto;
}
-proto::DisplayState TransactionProtoParser::toProto(const DisplayState& display,
- DisplayHandleToIdFn getDisplayId) {
+proto::DisplayState TransactionProtoParser::toProto(const DisplayState& display) {
proto::DisplayState proto;
proto.set_what(display.what);
- if (getDisplayId != nullptr) {
- proto.set_id(getDisplayId(display.token));
- }
+ proto.set_id(mMapper->getDisplayId(display.token));
if (display.what & DisplayState::eLayerStackChanged) {
proto.set_layer_stack(display.layerStack.id);
@@ -290,9 +297,7 @@
return proto;
}
-TransactionState TransactionProtoParser::fromProto(const proto::TransactionState& proto,
- LayerIdToHandleFn getLayerHandle,
- DisplayIdToHandleFn getDisplayHandle) {
+TransactionState TransactionProtoParser::fromProto(const proto::TransactionState& proto) {
TransactionState t;
t.originPid = proto.pid();
t.originUid = proto.uid();
@@ -306,14 +311,14 @@
for (int i = 0; i < layerCount; i++) {
ComposerState s;
s.state.what = 0;
- fromProto(proto.layer_changes(i), getLayerHandle, s.state);
+ fromProto(proto.layer_changes(i), s.state);
t.states.add(s);
}
int32_t displayCount = proto.display_changes_size();
t.displays.reserve(static_cast<size_t>(displayCount));
for (int i = 0; i < displayCount; i++) {
- t.displays.add(fromProto(proto.display_changes(i), getDisplayHandle));
+ t.displays.add(fromProto(proto.display_changes(i)));
}
return t;
}
@@ -328,10 +333,9 @@
}
void TransactionProtoParser::mergeFromProto(const proto::LayerState& proto,
- LayerIdToHandleFn getLayerHandle,
TracingLayerState& outState) {
layer_state_t state;
- fromProto(proto, getLayerHandle, state);
+ fromProto(proto, state);
outState.merge(state);
if (state.what & layer_state_t::eReparent) {
@@ -356,14 +360,10 @@
}
}
-void TransactionProtoParser::fromProto(const proto::LayerState& proto,
- LayerIdToHandleFn getLayerHandle, layer_state_t& layer) {
+void TransactionProtoParser::fromProto(const proto::LayerState& proto, layer_state_t& layer) {
layer.layerId = proto.layer_id();
layer.what |= proto.what();
-
- if (getLayerHandle != nullptr) {
- layer.surface = getLayerHandle(layer.layerId);
- }
+ layer.surface = mMapper->getLayerHandle(layer.layerId);
if (proto.what() & layer_state_t::ePositionChanged) {
layer.x = proto.x();
@@ -420,10 +420,11 @@
LayerProtoHelper::readFromProto(proto.crop(), layer.crop);
}
if (proto.what() & layer_state_t::eBufferChanged) {
- if (!layer.bufferData) {
- layer.bufferData = std::make_shared<BufferData>();
- }
const proto::LayerState_BufferData& bufferProto = proto.buffer_data();
+ layer.bufferData =
+ std::move(mMapper->getGraphicData(bufferProto.buffer_id(), bufferProto.width(),
+ bufferProto.height(), bufferProto.pixel_format(),
+ bufferProto.usage()));
layer.bufferData->frameNumber = bufferProto.frame_number();
layer.bufferData->flags = Flags<BufferData::BufferDataChange>(bufferProto.flags());
layer.bufferData->cachedBuffer.id = bufferProto.cached_buffer_id();
@@ -445,24 +446,24 @@
}
}
- if ((proto.what() & layer_state_t::eReparent) && (getLayerHandle != nullptr)) {
+ if (proto.what() & layer_state_t::eReparent) {
int32_t layerId = proto.parent_id();
if (layerId == -1) {
layer.parentSurfaceControlForChild = nullptr;
} else {
layer.parentSurfaceControlForChild =
- new SurfaceControl(SurfaceComposerClient::getDefault(), getLayerHandle(layerId),
- nullptr, layerId);
+ new SurfaceControl(SurfaceComposerClient::getDefault(),
+ mMapper->getLayerHandle(layerId), nullptr, layerId);
}
}
if (proto.what() & layer_state_t::eRelativeLayerChanged) {
int32_t layerId = proto.relative_parent_id();
if (layerId == -1) {
layer.relativeLayerSurfaceControl = nullptr;
- } else if (getLayerHandle != nullptr) {
+ } else {
layer.relativeLayerSurfaceControl =
- new SurfaceControl(SurfaceComposerClient::getDefault(), getLayerHandle(layerId),
- nullptr, layerId);
+ new SurfaceControl(SurfaceComposerClient::getDefault(),
+ mMapper->getLayerHandle(layerId), nullptr, layerId);
}
layer.z = proto.z();
}
@@ -486,9 +487,7 @@
inputInfo.replaceTouchableRegionWithCrop =
windowInfoProto.replace_touchable_region_with_crop();
int32_t layerId = windowInfoProto.crop_layer_id();
- if (getLayerHandle != nullptr) {
- inputInfo.touchableRegionCropHandle = getLayerHandle(layerId);
- }
+ inputInfo.touchableRegionCropHandle = mMapper->getLayerHandle(layerId);
layer.windowInfoHandle = sp<gui::WindowInfoHandle>::make(inputInfo);
}
if (proto.what() & layer_state_t::eBackgroundColorChanged) {
@@ -534,13 +533,10 @@
}
}
-DisplayState TransactionProtoParser::fromProto(const proto::DisplayState& proto,
- DisplayIdToHandleFn getDisplayHandle) {
+DisplayState TransactionProtoParser::fromProto(const proto::DisplayState& proto) {
DisplayState display;
display.what = proto.what();
- if (getDisplayHandle != nullptr) {
- display.token = getDisplayHandle(proto.id());
- }
+ display.token = mMapper->getDisplayHandle(proto.id());
if (display.what & DisplayState::eLayerStackChanged) {
display.layerStack.id = proto.layer_stack();
diff --git a/services/surfaceflinger/Tracing/TransactionProtoParser.h b/services/surfaceflinger/Tracing/TransactionProtoParser.h
index d589936..2f70b27 100644
--- a/services/surfaceflinger/Tracing/TransactionProtoParser.h
+++ b/services/surfaceflinger/Tracing/TransactionProtoParser.h
@@ -43,33 +43,77 @@
TracingLayerCreationArgs args;
};
-class TransactionProtoParser {
+// Class which exposes buffer properties from BufferData without holding on to the actual buffer
+// handle.
+class BufferDataStub : public BufferData {
public:
- typedef std::function<sp<IBinder>(int32_t)> LayerIdToHandleFn;
- typedef std::function<sp<IBinder>(int32_t)> DisplayIdToHandleFn;
- typedef std::function<int32_t(const sp<IBinder>&)> LayerHandleToIdFn;
- typedef std::function<int32_t(const sp<IBinder>&)> DisplayHandleToIdFn;
-
- static proto::TransactionState toProto(const TransactionState&, LayerHandleToIdFn getLayerIdFn,
- DisplayHandleToIdFn getDisplayIdFn);
- static proto::TransactionState toProto(
- const std::map<int32_t /* layerId */, TracingLayerState>&);
-
- static proto::LayerCreationArgs toProto(const TracingLayerCreationArgs& args);
-
- static TransactionState fromProto(const proto::TransactionState&,
- LayerIdToHandleFn getLayerHandleFn,
- DisplayIdToHandleFn getDisplayHandleFn);
- static void mergeFromProto(const proto::LayerState&, LayerIdToHandleFn getLayerHandleFn,
- TracingLayerState& outState);
- static void fromProto(const proto::LayerCreationArgs&, TracingLayerCreationArgs& outArgs);
+ BufferDataStub(uint64_t bufferId, uint32_t width, uint32_t height, int32_t pixelFormat,
+ uint64_t outUsage)
+ : mBufferId(bufferId),
+ mWidth(width),
+ mHeight(height),
+ mPixelFormat(pixelFormat),
+ mOutUsage(outUsage) {}
+ bool hasBuffer() const override { return mBufferId != 0; }
+ bool hasSameBuffer(const BufferData& other) const override {
+ return getId() == other.getId() && frameNumber == other.frameNumber;
+ }
+ uint32_t getWidth() const override { return mWidth; }
+ uint32_t getHeight() const override { return mHeight; }
+ uint64_t getId() const override { return mBufferId; }
+ PixelFormat getPixelFormat() const override { return mPixelFormat; }
+ uint64_t getUsage() const override { return mOutUsage; }
private:
- static proto::LayerState toProto(const layer_state_t&, LayerHandleToIdFn getLayerId);
- static proto::DisplayState toProto(const DisplayState&, DisplayHandleToIdFn getDisplayId);
- static void fromProto(const proto::LayerState&, LayerIdToHandleFn getLayerHandle,
- layer_state_t& out);
- static DisplayState fromProto(const proto::DisplayState&, DisplayIdToHandleFn getDisplayHandle);
+ uint64_t mBufferId;
+ uint32_t mWidth;
+ uint32_t mHeight;
+ int32_t mPixelFormat;
+ uint64_t mOutUsage;
+};
+
+class TransactionProtoParser {
+public:
+ // Utility class to map handles to ids and buffers to buffer properties without pulling
+ // in SurfaceFlinger dependencies.
+ class FlingerDataMapper {
+ public:
+ virtual ~FlingerDataMapper() = default;
+ virtual sp<IBinder> getLayerHandle(int32_t /* layerId */) const { return nullptr; }
+ virtual int32_t getLayerId(const sp<IBinder>& /* layerHandle */) const { return -1; }
+ virtual sp<IBinder> getDisplayHandle(int32_t /* displayId */) const { return nullptr; }
+ virtual int32_t getDisplayId(const sp<IBinder>& /* displayHandle */) const { return -1; }
+ virtual std::shared_ptr<BufferData> getGraphicData(uint64_t bufferId, uint32_t width,
+ uint32_t height, int32_t pixelFormat,
+ uint64_t usage) const {
+ return std::make_shared<BufferDataStub>(bufferId, width, height, pixelFormat, usage);
+ }
+ virtual void getGraphicBufferPropertiesFromCache(client_cache_t /* cachedBuffer */,
+ uint64_t* /* outBufferId */,
+ uint32_t* /* outWidth */,
+ uint32_t* /* outHeight */,
+ int32_t* /* outPixelFormat */,
+ uint64_t* /* outUsage */) const {}
+ };
+
+ TransactionProtoParser(std::unique_ptr<FlingerDataMapper> provider)
+ : mMapper(std::move(provider)) {}
+
+ proto::TransactionState toProto(const TransactionState&);
+ proto::TransactionState toProto(const std::map<int32_t /* layerId */, TracingLayerState>&);
+ proto::LayerCreationArgs toProto(const TracingLayerCreationArgs& args);
+
+ TransactionState fromProto(const proto::TransactionState&);
+ void mergeFromProto(const proto::LayerState&, TracingLayerState& outState);
+ void fromProto(const proto::LayerCreationArgs&, TracingLayerCreationArgs& outArgs);
+
+private:
+ proto::LayerState toProto(const layer_state_t&);
+ proto::DisplayState toProto(const DisplayState&);
+ void fromProto(const proto::LayerState&, layer_state_t& out);
+ DisplayState fromProto(const proto::DisplayState&);
+
+ std::unique_ptr<FlingerDataMapper> mMapper;
};
} // namespace android::surfaceflinger
diff --git a/services/surfaceflinger/Tracing/TransactionTracing.cpp b/services/surfaceflinger/Tracing/TransactionTracing.cpp
index a46b795..d5e837f 100644
--- a/services/surfaceflinger/Tracing/TransactionTracing.cpp
+++ b/services/surfaceflinger/Tracing/TransactionTracing.cpp
@@ -23,11 +23,57 @@
#include <utils/SystemClock.h>
#include <utils/Trace.h>
+#include "ClientCache.h"
#include "TransactionTracing.h"
+#include "renderengine/ExternalTexture.h"
namespace android {
-TransactionTracing::TransactionTracing() {
+class FlingerDataMapper : public TransactionProtoParser::FlingerDataMapper {
+ std::unordered_map<BBinder* /* layerHandle */, int32_t /* layerId */>& mLayerHandles;
+
+public:
+ FlingerDataMapper(std::unordered_map<BBinder* /* handle */, int32_t /* id */>& layerHandles)
+ : mLayerHandles(layerHandles) {}
+
+ int32_t getLayerId(const sp<IBinder>& layerHandle) const override {
+ if (layerHandle == nullptr) {
+ return -1;
+ }
+ auto it = mLayerHandles.find(layerHandle->localBinder());
+ if (it == mLayerHandles.end()) {
+ ALOGW("Could not find layer handle %p", layerHandle->localBinder());
+ return -1;
+ }
+ return it->second;
+ }
+
+ void getGraphicBufferPropertiesFromCache(client_cache_t cachedBuffer, uint64_t* outBufferId,
+ uint32_t* outWidth, uint32_t* outHeight,
+ int32_t* outPixelFormat,
+ uint64_t* outUsage) const override {
+ std::shared_ptr<renderengine::ExternalTexture> buffer =
+ ClientCache::getInstance().get(cachedBuffer);
+ if (!buffer || !buffer->getBuffer()) {
+ *outBufferId = 0;
+ *outWidth = 0;
+ *outHeight = 0;
+ *outPixelFormat = 0;
+ *outUsage = 0;
+ return;
+ }
+
+ *outBufferId = buffer->getId();
+ *outWidth = buffer->getWidth();
+ *outHeight = buffer->getHeight();
+ *outPixelFormat = buffer->getPixelFormat();
+ *outUsage = buffer->getUsage();
+ return;
+ }
+};
+
+TransactionTracing::TransactionTracing()
+ : mProtoParser(std::make_unique<FlingerDataMapper>(mLayerHandles)) {
std::scoped_lock lock(mTraceLock);
mBuffer.setSize(mBufferSizeInBytes);
@@ -53,11 +99,11 @@
writeToFile();
}
-status_t TransactionTracing::writeToFile() {
+status_t TransactionTracing::writeToFile(std::string filename) {
std::scoped_lock lock(mTraceLock);
proto::TransactionTraceFile fileProto = createTraceFileProto();
addStartingStateToProtoLocked(fileProto);
- return mBuffer.writeToFile(fileProto, FILE_NAME);
+ return mBuffer.writeToFile(fileProto, filename);
}
void TransactionTracing::setBufferSize(size_t bufferSizeInBytes) {
@@ -85,11 +131,7 @@
void TransactionTracing::addQueuedTransaction(const TransactionState& transaction) {
std::scoped_lock lock(mTraceLock);
ATRACE_CALL();
- mQueuedTransactions[transaction.id] =
- TransactionProtoParser::toProto(transaction,
- std::bind(&TransactionTracing::getLayerIdLocked, this,
- std::placeholders::_1),
- nullptr);
+ mQueuedTransactions[transaction.id] = mProtoParser.toProto(transaction);
}
void TransactionTracing::addCommittedTransactions(std::vector<TransactionState>& transactions,
@@ -212,9 +254,7 @@
ALOGW("Duplicate handles found. %p", layerHandle);
}
mLayerHandles[layerHandle] = layerId;
- proto::LayerCreationArgs protoArgs = TransactionProtoParser::toProto(args);
- proto::LayerCreationArgs protoArgsCopy = protoArgs;
- mCreatedLayers.push_back(protoArgs);
+ mCreatedLayers.push_back(mProtoParser.toProto(args));
}
void TransactionTracing::onMirrorLayerAdded(BBinder* layerHandle, int layerId,
@@ -225,7 +265,7 @@
ALOGW("Duplicate handles found. %p", layerHandle);
}
mLayerHandles[layerHandle] = layerId;
- mCreatedLayers.emplace_back(TransactionProtoParser::toProto(args));
+ mCreatedLayers.emplace_back(mProtoParser.toProto(args));
}
void TransactionTracing::onLayerRemoved(int32_t layerId) {
@@ -263,18 +303,6 @@
}
}
-int32_t TransactionTracing::getLayerIdLocked(const sp<IBinder>& layerHandle) {
- if (layerHandle == nullptr) {
- return -1;
- }
- auto it = mLayerHandles.find(layerHandle->localBinder());
- if (it == mLayerHandles.end()) {
- ALOGW("Could not find layer handle %p", layerHandle->localBinder());
- return -1;
- }
- return it->second;
-}
-
void TransactionTracing::updateStartingStateLocked(
const proto::TransactionTraceEntry& removedEntry) {
mStartingTimestamp = removedEntry.elapsed_realtime_nanos();
@@ -283,7 +311,7 @@
for (const proto::LayerCreationArgs& addedLayer : removedEntry.added_layers()) {
TracingLayerState& startingState = mStartingStates[addedLayer.layer_id()];
startingState.layerId = addedLayer.layer_id();
- TransactionProtoParser::fromProto(addedLayer, startingState.args);
+ mProtoParser.fromProto(addedLayer, startingState.args);
}
// Merge layer states to starting transaction state.
@@ -294,7 +322,7 @@
ALOGW("Could not find layer id %d", layerState.layer_id());
continue;
}
- TransactionProtoParser::mergeFromProto(layerState, nullptr, it->second);
+ mProtoParser.mergeFromProto(layerState, it->second);
}
}
@@ -316,10 +344,10 @@
entryProto->mutable_added_layers()->Reserve(static_cast<int32_t>(mStartingStates.size()));
for (auto& [layerId, state] : mStartingStates) {
- entryProto->mutable_added_layers()->Add(TransactionProtoParser::toProto(state.args));
+ entryProto->mutable_added_layers()->Add(mProtoParser.toProto(state.args));
}
- proto::TransactionState transactionProto = TransactionProtoParser::toProto(mStartingStates);
+ proto::TransactionState transactionProto = mProtoParser.toProto(mStartingStates);
transactionProto.set_vsync_id(0);
transactionProto.set_post_time(mStartingTimestamp);
entryProto->mutable_transactions()->Add(std::move(transactionProto));
diff --git a/services/surfaceflinger/Tracing/TransactionTracing.h b/services/surfaceflinger/Tracing/TransactionTracing.h
index d5d98ce..95256c4 100644
--- a/services/surfaceflinger/Tracing/TransactionTracing.h
+++ b/services/surfaceflinger/Tracing/TransactionTracing.h
@@ -55,7 +55,7 @@
void addQueuedTransaction(const TransactionState&);
void addCommittedTransactions(std::vector<TransactionState>& transactions, int64_t vsyncId);
- status_t writeToFile();
+ status_t writeToFile(std::string filename = FILE_NAME);
void setBufferSize(size_t bufferSizeInBytes);
void onLayerAdded(BBinder* layerHandle, int layerId, const std::string& name, uint32_t flags,
int parentId);
@@ -84,6 +84,7 @@
GUARDED_BY(mTraceLock);
std::vector<int32_t /* layerId */> mRemovedLayerHandles GUARDED_BY(mTraceLock);
std::map<int32_t /* layerId */, TracingLayerState> mStartingStates GUARDED_BY(mTraceLock);
+ TransactionProtoParser mProtoParser GUARDED_BY(mTraceLock);
// We do not want main thread to block so main thread will try to acquire mMainThreadLock,
// otherwise will push data to temporary container.
diff --git a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp
index 271b1c0..ab893a3 100644
--- a/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionProtoParserTest.cpp
@@ -70,23 +70,32 @@
t1.displays.add(display);
}
- TransactionProtoParser::LayerHandleToIdFn getLayerIdFn = [&](const sp<IBinder>& handle) {
- return (handle == layerHandle) ? 42 : -1;
- };
- TransactionProtoParser::DisplayHandleToIdFn getDisplayIdFn = [&](const sp<IBinder>& handle) {
- return (handle == displayHandle) ? 43 : -1;
- };
- TransactionProtoParser::LayerIdToHandleFn getLayerHandleFn = [&](int32_t id) {
- return (id == 42) ? layerHandle : nullptr;
- };
- TransactionProtoParser::DisplayIdToHandleFn getDisplayHandleFn = [&](int32_t id) {
- return (id == 43) ? displayHandle : nullptr;
+ class TestMapper : public TransactionProtoParser::FlingerDataMapper {
+ public:
+ sp<IBinder> layerHandle;
+ sp<IBinder> displayHandle;
+
+ TestMapper(sp<IBinder> layerHandle, sp<IBinder> displayHandle)
+ : layerHandle(layerHandle), displayHandle(displayHandle) {}
+
+ sp<IBinder> getLayerHandle(int32_t id) const override {
+ return (id == 42) ? layerHandle : nullptr;
+ }
+ int32_t getLayerId(const sp<IBinder>& handle) const override {
+ return (handle == layerHandle) ? 42 : -1;
+ }
+ sp<IBinder> getDisplayHandle(int32_t id) const {
+ return (id == 43) ? displayHandle : nullptr;
+ }
+ int32_t getDisplayId(const sp<IBinder>& handle) const {
+ return (handle == displayHandle) ? 43 : -1;
+ }
};
- proto::TransactionState proto =
- TransactionProtoParser::toProto(t1, getLayerIdFn, getDisplayIdFn);
- TransactionState t2 =
- TransactionProtoParser::fromProto(proto, getLayerHandleFn, getDisplayHandleFn);
+ TransactionProtoParser parser(std::make_unique<TestMapper>(layerHandle, displayHandle));
+
+ proto::TransactionState proto = parser.toProto(t1);
+ TransactionState t2 = parser.fromProto(proto);
ASSERT_EQ(t1.originPid, t2.originPid);
ASSERT_EQ(t1.originUid, t2.originUid);
diff --git a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
index 39dbb07..61b72a0 100644
--- a/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
+++ b/services/surfaceflinger/tests/unittests/TransactionTracingTest.cpp
@@ -178,8 +178,8 @@
// verify we can still retrieve the layer change from the first entry containing starting
// states.
EXPECT_GT(proto.entry().size(), 0);
- EXPECT_GT(proto.entry(0).transactions().size(), 0);
- EXPECT_GT(proto.entry(0).added_layers().size(), 0);
+ EXPECT_EQ(proto.entry(0).transactions().size(), 1);
+ EXPECT_EQ(proto.entry(0).added_layers().size(), 2);
EXPECT_EQ(proto.entry(0).transactions(0).layer_changes().size(), 2);
EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).layer_id(), mParentLayerId);
EXPECT_EQ(proto.entry(0).transactions(0).layer_changes(0).z(), 42);