| Index: src/gpu/GrBitmapTextContext.h
|
| diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h
|
| index 3bf3a941c646cb42d28464d1afbd6efbd4ffe897..1f8a82f35aae21690d556eac28ebc38eb50db74d 100644
|
| --- a/src/gpu/GrBitmapTextContext.h
|
| +++ b/src/gpu/GrBitmapTextContext.h
|
| @@ -11,6 +11,8 @@
|
| #include "GrTextContext.h"
|
|
|
| #include "GrGeometryProcessor.h"
|
| +#include "GrMemoryPool.h"
|
| +#include "SkDescriptor.h"
|
| #include "SkTHash.h"
|
|
|
| class GrBatchTextStrike;
|
| @@ -65,63 +67,108 @@ private:
|
| // this at a more fine grained level, but its not clear if this is worth it, as evictions
|
| // should be fairly rare.
|
| // One additional point, each run can contain glyphs with any of the three mask formats.
|
| - // We maintain separate arrays for each format type, and flush them separately. In practice
|
| - // most of the time a run will have the same format type
|
| + // We call these SubRuns. Because a subrun must be a contiguous range, we have to create
|
| + // a new subrun each time the mask format changes in a run. In theory, a run can have as
|
| + // many SubRuns as it has glyphs, ie if a run alternates between color emoji and A8. In
|
| + // practice, the vast majority of runs have only a single subrun.
|
| +
|
| struct Run {
|
| - Run() : fColor(GrColor_ILLEGAL) { fVertexBounds.setLargestInverted(); }
|
| - struct PerFormatInfo {
|
| - PerFormatInfo() : fAtlasGeneration(GrBatchAtlas::kInvalidAtlasGeneration) {}
|
| - SkTDArray<unsigned char> fVertices;
|
| - SkTDArray<GrGlyph::PackedID> fGlyphIDs;
|
| + Run() : fColor(GrColor_ILLEGAL), fInitialized(false) {
|
| + fVertexBounds.setLargestInverted();
|
| + // We insert the first subrun to gurantee a run always has atleast one subrun.
|
| + // We do this to simplify things when we 'hand off' data from one subrun to the
|
| + // next
|
| + fSubRunInfo.push_back();
|
| + }
|
| + struct SubRunInfo {
|
| + SubRunInfo()
|
| + : fAtlasGeneration(GrBatchAtlas::kInvalidAtlasGeneration)
|
| + , fGlyphStartIndex(0)
|
| + , fGlyphEndIndex(0)
|
| + , fVertexStartIndex(0)
|
| + , fVertexEndIndex(0) {}
|
| + GrMaskFormat fMaskFormat;
|
| uint64_t fAtlasGeneration;
|
| + uint32_t fGlyphStartIndex;
|
| + uint32_t fGlyphEndIndex;
|
| + size_t fVertexStartIndex;
|
| + size_t fVertexEndIndex;
|
| };
|
| - SkAutoTUnref<const SkData> fDescriptor;
|
| + SkSTArray<1, SubRunInfo, true> fSubRunInfo;
|
| + SkAutoDescriptor fDescriptor;
|
| SkAutoTUnref<SkTypeface> fTypeface;
|
| - PerFormatInfo fInfos[kMaskFormatCount];
|
| SkRect fVertexBounds;
|
| GrColor fColor;
|
| + bool fInitialized;
|
| };
|
| - SkSTArray<1, Run, true> fRuns;
|
| +
|
| struct BigGlyph {
|
| BigGlyph(const SkPath& path, int vx, int vy) : fPath(path), fVx(vx), fVy(vy) {}
|
| SkPath fPath;
|
| int fVx;
|
| int fVy;
|
| };
|
| +
|
| SkTArray<BigGlyph> fBigGlyphs;
|
| - SkTextBlob* fBlob;
|
| SkMatrix fViewMatrix;
|
| SkScalar fX;
|
| SkScalar fY;
|
| SkPaint::Style fStyle;
|
| + uint32_t fRunCount;
|
| +
|
| + // all glyph / vertex offsets are into these pools.
|
| + unsigned char* fVertices;
|
| + GrGlyph::PackedID* fGlyphIDs;
|
| + Run* fRuns;
|
|
|
| static uint32_t Hash(const uint32_t& key) {
|
| return SkChecksum::Mix(key);
|
| }
|
| +
|
| + void operator delete(void* p) { sk_free(p); }
|
| + void* operator new(size_t) {
|
| + SkFAIL("All blobs are created by placement new.");
|
| + return sk_malloc_throw(0);
|
| + }
|
| +
|
| + void* operator new(size_t, void* p) { return p; }
|
| + void operator delete(void* target, void* placement) {
|
| + ::operator delete(target, placement);
|
| + }
|
| };
|
|
|
| + typedef BitmapTextBlob::Run Run;
|
| + typedef Run::SubRunInfo PerSubRunInfo;
|
| +
|
| + BitmapTextBlob* CreateBlob(int glyphCount, int runCount);
|
| +
|
| void appendGlyph(BitmapTextBlob*, int runIndex, GrGlyph::PackedID, int left, int top,
|
| GrFontScaler*, const SkIRect& clipRect);
|
| - void flushSubRun(GrDrawTarget*, BitmapTextBlob*, int i, GrPipelineBuilder*, GrMaskFormat,
|
| - GrColor color, int paintAlpha);
|
| void flush(GrDrawTarget*, BitmapTextBlob*, GrRenderTarget*, const GrPaint&, const GrClip&,
|
| const SkMatrix& viewMatrix, int paintAlpha);
|
|
|
| - void internalDrawText(BitmapTextBlob*, int runIndex, const SkPaint&,
|
| + void internalDrawText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
|
| const SkMatrix& viewMatrix, const char text[], size_t byteLength,
|
| SkScalar x, SkScalar y, const SkIRect& clipRect);
|
| - void internalDrawPosText(BitmapTextBlob*, int runIndex, const SkPaint&,
|
| + void internalDrawPosText(BitmapTextBlob*, int runIndex, SkGlyphCache*, const SkPaint&,
|
| const SkMatrix& viewMatrix,
|
| const char text[], size_t byteLength,
|
| const SkScalar pos[], int scalarsPerPosition,
|
| const SkPoint& offset, const SkIRect& clipRect);
|
|
|
| + // sets up the descriptor on the blob and returns a detached cache. Client must attach
|
| + inline SkGlyphCache* setupCache(Run*, const SkPaint&, const SkMatrix& viewMatrix);
|
| static inline bool MustRegenerateBlob(const BitmapTextBlob&, const SkPaint&,
|
| const SkMatrix& viewMatrix, SkScalar x, SkScalar y);
|
| void regenerateTextBlob(BitmapTextBlob* bmp, const SkPaint& skPaint, const SkMatrix& viewMatrix,
|
| const SkTextBlob* blob, SkScalar x, SkScalar y,
|
| SkDrawFilter* drawFilter, const SkIRect& clipRect);
|
|
|
| + // TODO this currently only uses the public interface of SkTextBlob, however, I may need to add
|
| + // functionality to it while looping over the runs so I'm putting this here for the time being.
|
| + // If this lands in Chrome without changes, move it to SkTextBlob.
|
| + static inline void BlobGlyphCount(int* glyphCount, int* runCount, const SkTextBlob*);
|
| +
|
| GrBatchTextStrike* fCurrStrike;
|
|
|
| // TODO use real cache
|
|
|