Commit 81a71217 authored by Khushal's avatar Khushal Committed by Commit Bot

gpu: Add memory tracing for ServiceTransferCache.

Add memory dumps for ServiceTransferCache. Note that this is expected to
come up as a regression in memory reported by the GPU process since this
data was not being reported until now.

R=ericrk@chromium.org

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;master.tryserver.blink:linux_trusty_blink_rel
Change-Id: I03de3eef4ef688b62b4714897c1f301f98d63e74
Reviewed-on: https://chromium-review.googlesource.com/1125524Reviewed-by: default avatarEric Karl <ericrk@chromium.org>
Commit-Queue: Khushal <khushalsagar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#573496}
parent a8ba451f
...@@ -132,8 +132,8 @@ bool ServiceImageTransferCacheEntry::Deserialize( ...@@ -132,8 +132,8 @@ bool ServiceImageTransferCacheEntry::Deserialize(
// Depending on whether the pixmap will fit in a GPU texture, either create // Depending on whether the pixmap will fit in a GPU texture, either create
// a software or GPU SkImage. // a software or GPU SkImage.
uint32_t max_size = context->maxTextureSize(); uint32_t max_size = context->maxTextureSize();
bool fits_on_gpu = width <= max_size && height <= max_size; fits_on_gpu_ = width <= max_size && height <= max_size;
if (fits_on_gpu) { if (fits_on_gpu_) {
sk_sp<SkImage> image = SkImage::MakeFromRaster(pixmap, nullptr, nullptr); sk_sp<SkImage> image = SkImage::MakeFromRaster(pixmap, nullptr, nullptr);
if (!image) if (!image)
return false; return false;
......
...@@ -56,11 +56,13 @@ class CC_PAINT_EXPORT ServiceImageTransferCacheEntry ...@@ -56,11 +56,13 @@ class CC_PAINT_EXPORT ServiceImageTransferCacheEntry
size_t CachedSize() const final; size_t CachedSize() const final;
bool Deserialize(GrContext* context, base::span<const uint8_t> data) final; bool Deserialize(GrContext* context, base::span<const uint8_t> data) final;
bool fits_on_gpu() const { return fits_on_gpu_; }
const sk_sp<SkImage>& image() { return image_; } const sk_sp<SkImage>& image() { return image_; }
private: private:
sk_sp<SkImage> image_; sk_sp<SkImage> image_;
size_t size_ = 0; size_t size_ = 0;
bool fits_on_gpu_ = false;
}; };
} // namespace cc } // namespace cc
......
...@@ -4,9 +4,14 @@ ...@@ -4,9 +4,14 @@
#include "gpu/command_buffer/service/service_transfer_cache.h" #include "gpu/command_buffer/service/service_transfer_cache.h"
#include <inttypes.h>
#include "base/bind.h" #include "base/bind.h"
#include "base/memory/memory_coordinator_client_registry.h" #include "base/memory/memory_coordinator_client_registry.h"
#include "base/strings/stringprintf.h"
#include "base/sys_info.h" #include "base/sys_info.h"
#include "base/trace_event/memory_dump_manager.h"
#include "cc/paint/image_transfer_cache_entry.h"
namespace gpu { namespace gpu {
namespace { namespace {
...@@ -51,10 +56,19 @@ ServiceTransferCache::ServiceTransferCache() ...@@ -51,10 +56,19 @@ ServiceTransferCache::ServiceTransferCache()
base::BindRepeating(&ServiceTransferCache::OnMemoryPressure, base::BindRepeating(&ServiceTransferCache::OnMemoryPressure,
base::Unretained(this))) { base::Unretained(this))) {
base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this); base::MemoryCoordinatorClientRegistry::GetInstance()->Register(this);
// In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview).
// Don't register a dump provider in these cases.
if (base::ThreadTaskRunnerHandle::IsSet()) {
base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider(
this, "cc::GpuImageDecodeCache", base::ThreadTaskRunnerHandle::Get());
}
} }
ServiceTransferCache::~ServiceTransferCache() { ServiceTransferCache::~ServiceTransferCache() {
base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this); base::MemoryCoordinatorClientRegistry::GetInstance()->Unregister(this);
base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider(
this);
} }
bool ServiceTransferCache::CreateLockedEntry( bool ServiceTransferCache::CreateLockedEntry(
...@@ -166,4 +180,49 @@ void ServiceTransferCache::OnPurgeMemory() { ...@@ -166,4 +180,49 @@ void ServiceTransferCache::OnPurgeMemory() {
cache_size_limit_ = CacheSizeLimit(memory_state_); cache_size_limit_ = CacheSizeLimit(memory_state_);
} }
bool ServiceTransferCache::OnMemoryDump(
const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) {
using base::trace_event::MemoryAllocatorDump;
using base::trace_event::MemoryAllocatorDumpGuid;
using base::trace_event::MemoryDumpLevelOfDetail;
if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) {
std::string dump_name =
base::StringPrintf("gpu/transfer_cache/cache_0x%" PRIXPTR,
reinterpret_cast<uintptr_t>(this));
MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(dump_name);
dump->AddScalar(MemoryAllocatorDump::kNameSize,
MemoryAllocatorDump::kUnitsBytes, total_size_);
// Early out, no need for more detail in a BACKGROUND dump.
return true;
}
for (auto it = entries_.begin(); it != entries_.end(); it++) {
uint32_t entry_id = it->first.second;
auto entry_type = it->first.first;
const auto* entry = it->second.entry.get();
std::string dump_name;
if (entry_type == cc::TransferCacheEntryType::kImage &&
static_cast<const cc::ServiceImageTransferCacheEntry*>(entry)
->fits_on_gpu()) {
dump_name = base::StringPrintf(
"gpu/transfer_cache/cache_0x%" PRIXPTR "/gpu/entry_%d",
reinterpret_cast<uintptr_t>(this), entry_id);
} else {
dump_name = base::StringPrintf(
"gpu/transfer_cache/cache_0x%" PRIXPTR "/cpu/entry_%d",
reinterpret_cast<uintptr_t>(this), entry_id);
}
MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(dump_name);
dump->AddScalar(MemoryAllocatorDump::kNameSize,
MemoryAllocatorDump::kUnitsBytes, entry->CachedSize());
}
return true;
}
} // namespace gpu } // namespace gpu
...@@ -27,7 +27,8 @@ namespace gpu { ...@@ -27,7 +27,8 @@ namespace gpu {
// cache limits. If the cache exceeds its specified limits, unlocked transfer // cache limits. If the cache exceeds its specified limits, unlocked transfer
// cache entries may be deleted. // cache entries may be deleted.
class GPU_GLES2_EXPORT ServiceTransferCache class GPU_GLES2_EXPORT ServiceTransferCache
: public base::MemoryCoordinatorClient { : public base::MemoryCoordinatorClient,
public base::trace_event::MemoryDumpProvider {
public: public:
ServiceTransferCache(); ServiceTransferCache();
~ServiceTransferCache() override; ~ServiceTransferCache() override;
...@@ -48,6 +49,10 @@ class GPU_GLES2_EXPORT ServiceTransferCache ...@@ -48,6 +49,10 @@ class GPU_GLES2_EXPORT ServiceTransferCache
void OnMemoryStateChange(base::MemoryState state) override; void OnMemoryStateChange(base::MemoryState state) override;
void OnPurgeMemory() override; void OnPurgeMemory() override;
// base::trace_event::MemoryDumpProvider implementation.
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) override;
// Test-only functions: // Test-only functions:
void SetCacheSizeLimitForTesting(size_t cache_size_limit) { void SetCacheSizeLimitForTesting(size_t cache_size_limit) {
cache_size_limit_ = cache_size_limit; cache_size_limit_ = cache_size_limit;
......
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