blob: 9e583d77ab99d8976358a31b6fd72534d96071e1 [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "gpu/command_buffer/service/gpu_command_buffer_memory_tracker.h"
#include <utility>
#include "base/bind.h"
#include "base/metrics/histogram_macros.h"
// Macro to reduce code duplication when logging memory in
// GpuCommandBufferMemoryTracker. This is needed as the UMA_HISTOGRAM_* macros
// require a unique call-site per histogram (you can't funnel multiple strings
// into the same call-site).
#define GPU_COMMAND_BUFFER_MEMORY_BLOCK(category) \
do { \
size_t mb_used = size_ / (1024 * 1024); \
switch (context_type_) { \
case CONTEXT_TYPE_WEBGL1: \
case CONTEXT_TYPE_WEBGL2: \
case CONTEXT_TYPE_WEBGL2_COMPUTE: \
UMA_HISTOGRAM_MEMORY_LARGE_MB("GPU.ContextMemory.WebGL." category, \
mb_used); \
break; \
case CONTEXT_TYPE_OPENGLES2: \
case CONTEXT_TYPE_OPENGLES3: \
UMA_HISTOGRAM_MEMORY_LARGE_MB("GPU.ContextMemory.GLES." category, \
mb_used); \
break; \
case CONTEXT_TYPE_WEBGPU: \
break; \
} \
} while (false)
namespace gpu {
GpuCommandBufferMemoryTracker::GpuCommandBufferMemoryTracker(
int client_id,
uint64_t client_tracing_id,
uint64_t context_group_tracing_id,
ContextType context_type,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
: client_id_(client_id),
client_tracing_id_(client_tracing_id),
context_group_tracing_id_(context_group_tracing_id),
context_type_(context_type),
memory_pressure_listener_(base::BindRepeating(
&GpuCommandBufferMemoryTracker::LogMemoryStatsPressure,
base::Unretained(this))) {
// Set up |memory_stats_timer_| to call LogMemoryPeriodic periodically
// via the provided |task_runner|.
memory_stats_timer_.SetTaskRunner(std::move(task_runner));
memory_stats_timer_.Start(
FROM_HERE, base::TimeDelta::FromSeconds(30), this,
&GpuCommandBufferMemoryTracker::LogMemoryStatsPeriodic);
}
GpuCommandBufferMemoryTracker::~GpuCommandBufferMemoryTracker() {
LogMemoryStatsShutdown();
}
void GpuCommandBufferMemoryTracker::TrackMemoryAllocatedChange(uint64_t delta) {
size_ += delta;
}
uint64_t GpuCommandBufferMemoryTracker::GetSize() const {
return size_;
}
uint64_t GpuCommandBufferMemoryTracker::ClientTracingId() const {
return client_tracing_id_;
}
int GpuCommandBufferMemoryTracker::ClientId() const {
return client_id_;
}
uint64_t GpuCommandBufferMemoryTracker::ContextGroupTracingId() const {
return context_group_tracing_id_;
}
void GpuCommandBufferMemoryTracker::LogMemoryStatsPeriodic() {
GPU_COMMAND_BUFFER_MEMORY_BLOCK("Periodic");
}
void GpuCommandBufferMemoryTracker::LogMemoryStatsShutdown() {
GPU_COMMAND_BUFFER_MEMORY_BLOCK("Shutdown");
}
void GpuCommandBufferMemoryTracker::LogMemoryStatsPressure(
base::MemoryPressureListener::MemoryPressureLevel pressure_level) {
// Only log on CRITICAL memory pressure.
if (pressure_level ==
base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) {
GPU_COMMAND_BUFFER_MEMORY_BLOCK("Pressure");
}
}
} // namespace gpu