#include "gpu/command_buffer/common/skia_utils.h"
#include <inttypes.h>
#include "base/compiler_specific.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/stringprintf.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/process_memory_dump.h"
#include "build/build_config.h"
#include "third_party/skia/include/core/SkTraceMemoryDump.h"
#include "third_party/skia/include/gpu/ganesh/GrDirectContext.h"
#include "ui/gl/trace_util.h"
namespace gpu {
namespace raster {
namespace {
class SkiaGpuTraceMemoryDump : public SkTraceMemoryDump {
public:
SkiaGpuTraceMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
std::optional<uint64_t> share_group_tracing_guid)
: pmd_(pmd),
share_group_tracing_guid_(share_group_tracing_guid),
tracing_process_id_(base::trace_event::MemoryDumpManager::GetInstance()
->GetTracingProcessId()) {}
SkiaGpuTraceMemoryDump(const SkiaGpuTraceMemoryDump&) = delete;
SkiaGpuTraceMemoryDump& operator=(const SkiaGpuTraceMemoryDump&) = delete;
~SkiaGpuTraceMemoryDump() override = default;
void dumpNumericValue(const char* dump_name,
const char* value_name,
const char* units,
uint64_t value) override {
auto* dump = GetOrCreateAllocatorDump(dump_name);
dump->AddScalar(value_name, units, value);
}
void dumpStringValue(const char* dump_name,
const char* value_name,
const char* value) override {
auto* dump = GetOrCreateAllocatorDump(dump_name);
dump->AddString(value_name, "", value);
}
void setMemoryBacking(const char* dump_name,
const char* backing_type,
const char* backing_object_id) override {
uint32_t gl_id = UNSAFE_TODO(
std::strtoul(backing_object_id, nullptr , 10 ));
const char* kGLTextureBackingType = "gl_texture";
const char* kGLBufferBackingType = "gl_buffer";
const char* kGLRenderbufferBackingType = "gl_renderbuffer";
base::trace_event::MemoryAllocatorDumpGuid guid;
if (share_group_tracing_guid_) {
if (UNSAFE_TODO(strcmp(backing_type, kGLTextureBackingType)) == 0) {
guid = gl::GetGLTextureClientGUIDForTracing(*share_group_tracing_guid_,
gl_id);
} else if (UNSAFE_TODO(strcmp(backing_type, kGLBufferBackingType)) == 0) {
guid = gl::GetGLBufferGUIDForTracing(tracing_process_id_, gl_id);
} else if (UNSAFE_TODO(
strcmp(backing_type, kGLRenderbufferBackingType)) == 0) {
guid = gl::GetGLRenderbufferGUIDForTracing(tracing_process_id_, gl_id);
}
} else {
if (UNSAFE_TODO(strcmp(backing_type, kGLTextureBackingType)) == 0) {
guid = gl::GetGLTextureRasterGUIDForTracing(gl_id);
}
}
if (!guid.empty()) {
pmd_->CreateSharedGlobalAllocatorDump(guid);
auto* dump = GetOrCreateAllocatorDump(dump_name);
const int kImportance = 2;
pmd_->AddOwnershipEdge(dump->guid(), guid, kImportance);
}
}
void setDiscardableMemoryBacking(
const char* dump_name,
const SkDiscardableMemory& discardable_memory_object) override {
NOTREACHED();
}
LevelOfDetail getRequestedDetails() const override {
return kObjectsBreakdowns_LevelOfDetail;
}
bool shouldDumpWrappedObjects() const override {
return false;
}
private:
base::trace_event::MemoryAllocatorDump* GetOrCreateAllocatorDump(
const char* dump_name) {
auto* dump = pmd_->GetAllocatorDump(dump_name);
if (!dump)
dump = pmd_->CreateAllocatorDump(dump_name);
return dump;
}
raw_ptr<base::trace_event::ProcessMemoryDump> pmd_;
std::optional<uint64_t> share_group_tracing_guid_;
uint64_t tracing_process_id_;
};
}
void DumpGrMemoryStatistics(const GrDirectContext* context,
base::trace_event::ProcessMemoryDump* pmd,
std::optional<uint64_t> tracing_guid) {
SkiaGpuTraceMemoryDump trace_memory_dump(pmd, tracing_guid);
context->dumpMemoryStatistics(&trace_memory_dump);
}
void DumpBackgroundGrMemoryStatistics(
const GrDirectContext* context,
base::trace_event::ProcessMemoryDump* pmd) {
using base::trace_event::MemoryAllocatorDump;
size_t skia_gr_cache_size;
context->getResourceCacheUsage(nullptr ,
&skia_gr_cache_size);
std::string dump_name =
base::StringPrintf("skia/gpu_resources/context_0x%" PRIXPTR,
reinterpret_cast<uintptr_t>(context));
MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(dump_name);
dump->AddScalar(MemoryAllocatorDump::kNameSize,
MemoryAllocatorDump::kUnitsBytes, skia_gr_cache_size);
}
}
}