diff options
author | Herb Derby <herb@google.com> | 2018-06-07 12:44:09 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-06-08 19:25:43 +0000 |
commit | 59d997a6e1d32f2d0a3021931aed87984d15a7ee (patch) | |
tree | e5f920dc6f1b33b4fcde0f1058738512e376021b /src/core/SkGlyphRun.h | |
parent | f0aacafe9e7a74475493c71c4c3679e80a8b2a82 (diff) |
New more efficient run builder
A system for building glyph runs. In the future the builder will
only live in canvas, but it's internal structures facilitate
interacting with the cache a single glyph at a time. When all
the bulk code is in place, only runs will be passed around.
Passing the builder down the text draw stack is temporary.
Change-Id: I6e3ed184b3f3a58b919377f2d31936e971bd8efa
Reviewed-on: https://skia-review.googlesource.com/132928
Reviewed-by: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Herb Derby <herb@google.com>
Diffstat (limited to 'src/core/SkGlyphRun.h')
-rw-r--r-- | src/core/SkGlyphRun.h | 124 |
1 files changed, 81 insertions, 43 deletions
diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h index 53d57af8c4..eeb9c2924e 100644 --- a/src/core/SkGlyphRun.h +++ b/src/core/SkGlyphRun.h @@ -8,6 +8,7 @@ #ifndef SkGlyphRunInfo_DEFINED #define SkGlyphRunInfo_DEFINED +#include <functional> #include <memory> #include <vector> @@ -17,6 +18,43 @@ #include "SkPoint.h" #include "SkTypes.h" +class SkBaseDevice; + +template <typename T> +class SkSpan { +public: + SkSpan() = default; + SkSpan(const T* ptr, size_t size) : fPtr{ptr}, fSize{size} {} + explicit SkSpan(const std::vector<T>& v) : fPtr{v.data()}, fSize{v.size()} {} + const T& operator [] (ptrdiff_t i) const { return fPtr[i]; } + const T* begin() const { return fPtr; } + const T* end() const { return fPtr + fSize; } + ptrdiff_t size() const { return fSize; } + +private: + const T* fPtr; + size_t fSize; +}; + +class SkGlyphRun { +public: + SkGlyphRun() = default; + SkGlyphRun(SkSpan<uint16_t> denseIndex, SkSpan<SkPoint> positions, + SkSpan<SkGlyphID> uniqueGlyphIDs) + : fDenseIndex{denseIndex} + , fPositions{positions} + , fUniqueGlyphIDs{uniqueGlyphIDs} {} + + size_t runSize() const { return fDenseIndex.size(); } + uint16_t uniqueSize() const { return fUniqueGlyphIDs.size(); } + SkSpan<SkPoint> positions() const { return SkSpan<SkPoint>(fPositions); } + +private: + SkSpan<uint16_t> fDenseIndex; + SkSpan<SkPoint> fPositions; + SkSpan<SkGlyphID> fUniqueGlyphIDs; +}; + // A faster set implementation that does not need any initialization, and reading the set items // is order the number of items, and not the size of the universe. // This implementation is based on the paper by Briggs and Torczon, "An Efficient Representation @@ -25,63 +63,63 @@ class SkGlyphSet { public: SkGlyphSet() = default; uint16_t add(SkGlyphID glyphID); - std::vector<SkGlyphID> uniqueGlyphIDs(); - void reuse(uint32_t glyphUniverseSize); + void reuse(uint32_t glyphUniverseSize, std::vector<SkGlyphID>* uniqueGlyphIDs); private: uint32_t fUniverseSize{0}; std::vector<uint16_t> fIndices; - std::vector<SkGlyphID> fUniqueGlyphIDs; + std::vector<SkGlyphID>* fUniqueGlyphIDs{nullptr}; }; -class SkGlyphRun { +// Currently the old code is passing around SkGlyphRunBuilder because it facilitates working in the +// old single glyph lookup style with the cache. When the lower level code is transitioned over to +// the bulk glyph cache style, then the builder will only be used in the canvas, and only runs will +// be passed around. +class SkGlyphRunBuilder { public: - SkGlyphRun() = default; - SkGlyphRun(SkGlyphRun&&) = default; - static SkGlyphRun MakeFromDrawText( + SkGlyphRunBuilder() = default; + void prepareDrawText( + const SkPaint& paint, const void* bytes, size_t byteLength, SkPoint origin); + void prepareDrawPosTextH( const SkPaint& paint, const void* bytes, size_t byteLength, - SkPoint origin, SkGlyphSet* glyphSet); - static SkGlyphRun MakeFromDrawPosTextH( - const SkPaint& paint, const void* bytes, size_t byteLength, - const SkScalar xpos[], SkScalar constY, SkGlyphSet* glyphSet); - static SkGlyphRun MakeFromDrawPosText( - const SkPaint& paint, const void* bytes, size_t byteLength, - const SkPoint pos[], SkGlyphSet* glyphSet); + const SkScalar xpos[], SkScalar constY); + void prepareDrawPosText( + const SkPaint& paint, const void* bytes, size_t byteLength, const SkPoint pos[]); + + size_t runSize() const {return fDenseIndex.size();} + size_t uniqueSize() const {return fUniqueGlyphs.size();} - size_t runSize() const { return fRunSize; } - uint16_t uniqueSize() const { return fUniqueGlyphs.size(); } + const SkGlyphRun& useGlyphRun() const; - // copyGlyphIDs is temporary glue to work with the existing system. Don't use with new code. - std::unique_ptr<SkGlyphID[]> copyGlyphIDs() const; - const SkScalar* getPositions() const { - return reinterpret_cast<const SkScalar*>(fPositions.get()); - } + // The temporaryShunt calls are to allow inter-operating with existing code while glyph runs + // are developed. + void temporaryShuntToDrawPosText(const SkPaint& paint, SkBaseDevice* device); + using TemporaryShuntCallback = std::function<void(size_t, const char*, const SkScalar*)>; + void temporaryShuntToCallback(TemporaryShuntCallback callback); private: - SkGlyphRun(size_t runSize, - std::unique_ptr<uint16_t[]>&& denseIndex, - std::unique_ptr<SkPoint[]>&& positions, - std::vector<SkGlyphID>&& uniqueGlyphIDs); - - std::unique_ptr<uint16_t[]> fDenseIndex; - std::unique_ptr<SkPoint[]> fPositions; - std::vector<SkGlyphID> fUniqueGlyphs; - const size_t fRunSize{0}; -}; + void initializeDenseAndUnique(const SkPaint& paint, const void* bytes, size_t byteLength); -template <typename T> -class SkSpan { -public: - SkSpan(const T* ptr, size_t size) : fPtr{ptr}, fSize{size} {} - SkSpan(const std::vector<T>& v) : fPtr{v.data()}, fSize{v.size()} {} - const T& operator [] (ptrdiff_t i) const { return fPtr[i]; } - const T* begin() const { return fPtr; } - const T* end() const { return fPtr + fSize; } - ptrdiff_t size() const { return fSize; } + std::vector<uint16_t> fDenseIndex; + std::vector<SkPoint> fPositions; + std::vector<SkGlyphID> fUniqueGlyphs; -private: - const T* fPtr; - size_t fSize; + // Used as a temporary for preparing using utfN text. + std::vector<SkGlyphID> fScratchGlyphIDs; + + // Used as temporary storage for calculating positions for drawText. + std::vector<SkPoint> fScratchAdvances; + + // Used to temporarily use of a glyph run for bulk cache API calls (just an experiment at + // this point). + SkGlyphRun fScratchGlyphRun; + + // Used as an aid to shunt from glyph runs to drawPosText. It will either be fScratchIDs or + // the bytes passed in. + const SkGlyphID* fTemporaryShuntGlyphIDs{nullptr}; + + // Used for collecting the set of unique glyphs. + SkGlyphSet fGlyphSet; }; #endif // SkGlyphRunInfo_DEFINED |