aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/gpu/ops
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/ops
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/ops')
-rw-r--r--src/gpu/ops/GrAtlasTextOp.cpp57
-rw-r--r--src/gpu/ops/GrAtlasTextOp.h22
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