diff options
author | Brian Salomon <bsalomon@google.com> | 2017-11-06 16:26:02 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-11-07 01:56:36 +0000 |
commit | 18923f9a2e83675aecba7561f5095429fb467633 (patch) | |
tree | e59e9a98ee1f7422ecf641cc998a977f28151a70 /src/gpu/ops | |
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/ops')
-rw-r--r-- | src/gpu/ops/GrAtlasTextOp.cpp | 57 | ||||
-rw-r--r-- | src/gpu/ops/GrAtlasTextOp.h | 22 |
2 files changed, 29 insertions, 50 deletions
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<SkPoint*>(blobVertices); - SkPoint* blobPositionRB = reinterpret_cast<SkPoint*>(blobVertices + 3*vertexStride); + const SkPoint* blobPositionLT = reinterpret_cast<const SkPoint*>(blobVertices); + const SkPoint* blobPositionRB = + reinterpret_cast<const SkPoint*>(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<SkColor*>(blobVertices + sizeof(SkPoint)); + auto color = *reinterpret_cast<const SkColor*>(blobVertices + sizeof(SkPoint)); size_t coordOffset = vertexStride - 2*sizeof(uint16_t); - uint16_t* blobCoordsLT = reinterpret_cast<uint16_t*>(blobVertices + coordOffset); - uint16_t* blobCoordsRB = reinterpret_cast<uint16_t*>(blobVertices + 3*vertexStride + - coordOffset); + auto* blobCoordsLT = reinterpret_cast<const uint16_t*>(blobVertices + coordOffset); + auto* blobCoordsRB = reinterpret_cast<const uint16_t*>(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<unsigned char*>(vertices); + char* currVertex = reinterpret_cast<char*>(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<unsigned char*>(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<GrGeometryProcessor> 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 |