gecko-dev/dom/canvas/WebGLMemoryTracker.cpp
Morris Tseng d5147a9b2a Bug 709490 - Part 2: Introduce OffscreenCanvas and let WebGL context work on workers. r=nical, r=jgilbert, r=jrmuizel, sr=ehsan
Thanks Jon Morton [:jmorton] (jonanin@gmail.com) for polishing patches.

--HG--
extra : rebase_source : ce16acdc340cbe67102da651552f574eee897ca9
2015-10-12 11:21:03 +08:00

274 lines
8.2 KiB
C++

/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLMemoryTracker.h"
#include "WebGLBuffer.h"
#include "WebGLContext.h"
#include "WebGLVertexAttribData.h"
#include "WebGLProgram.h"
#include "WebGLRenderbuffer.h"
#include "WebGLShader.h"
#include "WebGLTexture.h"
#include "WebGLUniformLocation.h"
namespace mozilla {
NS_IMETHODIMP
WebGLMemoryTracker::CollectReports(nsIHandleReportCallback* handleReport,
nsISupports* data, bool)
{
#define REPORT(_path, _kind, _units, _amount, _desc) \
do { \
nsresult rv; \
rv = handleReport->Callback(EmptyCString(), NS_LITERAL_CSTRING(_path), \
_kind, _units, _amount, \
NS_LITERAL_CSTRING(_desc), data); \
NS_ENSURE_SUCCESS(rv, rv); \
} while (0)
REPORT("webgl-texture-memory",
KIND_OTHER, UNITS_BYTES, GetTextureMemoryUsed(),
"Memory used by WebGL textures.The OpenGL"
" implementation is free to store these textures in either video"
" memory or main memory. This measurement is only a lower bound,"
" actual memory usage may be higher for example if the storage"
" is strided.");
REPORT("webgl-texture-count",
KIND_OTHER, UNITS_COUNT, GetTextureCount(),
"Number of WebGL textures.");
REPORT("webgl-buffer-memory",
KIND_OTHER, UNITS_BYTES, GetBufferMemoryUsed(),
"Memory used by WebGL buffers. The OpenGL"
" implementation is free to store these buffers in either video"
" memory or main memory. This measurement is only a lower bound,"
" actual memory usage may be higher for example if the storage"
" is strided.");
REPORT("explicit/webgl/buffer-cache-memory",
KIND_HEAP, UNITS_BYTES, GetBufferCacheMemoryUsed(),
"Memory used by WebGL buffer caches. The WebGL"
" implementation caches the contents of element array buffers"
" only.This adds up with the webgl-buffer-memory value, but"
" contrary to it, this one represents bytes on the heap,"
" not managed by OpenGL.");
REPORT("webgl-buffer-count",
KIND_OTHER, UNITS_COUNT, GetBufferCount(),
"Number of WebGL buffers.");
REPORT("webgl-renderbuffer-memory",
KIND_OTHER, UNITS_BYTES, GetRenderbufferMemoryUsed(),
"Memory used by WebGL renderbuffers. The OpenGL"
" implementation is free to store these renderbuffers in either"
" video memory or main memory. This measurement is only a lower"
" bound, actual memory usage may be higher for example if the"
" storage is strided.");
REPORT("webgl-renderbuffer-count",
KIND_OTHER, UNITS_COUNT, GetRenderbufferCount(),
"Number of WebGL renderbuffers.");
REPORT("explicit/webgl/shader",
KIND_HEAP, UNITS_BYTES, GetShaderSize(),
"Combined size of WebGL shader ASCII sources and translation"
" logs cached on the heap.");
REPORT("webgl-shader-count",
KIND_OTHER, UNITS_COUNT, GetShaderCount(),
"Number of WebGL shaders.");
REPORT("webgl-context-count",
KIND_OTHER, UNITS_COUNT, GetContextCount(),
"Number of WebGL contexts.");
#undef REPORT
return NS_OK;
}
NS_IMPL_ISUPPORTS(WebGLMemoryTracker, nsIMemoryReporter)
StaticRefPtr<WebGLMemoryTracker> WebGLMemoryTracker::sUniqueInstance;
WebGLMemoryTracker*
WebGLMemoryTracker::UniqueInstance()
{
if (!sUniqueInstance) {
sUniqueInstance = new WebGLMemoryTracker;
sUniqueInstance->InitMemoryReporter();
}
return sUniqueInstance;
}
WebGLMemoryTracker::WebGLMemoryTracker()
{
}
void
WebGLMemoryTracker::InitMemoryReporter()
{
RegisterWeakMemoryReporter(this);
}
WebGLMemoryTracker::~WebGLMemoryTracker()
{
UnregisterWeakMemoryReporter(this);
}
MOZ_DEFINE_MALLOC_SIZE_OF(WebGLBufferMallocSizeOf)
int64_t
WebGLMemoryTracker::GetBufferCacheMemoryUsed()
{
const ContextsArrayType& contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLBuffer* buffer = contexts[i]->mBuffers.getFirst();
buffer;
buffer = buffer->getNext())
{
if (buffer->Content() == WebGLBuffer::Kind::ElementArray) {
result += buffer->SizeOfIncludingThis(WebGLBufferMallocSizeOf);
}
}
}
return result;
}
MOZ_DEFINE_MALLOC_SIZE_OF(WebGLShaderMallocSizeOf)
int64_t
WebGLMemoryTracker::GetShaderSize()
{
const ContextsArrayType& contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLShader* shader = contexts[i]->mShaders.getFirst();
shader;
shader = shader->getNext())
{
result += shader->SizeOfIncludingThis(WebGLShaderMallocSizeOf);
}
}
return result;
}
/*static*/ int64_t
WebGLMemoryTracker::GetTextureMemoryUsed()
{
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLTexture* texture = contexts[i]->mTextures.getFirst();
texture;
texture = texture->getNext())
{
result += texture->MemoryUsage();
}
}
return result;
}
/*static*/ int64_t
WebGLMemoryTracker::GetTextureCount()
{
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLTexture* texture = contexts[i]->mTextures.getFirst();
texture;
texture = texture->getNext())
{
result++;
}
}
return result;
}
/*static*/ int64_t
WebGLMemoryTracker::GetBufferMemoryUsed()
{
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLBuffer* buffer = contexts[i]->mBuffers.getFirst();
buffer;
buffer = buffer->getNext())
{
result += buffer->ByteLength();
}
}
return result;
}
/*static*/ int64_t
WebGLMemoryTracker::GetBufferCount()
{
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLBuffer* buffer = contexts[i]->mBuffers.getFirst();
buffer;
buffer = buffer->getNext())
{
result++;
}
}
return result;
}
/*static*/ int64_t
WebGLMemoryTracker::GetRenderbufferMemoryUsed()
{
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLRenderbuffer* rb = contexts[i]->mRenderbuffers.getFirst();
rb;
rb = rb->getNext())
{
result += rb->MemoryUsage();
}
}
return result;
}
/*static*/ int64_t
WebGLMemoryTracker::GetRenderbufferCount()
{
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLRenderbuffer* rb = contexts[i]->mRenderbuffers.getFirst();
rb;
rb = rb->getNext())
{
result++;
}
}
return result;
}
/*static*/ int64_t
WebGLMemoryTracker::GetShaderCount()
{
const ContextsArrayType & contexts = Contexts();
int64_t result = 0;
for(size_t i = 0; i < contexts.Length(); ++i) {
for (const WebGLShader* shader = contexts[i]->mShaders.getFirst();
shader;
shader = shader->getNext())
{
result++;
}
}
return result;
}
} // namespace mozilla