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