Commit 93b4ec1b authored by khmel@chromium.org's avatar khmel@chromium.org Committed by Commit Bot

arc: Discard queueBuffer and dequeueBuffer from client tasks.

Before tracing was not activated for client tasks due to problem of
activating tracing in their processes. Now it is solved and we have
extra events to analyze. queueBuffer and dequeueBuffer may have the same
hierarchy as surface flinger events that cause false error reporting.
This CL adds detection of surface flinger process id and consume events
from it.

TEST=Locally
BUG=b:122555793

Change-Id: I048275c56d21de0c6bf19f07ab472972af8f0e82
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1574648Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Yury Khmel <khmel@chromium.org>
Cr-Commit-Position: refs/heads/master@{#652892}
parent d899fb69
...@@ -293,42 +293,97 @@ std::string GetActivityFromBufferName(const std::string& android_buffer_name) { ...@@ -293,42 +293,97 @@ std::string GetActivityFromBufferName(const std::string& android_buffer_name) {
// Processes surface flinger events. It selects events using |query| from the // Processes surface flinger events. It selects events using |query| from the
// model. Buffer id is extracted for the each returned event and new events are // model. Buffer id is extracted for the each returned event and new events are
// grouped by its buffer id. // grouped by its buffer id. If |surface_flinger_pid| is set to the positive
void ProcessSurfaceFlingerEvents(const ArcTracingModel& common_model, // value than this activates filtering events by process id to avoid the case
const std::string& query, // when android:queueBuffer/dequeueBuffer events may appear in context of child
BufferToEvents* buffer_to_events) { // process and could be processed as surface flinger event. Returns positive
// process id in case surface flinger events are found and belong to the same
// process. In case of error -1 is returned.
int ProcessSurfaceFlingerEvents(const ArcTracingModel& common_model,
const std::string& query,
BufferToEvents* buffer_to_events,
int surface_flinger_pid) {
int detected_pid = -1;
const ArcTracingModel::TracingEventPtrs surface_flinger_events = const ArcTracingModel::TracingEventPtrs surface_flinger_events =
common_model.Select(query); common_model.Select(query);
std::string buffer_id; std::string buffer_id;
for (const ArcTracingEvent* event : surface_flinger_events) { for (const ArcTracingEvent* event : surface_flinger_events) {
if (surface_flinger_pid > 0 && event->GetPid() != surface_flinger_pid)
continue;
if (!ExtractBufferIdFromSurfaceFlingerEvent(*event, &buffer_id)) { if (!ExtractBufferIdFromSurfaceFlingerEvent(*event, &buffer_id)) {
LOG(ERROR) << "Failed to get buffer id from surface flinger event"; LOG(ERROR) << "Failed to get buffer id from surface flinger event";
continue; continue;
} }
if (detected_pid < 0) {
DCHECK_GE(event->GetPid(), 0);
detected_pid = event->GetPid();
} else if (detected_pid != event->GetPid()) {
LOG(ERROR) << "Found multiple surface flinger process ids "
<< detected_pid << "/" << event->GetPid();
return -1;
}
ArcTracingGraphicsModel::BufferEvents& graphics_events = ArcTracingGraphicsModel::BufferEvents& graphics_events =
(*buffer_to_events)[buffer_id]; (*buffer_to_events)[buffer_id];
GetEventMapper().Produce(*event, &graphics_events); GetEventMapper().Produce(*event, &graphics_events);
} }
return detected_pid;
} }
// Processes Android events acquireBuffer, releaseBuffer, dequeueBuffer and // Processes Android events acquireBuffer, releaseBuffer, dequeueBuffer and
// queueBuffer. It returns map buffer id to the list of sorted by timestamp // queueBuffer. It returns map buffer id to the list of sorted by timestamp
// events. // events.
BufferToEvents GetSurfaceFlingerEvents(const ArcTracingModel& common_model) { bool GetSurfaceFlingerEvents(const ArcTracingModel& common_model,
BufferToEvents per_buffer_surface_flinger_events; BufferToEvents* out_events) {
ProcessSurfaceFlingerEvents(common_model, kAcquireBufferQuery, // Detect surface_flinger_pid using |kAcquireBufferQuery| that has unique
&per_buffer_surface_flinger_events); // hierarchy.
ProcessSurfaceFlingerEvents(common_model, kReleaseBufferQueryP, const int surface_flinger_pid =
&per_buffer_surface_flinger_events); ProcessSurfaceFlingerEvents(common_model, kAcquireBufferQuery, out_events,
ProcessSurfaceFlingerEvents(common_model, kReleaseBufferQueryN, -1 /* surface_flinger_pid */);
&per_buffer_surface_flinger_events); if (surface_flinger_pid <= 0) {
ProcessSurfaceFlingerEvents(common_model, kQueueBufferQuery, LOG(ERROR) << "Failed to detect acquireBuffer events.";
&per_buffer_surface_flinger_events); return false;
ProcessSurfaceFlingerEvents(common_model, kDequeueBufferQuery, }
&per_buffer_surface_flinger_events);
for (auto& buffer : per_buffer_surface_flinger_events) const int surface_flinger_pid_p =
ProcessSurfaceFlingerEvents(common_model, kReleaseBufferQueryP,
out_events, -1 /* surface_flinger_pid */);
const int surface_flinger_pid_n =
ProcessSurfaceFlingerEvents(common_model, kReleaseBufferQueryN,
out_events, -1 /* surface_flinger_pid */);
if (surface_flinger_pid_p <= 0 && surface_flinger_pid_n <= 0) {
LOG(ERROR) << "Failed to detect releaseBuffer events.";
return false;
}
if (surface_flinger_pid_p > 0 && surface_flinger_pid_n > 0) {
LOG(ERROR) << "Detected releaseBuffer events from both NYC and PI.";
return false;
}
if (surface_flinger_pid_p != surface_flinger_pid &&
surface_flinger_pid_n != surface_flinger_pid) {
LOG(ERROR) << "Detected acquireBuffer and releaseBuffer from"
" different processes.";
return false;
}
// queueBuffer and dequeueBuffer may appear in context of client task.
// Use detected |surface_flinger_pid| to filter out such events.
if (ProcessSurfaceFlingerEvents(common_model, kQueueBufferQuery, out_events,
surface_flinger_pid) < 0) {
LOG(ERROR) << "Failed to detect queueBuffer events.";
return false;
}
if (ProcessSurfaceFlingerEvents(common_model, kDequeueBufferQuery, out_events,
surface_flinger_pid) < 0) {
LOG(ERROR) << "Failed to detect dequeueBuffer events.";
return false;
}
for (auto& buffer : *out_events)
SortBufferEventsByTimestamp(&buffer.second); SortBufferEventsByTimestamp(&buffer.second);
return per_buffer_surface_flinger_events; return true;
} }
// Processes exo events Surface::Attach and Buffer::ReleaseContents. Each event // Processes exo events Surface::Attach and Buffer::ReleaseContents. Each event
...@@ -945,8 +1000,11 @@ ArcTracingGraphicsModel::~ArcTracingGraphicsModel() = default; ...@@ -945,8 +1000,11 @@ ArcTracingGraphicsModel::~ArcTracingGraphicsModel() = default;
bool ArcTracingGraphicsModel::Build(const ArcTracingModel& common_model) { bool ArcTracingGraphicsModel::Build(const ArcTracingModel& common_model) {
Reset(); Reset();
BufferToEvents per_buffer_surface_flinger_events = BufferToEvents per_buffer_surface_flinger_events;
GetSurfaceFlingerEvents(common_model); if (!GetSurfaceFlingerEvents(common_model,
&per_buffer_surface_flinger_events)) {
return false;
}
BufferToEvents per_buffer_chrome_events = BufferToEvents per_buffer_chrome_events =
GetChromeEvents(common_model, &chrome_buffer_id_to_task_id_); GetChromeEvents(common_model, &chrome_buffer_id_to_task_id_);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment