Commit 2c905214 authored by Khushal's avatar Khushal Committed by Commit Bot

gpu: Add memory tracing for GrContext in GPU process.

Include memory dump from GrContext used for OOP raster in the GPU
process in traces.

R=bsalomon@chromium.org, ericrk@chromium.org, sadrul@chromium.org
TBR=bsalomon@google.com

Bug: 859419
Cq-Include-Trybots: luci.chromium.try:android_optional_gpu_tests_rel;luci.chromium.try:linux_optional_gpu_tests_rel;luci.chromium.try:mac_optional_gpu_tests_rel;luci.chromium.try:win_optional_gpu_tests_rel
Change-Id: Ie010e1c567626343d5698b02c45776d215640da0
Reviewed-on: https://chromium-review.googlesource.com/1123894
Commit-Queue: Khushal <khushalsagar@chromium.org>
Reviewed-by: default avatarBrian Salomon <bsalomon@google.com>
Reviewed-by: default avatarEric Karl <ericrk@chromium.org>
Reviewed-by: default avatarSadrul Chowdhury <sadrul@chromium.org>
Cr-Commit-Position: refs/heads/master@{#573479}
parent ac2aa68e
...@@ -146,6 +146,8 @@ source_set("raster_sources") { ...@@ -146,6 +146,8 @@ source_set("raster_sources") {
deps = [ deps = [
":gles2_utils", ":gles2_utils",
"//base", "//base",
"//skia",
"//ui/gl:gl",
] ]
public_deps = [ public_deps = [
":common", ":common",
......
include_rules = [ include_rules = [
"+components/viz/common/resources/resource_format.h", "+components/viz/common/resources/resource_format.h",
"+components/viz/common/resources/resource_format_utils.h", "+components/viz/common/resources/resource_format_utils.h",
"+third_party/skia/include",
] ]
specific_include_rules = { specific_include_rules = {
"unittest_main\.cc": [ "unittest_main\.cc": [
......
...@@ -5,10 +5,119 @@ ...@@ -5,10 +5,119 @@
#include "gpu/command_buffer/common/skia_utils.h" #include "gpu/command_buffer/common/skia_utils.h"
#include "base/sys_info.h" #include "base/sys_info.h"
#include "base/trace_event/memory_dump_manager.h"
#include "base/trace_event/process_memory_dump.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "third_party/skia/include/core/SkTraceMemoryDump.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "ui/gl/trace_util.h"
namespace gpu { namespace gpu {
namespace raster { namespace raster {
namespace {
// Derives from SkTraceMemoryDump and implements graphics specific memory
// backing functionality.
class SkiaGpuTraceMemoryDump : public SkTraceMemoryDump {
public:
// This should never outlive the provided ProcessMemoryDump, as it should
// always be scoped to a single OnMemoryDump funciton call.
SkiaGpuTraceMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
base::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() override = default;
// Overridden from SkTraceMemoryDump:
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 setMemoryBacking(const char* dump_name,
const char* backing_type,
const char* backing_object_id) override {
// If we don't have a unique tracing guid, these resources are not
// referenced across processes and don't need ownership edges.
if (!share_group_tracing_guid_)
return;
// For uniformity, skia provides this value as a string. Convert back to a
// uint32_t.
uint32_t gl_id =
std::strtoul(backing_object_id, nullptr /* str_end */, 10 /* base */);
// Constants used by SkiaGpuTraceMemoryDump to identify different memory
// types.
const char* kGLTextureBackingType = "gl_texture";
const char* kGLBufferBackingType = "gl_buffer";
const char* kGLRenderbufferBackingType = "gl_renderbuffer";
// Populated in if statements below.
base::trace_event::MemoryAllocatorDumpGuid guid;
if (strcmp(backing_type, kGLTextureBackingType) == 0) {
guid = gl::GetGLTextureClientGUIDForTracing(*share_group_tracing_guid_,
gl_id);
} else if (strcmp(backing_type, kGLBufferBackingType) == 0) {
guid = gl::GetGLBufferGUIDForTracing(tracing_process_id_, gl_id);
} else if (strcmp(backing_type, kGLRenderbufferBackingType) == 0) {
guid = gl::GetGLRenderbufferGUIDForTracing(tracing_process_id_, 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 {
// We don't use this class for dumping discardable memory.
NOTREACHED();
}
LevelOfDetail getRequestedDetails() const override {
// TODO(ssid): Use MemoryDumpArgs to create light dumps when requested
// (crbug.com/499731).
return kObjectsBreakdowns_LevelOfDetail;
}
bool shouldDumpWrappedObjects() const override {
// Chrome already dumps objects it imports into Skia. Avoid duplicate dumps
// by asking Skia not to dump them.
return false;
}
private:
// Helper to create allocator dumps.
base::trace_event::MemoryAllocatorDump* GetOrCreateAllocatorDump(
const char* dump_name) {
auto* dump = pmd_->GetAllocatorDump(dump_name);
if (!dump)
dump = pmd_->CreateAllocatorDump(dump_name);
return dump;
}
base::trace_event::ProcessMemoryDump* pmd_;
base::Optional<uint64_t> share_group_tracing_guid_;
uint64_t tracing_process_id_;
DISALLOW_COPY_AND_ASSIGN(SkiaGpuTraceMemoryDump);
};
} // namespace
void DetermineGrCacheLimitsFromAvailableMemory( void DetermineGrCacheLimitsFromAvailableMemory(
size_t* max_resource_cache_bytes, size_t* max_resource_cache_bytes,
...@@ -50,5 +159,12 @@ void DefaultGrCacheLimitsForTests(size_t* max_resource_cache_bytes, ...@@ -50,5 +159,12 @@ void DefaultGrCacheLimitsForTests(size_t* max_resource_cache_bytes,
*max_glyph_cache_texture_bytes = kDefaultGlyphCacheTextureBytes; *max_glyph_cache_texture_bytes = kDefaultGlyphCacheTextureBytes;
} }
void DumpGrMemoryStatistics(const GrContext* context,
base::trace_event::ProcessMemoryDump* pmd,
base::Optional<uint64_t> tracing_guid) {
SkiaGpuTraceMemoryDump trace_memory_dump(pmd, tracing_guid);
context->dumpMemoryStatistics(&trace_memory_dump);
}
} // namespace raster } // namespace raster
} // namespace gpu } // namespace gpu
...@@ -6,8 +6,18 @@ ...@@ -6,8 +6,18 @@
#define GPU_COMMAND_BUFFER_COMMON_SKIA_UTILS_H_ #define GPU_COMMAND_BUFFER_COMMON_SKIA_UTILS_H_
#include <memory> #include <memory>
#include "base/optional.h"
#include "gpu/raster_export.h" #include "gpu/raster_export.h"
class GrContext;
namespace base {
namespace trace_event {
class ProcessMemoryDump;
}
} // namespace base
namespace gpu { namespace gpu {
namespace raster { namespace raster {
...@@ -19,6 +29,13 @@ RASTER_EXPORT void DefaultGrCacheLimitsForTests( ...@@ -19,6 +29,13 @@ RASTER_EXPORT void DefaultGrCacheLimitsForTests(
size_t* max_resource_cache_bytes, size_t* max_resource_cache_bytes,
size_t* max_glyph_cache_texture_bytes); size_t* max_glyph_cache_texture_bytes);
// Dumps memory usage from the |context| to |pmd|. A |tracing_guid| can be used
// if these resources are referenced across processes for sharing across dumps.
RASTER_EXPORT void DumpGrMemoryStatistics(
const GrContext* context,
base::trace_event::ProcessMemoryDump* pmd,
base::Optional<uint64_t> tracing_guid);
} // namespace raster } // namespace raster
} // namespace gpu } // namespace gpu
......
...@@ -4,6 +4,8 @@ ...@@ -4,6 +4,8 @@
#include "gpu/command_buffer/service/raster_decoder_context_state.h" #include "gpu/command_buffer/service/raster_decoder_context_state.h"
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/memory_dump_manager.h"
#include "gpu/config/gpu_driver_bug_workarounds.h" #include "gpu/config/gpu_driver_bug_workarounds.h"
#include "ui/gl/gl_context.h" #include "ui/gl/gl_context.h"
#include "ui/gl/gl_share_group.h" #include "ui/gl/gl_share_group.h"
...@@ -21,11 +23,18 @@ RasterDecoderContextState::RasterDecoderContextState( ...@@ -21,11 +23,18 @@ RasterDecoderContextState::RasterDecoderContextState(
: share_group(std::move(share_group)), : share_group(std::move(share_group)),
surface(std::move(surface)), surface(std::move(surface)),
context(std::move(context)), context(std::move(context)),
use_virtualized_gl_contexts(use_virtualized_gl_contexts) {} use_virtualized_gl_contexts(use_virtualized_gl_contexts) {
if (base::ThreadTaskRunnerHandle::IsSet()) {
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
this, "RasterDecoderContextState", base::ThreadTaskRunnerHandle::Get());
}
}
RasterDecoderContextState::~RasterDecoderContextState() { RasterDecoderContextState::~RasterDecoderContextState() {
if (gr_context) if (gr_context)
gr_context->abandonContext(); gr_context->abandonContext();
base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
this);
} }
void RasterDecoderContextState::InitializeGrContext( void RasterDecoderContextState::InitializeGrContext(
...@@ -62,5 +71,13 @@ void RasterDecoderContextState::InitializeGrContext( ...@@ -62,5 +71,13 @@ void RasterDecoderContextState::InitializeGrContext(
} }
} }
bool RasterDecoderContextState::OnMemoryDump(
const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) {
if (gr_context)
DumpGrMemoryStatistics(gr_context.get(), pmd, base::nullopt);
return true;
}
} // namespace raster } // namespace raster
} // namespace gpu } // namespace gpu
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_CONTEXT_STATE_H_ #define GPU_COMMAND_BUFFER_SERVICE_RASTER_DECODER_CONTEXT_STATE_H_
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/trace_event/memory_dump_provider.h"
#include "gpu/command_buffer/common/skia_utils.h" #include "gpu/command_buffer/common/skia_utils.h"
#include "gpu/gpu_gles2_export.h" #include "gpu/gpu_gles2_export.h"
#include "third_party/skia/include/gpu/GrContext.h" #include "third_party/skia/include/gpu/GrContext.h"
...@@ -22,7 +23,8 @@ class GpuDriverBugWorkarounds; ...@@ -22,7 +23,8 @@ class GpuDriverBugWorkarounds;
namespace raster { namespace raster {
struct GPU_GLES2_EXPORT RasterDecoderContextState struct GPU_GLES2_EXPORT RasterDecoderContextState
: public base::RefCounted<RasterDecoderContextState> { : public base::RefCounted<RasterDecoderContextState>,
public base::trace_event::MemoryDumpProvider {
public: public:
RasterDecoderContextState(scoped_refptr<gl::GLShareGroup> share_group, RasterDecoderContextState(scoped_refptr<gl::GLShareGroup> share_group,
scoped_refptr<gl::GLSurface> surface, scoped_refptr<gl::GLSurface> surface,
...@@ -44,9 +46,13 @@ struct GPU_GLES2_EXPORT RasterDecoderContextState ...@@ -44,9 +46,13 @@ struct GPU_GLES2_EXPORT RasterDecoderContextState
// PermitsInconsistentContextState. // PermitsInconsistentContextState.
bool need_context_state_reset = false; bool need_context_state_reset = false;
// base::trace_event::MemoryDumpProvider implementation.
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) override;
private: private:
friend class base::RefCounted<RasterDecoderContextState>; friend class base::RefCounted<RasterDecoderContextState>;
~RasterDecoderContextState(); ~RasterDecoderContextState() override;
}; };
} // namespace raster } // namespace raster
......
...@@ -40,104 +40,6 @@ ...@@ -40,104 +40,6 @@
class SkDiscardableMemory; class SkDiscardableMemory;
namespace {
// Derives from SkTraceMemoryDump and implements graphics specific memory
// backing functionality.
class SkiaGpuTraceMemoryDump : public SkTraceMemoryDump {
public:
// This should never outlive the provided ProcessMemoryDump, as it should
// always be scoped to a single OnMemoryDump funciton call.
explicit SkiaGpuTraceMemoryDump(base::trace_event::ProcessMemoryDump* pmd,
uint64_t share_group_tracing_guid)
: pmd_(pmd), share_group_tracing_guid_(share_group_tracing_guid) {}
// Overridden from SkTraceMemoryDump:
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 setMemoryBacking(const char* dump_name,
const char* backing_type,
const char* backing_object_id) override {
const uint64_t tracing_process_id =
base::trace_event::MemoryDumpManager::GetInstance()
->GetTracingProcessId();
// For uniformity, skia provides this value as a string. Convert back to a
// uint32_t.
uint32_t gl_id =
std::strtoul(backing_object_id, nullptr /* str_end */, 10 /* base */);
// Constants used by SkiaGpuTraceMemoryDump to identify different memory
// types.
const char* kGLTextureBackingType = "gl_texture";
const char* kGLBufferBackingType = "gl_buffer";
const char* kGLRenderbufferBackingType = "gl_renderbuffer";
// Populated in if statements below.
base::trace_event::MemoryAllocatorDumpGuid guid;
if (strcmp(backing_type, kGLTextureBackingType) == 0) {
guid = gl::GetGLTextureClientGUIDForTracing(share_group_tracing_guid_,
gl_id);
} else if (strcmp(backing_type, kGLBufferBackingType) == 0) {
guid = gl::GetGLBufferGUIDForTracing(tracing_process_id, gl_id);
} else if (strcmp(backing_type, kGLRenderbufferBackingType) == 0) {
guid = gl::GetGLRenderbufferGUIDForTracing(tracing_process_id, 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 {
// We don't use this class for dumping discardable memory.
NOTREACHED();
}
LevelOfDetail getRequestedDetails() const override {
// TODO(ssid): Use MemoryDumpArgs to create light dumps when requested
// (crbug.com/499731).
return kObjectsBreakdowns_LevelOfDetail;
}
bool shouldDumpWrappedObjects() const override {
// Chrome already dumps objects it imports into Skia. Avoid duplicate dumps
// by asking Skia not to dump them.
return false;
}
private:
// Helper to create allocator dumps.
base::trace_event::MemoryAllocatorDump* GetOrCreateAllocatorDump(
const char* dump_name) {
auto* dump = pmd_->GetAllocatorDump(dump_name);
if (!dump)
dump = pmd_->CreateAllocatorDump(dump_name);
return dump;
}
base::trace_event::ProcessMemoryDump* pmd_;
uint64_t share_group_tracing_guid_;
DISALLOW_COPY_AND_ASSIGN(SkiaGpuTraceMemoryDump);
};
} // namespace
namespace ui { namespace ui {
ContextProviderCommandBuffer::ContextProviderCommandBuffer( ContextProviderCommandBuffer::ContextProviderCommandBuffer(
...@@ -538,9 +440,8 @@ bool ContextProviderCommandBuffer::OnMemoryDump( ...@@ -538,9 +440,8 @@ bool ContextProviderCommandBuffer::OnMemoryDump(
if (gr_context_) { if (gr_context_) {
context_thread_checker_.DetachFromThread(); context_thread_checker_.DetachFromThread();
SkiaGpuTraceMemoryDump trace_memory_dump( gpu::raster::DumpGrMemoryStatistics(gr_context_->get(), pmd,
pmd, gles2_impl_->ShareGroupTracingGUID()); gles2_impl_->ShareGroupTracingGUID());
gr_context_->get()->dumpMemoryStatistics(&trace_memory_dump);
context_thread_checker_.DetachFromThread(); context_thread_checker_.DetachFromThread();
} }
return true; return true;
......
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