Files
tubestation/gfx/2d/SourceSurfaceRawData.cpp
Brad Werth b82c56561d Bug 1905674: Create an aggregate memory reporter for SourceSurfaceRawData. r=gfx-reviewers,lsalzman
This aggregates all SourceSurfaceAlignedRawdata into a single line item
of "explicit/gfx/source-surface-aligned-raw-data". If we want to get
more granular, we just need to decide if we split by SurfaceFormat, by
size buckets, or whatever.

I've confirmed this measures the memory held by the reproduction case in
Bug 1904048, which was the motivation for this issue.

Differential Revision: https://phabricator.services.mozilla.com/D217181
2024-07-24 20:10:42 +00:00

116 lines
3.8 KiB
C++

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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 "SourceSurfaceRawData.h"
#include "DataSurfaceHelpers.h"
#include "Logging.h"
#include "mozilla/Types.h" // for decltype
#include "nsIMemoryReporter.h"
namespace mozilla {
namespace gfx {
class SourceSurfaceAlignedRawDataReporter final : public nsIMemoryReporter {
~SourceSurfaceAlignedRawDataReporter() = default;
public:
NS_DECL_ISUPPORTS
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData, bool aAnonymize) override {
MOZ_COLLECT_REPORT("explicit/gfx/source-surface-aligned-raw-data",
KIND_HEAP, UNITS_BYTES, sTotalDataBytes,
"Total memory used by source surface aligned raw data.");
return NS_OK;
}
private:
friend class SourceSurfaceAlignedRawData;
static Atomic<size_t> sTotalDataBytes;
};
NS_IMPL_ISUPPORTS(SourceSurfaceAlignedRawDataReporter, nsIMemoryReporter)
/* static */
Atomic<size_t> SourceSurfaceAlignedRawDataReporter::sTotalDataBytes(0);
/* static */
void SourceSurfaceAlignedRawData::RegisterMemoryReporter() {
RegisterStrongMemoryReporter(new SourceSurfaceAlignedRawDataReporter);
}
void SourceSurfaceRawData::InitWrappingData(
uint8_t* aData, const IntSize& aSize, int32_t aStride,
SurfaceFormat aFormat, Factory::SourceSurfaceDeallocator aDeallocator,
void* aClosure) {
mRawData = aData;
mSize = aSize;
mStride = aStride;
mFormat = aFormat;
mDeallocator = aDeallocator;
mClosure = aClosure;
}
void SourceSurfaceRawData::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf,
SizeOfInfo& aInfo) const {
aInfo.AddType(SurfaceType::DATA);
if (mDeallocator) {
aInfo.mUnknownBytes = mStride * mSize.height;
}
}
SourceSurfaceAlignedRawData::SourceSurfaceAlignedRawData()
: mStride(0), mFormat(SurfaceFormat::UNKNOWN) {}
SourceSurfaceAlignedRawData::~SourceSurfaceAlignedRawData() {
size_t bufLen = BufferSizeFromStrideAndHeight(mStride, mSize.height);
SourceSurfaceAlignedRawDataReporter::sTotalDataBytes -= bufLen;
}
bool SourceSurfaceAlignedRawData::Init(const IntSize& aSize,
SurfaceFormat aFormat, bool aClearMem,
uint8_t aClearValue, int32_t aStride) {
mFormat = aFormat;
mStride = aStride ? aStride
: GetAlignedStride<16>(aSize.width, BytesPerPixel(aFormat));
size_t bufLen = BufferSizeFromStrideAndHeight(mStride, aSize.height);
if (bufLen > 0) {
bool zeroMem = aClearMem && !aClearValue;
static_assert(sizeof(decltype(mArray[0])) == 1,
"mArray.Realloc() takes an object count, so its objects must "
"be 1-byte sized if we use bufLen");
// AlignedArray uses cmalloc to zero mem for a fast path.
mArray.Realloc(/* actually an object count */ bufLen, zeroMem);
mSize = aSize;
SourceSurfaceAlignedRawDataReporter::sTotalDataBytes += bufLen;
if (mArray && aClearMem && aClearValue) {
memset(mArray, aClearValue, mStride * aSize.height);
}
} else {
mArray.Dealloc();
mSize.SizeTo(0, 0);
}
return mArray != nullptr;
}
void SourceSurfaceAlignedRawData::SizeOfExcludingThis(
MallocSizeOf aMallocSizeOf, SizeOfInfo& aInfo) const {
aInfo.AddType(SurfaceType::DATA_ALIGNED);
// This memory is accounted for in aggregate by sTotalDataBytes. We return
// zero here to prevent double-counting.
aInfo.mHeapBytes = 0;
}
} // namespace gfx
} // namespace mozilla