diff options
author | 2017-11-06 16:26:02 -0500 | |
---|---|---|
committer | 2017-11-07 01:56:36 +0000 | |
commit | 18923f9a2e83675aecba7561f5095429fb467633 (patch) | |
tree | e59e9a98ee1f7422ecf641cc998a977f28151a70 /src/gpu/text/GrAtlasTextBlob.h | |
parent | 75a1377e54fb44c84a2712d9c678b1b448a9cffe (diff) |
Make GrAtlasTextBlob return to caller when a flush is required during subrun tessellation.
The old code used a helper object in the tessellation code that called flush() on GrAtlasTextOp.
A confusing aspect of this was that the pre-flush vertex data generated for the sub run was copied
to the op's vertex buffer after flush() had already recorded the draw that read the data.
The new code adds a tessellator nested helper class to GrAtlasTextBlob. The helper exits early if
a flush is required, the op performs the flush, and then the helper is invoked again until
tessellation is complete.
This also changes the blob object to use char* instead of unsigned char* for its vertex pointers.
Change-Id: I31bed251435f13b2172e6f5829ba437b882dd44d
Reviewed-on: https://skia-review.googlesource.com/67856
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Diffstat (limited to 'src/gpu/text/GrAtlasTextBlob.h')
-rw-r--r-- | src/gpu/text/GrAtlasTextBlob.h | 81 |
1 files changed, 64 insertions, 17 deletions
diff --git a/src/gpu/text/GrAtlasTextBlob.h b/src/gpu/text/GrAtlasTextBlob.h index 495e72aa92..403cbbfa3f 100644 --- a/src/gpu/text/GrAtlasTextBlob.h +++ b/src/gpu/text/GrAtlasTextBlob.h @@ -21,7 +21,6 @@ #include "SkSurfaceProps.h" #include "SkTInternalLList.h" -class GrBlobRegenHelper; struct GrDistanceFieldAdjustTable; class GrMemoryPool; class SkDrawFilter; @@ -50,6 +49,8 @@ class GrAtlasTextBlob : public SkNVRefCnt<GrAtlasTextBlob> { public: SK_DECLARE_INTERNAL_LLIST_INTERFACE(GrAtlasTextBlob); + class VertexRegenerator; + static sk_sp<GrAtlasTextBlob> Make(GrMemoryPool* pool, int glyphCount, int runCount); struct Key { @@ -250,16 +251,6 @@ public: this->setupViewMatrix(viewMatrix, x, y); } - /** - * Consecutive calls to regenInOp often use the same SkGlyphCache. If the same instance of - * SkAutoGlyphCache is passed to multiple calls of regenInOp then it can save the cost of - * multiple detach/attach operations of SkGlyphCache. - */ - void regenInOp(GrDeferredUploadTarget*, GrAtlasGlyphCache* fontCache, GrBlobRegenHelper* helper, - int run, int subRun, SkAutoGlyphCache*, size_t vertexStride, - const SkMatrix& viewMatrix, SkScalar x, SkScalar y, GrColor color, - void** vertices, size_t* byteCount, int* glyphCount); - const Key& key() const { return fKey; } ~GrAtlasTextBlob() { @@ -492,11 +483,6 @@ private: bool fDrawAsPaths; }; // Run - template <bool regenPos, bool regenCol, bool regenTexCoords, bool regenGlyphs> - void regenInOp(GrDeferredUploadTarget*, GrAtlasGlyphCache* fontCache, GrBlobRegenHelper* helper, - Run* run, Run::SubRunInfo* info, SkAutoGlyphCache*, int glyphCount, - size_t vertexStride, GrColor color, SkScalar transX, SkScalar transY) const; - inline std::unique_ptr<GrAtlasTextOp> makeOp( const Run::SubRunInfo& info, int glyphCount, uint16_t run, uint16_t subRun, const SkMatrix& viewMatrix, SkScalar x, SkScalar y, const SkIRect& clipRect, @@ -530,7 +516,7 @@ private: }; // all glyph / vertex offsets are into these pools. - unsigned char* fVertices; + char* fVertices; GrGlyph** fGlyphs; Run* fRuns; GrMemoryPool* fPool; @@ -554,4 +540,65 @@ private: uint8_t fTextType; }; +/** + * Used to produce vertices for a subrun of a blob. The vertices are cached in the blob itself. + * This is invoked each time a sub run is drawn. It regenerates the vertex data as required either + * because of changes to the atlas or because of different draw parameters (e.g. color change). In + * rare cases the draw may have to interrupted and flushed in the middle of the sub run in order to + * free up atlas space. Thus, this generator is stateful and should be invoked in a loop until the + * entire sub run has been completed. + */ +class GrAtlasTextBlob::VertexRegenerator { +public: + /** + * Consecutive VertexRegenerators often use the same SkGlyphCache. If the same instance of + * SkAutoGlyphCache is reused then it can save the cost of multiple detach/attach operations of + * SkGlyphCache. + */ + VertexRegenerator(GrAtlasTextBlob* blob, int runIdx, int subRunIdx, const SkMatrix& viewMatrix, + SkScalar x, SkScalar y, GrColor color, GrDeferredUploadTarget*, + GrAtlasGlyphCache*, SkAutoGlyphCache*, size_t vertexStride); + + struct Result { + /** + * Was regenerate() able to draw all the glyphs from the sub run? If not flush all glyph + * draws and call regenerate() again. + */ + bool fFinished = true; + + /** + * How many glyphs were regenerated. Will be equal to the sub run's glyph count if + * fType is kFinished. + */ + int fGlyphsRegenerated = 0; + + /** + * Pointer where the caller finds the first regenerated vertex. + */ + const char* fFirstVertex; + }; + + Result regenerate(); + +private: + template <bool regenPos, bool regenCol, bool regenTexCoords, bool regenGlyphs> + Result doRegen(); + + const SkMatrix& fViewMatrix; + GrAtlasTextBlob* fBlob; + GrDeferredUploadTarget* fUploadTarget; + GrAtlasGlyphCache* fGlyphCache; + SkAutoGlyphCache* fLazyCache; + Run* fRun; + Run::SubRunInfo* fSubRun; + size_t fVertexStride; + GrColor fColor; + SkScalar fTransX; + SkScalar fTransY; + + uint32_t fRegenFlags = 0; + int fCurrGlyph = 0; + bool fBrokenRun = false; +}; + #endif |