Bug 1622408 [wpt PR 22244] - Restore the event delegate for a CSSTransition after...
[gecko.git] / image / ImageMemoryReporter.cpp
blob573d0ddc8a910a6531fa18484b7a5fdad7a84777
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ImageMemoryReporter.h"
8 #include "Image.h"
9 #include "mozilla/layers/SharedSurfacesParent.h"
10 #include "mozilla/StaticPrefs_image.h"
11 #include "nsIMemoryReporter.h"
12 #include "nsISupportsImpl.h"
14 namespace mozilla {
15 namespace image {
17 ImageMemoryReporter::WebRenderReporter* ImageMemoryReporter::sWrReporter;
19 class ImageMemoryReporter::WebRenderReporter final : public nsIMemoryReporter {
20 public:
21 NS_DECL_ISUPPORTS
23 WebRenderReporter() {}
25 NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
26 nsISupports* aData, bool aAnonymize) override {
27 layers::SharedSurfacesMemoryReport report;
28 layers::SharedSurfacesParent::AccumulateMemoryReport(report);
29 ReportSharedSurfaces(aHandleReport, aData, /* aIsForCompositor */ true,
30 report);
31 return NS_OK;
34 private:
35 virtual ~WebRenderReporter() {}
38 NS_IMPL_ISUPPORTS(ImageMemoryReporter::WebRenderReporter, nsIMemoryReporter)
40 /* static */
41 void ImageMemoryReporter::InitForWebRender() {
42 MOZ_ASSERT(XRE_IsParentProcess() || XRE_IsGPUProcess());
43 if (!sWrReporter) {
44 sWrReporter = new WebRenderReporter();
45 RegisterStrongMemoryReporter(sWrReporter);
49 /* static */
50 void ImageMemoryReporter::ShutdownForWebRender() {
51 MOZ_ASSERT(XRE_IsParentProcess() || XRE_IsGPUProcess());
52 if (sWrReporter) {
53 UnregisterStrongMemoryReporter(sWrReporter);
54 sWrReporter = nullptr;
58 /* static */
59 void ImageMemoryReporter::ReportSharedSurfaces(
60 nsIHandleReportCallback* aHandleReport, nsISupports* aData,
61 const layers::SharedSurfacesMemoryReport& aSharedSurfaces) {
62 ReportSharedSurfaces(aHandleReport, aData,
63 /* aIsForCompositor */ false, aSharedSurfaces);
66 /* static */
67 void ImageMemoryReporter::ReportSharedSurfaces(
68 nsIHandleReportCallback* aHandleReport, nsISupports* aData,
69 bool aIsForCompositor,
70 const layers::SharedSurfacesMemoryReport& aSharedSurfaces) {
71 MOZ_ASSERT_IF(aIsForCompositor, XRE_IsParentProcess() || XRE_IsGPUProcess());
72 MOZ_ASSERT_IF(!aIsForCompositor,
73 XRE_IsParentProcess() || XRE_IsContentProcess());
75 for (auto i = aSharedSurfaces.mSurfaces.begin();
76 i != aSharedSurfaces.mSurfaces.end(); ++i) {
77 ReportSharedSurface(aHandleReport, aData, aIsForCompositor, i->first,
78 i->second);
82 /* static */
83 void ImageMemoryReporter::ReportSharedSurface(
84 nsIHandleReportCallback* aHandleReport, nsISupports* aData,
85 bool aIsForCompositor, uint64_t aExternalId,
86 const layers::SharedSurfacesMemoryReport::SurfaceEntry& aEntry) {
87 nsAutoCString path;
88 if (aIsForCompositor) {
89 path.AppendLiteral("gfx/webrender/images/mapped_from_owner/");
90 } else {
91 path.AppendLiteral("gfx/webrender/images/owner_cache_missing/");
94 if (aIsForCompositor) {
95 path.AppendLiteral("pid=");
96 path.AppendInt(uint32_t(aEntry.mCreatorPid));
97 path.AppendLiteral("/");
100 if (StaticPrefs::image_mem_debug_reporting()) {
101 path.AppendInt(aExternalId, 16);
102 path.AppendLiteral("/");
105 path.AppendLiteral("image(");
106 path.AppendInt(aEntry.mSize.width);
107 path.AppendLiteral("x");
108 path.AppendInt(aEntry.mSize.height);
109 path.AppendLiteral(", compositor_ref:");
110 path.AppendInt(aEntry.mConsumers);
111 path.AppendLiteral(", creator_ref:");
112 path.AppendInt(aEntry.mCreatorRef);
113 path.AppendLiteral(")/decoded-nonheap");
115 size_t surfaceSize = mozilla::ipc::SharedMemory::PageAlignedSize(
116 aEntry.mSize.height * aEntry.mStride);
118 // If this memory has already been reported elsewhere (e.g. as part of our
119 // explicit section in the surface cache), we don't want report it again as
120 // KIND_NONHEAP and have it counted again.
121 bool sameProcess = aEntry.mCreatorPid == base::GetCurrentProcId();
122 int32_t kind = aIsForCompositor && !sameProcess
123 ? nsIMemoryReporter::KIND_NONHEAP
124 : nsIMemoryReporter::KIND_OTHER;
126 NS_NAMED_LITERAL_CSTRING(desc, "Decoded image data stored in shared memory.");
127 aHandleReport->Callback(EmptyCString(), path, kind,
128 nsIMemoryReporter::UNITS_BYTES, surfaceSize, desc,
129 aData);
132 /* static */
133 void ImageMemoryReporter::AppendSharedSurfacePrefix(
134 nsACString& aPathPrefix, const SurfaceMemoryCounter& aCounter,
135 layers::SharedSurfacesMemoryReport& aSharedSurfaces) {
136 uint64_t extId = aCounter.Values().ExternalId();
137 if (extId) {
138 auto gpuEntry = aSharedSurfaces.mSurfaces.find(extId);
140 if (StaticPrefs::image_mem_debug_reporting()) {
141 aPathPrefix.AppendLiteral(", external_id:");
142 aPathPrefix.AppendInt(extId, 16);
143 if (gpuEntry != aSharedSurfaces.mSurfaces.end()) {
144 aPathPrefix.AppendLiteral(", compositor_ref:");
145 aPathPrefix.AppendInt(gpuEntry->second.mConsumers);
146 } else {
147 aPathPrefix.AppendLiteral(", compositor_ref:missing");
151 if (gpuEntry != aSharedSurfaces.mSurfaces.end()) {
152 MOZ_ASSERT(gpuEntry->second.mCreatorRef);
153 aSharedSurfaces.mSurfaces.erase(gpuEntry);
158 /* static */
159 void ImageMemoryReporter::TrimSharedSurfaces(
160 const ImageMemoryCounter& aCounter,
161 layers::SharedSurfacesMemoryReport& aSharedSurfaces) {
162 if (aSharedSurfaces.mSurfaces.empty()) {
163 return;
166 for (const SurfaceMemoryCounter& counter : aCounter.Surfaces()) {
167 uint64_t extId = counter.Values().ExternalId();
168 if (extId) {
169 auto gpuEntry = aSharedSurfaces.mSurfaces.find(extId);
170 if (gpuEntry != aSharedSurfaces.mSurfaces.end()) {
171 MOZ_ASSERT(gpuEntry->second.mCreatorRef);
172 aSharedSurfaces.mSurfaces.erase(gpuEntry);
178 } // namespace image
179 } // namespace mozilla