Add initializer class to improve safety of AllocateClassMemoryAndArena

Change-Id: If5f14828029473afef25c5ef69db3971796cdfc4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/537076
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
This commit is contained in:
Herb Derby 2022-05-04 09:00:23 -04:00 committed by SkCQ
parent ad09d4b41d
commit 33583b9c36
3 changed files with 33 additions and 25 deletions

View File

@ -165,6 +165,21 @@ private:
SkFibBlockSizes<kMaxByteSize> fFibProgression;
};
template <typename T>
class GrSubRunInitializer {
public:
GrSubRunInitializer(void* memory) : fMemory{memory} { SkASSERT(memory != nullptr); }
template <typename... Args>
T* initialize(Args&&... args) {
// Warn on more than one initialization.
SkASSERT(fMemory != nullptr);
return new (std::exchange(fMemory, nullptr)) T(std::forward<Args>(args)...);
}
private:
void* fMemory;
};
// GrSubRunAllocator provides fast allocation where the user takes care of calling the destructors
// of the returned pointers, and GrSubRunAllocator takes care of deleting the storage. The
// unique_ptrs returned, are to assist in assuring the object's destructor is called.
@ -196,7 +211,7 @@ public:
GrSubRunAllocator& operator=(GrSubRunAllocator&&) = default;
template <typename T>
static std::tuple<void *, int, GrSubRunAllocator>
static std::tuple<GrSubRunInitializer<T>, int, GrSubRunAllocator>
AllocateClassMemoryAndArena(int allocSizeHint) {
SkASSERT_RELEASE(allocSizeHint >= 0);
// Round the size after the object the optimal amount.

View File

@ -2178,13 +2178,11 @@ sk_sp<GrTextBlob> GrTextBlob::Make(const SkGlyphRunList& glyphRunList,
+ GrGlyphVector::GlyphVectorSize(totalGlyphCount)
+ glyphRunList.runCount() * (sizeof(DirectMaskSubRun) + vertexDataToSubRunPadding);
auto [memory, totalMemoryAllocated, alloc] =
auto [initializer, totalMemoryAllocated, alloc] =
GrSubRunAllocator::AllocateClassMemoryAndArena<GrTextBlob>(subRunSizeHint);
SkColor initialLuminance = SkPaintPriv::ComputeLuminanceColor(paint);
sk_sp<GrTextBlob> blob{new (memory) GrTextBlob(std::move(alloc),
totalMemoryAllocated,
positionMatrix,
initialLuminance)};
sk_sp<GrTextBlob> blob = sk_sp<GrTextBlob>(initializer.initialize(
std::move(alloc), totalMemoryAllocated, positionMatrix, initialLuminance));
const uint64_t uniqueID = glyphRunList.uniqueID();
for (auto& glyphRun : glyphRunList) {
@ -2451,13 +2449,11 @@ sk_sp<GrSlug> Slug::MakeFromBuffer(SkReadBuffer& buffer, const SkStrikeClient* c
subRunsSizeHint = 128;
}
auto [memory, _, alloc] = GrSubRunAllocator::AllocateClassMemoryAndArena<Slug>(subRunsSizeHint);
auto [initializer, _, alloc] =
GrSubRunAllocator::AllocateClassMemoryAndArena<Slug>(subRunsSizeHint);
sk_sp<Slug> slug{new (memory) Slug(std::move(alloc),
sourceBounds,
paint,
positionMatrix,
origin)};
sk_sp<Slug> slug = sk_sp<Slug>(
initializer.initialize(std::move(alloc), sourceBounds, paint, positionMatrix, origin));
for (int i = 0; i < subRunCount; ++i) {
auto subRun = GrSubRun::MakeFromBuffer(slug.get(), buffer, &slug->fAlloc, client);
@ -2474,8 +2470,6 @@ sk_sp<GrSlug> Slug::MakeFromBuffer(SkReadBuffer& buffer, const SkStrikeClient* c
return std::move(slug);
}
void Slug::processDeviceMasks(
const SkZip<SkGlyphVariant, SkPoint>& accepted, sk_sp<SkStrike>&& strike) {
auto addGlyphsWithSameFormat = [&] (const SkZip<SkGlyphVariant, SkPoint>& accepted,
@ -2508,16 +2502,15 @@ sk_sp<Slug> Slug::Make(const SkMatrixProvider& viewMatrix,
+ GrGlyphVector::GlyphVectorSize(totalGlyphCount)
+ glyphRunList.runCount() * (sizeof(DirectMaskSubRun) + vertexDataToSubRunPadding);
auto [memory, _, alloc] = GrSubRunAllocator::AllocateClassMemoryAndArena<Slug>(subRunSizeHint);
auto [initializer, _, alloc] =
GrSubRunAllocator::AllocateClassMemoryAndArena<Slug>(subRunSizeHint);
const SkMatrix positionMatrix =
position_matrix(viewMatrix.localToDevice(), glyphRunList.origin());
sk_sp<Slug> slug{new (memory) Slug(std::move(alloc),
glyphRunList.sourceBounds(),
initialPaint,
positionMatrix,
glyphRunList.origin())};
sk_sp<Slug> slug = sk_sp<Slug>(initializer.initialize(
std::move(alloc), glyphRunList.sourceBounds(), initialPaint, positionMatrix,
glyphRunList.origin()));
const uint64_t uniqueID = glyphRunList.uniqueID();
for (auto& glyphRun : glyphRunList) {

View File

@ -230,6 +230,11 @@ public:
const GrSDFTControl& control,
SkGlyphRunListPainter* painter);
GrTextBlob(GrSubRunAllocator&& alloc,
int totalMemorySize,
const SkMatrix& positionMatrix,
SkColor initialLuminance);
~GrTextBlob() override;
// Change memory management to handle the data after GrTextBlob, but in the same allocation
@ -258,11 +263,6 @@ public:
const GrAtlasSubRun* testingOnlyFirstSubRun() const;
private:
GrTextBlob(GrSubRunAllocator&& alloc,
int totalMemorySize,
const SkMatrix& positionMatrix,
SkColor initialLuminance);
// Methods to satisfy SkGlyphRunPainterInterface
void processDeviceMasks(const SkZip<SkGlyphVariant, SkPoint>& accepted,
sk_sp<SkStrike>&& strike) override;