From 18923f9a2e83675aecba7561f5095429fb467633 Mon Sep 17 00:00:00 2001 From: Brian Salomon Date: Mon, 6 Nov 2017 16:26:02 -0500 Subject: 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 Reviewed-by: Jim Van Verth --- src/gpu/ops/GrAtlasTextOp.cpp | 57 ++++++++++++++++++++++--------------------- src/gpu/ops/GrAtlasTextOp.h | 22 ----------------- 2 files changed, 29 insertions(+), 50 deletions(-) (limited to 'src/gpu/ops') diff --git a/src/gpu/ops/GrAtlasTextOp.cpp b/src/gpu/ops/GrAtlasTextOp.cpp index 2383510a47..9e98466d5d 100644 --- a/src/gpu/ops/GrAtlasTextOp.cpp +++ b/src/gpu/ops/GrAtlasTextOp.cpp @@ -76,12 +76,12 @@ GrDrawOp::RequiresDstTexture GrAtlasTextOp::finalize(const GrCaps& caps, return analysis.requiresDstTexture() ? RequiresDstTexture::kYes : RequiresDstTexture::kNo; } -static void clip_quads(const SkIRect& clipRect, - unsigned char* currVertex, unsigned char* blobVertices, +static void clip_quads(const SkIRect& clipRect, char* currVertex, const char* blobVertices, size_t vertexStride, int glyphCount) { for (int i = 0; i < glyphCount; ++i) { - SkPoint* blobPositionLT = reinterpret_cast(blobVertices); - SkPoint* blobPositionRB = reinterpret_cast(blobVertices + 3*vertexStride); + const SkPoint* blobPositionLT = reinterpret_cast(blobVertices); + const SkPoint* blobPositionRB = + reinterpret_cast(blobVertices + 3 * vertexStride); // positions for bitmap glyphs are pixel boundary aligned SkIRect positionRect = SkIRect::MakeLTRB(SkScalarFloorToInt(blobPositionLT->fX), @@ -95,11 +95,11 @@ static void clip_quads(const SkIRect& clipRect, // Pull out some more data that we'll need. // In the LCD case the color will be garbage, but we'll overwrite it with the texcoords // and it avoids a lot of conditionals. - SkColor color = *reinterpret_cast(blobVertices + sizeof(SkPoint)); + auto color = *reinterpret_cast(blobVertices + sizeof(SkPoint)); size_t coordOffset = vertexStride - 2*sizeof(uint16_t); - uint16_t* blobCoordsLT = reinterpret_cast(blobVertices + coordOffset); - uint16_t* blobCoordsRB = reinterpret_cast(blobVertices + 3*vertexStride + - coordOffset); + auto* blobCoordsLT = reinterpret_cast(blobVertices + coordOffset); + auto* blobCoordsRB = reinterpret_cast(blobVertices + 3 * vertexStride + + coordOffset); // Pull out the texel coordinates and texture index bits uint16_t coordsRectL = blobCoordsLT[0] >> 1; uint16_t coordsRectT = blobCoordsLT[1] >> 1; @@ -224,32 +224,34 @@ void GrAtlasTextOp::onPrepareDraws(Target* target) { return; } - unsigned char* currVertex = reinterpret_cast(vertices); + char* currVertex = reinterpret_cast(vertices); - GrBlobRegenHelper helper(this, target, &flushInfo); SkAutoGlyphCache glyphCache; // each of these is a SubRun for (int i = 0; i < fGeoCount; i++) { const Geometry& args = fGeoData[i]; Blob* blob = args.fBlob; - size_t byteCount; - void* blobVertices; - int subRunGlyphCount; - blob->regenInOp(target->deferredUploadTarget(), fFontCache, &helper, args.fRun, - args.fSubRun, &glyphCache, vertexStride, args.fViewMatrix, args.fX, args.fY, - args.fColor, &blobVertices, &byteCount, &subRunGlyphCount); - - // now copy all vertices - if (args.fClipRect.isEmpty()) { - memcpy(currVertex, blobVertices, byteCount); - } else { - clip_quads(args.fClipRect, currVertex, reinterpret_cast(blobVertices), - vertexStride, subRunGlyphCount); - } - - currVertex += byteCount; + GrAtlasTextBlob::VertexRegenerator regenerator( + blob, args.fRun, args.fSubRun, args.fViewMatrix, args.fX, args.fY, args.fColor, + target->deferredUploadTarget(), fFontCache, &glyphCache, vertexStride); + GrAtlasTextBlob::VertexRegenerator::Result result; + do { + result = regenerator.regenerate(); + // Copy regenerated vertices from the blob to our vertex buffer. + size_t vertexBytes = result.fGlyphsRegenerated * kVerticesPerGlyph * vertexStride; + if (args.fClipRect.isEmpty()) { + memcpy(currVertex, result.fFirstVertex, vertexBytes); + } else { + clip_quads(args.fClipRect, currVertex, result.fFirstVertex, vertexStride, + result.fGlyphsRegenerated); + } + flushInfo.fGlyphsToFlush += result.fGlyphsRegenerated; + if (!result.fFinished) { + this->flush(target, &flushInfo); + } + currVertex += vertexBytes; + } while (!result.fFinished); } - this->flush(target, &flushInfo); } @@ -406,4 +408,3 @@ sk_sp GrAtlasTextOp::setupDfProcessor() const { } } -void GrBlobRegenHelper::flush() { fOp->flush(fTarget, fFlushInfo); } diff --git a/src/gpu/ops/GrAtlasTextOp.h b/src/gpu/ops/GrAtlasTextOp.h index 1814676445..240b98b6f0 100644 --- a/src/gpu/ops/GrAtlasTextOp.h +++ b/src/gpu/ops/GrAtlasTextOp.h @@ -206,29 +206,7 @@ private: SkColor fLuminanceColor; bool fUseGammaCorrectDistanceTable; - friend class GrBlobRegenHelper; // Needs to trigger flushes - typedef GrMeshDrawOp INHERITED; }; -/* - * A simple helper class to abstract the interface GrAtlasTextBlob needs to regenerate itself. - * It'd be nicer if this was nested, but we need to forward declare it in GrAtlasTextBlob.h - */ -class GrBlobRegenHelper { -public: - GrBlobRegenHelper(const GrAtlasTextOp* op, GrMeshDrawOp::Target* target, - GrAtlasTextOp::FlushInfo* flushInfo) - : fOp(op), fTarget(target), fFlushInfo(flushInfo) {} - - void flush(); - - void incGlyphCount(int glyphCount = 1) { fFlushInfo->fGlyphsToFlush += glyphCount; } - -private: - const GrAtlasTextOp* fOp; - GrMeshDrawOp::Target* fTarget; - GrAtlasTextOp::FlushInfo* fFlushInfo; -}; - #endif -- cgit v1.2.3