blob: 9c3994392a20e0cce2f2b3f72a573d7ca2f2df5a [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "src/trace_processor/vulkan_memory_tracker.h"
#include "src/trace_processor/process_tracker.h"
#include "src/trace_processor/trace_processor_context.h"
#include "perfetto/base/logging.h"
namespace perfetto {
namespace trace_processor {
VulkanMemoryTracker::VulkanMemoryTracker(TraceProcessorContext* context)
: context_(context), empty_(context_->storage->InternString({"", 0})) {
SetupSourceAndTypeInternedStrings();
}
void VulkanMemoryTracker::SetupSourceAndTypeInternedStrings() {
// It seems a good idea to have the source and type of the event coded as
// a string id inside the Perfetto db instead of having the enum value
// stored. However, it seems that Perfetto only allows protobufs which are
// optimized for LITE_RUNTIME (removing the line results in link errors).
// Apparently, there is also a minimal implementation of protobuf descriptor
// in the code base, but it does not have the reflection to retrieve the name
// of the enum. More investigation is required to resolve this.
// TODO (zakerinasab): Fix and uncomment the following code to avoid
// hardcoding the interned strings for the source and type of memory events.
// const protos::pbzero::EnumDescriptor* source_descriptor =
// protos::pbzero::VulkanMemoryEvent::Source_descriptor();
// for (int i = 0; i < source_descriptor->value_count(); i++) {
// auto source_enum = source_descriptor->value(i);
// auto source_str = source_enum->name();
// auto str_id = context_->storage->InternString(
// base::StringView(source_str.c_str(), source_str.length()));
// source_string_map_.emplace(source_enum->number(), str_id);
// }
// const protos::pbzero::EnumDescriptor* type_descriptor =
// protos::pbzero::VulkanMemoryEvent::Type_descriptor();
// for (int i = 0; i < type_descriptor->value_count(); i++) {
// auto type_enum = type_descriptor->value(i);
// auto type_str = type_enum->name();
// auto str_id = context_->storage->InternString(
// base::StringView(type_str.c_str(), type_str.length()));
// type_string_map_.emplace(type_enum->number(), str_id);
// }
std::unordered_map<int, std::string> event_sources({
{0, "UNKNOWN_SOURCE"},
{1, "DEVICE"},
{2, "HOST"},
{3, "GPU_DEVICE_MEMORY"},
{4, "GPU_BUFFER"},
{5, "GPU_IMAGE"},
});
for (const auto& source : event_sources) {
source_string_map_.emplace(
source.first, context_->storage->InternString(base::StringView(
source.second.c_str(), source.second.length())));
}
std::unordered_map<int, std::string> event_types({
{0, "UNKNOWN_TYPE"},
{1, "CREATE"},
{2, "DESTROY"},
{3, "BIND"},
{4, "DESTROY_BOUND"},
{5, "ANNOTATIONS"},
});
for (const auto& type : event_types) {
type_string_map_.emplace(type.first,
context_->storage->InternString(base::StringView(
type.second.c_str(), type.second.length())));
}
}
void VulkanMemoryTracker::AddString(SourceStringId id, StringId str) {
string_map_.emplace(id, str);
}
base::Optional<StringId> VulkanMemoryTracker::FindString(SourceStringId id) {
base::Optional<StringId> res;
if (id == 0) {
res = empty_;
return res;
}
auto it = string_map_.find(id);
if (it == string_map_.end()) {
context_->storage->IncrementStats(
stats::vulkan_allocations_invalid_string_id);
PERFETTO_DFATAL("Invalid string.");
return res;
}
res = it->second;
return res;
}
base::Optional<StringId> VulkanMemoryTracker::FindSourceString(
SourceStringId source) {
base::Optional<StringId> res = empty_;
auto it = source_string_map_.find(source);
if (it == source_string_map_.end()) {
context_->storage->IncrementStats(
stats::vulkan_memory_allocations_invalid_source_string_id);
PERFETTO_DFATAL("Invalid memory event source string.");
return res;
}
res = it->second;
return res;
}
base::Optional<StringId> VulkanMemoryTracker::FindTypeString(
SourceStringId type) {
base::Optional<StringId> res = empty_;
auto it = type_string_map_.find(type);
if (it == type_string_map_.end()) {
context_->storage->IncrementStats(
stats::vulkan_memory_allocations_invalid_type_string_id);
PERFETTO_DFATAL("Invalid memory event type string.");
return res;
}
res = it->second;
return res;
}
} // namespace trace_processor
} // namespace perfetto