Use simple buffers instead of vectors
Start using simple buffers, these will be used for multiple runs latter on. Change-Id: Iab0559d5a47eb5e54254a985051d5d25a91be69f Reviewed-on: https://skia-review.googlesource.com/140791 Commit-Queue: Herb Derby <herb@google.com> Reviewed-by: Mike Klein <mtklein@google.com>
This commit is contained in:
parent
8b5092671b
commit
ff19d3473b
@ -131,9 +131,9 @@ const SkGlyph& SkGlyphCache::getGlyphIDMetrics(uint16_t glyphID, SkFixed x, SkFi
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SkGlyphCache::getAdvances(SkSpan<const SkGlyphID> glyphIDs, SkPoint advances[]) {
|
void SkGlyphCache::getAdvances(SkSpan<const SkGlyphID> glyphIDs, SkPoint advances[]) {
|
||||||
for (ptrdiff_t i = 0; i < glyphIDs.size(); i++) {
|
for (auto glyphID : glyphIDs) {
|
||||||
auto glyph = this->getGlyphIDAdvance(glyphIDs[i]);
|
auto glyph = this->getGlyphIDAdvance(glyphID);
|
||||||
advances[i] = SkPoint::Make(glyph.fAdvanceX, glyph.fAdvanceY);
|
*advances++ = SkPoint::Make(glyph.fAdvanceX, glyph.fAdvanceY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ SkSpan<const SkGlyphID> SkGlyphIDSet::uniquifyGlyphIDs(
|
|||||||
// If the following bzero becomes a performance problem, the memory can be marked as
|
// If the following bzero becomes a performance problem, the memory can be marked as
|
||||||
// initialized for valgrind and msan.
|
// initialized for valgrind and msan.
|
||||||
// valgrind = VALGRIND_MAKE_MEM_DEFINED(fUniverseToUnique, universeSize * sizeof(SkGlyphID))
|
// valgrind = VALGRIND_MAKE_MEM_DEFINED(fUniverseToUnique, universeSize * sizeof(SkGlyphID))
|
||||||
// msan = sk_msan_assert_initialized(fUniverseToUnique, universeSize * sizeof(SkGlyphID))
|
// msan = sk_msan_mark_initialized(fUniverseToUnique, universeSize * sizeof(SkGlyphID))
|
||||||
sk_bzero(fUniverseToUnique, universeSize * sizeof(SkGlyphID));
|
sk_bzero(fUniverseToUnique, universeSize * sizeof(SkGlyphID));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,10 +168,12 @@ SkGlyphRun* SkGlyphRunBuilder::useGlyphRun() {
|
|||||||
void SkGlyphRunBuilder::initialize(size_t totalRunSize) {
|
void SkGlyphRunBuilder::initialize(size_t totalRunSize) {
|
||||||
fUniqueID = 0;
|
fUniqueID = 0;
|
||||||
|
|
||||||
// Using resize is temporary until simpler buffers are in place.
|
if (totalRunSize > fMaxTotalRunSize) {
|
||||||
fDenseIndex.resize(totalRunSize);
|
fMaxTotalRunSize = totalRunSize;
|
||||||
fPositions.resize(totalRunSize);
|
fUniqueGlyphIDIndices.reset(fMaxTotalRunSize);
|
||||||
fUniqueGlyphIDs.resize(totalRunSize);
|
fPositions.reset(fMaxTotalRunSize);
|
||||||
|
fUniqueGlyphIDs.reset(fMaxTotalRunSize);
|
||||||
|
}
|
||||||
|
|
||||||
// Be sure to clean up the last run before we reuse it.
|
// Be sure to clean up the last run before we reuse it.
|
||||||
fScratchGlyphRun.~SkGlyphRun();
|
fScratchGlyphRun.~SkGlyphRun();
|
||||||
@ -207,7 +209,7 @@ SkSpan<const SkGlyphID> SkGlyphRunBuilder::addDenseAndUnique(
|
|||||||
// There better be glyphs in the font if we want to uniqify.
|
// There better be glyphs in the font if we want to uniqify.
|
||||||
if (glyphUniverseSize > 0) {
|
if (glyphUniverseSize > 0) {
|
||||||
uniquifiedGlyphIDs = fGlyphIDSet.uniquifyGlyphIDs(
|
uniquifiedGlyphIDs = fGlyphIDSet.uniquifyGlyphIDs(
|
||||||
glyphUniverseSize, glyphIDs, fUniqueGlyphIDs.data(), fDenseIndex.data());
|
glyphUniverseSize, glyphIDs, fUniqueGlyphIDs, fUniqueGlyphIDIndices);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,21 +220,23 @@ void SkGlyphRunBuilder::makeGlyphRun(
|
|||||||
const SkPaint& runPaint,
|
const SkPaint& runPaint,
|
||||||
SkSpan<const SkGlyphID> glyphIDs,
|
SkSpan<const SkGlyphID> glyphIDs,
|
||||||
SkSpan<const SkPoint> positions,
|
SkSpan<const SkPoint> positions,
|
||||||
|
SkSpan<const uint16_t> uniqueGlyphIDIndices,
|
||||||
|
SkSpan<const SkGlyphID> uniqueGlyphIDs,
|
||||||
SkSpan<const char> text,
|
SkSpan<const char> text,
|
||||||
SkSpan<const uint32_t> clusters) {
|
SkSpan<const uint32_t> clusters) {
|
||||||
|
|
||||||
// Ignore empty runs.
|
// Ignore empty runs.
|
||||||
if (!fDenseIndex.empty()) {
|
if (!glyphIDs.empty()) {
|
||||||
SkPaint glyphRunPaint{runPaint};
|
SkPaint glyphRunPaint{runPaint};
|
||||||
glyphRunPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
glyphRunPaint.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
|
||||||
glyphRunPaint.setTextAlign(SkPaint::kLeft_Align);
|
glyphRunPaint.setTextAlign(SkPaint::kLeft_Align);
|
||||||
|
|
||||||
new ((void*)&fScratchGlyphRun) SkGlyphRun{
|
new ((void*)&fScratchGlyphRun) SkGlyphRun{
|
||||||
std::move(glyphRunPaint),
|
std::move(glyphRunPaint),
|
||||||
SkSpan<const uint16_t>{fDenseIndex},
|
uniqueGlyphIDIndices,
|
||||||
positions,
|
positions,
|
||||||
glyphIDs,
|
glyphIDs,
|
||||||
SkSpan<const SkGlyphID>{fUniqueGlyphIDs},
|
uniqueGlyphIDs,
|
||||||
text,
|
text,
|
||||||
clusters
|
clusters
|
||||||
};
|
};
|
||||||
@ -244,10 +248,12 @@ void SkGlyphRunBuilder::drawText(
|
|||||||
SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
|
SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
|
||||||
SkASSERT(!glyphIDs.empty());
|
SkASSERT(!glyphIDs.empty());
|
||||||
|
|
||||||
|
auto runSize = glyphIDs.size();
|
||||||
|
|
||||||
auto unqiueGlyphIDs = this->addDenseAndUnique(paint, glyphIDs);
|
auto unqiueGlyphIDs = this->addDenseAndUnique(paint, glyphIDs);
|
||||||
|
|
||||||
if (!unqiueGlyphIDs.empty()) {
|
if (!unqiueGlyphIDs.empty()) {
|
||||||
fScratchAdvances.resize(fUniqueGlyphIDs.size());
|
fScratchAdvances.resize(runSize);
|
||||||
{
|
{
|
||||||
auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(paint);
|
auto cache = SkStrikeCache::FindOrCreateStrikeExclusive(paint);
|
||||||
cache->getAdvances(unqiueGlyphIDs, fScratchAdvances.data());
|
cache->getAdvances(unqiueGlyphIDs, fScratchAdvances.data());
|
||||||
@ -255,9 +261,9 @@ void SkGlyphRunBuilder::drawText(
|
|||||||
|
|
||||||
SkPoint endOfLastGlyph = origin;
|
SkPoint endOfLastGlyph = origin;
|
||||||
|
|
||||||
for (size_t i = 0; i < fDenseIndex.size(); i++) {
|
for (size_t i = 0; i < runSize; i++) {
|
||||||
fPositions[i] = endOfLastGlyph;
|
fPositions[i] = endOfLastGlyph;
|
||||||
endOfLastGlyph += fScratchAdvances[fDenseIndex[i]];
|
endOfLastGlyph += fScratchAdvances[fUniqueGlyphIDIndices[i]];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (paint.getTextAlign() != SkPaint::kLeft_Align) {
|
if (paint.getTextAlign() != SkPaint::kLeft_Align) {
|
||||||
@ -265,12 +271,20 @@ void SkGlyphRunBuilder::drawText(
|
|||||||
if (paint.getTextAlign() == SkPaint::kCenter_Align) {
|
if (paint.getTextAlign() == SkPaint::kCenter_Align) {
|
||||||
len.scale(SK_ScalarHalf);
|
len.scale(SK_ScalarHalf);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < fDenseIndex.size(); i++) {
|
for (auto& pt : SkSpan<SkPoint>{fPositions, runSize}) {
|
||||||
fPositions[i] -= len;
|
pt -= len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->makeGlyphRun(paint, glyphIDs, SkSpan<const SkPoint>{fPositions}, text, clusters);
|
|
||||||
|
this->makeGlyphRun(
|
||||||
|
paint,
|
||||||
|
glyphIDs,
|
||||||
|
SkSpan<const SkPoint>{fPositions, runSize},
|
||||||
|
SkSpan<const uint16_t>{fUniqueGlyphIDIndices, runSize},
|
||||||
|
unqiueGlyphIDs,
|
||||||
|
text,
|
||||||
|
clusters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,6 +292,7 @@ void SkGlyphRunBuilder::drawPosTextH(const SkPaint& paint, SkSpan<const SkGlyphI
|
|||||||
const SkScalar* xpos, SkScalar constY,
|
const SkScalar* xpos, SkScalar constY,
|
||||||
SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
|
SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
|
||||||
SkASSERT(!glyphIDs.empty());
|
SkASSERT(!glyphIDs.empty());
|
||||||
|
auto runSize = glyphIDs.size();
|
||||||
|
|
||||||
// The dense indices are not used by the rest of the stack yet.
|
// The dense indices are not used by the rest of the stack yet.
|
||||||
#ifdef SK_DEBUG
|
#ifdef SK_DEBUG
|
||||||
@ -286,17 +301,26 @@ void SkGlyphRunBuilder::drawPosTextH(const SkPaint& paint, SkSpan<const SkGlyphI
|
|||||||
|
|
||||||
// TODO: when using the unique glyph system have a guard that there are actually glyphs like
|
// TODO: when using the unique glyph system have a guard that there are actually glyphs like
|
||||||
// drawText above.
|
// drawText above.
|
||||||
for (size_t i = 0; i < fDenseIndex.size(); i++) {
|
auto posCursor = fPositions.get();
|
||||||
fPositions[i] = SkPoint::Make(xpos[i], constY);
|
for (auto x : SkSpan<const SkScalar>{xpos, runSize}) {
|
||||||
|
*posCursor++ = SkPoint::Make(x, constY);
|
||||||
}
|
}
|
||||||
|
|
||||||
this->makeGlyphRun(paint, glyphIDs, SkSpan<const SkPoint>{fPositions}, text, clusters);
|
this->makeGlyphRun(
|
||||||
|
paint,
|
||||||
|
glyphIDs,
|
||||||
|
SkSpan<const SkPoint>{fPositions, runSize},
|
||||||
|
SkSpan<const uint16_t>{},
|
||||||
|
SkSpan<const SkGlyphID>{},
|
||||||
|
text,
|
||||||
|
clusters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkGlyphRunBuilder::drawPosText(const SkPaint& paint, SkSpan<const SkGlyphID> glyphIDs,
|
void SkGlyphRunBuilder::drawPosText(const SkPaint& paint, SkSpan<const SkGlyphID> glyphIDs,
|
||||||
const SkPoint* pos,
|
const SkPoint* pos,
|
||||||
SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
|
SkSpan<const char> text, SkSpan<const uint32_t> clusters) {
|
||||||
SkASSERT(!glyphIDs.empty());
|
SkASSERT(!glyphIDs.empty());
|
||||||
|
auto runSize = glyphIDs.size();
|
||||||
|
|
||||||
// The dense indices are not used by the rest of the stack yet.
|
// The dense indices are not used by the rest of the stack yet.
|
||||||
#ifdef SK_DEBUG
|
#ifdef SK_DEBUG
|
||||||
@ -305,11 +329,14 @@ void SkGlyphRunBuilder::drawPosText(const SkPaint& paint, SkSpan<const SkGlyphID
|
|||||||
|
|
||||||
// TODO: when using the unique glyph system have a guard that there are actually glyphs like
|
// TODO: when using the unique glyph system have a guard that there are actually glyphs like
|
||||||
// drawText above.
|
// drawText above.
|
||||||
for (size_t i = 0; i < fDenseIndex.size(); i++) {
|
this->makeGlyphRun(
|
||||||
fPositions[i] = pos[i];
|
paint,
|
||||||
}
|
glyphIDs,
|
||||||
|
SkSpan<const SkPoint>{pos, runSize},
|
||||||
this->makeGlyphRun(paint, glyphIDs, SkSpan<const SkPoint>{fPositions}, text, clusters);
|
SkSpan<const uint16_t>{},
|
||||||
|
SkSpan<const SkGlyphID>{},
|
||||||
|
text,
|
||||||
|
clusters);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -24,23 +24,23 @@ template <typename T>
|
|||||||
class SkSpan {
|
class SkSpan {
|
||||||
public:
|
public:
|
||||||
SkSpan() : fPtr{nullptr}, fSize{0} {}
|
SkSpan() : fPtr{nullptr}, fSize{0} {}
|
||||||
SkSpan(T* ptr, ptrdiff_t size) : fPtr{ptr}, fSize{size} { SkASSERT(size >= 0); }
|
SkSpan(T* ptr, size_t size) : fPtr{ptr}, fSize{size} { }
|
||||||
template <typename U>
|
template <typename U>
|
||||||
explicit SkSpan(std::vector<U>& v) : fPtr{v.data()}, fSize{SkTo<ptrdiff_t>(v.size())} {}
|
explicit SkSpan(std::vector<U>& v) : fPtr{v.data()}, fSize{v.size()} {}
|
||||||
SkSpan(const SkSpan<T>& o) = default;
|
SkSpan(const SkSpan<T>& o) = default;
|
||||||
SkSpan& operator=( const SkSpan& other ) = default;
|
SkSpan& operator=( const SkSpan& other ) = default;
|
||||||
T& operator [] (ptrdiff_t i) const { return fPtr[i]; }
|
T& operator [] (size_t i) const { return fPtr[i]; }
|
||||||
T* begin() const { return fPtr; }
|
T* begin() const { return fPtr; }
|
||||||
T* end() const { return fPtr + fSize; }
|
T* end() const { return fPtr + fSize; }
|
||||||
const T* cbegin() const { return fPtr; }
|
const T* cbegin() const { return fPtr; }
|
||||||
const T* cend() const { return fPtr + fSize; }
|
const T* cend() const { return fPtr + fSize; }
|
||||||
T* data() const { return fPtr; }
|
T* data() const { return fPtr; }
|
||||||
ptrdiff_t size() const { return fSize; }
|
size_t size() const { return fSize; }
|
||||||
bool empty() const { return fSize == 0; }
|
bool empty() const { return fSize == 0; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
T* fPtr;
|
T* fPtr;
|
||||||
ptrdiff_t fSize;
|
size_t fSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SkGlyphRun {
|
class SkGlyphRun {
|
||||||
@ -120,6 +120,8 @@ private:
|
|||||||
const SkPaint& runPaint,
|
const SkPaint& runPaint,
|
||||||
SkSpan<const SkGlyphID> glyphIDs,
|
SkSpan<const SkGlyphID> glyphIDs,
|
||||||
SkSpan<const SkPoint> positions,
|
SkSpan<const SkPoint> positions,
|
||||||
|
SkSpan<const uint16_t> uniqueGlyphIDIndices,
|
||||||
|
SkSpan<const SkGlyphID> uniqueGlyphIDs,
|
||||||
SkSpan<const char> text,
|
SkSpan<const char> text,
|
||||||
SkSpan<const uint32_t> clusters);
|
SkSpan<const uint32_t> clusters);
|
||||||
|
|
||||||
@ -136,9 +138,10 @@ private:
|
|||||||
|
|
||||||
uint64_t fUniqueID{0};
|
uint64_t fUniqueID{0};
|
||||||
|
|
||||||
std::vector<uint16_t> fDenseIndex;
|
size_t fMaxTotalRunSize{0};
|
||||||
std::vector<SkPoint> fPositions;
|
SkAutoTMalloc<uint16_t> fUniqueGlyphIDIndices;
|
||||||
std::vector<SkGlyphID> fUniqueGlyphIDs;
|
SkAutoTMalloc<SkPoint> fPositions;
|
||||||
|
SkAutoTMalloc<SkGlyphID> fUniqueGlyphIDs;
|
||||||
|
|
||||||
// Used as a temporary for preparing using utfN text. This implies that only one run of
|
// Used as a temporary for preparing using utfN text. This implies that only one run of
|
||||||
// glyph ids will ever be needed because blobs are already glyph based.
|
// glyph ids will ever be needed because blobs are already glyph based.
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "SkGlyphCache.h"
|
#include "SkGlyphCache.h"
|
||||||
#include "SkGraphics.h"
|
#include "SkGraphics.h"
|
||||||
#include "SkMutex.h"
|
#include "SkMutex.h"
|
||||||
|
#include "SkTemplates.h"
|
||||||
#include "SkTraceMemoryDump.h"
|
#include "SkTraceMemoryDump.h"
|
||||||
#include "SkTypeface.h"
|
#include "SkTypeface.h"
|
||||||
#include "SkPaintPriv.h"
|
#include "SkPaintPriv.h"
|
||||||
|
@ -24,7 +24,7 @@ DEF_TEST(GlyphRunGlyphIDSetBasic, reporter) {
|
|||||||
std::vector<SkGlyphID> test{uniqueGlyphIDs.begin(), uniqueGlyphIDs.end()};
|
std::vector<SkGlyphID> test{uniqueGlyphIDs.begin(), uniqueGlyphIDs.end()};
|
||||||
std::sort(test.begin(), test.end());
|
std::sort(test.begin(), test.end());
|
||||||
auto newEnd = std::unique(test.begin(), test.end());
|
auto newEnd = std::unique(test.begin(), test.end());
|
||||||
REPORTER_ASSERT(reporter, uniqueGlyphIDs.size() == newEnd - test.begin());
|
REPORTER_ASSERT(reporter, uniqueGlyphIDs.size() == (size_t)(newEnd - test.begin()));
|
||||||
REPORTER_ASSERT(reporter, uniqueGlyphIDs.size() == 4);
|
REPORTER_ASSERT(reporter, uniqueGlyphIDs.size() == 4);
|
||||||
{
|
{
|
||||||
uint16_t answer[] = {0, 1, 2, 1, 3};
|
uint16_t answer[] = {0, 1, 2, 1, 3};
|
||||||
|
Loading…
Reference in New Issue
Block a user