aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/text/GrAtlasTextBlob.h
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-11-06 16:26:02 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-11-07 01:56:36 +0000
commit18923f9a2e83675aecba7561f5095429fb467633 (patch)
treee59e9a98ee1f7422ecf641cc998a977f28151a70 /src/gpu/text/GrAtlasTextBlob.h
parent75a1377e54fb44c84a2712d9c678b1b448a9cffe (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.h81
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