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:
parent
a59af6e4f2
commit
a9ac0ce55d
@ -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",
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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};
|
||||
|
60
tests/GrGlyphVectorTest.cpp
Normal file
60
tests/GrGlyphVectorTest.cpp
Normal 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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user