add flatten and MakeFromBuffer for GrGlyphVector

Serialize all the glyphID information for the different
sub runs.

Bug: chromium:1278340

Change-Id: I04387ffadcf5cb20fbaca17a02d7ca1faf883806
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/507318
Reviewed-by: Robert Phillips <robertphillips@google.com>
Commit-Queue: Herb Derby <herb@google.com>
This commit is contained in:
Herb Derby 2022-02-10 13:18:17 -05:00 committed by SkCQ
parent a59af6e4f2
commit a9ac0ce55d
4 changed files with 98 additions and 0 deletions

View File

@ -98,6 +98,7 @@ tests_sources = [
"$_tests/GrContextOOM.cpp",
"$_tests/GrDDLImageTest.cpp",
"$_tests/GrFinishedFlushTest.cpp",
"$_tests/GrGlyphVectorTest.cpp",
"$_tests/GrMemoryPoolTest.cpp",
"$_tests/GrOpListFlushTest.cpp",
"$_tests/GrPorterDuffTest.cpp",

View File

@ -32,6 +32,38 @@ GrGlyphVector GrGlyphVector::Make(
return GrGlyphVector{std::move(strike), SkMakeSpan(variants, glyphs.size())};
}
std::optional<GrGlyphVector> GrGlyphVector::MakeFromBuffer(SkReadBuffer& buffer,
GrSubRunAllocator* alloc) {
auto descriptor = SkAutoDescriptor::MakeFromBuffer(buffer);
if (!descriptor.has_value()) { return {}; }
sk_sp<SkStrike> strike = SkStrikeCache::GlobalStrikeCache()->findStrike(*descriptor->getDesc());
int32_t glyphCount = buffer.read32();
// Since the glyph count can never be zero. There was a buffer reading problem.
if (glyphCount == 0) { return {}; }
Variant* variants = alloc->makePODArray<Variant>(glyphCount);
for (int i = 0; i < glyphCount; i++) {
variants[i].packedGlyphID = SkPackedGlyphID(buffer.readUInt());
}
return {GrGlyphVector{std::move(strike), SkMakeSpan(variants, glyphCount)}};
}
void GrGlyphVector::flatten(SkWriteBuffer& buffer) {
// There should never be a glyph vector with zero glyphs.
SkASSERT(fGlyphs.size() != 0);
if (!fStrike) { SK_ABORT("Can't flatten with already drawn."); }
fStrike->getDescriptor().flatten(buffer);
// Write out the span of packedGlyphIDs.
buffer.write32(SkTo<int32_t>(fGlyphs.size()));
for (auto variant : fGlyphs) {
buffer.writeUInt(variant.packedGlyphID.value());
}
}
SkSpan<const GrGlyph*> GrGlyphVector::glyphs() const {
return SkMakeSpan(reinterpret_cast<const GrGlyph**>(fGlyphs.data()), fGlyphs.size());
}

View File

@ -37,6 +37,10 @@ public:
sk_sp<SkStrike>&& strike, SkSpan<SkGlyphVariant> glyphs, GrSubRunAllocator* alloc);
SkSpan<const GrGlyph*> glyphs() const;
static std::optional<GrGlyphVector> MakeFromBuffer(SkReadBuffer& buffer,
GrSubRunAllocator* alloc);
void flatten(SkWriteBuffer& buffer);
void packedGlyphIDToGrGlyph(GrStrikeCache* cache);
std::tuple<bool, int> regenerateAtlas(
@ -51,6 +55,7 @@ public:
}
private:
friend class TestingPeer;
sk_sp<SkStrike> fStrike;
SkSpan<Variant> fGlyphs;
sk_sp<GrTextStrike> fGrStrike{nullptr};

View File

@ -0,0 +1,60 @@
/*
* Copyright 2022 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "src/core/SkGlyph.h"
#include "src/gpu/GrResourceProvider.h"
#include "src/gpu/text/GrGlyphVector.h"
#include "src/core/SkGlyphBuffer.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkWriteBuffer.h"
#include "src/gpu/GrSubRunAllocator.h"
#include "tests/Test.h"
class TestingPeer {
public:
static const SkDescriptor& GetDescriptor(const GrGlyphVector& v) {
return v.fStrike->getDescriptor();
}
static SkSpan<GrGlyphVector::Variant> GetGlyphs(const GrGlyphVector& v) {
return v.fGlyphs;
}
};
DEF_TEST(GrGlyphVector_Serialization, r) {
SkFont font;
auto [strikeSpec, _] = SkStrikeSpec::MakeCanonicalized(font);
GrSubRunAllocator alloc;
SkBulkGlyphMetricsAndImages glyphFinder{strikeSpec};
const int N = 10;
SkGlyphVariant* glyphs = alloc.makePODArray<SkGlyphVariant>(N);
for (int i = 0; i < N; i++) {
glyphs[i] = glyphFinder.glyph(SkPackedGlyphID(SkTo<SkGlyphID>(i + 1)));
}
GrGlyphVector src = GrGlyphVector::Make(
strikeSpec.findOrCreateStrike(), SkMakeSpan(glyphs, N), &alloc);
SkBinaryWriteBuffer wBuffer;
src.flatten(wBuffer);
auto data = wBuffer.snapshotAsData();
SkReadBuffer rBuffer{data->data(), data->size()};
auto dst = GrGlyphVector::MakeFromBuffer(rBuffer, &alloc);
REPORTER_ASSERT(r, dst.has_value());
REPORTER_ASSERT(r, TestingPeer::GetDescriptor(src) == TestingPeer::GetDescriptor(*dst));
auto srcGlyphs = TestingPeer::GetGlyphs(src);
auto dstGlyphs = TestingPeer::GetGlyphs(*dst);
for (auto [srcGlyphID, dstGlyphID] : SkMakeZip(srcGlyphs, dstGlyphs)) {
REPORTER_ASSERT(r, srcGlyphID.packedGlyphID == dstGlyphID.packedGlyphID);
}
}