From b4ec64119bbe9f9232a08da593e04127300cce32 Mon Sep 17 00:00:00 2001 From: Kelsey Gilbert Date: Mon, 11 Mar 2024 17:37:24 +0000 Subject: [PATCH] Bug 1870585 - Add webgl::dmd_unordered_map for WebGLTexture memory reporting of cache map. r=gfx-reviewers,lsalzman,bradwerth Differential Revision: https://phabricator.services.mozilla.com/D203869 --- dom/canvas/CacheInvalidator.h | 19 ++++-- dom/canvas/DmdStdContainers.h | 100 ++++++++++++++++++++++++++++++ dom/canvas/WebGLMemoryTracker.cpp | 15 +++-- dom/canvas/WebGLShaderValidator.h | 2 +- dom/canvas/WebGLTexture.h | 8 +++ dom/canvas/moz.build | 1 + gfx/layers/BuildConstants.h | 7 +++ 7 files changed, 142 insertions(+), 10 deletions(-) create mode 100644 dom/canvas/DmdStdContainers.h diff --git a/dom/canvas/CacheInvalidator.h b/dom/canvas/CacheInvalidator.h index e63f1e4cc2ef..909aacfc378a 100644 --- a/dom/canvas/CacheInvalidator.h +++ b/dom/canvas/CacheInvalidator.h @@ -9,8 +9,7 @@ #include "mozilla/Maybe.h" #include "mozilla/UniquePtr.h" -#include -#include +#include "DmdStdContainers.h" #include // - @@ -25,7 +24,7 @@ class CacheInvalidator { friend class AbstractCache; private: - mutable std::unordered_set mCaches; + mutable webgl::dmd_unordered_set mCaches; public: virtual ~CacheInvalidator() { @@ -38,6 +37,12 @@ class CacheInvalidator { } void InvalidateCaches() const; + + // - + + size_t SizeOfExcludingThis(mozilla::MallocSizeOf mso) const { + return mCaches.SizeOfExcludingThis(mso); + } }; // - @@ -122,11 +127,15 @@ class CacheWeakMap final { } }; - using MapT = - std::unordered_map, DerefHash, DerefEqual>; + using MapT = webgl::dmd_unordered_map, + DerefHash, DerefEqual>; MapT mMap; public: + size_t SizeOfExcludingThis(mozilla::MallocSizeOf mso) const { + return mMap.SizeOfExcludingThis(mso); + } + UniquePtr MakeEntry(const KeyT& key, ValueT&& value) { return UniquePtr(new Entry(*this, key, std::move(value))); } diff --git a/dom/canvas/DmdStdContainers.h b/dom/canvas/DmdStdContainers.h new file mode 100644 index 000000000000..2975abc5800a --- /dev/null +++ b/dom/canvas/DmdStdContainers.h @@ -0,0 +1,100 @@ +/* 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/. */ + +#ifndef dom_canvas_DmdStdContainers_h +#define dom_canvas_DmdStdContainers_h + +#include "mozilla/MemoryReporting.h" +#include "mozilla/layers/BuildConstants.h" +#include +#include + +namespace mozilla::webgl { + +// - + +template +class dmd_allocator { + public: + using value_type = T; + + private: + size_t mMallocSize = 0; + + public: + dmd_allocator() = default; + + // - + + template + friend class dmd_allocator; + + template + explicit dmd_allocator(const dmd_allocator& rhs) { + if constexpr (kIsDmd) { + mMallocSize = rhs.mMallocSize; + } + } + + // - + + value_type* allocate(const size_t n) { + const auto p = std::allocator{}.allocate(n); + if constexpr (kIsDmd) { + mMallocSize += moz_malloc_size_of(p); + } + return p; + } + + void deallocate(value_type* const p, const size_t n) { + if constexpr (kIsDmd) { + mMallocSize -= moz_malloc_size_of(p); + } + std::allocator{}.deallocate(p, n); + } + + // - + + size_t SizeOfExcludingThis(mozilla::MallocSizeOf) const { + return mMallocSize; + } +}; + +// - + +template , + class KeyEqual = std::equal_to, + class Allocator = dmd_allocator>, + class _StdT = std::unordered_map> +class dmd_unordered_map : public _StdT { + public: + using StdT = _StdT; + + size_t SizeOfExcludingThis(mozilla::MallocSizeOf mso) const { + const auto& a = StdT::get_allocator(); + return a.SizeOfExcludingThis(mso); + } +}; + +// - + +template , + class KeyEqual = std::equal_to, + class Allocator = dmd_allocator, + class _StdT = std::unordered_set> +class dmd_unordered_set : public _StdT { + public: + using StdT = _StdT; + + size_t SizeOfExcludingThis(mozilla::MallocSizeOf mso) const { + const auto& a = StdT::get_allocator(); + return a.SizeOfExcludingThis(mso); + } +}; + +// - + +} // namespace mozilla::webgl + +#endif // dom_canvas_DmdStdContainers_h diff --git a/dom/canvas/WebGLMemoryTracker.cpp b/dom/canvas/WebGLMemoryTracker.cpp index 361d1be695b5..19d3847acc86 100644 --- a/dom/canvas/WebGLMemoryTracker.cpp +++ b/dom/canvas/WebGLMemoryTracker.cpp @@ -12,8 +12,9 @@ #include "WebGLTexture.h" namespace mozilla { - -MOZ_DEFINE_MALLOC_SIZE_OF(WebGLShaderMallocSizeOf) +namespace webgl { +MOZ_DEFINE_MALLOC_SIZE_OF(MallocSizeOf) +} // namespace webgl void WebGLMemoryTracker::EnsureRegistered() { static bool sIsRegistered = []() { @@ -42,6 +43,7 @@ WebGLMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport, int64_t shaderCpuSize = 0; size_t texCount = 0; + size_t texHeapOverhead = 0; int64_t texGpuSize = 0; for (const auto& context : contexts) { @@ -70,7 +72,7 @@ WebGLMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport, shaderCount += context->mShaderMap.size(); for (const auto& pair : context->mShaderMap) { const auto& shader = pair.second; - shaderCpuSize += shader->SizeOfIncludingThis(WebGLShaderMallocSizeOf); + shaderCpuSize += shader->SizeOfIncludingThis(webgl::MallocSizeOf); } // - @@ -79,6 +81,7 @@ WebGLMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport, for (const auto& pair : context->mTextureMap) { const auto& texture = pair.second; texGpuSize += texture->MemoryUsage(); + texHeapOverhead += texture->SizeOfIncludingThis(webgl::MallocSizeOf); } } @@ -126,10 +129,14 @@ WebGLMemoryTracker::CollectReports(nsIHandleReportCallback* aHandleReport, "Number of WebGL renderbuffers."); MOZ_COLLECT_REPORT( - "explicit/webgl/shader", KIND_HEAP, UNITS_BYTES, shaderCpuSize, + "explicit/webgl/shaders", KIND_HEAP, UNITS_BYTES, shaderCpuSize, "Combined size of WebGL shader ASCII sources and translation logs " "cached on the heap."); + MOZ_COLLECT_REPORT("explicit/webgl/textures", KIND_HEAP, UNITS_BYTES, + texHeapOverhead, + "WebGLTexture implementation detail overhead."); + MOZ_COLLECT_REPORT("webgl-shader-count", KIND_OTHER, UNITS_COUNT, static_cast(shaderCount), "Number of WebGL shaders."); diff --git a/dom/canvas/WebGLShaderValidator.h b/dom/canvas/WebGLShaderValidator.h index ab05528f198f..7fc700937f3a 100644 --- a/dom/canvas/WebGLShaderValidator.h +++ b/dom/canvas/WebGLShaderValidator.h @@ -39,7 +39,7 @@ class ShaderValidatorResults final { bool CanLinkTo(const ShaderValidatorResults& vert, nsCString* const out_log) const; - size_t SizeOfIncludingThis(MallocSizeOf) const; + size_t SizeOfIncludingThis(mozilla::MallocSizeOf) const; }; class ShaderValidator final { diff --git a/dom/canvas/WebGLTexture.h b/dom/canvas/WebGLTexture.h index 8a451a927765..7d75bf50f6ad 100644 --- a/dom/canvas/WebGLTexture.h +++ b/dom/canvas/WebGLTexture.h @@ -203,6 +203,14 @@ class WebGLTexture final : public WebGLContextBoundObject, ~WebGLTexture() override; public: + size_t SizeOfExcludingThis(mozilla::MallocSizeOf mso) const { + return CacheInvalidator::SizeOfExcludingThis(mso) + + mSamplingCache.SizeOfExcludingThis(mso); + } + size_t SizeOfIncludingThis(mozilla::MallocSizeOf mso) const { + return mso(this) + SizeOfExcludingThis(mso); + } + //////////////////////////////////// // GL calls bool BindTexture(TexTarget texTarget); diff --git a/dom/canvas/moz.build b/dom/canvas/moz.build index 3337e97ad9fe..3a533d36d1ef 100644 --- a/dom/canvas/moz.build +++ b/dom/canvas/moz.build @@ -52,6 +52,7 @@ EXPORTS.mozilla.dom += [ "CanvasRenderingContext2D.h", "CanvasRenderingContextHelper.h", "CanvasUtils.h", + "DmdStdContainers.h", "GeneratePlaceholderCanvasData.h", "ImageBitmap.h", "ImageBitmapRenderingContext.h", diff --git a/gfx/layers/BuildConstants.h b/gfx/layers/BuildConstants.h index 6db150d136eb..cebdd3537162 100644 --- a/gfx/layers/BuildConstants.h +++ b/gfx/layers/BuildConstants.h @@ -52,6 +52,13 @@ constexpr bool kIsAndroid = false; #endif +constexpr bool kIsDmd = +#ifdef MOZ_DMD + true; +#else + false; +#endif + } // namespace mozilla #endif // BUILD_CONSTANTS_H_