Merge "perfetto-ui: Fix canvas limit px"
diff --git a/buildtools/BUILD.gn b/buildtools/BUILD.gn
index f8d73c9..eb63eee 100644
--- a/buildtools/BUILD.gn
+++ b/buildtools/BUILD.gn
@@ -973,10 +973,13 @@
]
sources = [
"android-core/base/file.cpp",
+ "android-core/base/liblog_symbols.cpp",
"android-core/base/logging.cpp",
"android-core/base/stringprintf.cpp",
"android-core/base/strings.cpp",
"android-core/base/threads.cpp",
+ "android-core/liblog/fake_log_device.cpp",
+ "android-core/liblog/logger_write.cpp",
"android-core/libunwindstack/ArmExidx.cpp",
"android-core/libunwindstack/DwarfCfa.cpp",
"android-core/libunwindstack/DwarfEhFrameWithHdr.cpp",
@@ -1002,7 +1005,6 @@
"android-core/libunwindstack/RegsX86_64.cpp",
"android-core/libunwindstack/Symbols.cpp",
"android-core/libunwindstack/Unwinder.cpp",
- "android-core/libunwindstack/tests/LogFake.cpp",
]
if (current_cpu == "x86") {
sources += [ "android-core/libunwindstack/AsmGetRegsX86.S" ]
@@ -1014,6 +1016,7 @@
"//gn/standalone:c++11",
"//gn/standalone:visibility_hidden",
]
+ cflags = [ "-DFAKE_LOG_DEVICE=1" ]
configs += [ "//gn/standalone:c++17" ]
public_configs = [ ":libunwindstack_config" ]
}
diff --git a/src/profiling/memory/unwinding.cc b/src/profiling/memory/unwinding.cc
index ad18031..339077b 100644
--- a/src/profiling/memory/unwinding.cc
+++ b/src/profiling/memory/unwinding.cc
@@ -157,6 +157,9 @@
std::string content;
if (!base::ReadFileDescriptor(*fd_, &content))
return false;
+
+ unwindstack::MapInfo* prev_map = nullptr;
+ unwindstack::MapInfo* prev_real_map = nullptr;
return android::procinfo::ReadMapFileContent(
&content[0], [&](uint64_t start, uint64_t end, uint16_t flags,
uint64_t pgoff, ino_t, const char* name) {
@@ -165,10 +168,12 @@
strncmp(name + 5, "ashmem/", 7) != 0) {
flags |= unwindstack::MAPS_FLAGS_DEVICE_MAP;
}
- unwindstack::MapInfo* prev_map =
- maps_.empty() ? nullptr : maps_.back().get();
maps_.emplace_back(
- new unwindstack::MapInfo(prev_map, start, end, pgoff, flags, name));
+ new unwindstack::MapInfo(prev_map, prev_real_map, start, end, pgoff, flags, name));
+ prev_map = maps_.back().get();
+ if (!prev_map->IsBlank()) {
+ prev_real_map = prev_map;
+ }
});
}
diff --git a/src/trace_processor/importers/proto/graphics_event_parser.cc b/src/trace_processor/importers/proto/graphics_event_parser.cc
index eb58594..5337e81 100644
--- a/src/trace_processor/importers/proto/graphics_event_parser.cc
+++ b/src/trace_processor/importers/proto/graphics_event_parser.cc
@@ -245,25 +245,6 @@
snprintf(buffer, sizeof(buffer), "render stage(%zu)", stage_id);
stage_name = context_->storage->InternString(buffer);
}
- // If the slice has a render target handle, we append the hex value of the
- // handle to the name. If a debug marker is available, we append the name
- // of the render target.
- if (event.has_render_target_handle()) {
- char buffer[256];
- base::StringWriter str_writer(buffer, sizeof(buffer));
- str_writer.AppendString(context_->storage->GetString(stage_name));
- auto debug_marker_name =
- FindDebugName(VK_OBJECT_TYPE_FRAMEBUFFER, event.render_target_handle());
- str_writer.AppendChar('[');
- if (debug_marker_name.has_value()) {
- str_writer.AppendString(base::StringView(debug_marker_name.value()));
- } else {
- str_writer.AppendLiteral("0x");
- str_writer.AppendHexInt(event.render_target_handle());
- }
- str_writer.AppendChar(']');
- stage_name = context_->storage->InternString(str_writer.GetStringView());
- }
return stage_name;
}
diff --git a/src/trace_processor/importers/proto/track_event_parser.cc b/src/trace_processor/importers/proto/track_event_parser.cc
index 2ca1a28..fc46e7b 100644
--- a/src/trace_processor/importers/proto/track_event_parser.cc
+++ b/src/trace_processor/importers/proto/track_event_parser.cc
@@ -265,7 +265,7 @@
protos::pbzero::ProcessDescriptor::Decoder decoder(process_descriptor);
UniquePid upid = context_->process_tracker->GetOrCreateProcess(
static_cast<uint32_t>(decoder.pid()));
- if (decoder.has_process_name()) {
+ if (decoder.has_process_name() && decoder.process_name().size) {
// Don't override system-provided names.
context_->process_tracker->SetProcessNameIfUnset(
upid, context_->storage->InternString(decoder.process_name()));
@@ -306,7 +306,7 @@
static_cast<uint32_t>(decoder.tid()),
static_cast<uint32_t>(decoder.pid()));
StringId name_id = kNullStringId;
- if (decoder.has_thread_name()) {
+ if (decoder.has_thread_name() && decoder.thread_name().size) {
name_id = context_->storage->InternString(decoder.thread_name());
} else if (decoder.has_chrome_thread_type()) {
// TODO(skyostil): Remove parsing for legacy chrome_thread_type field.
@@ -456,6 +456,12 @@
base::Optional<UniqueTid> utid;
base::Optional<UniqueTid> upid;
+ // All events in legacy JSON require a thread ID, but for some types of events
+ // (e.g. async events or process/global-scoped instants), we don't store it in
+ // the slice/track model. To pass the utid through to the json export, we
+ // store it in an arg.
+ base::Optional<UniqueTid> legacy_passthrough_utid;
+
// Determine track from track_uuid specified in either TrackEvent or
// TrackEventDefaults. If a non-default track is not set, we either:
// a) fall back to the track specified by the sequence's (or event's) pid +
@@ -481,8 +487,16 @@
} else {
auto process_track_row =
context_->storage->process_track_table().id().IndexOf(track_id);
- if (process_track_row)
+ if (process_track_row) {
upid = storage->process_track_table().upid()[*process_track_row];
+ if (sequence_state->state()->pid_and_tid_valid()) {
+ uint32_t pid = static_cast<uint32_t>(sequence_state->state()->pid());
+ uint32_t tid = static_cast<uint32_t>(sequence_state->state()->tid());
+ UniqueTid utid_candidate = procs->UpdateThread(tid, pid);
+ if (storage->thread_table().upid()[utid_candidate] == upid)
+ legacy_passthrough_utid = utid_candidate;
+ }
+ }
}
} else if ((!event.has_track_uuid() || !event.has_type()) &&
(sequence_state->state()->pid_and_tid_valid() ||
@@ -502,12 +516,6 @@
track_id = track_tracker->GetOrCreateDefaultDescriptorTrack();
}
- // All events in legacy JSON require a thread ID, but for some types of events
- // (e.g. async events or process/global-scoped instants), we don't store it in
- // the slice/track model. To pass the utid through to the json export, we
- // store it in an arg.
- base::Optional<UniqueTid> legacy_passthrough_utid;
-
// TODO(eseckler): Replace phase with type and remove handling of
// legacy_event.phase() once it is no longer used by producers.
int32_t phase = 0;
diff --git a/src/trace_processor/sqlite_raw_table.cc b/src/trace_processor/sqlite_raw_table.cc
index 3177a96..af66914 100644
--- a/src/trace_processor/sqlite_raw_table.cc
+++ b/src/trace_processor/sqlite_raw_table.cc
@@ -101,6 +101,8 @@
// the proto field order is also the order of insertion (which happens to
// be true but proabably shouldn't be relied on).
RowMap rm = storage_->arg_table().FilterToRowMap({set_ids.eq(arg_set_id)});
+ if (rm.empty())
+ return;
uint32_t start_row = rm.Get(0);
using ValueWriter = std::function<void(const Variadic&)>;
diff --git a/src/trace_processor/tables/macros_benchmark.cc b/src/trace_processor/tables/macros_benchmark.cc
index fec67ed..c4ed6e3 100644
--- a/src/trace_processor/tables/macros_benchmark.cc
+++ b/src/trace_processor/tables/macros_benchmark.cc
@@ -359,6 +359,31 @@
}
BENCHMARK(BM_TableFilterParentSortedEq)->Apply(TableFilterArgs);
+static void BM_TableFilterParentSortedAndOther(benchmark::State& state) {
+ StringPool pool;
+ RootTestTable root(&pool, nullptr);
+
+ uint32_t size = static_cast<uint32_t>(state.range(0));
+
+ for (uint32_t i = 0; i < size; ++i) {
+ // Group the rows into rows of 10. This emulates the behaviour of e.g.
+ // args.
+ RootTestTable::Row row;
+ row.root_sorted = (i / 10) * 10;
+ row.root_non_null = i;
+ root.Insert(row);
+ }
+
+ // We choose to search for the last group as if there is O(n^2), it will
+ // be more easily visible.
+ uint32_t last_group = ((size - 1) / 10) * 10;
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(root.Filter({root.root_sorted().eq(last_group),
+ root.root_non_null().eq(size - 1)}));
+ }
+}
+BENCHMARK(BM_TableFilterParentSortedAndOther)->Apply(TableFilterArgs);
+
static void BM_TableFilterChildSortedEq(benchmark::State& state) {
StringPool pool;
RootTestTable root(&pool, nullptr);
diff --git a/test/trace_processor/gpu_render_stages.out b/test/trace_processor/gpu_render_stages.out
index fc94c06..dfeb78d 100644
--- a/test/trace_processor/gpu_render_stages.out
+++ b/test/trace_processor/gpu_render_stages.out
@@ -10,17 +10,17 @@
"queue 0","queue desc 0",60,5,"stage 0",0,"key1","value1",42,0,0,0,0,0
"queue 0","queue desc 0",70,5,"stage 0",0,"key1","[NULL]",42,0,0,0,0,0
"queue 0","queue desc 0",80,5,"stage 2",0,"[NULL]","[NULL]",42,0,0,0,0,0
-"queue 0","queue desc 0",90,5,"stage 0[0x10]",0,"VkCommandBuffer","0x0000000000000030",42,16,32,48,0,0
-"queue 0","queue desc 0",90,5,"stage 0[0x10]",0,"VkFramebuffer","0x0000000000000010",42,16,32,48,0,0
-"queue 0","queue desc 0",90,5,"stage 0[0x10]",0,"VkRenderPass","0x0000000000000020",42,16,32,48,0,0
-"queue 0","queue desc 0",100,5,"stage 0[0x10]",0,"VkCommandBuffer","0x0000000000000010 (command_buffer)",42,16,16,16,0,0
-"queue 0","queue desc 0",100,5,"stage 0[0x10]",0,"VkFramebuffer","0x0000000000000010",42,16,16,16,0,0
-"queue 0","queue desc 0",100,5,"stage 0[0x10]",0,"VkRenderPass","0x0000000000000010",42,16,16,16,0,0
-"queue 0","queue desc 0",110,5,"stage 0[0x10]",0,"VkCommandBuffer","0x0000000000000010 (command_buffer)",42,16,16,16,0,0
-"queue 0","queue desc 0",110,5,"stage 0[0x10]",0,"VkFramebuffer","0x0000000000000010",42,16,16,16,0,0
-"queue 0","queue desc 0",110,5,"stage 0[0x10]",0,"VkRenderPass","0x0000000000000010 (render_pass)",42,16,16,16,0,0
-"queue 0","queue desc 0",120,5,"stage 0[framebuffer]",0,"VkCommandBuffer","0x0000000000000010 (command_buffer)",42,16,16,16,0,0
-"queue 0","queue desc 0",120,5,"stage 0[framebuffer]",0,"VkFramebuffer","0x0000000000000010 (framebuffer)",42,16,16,16,0,0
-"queue 0","queue desc 0",120,5,"stage 0[framebuffer]",0,"VkRenderPass","0x0000000000000010 (render_pass)",42,16,16,16,0,0
-"queue 0","queue desc 0",130,5,"stage 0[renamed_buffer]",0,"VkFramebuffer","0x0000000000000010 (renamed_buffer)",42,16,0,0,0,0
+"queue 0","queue desc 0",90,5,"stage 0",0,"VkCommandBuffer","0x0000000000000030",42,16,32,48,0,0
+"queue 0","queue desc 0",90,5,"stage 0",0,"VkFramebuffer","0x0000000000000010",42,16,32,48,0,0
+"queue 0","queue desc 0",90,5,"stage 0",0,"VkRenderPass","0x0000000000000020",42,16,32,48,0,0
+"queue 0","queue desc 0",100,5,"stage 0",0,"VkCommandBuffer","0x0000000000000010 (command_buffer)",42,16,16,16,0,0
+"queue 0","queue desc 0",100,5,"stage 0",0,"VkFramebuffer","0x0000000000000010",42,16,16,16,0,0
+"queue 0","queue desc 0",100,5,"stage 0",0,"VkRenderPass","0x0000000000000010",42,16,16,16,0,0
+"queue 0","queue desc 0",110,5,"stage 0",0,"VkCommandBuffer","0x0000000000000010 (command_buffer)",42,16,16,16,0,0
+"queue 0","queue desc 0",110,5,"stage 0",0,"VkFramebuffer","0x0000000000000010",42,16,16,16,0,0
+"queue 0","queue desc 0",110,5,"stage 0",0,"VkRenderPass","0x0000000000000010 (render_pass)",42,16,16,16,0,0
+"queue 0","queue desc 0",120,5,"stage 0",0,"VkCommandBuffer","0x0000000000000010 (command_buffer)",42,16,16,16,0,0
+"queue 0","queue desc 0",120,5,"stage 0",0,"VkFramebuffer","0x0000000000000010 (framebuffer)",42,16,16,16,0,0
+"queue 0","queue desc 0",120,5,"stage 0",0,"VkRenderPass","0x0000000000000010 (render_pass)",42,16,16,16,0,0
+"queue 0","queue desc 0",130,5,"stage 0",0,"VkFramebuffer","0x0000000000000010 (renamed_buffer)",42,16,0,0,0,0
"Unknown GPU Queue ","[NULL]",140,5,"render stage(18446744073709551615)",0,"[NULL]","[NULL]",42,0,0,0,0,1024
diff --git a/test/trace_processor/track_event_tracks_slices.out b/test/trace_processor/track_event_tracks_slices.out
index a031897..d7119df 100644
--- a/test/trace_processor/track_event_tracks_slices.out
+++ b/test/trace_processor/track_event_tracks_slices.out
@@ -2,12 +2,12 @@
"[NULL]","[NULL]","t1","p1",1000,0,"cat","event1_on_t1",0
"[NULL]","[NULL]","t2","p1",2000,0,"cat","event1_on_t2",0
"[NULL]","[NULL]","t2","p1",3000,0,"cat","event2_on_t2",0
-"[NULL]","p1","[NULL]","[NULL]",4000,0,"cat","event1_on_p1",0
-"async","p1","[NULL]","[NULL]",5000,0,"cat","event1_on_async",0
-"async2","p1","[NULL]","[NULL]",5100,100,"cat","event1_on_async2",0
+"[NULL]","p1","[NULL]","[NULL]",4000,0,"cat","event1_on_p1",8
+"async","p1","[NULL]","[NULL]",5000,0,"cat","event1_on_async",8
+"async2","p1","[NULL]","[NULL]",5100,100,"cat","event1_on_async2",3
"[NULL]","[NULL]","t1","p1",6000,0,"cat","event3_on_t1",0
"[NULL]","[NULL]","t3","p1",11000,0,"cat","event1_on_t3",0
-"[NULL]","p2","[NULL]","[NULL]",21000,0,"cat","event1_on_p2",0
+"[NULL]","p2","[NULL]","[NULL]",21000,0,"cat","event1_on_p2",7
"[NULL]","[NULL]","t4","p2",22000,0,"cat","event1_on_t4",0
"Default Track","[NULL]","[NULL]","[NULL]",30000,0,"cat","event1_on_t1",0
-"[NULL]","p2","[NULL]","[NULL]",31000,0,"cat","event1_on_t1",5
+"[NULL]","p2","[NULL]","[NULL]",31000,0,"cat","event1_on_t1",6
diff --git a/tools/install-build-deps b/tools/install-build-deps
index 1ed1fab..788a0fe 100755
--- a/tools/install-build-deps
+++ b/tools/install-build-deps
@@ -132,7 +132,7 @@
# These dependencies are for libunwindstack, which is used by src/profiling.
('buildtools/android-core',
'https://android.googlesource.com/platform/system/core.git',
- '860e8682e27eea30cc604b60c9cab83d0b047012', 'all'),
+ '8bf4e29e44098e3232ff646331675fb113064162', 'all'),
('buildtools/lzma',
'https://android.googlesource.com/platform/external/lzma.git',
'7851dce6f4ca17f5caa1c93a4e0a45686b1d56c3', 'all'),
diff --git a/ui/src/assets/record.scss b/ui/src/assets/record.scss
index b2170bb..d5d0e6a 100644
--- a/ui/src/assets/record.scss
+++ b/ui/src/assets/record.scss
@@ -274,6 +274,7 @@
transition: opacity 0.25s ease;
opacity: 0;
visibility: hidden;
+ overflow: auto;
&:not(.active) {
max-height: 0;
diff --git a/ui/src/frontend/legacy_trace_viewer.ts b/ui/src/frontend/legacy_trace_viewer.ts
index c55451d..253d6af 100644
--- a/ui/src/frontend/legacy_trace_viewer.ts
+++ b/ui/src/frontend/legacy_trace_viewer.ts
@@ -18,12 +18,48 @@
import {globals} from './globals';
-export function isLegacyTrace(fileName: string): boolean {
- fileName = fileName.toLowerCase();
- return (
- fileName.endsWith('.json') || fileName.endsWith('.json.gz') ||
+function readText(blob: Blob): Promise<string> {
+ return new Promise((resolve, reject) => {
+ const reader = new FileReader();
+ reader.onload = () => {
+ if (typeof reader.result === 'string') {
+ return resolve(reader.result);
+ }
+ };
+ reader.onerror = err => {
+ reject(err);
+ };
+ reader.readAsText(blob);
+ });
+}
+
+export async function isLegacyTrace(file: File): Promise<boolean> {
+ const fileName = file.name.toLowerCase();
+ if (fileName.endsWith('.json') || fileName.endsWith('.json.gz') ||
fileName.endsWith('.zip') || fileName.endsWith('.ctrace') ||
- fileName.endsWith('.html'));
+ fileName.endsWith('.html')) {
+ return true;
+ }
+
+ // Sometimes systrace formatted traces end with '.trace'. This is a
+ // little generic to assume all such traces are systrace format though
+ // so we read the beginning of the file and check to see if is has the
+ // systrace header (several comment lines):
+ if (fileName.endsWith('.trace')) {
+ const header = await readText(file.slice(0, 512));
+ const lines = header.split('\n');
+ let commentCount = 0;
+ for (const line of lines) {
+ if (line.startsWith('#')) {
+ commentCount++;
+ }
+ }
+ if (commentCount > 5) {
+ return true;
+ }
+ }
+
+ return false;
}
export function openFileWithLegacyTraceViewer(file: File) {
diff --git a/ui/src/frontend/sidebar.ts b/ui/src/frontend/sidebar.ts
index cfeeec5..a295a75 100644
--- a/ui/src/frontend/sidebar.ts
+++ b/ui/src/frontend/sidebar.ts
@@ -311,12 +311,7 @@
globals.frontendLocalState.localOnlyMode = false;
if (e.target.dataset['useCatapultLegacyUi'] === '1') {
- // Switch back to the old catapult UI.
- if (isLegacyTrace(file.name)) {
- openFileWithLegacyTraceViewer(file);
- return;
- }
- openInOldUIWithSizeCheck(file);
+ openWithLegacyUi(file);
return;
}
@@ -343,7 +338,15 @@
}
globals.dispatch(Actions.openTraceFromFile({file}));
+}
+async function openWithLegacyUi(file: File) {
+ // Switch back to the old catapult UI.
+ if (await isLegacyTrace(file)) {
+ openFileWithLegacyTraceViewer(file);
+ return;
+ }
+ openInOldUIWithSizeCheck(file);
}
function openInOldUIWithSizeCheck(trace: Blob) {