Remove runIndex as a concept for GrTextBlob
Change-Id: I8ac756a088c1dddf475bf96f9a4a84ec2cb500be
Reviewed-on: https://skia-review.googlesource.com/c/169763
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/src/gpu/text/GrTextBlob.cpp b/src/gpu/text/GrTextBlob.cpp
index e035124..fe52f19 100644
--- a/src/gpu/text/GrTextBlob.cpp
+++ b/src/gpu/text/GrTextBlob.cpp
@@ -54,96 +54,133 @@
for (int i = 0; i < runCount; i++) {
new (&cacheBlob->fRuns[i]) GrTextBlob::Run;
}
- cacheBlob->fRunCount = runCount;
+ cacheBlob->fRunCountLimit = runCount;
return cacheBlob;
}
-SkExclusiveStrikePtr GrTextBlob::setupCache(int runIndex,
- const SkPaint& skPaint,
- const SkSurfaceProps& props,
- SkScalerContextFlags scalerContextFlags,
- const SkMatrix& viewMatrix) {
- GrTextBlob::Run* run = &fRuns[runIndex];
+SkExclusiveStrikePtr GrTextBlob::Run::setupCache(const SkPaint& skPaint,
+ const SkSurfaceProps& props,
+ SkScalerContextFlags scalerContextFlags,
+ const SkMatrix& viewMatrix) {
// if we have an override descriptor for the run, then we should use that
- SkAutoDescriptor* desc = run->fOverrideDescriptor.get() ? run->fOverrideDescriptor.get() :
- &run->fDescriptor;
+ SkAutoDescriptor* desc = fOverrideDescriptor.get() ? fOverrideDescriptor.get() : &fDescriptor;
SkScalerContextEffects effects;
SkScalerContext::CreateDescriptorAndEffectsUsingPaint(
skPaint, props, scalerContextFlags, viewMatrix, desc, &effects);
- run->fTypeface = SkPaintPriv::RefTypefaceOrDefault(skPaint);
- run->fPathEffect = sk_ref_sp(effects.fPathEffect);
- run->fMaskFilter = sk_ref_sp(effects.fMaskFilter);
- return SkStrikeCache::FindOrCreateStrikeExclusive(*desc->getDesc(), effects, *run->fTypeface);
+ fTypeface = SkPaintPriv::RefTypefaceOrDefault(skPaint);
+ fPathEffect = sk_ref_sp(effects.fPathEffect);
+ fMaskFilter = sk_ref_sp(effects.fMaskFilter);
+ return SkStrikeCache::FindOrCreateStrikeExclusive(*desc->getDesc(), effects, *fTypeface);
}
-void GrTextBlob::appendGlyph(int runIndex,
- const SkRect& positions,
- const SkPMColor4f& color4f,
- const sk_sp<GrTextStrike>& strike,
- GrGlyph* glyph, bool preTransformed) {
- // TODO4F: Preserve float colors
- GrColor color = color4f.toBytes_RGBA();
+static SkRect rect_to_draw(
+ const SkGlyph& glyph, SkPoint origin, SkScalar textScale, bool isDFT) {
- Run& run = fRuns[runIndex];
- GrMaskFormat format = glyph->fMaskFormat;
+ SkScalar dx = SkIntToScalar(glyph.fLeft);
+ SkScalar dy = SkIntToScalar(glyph.fTop);
+ SkScalar width = SkIntToScalar(glyph.fWidth);
+ SkScalar height = SkIntToScalar(glyph.fHeight);
- Run::SubRunInfo* subRun = &run.fSubRunInfo.back();
- if (run.fInitialized && subRun->maskFormat() != format) {
- subRun = &run.push_back();
- subRun->setStrike(strike);
- } else if (!run.fInitialized) {
- subRun->setStrike(strike);
+ if (isDFT) {
+ dx += SK_DistanceFieldInset;
+ dy += SK_DistanceFieldInset;
+ width -= 2 * SK_DistanceFieldInset;
+ height -= 2 * SK_DistanceFieldInset;
}
- run.fInitialized = true;
+ dx *= textScale;
+ dy *= textScale;
+ width *= textScale;
+ height *= textScale;
- bool hasW = subRun->hasWCoord();
- // glyphs drawn in perspective must always have a w coord.
- SkASSERT(hasW || !fInitialViewMatrix.hasPerspective());
-
- size_t vertexStride = GetVertexStride(format, hasW);
-
- subRun->setMaskFormat(format);
-
- subRun->joinGlyphBounds(positions);
- subRun->setColor(color);
-
- intptr_t vertex = reinterpret_cast<intptr_t>(this->fVertices + subRun->vertexEndIndex());
-
- // We always write the third position component used by SDFs. If it is unused it gets
- // overwritten. Similarly, we always write the color and the blob will later overwrite it
- // with texture coords if it is unused.
- size_t colorOffset = hasW ? sizeof(SkPoint3) : sizeof(SkPoint);
- // V0
- *reinterpret_cast<SkPoint3*>(vertex) = {positions.fLeft, positions.fTop, 1.f};
- *reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
- vertex += vertexStride;
-
- // V1
- *reinterpret_cast<SkPoint3*>(vertex) = {positions.fLeft, positions.fBottom, 1.f};
- *reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
- vertex += vertexStride;
-
- // V2
- *reinterpret_cast<SkPoint3*>(vertex) = {positions.fRight, positions.fTop, 1.f};
- *reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
- vertex += vertexStride;
-
- // V3
- *reinterpret_cast<SkPoint3*>(vertex) = {positions.fRight, positions.fBottom, 1.f};
- *reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
-
- subRun->appendVertices(vertexStride);
- fGlyphs[subRun->glyphEndIndex()] = glyph;
- subRun->glyphAppended();
- subRun->setNeedsTransform(!preTransformed);
+ return SkRect::MakeXYWH(origin.x() + dx, origin.y() + dy, width, height);
}
-void GrTextBlob::appendPathGlyph(int runIndex, const SkPath& path, SkScalar x, SkScalar y,
+void GrTextBlob::Run::appendGlyph(GrTextBlob* blob,
+ const sk_sp<GrTextStrike>& strike,
+ const SkGlyph& skGlyph, GrGlyph::MaskStyle maskStyle,
+ SkPoint origin,
+ const SkPMColor4f& color4f, SkGlyphCache* skGlyphCache,
+ SkScalar textRatio, bool needsTransform) {
+
+ GrGlyph::PackedID id = GrGlyph::Pack(skGlyph.getGlyphID(),
+ skGlyph.getSubXFixed(),
+ skGlyph.getSubYFixed(),
+ maskStyle);
+ GrGlyph* glyph = strike->getGlyph(skGlyph, id, skGlyphCache);
+ if (!glyph) {
+ return;
+ }
+
+ SkASSERT(skGlyph.fWidth == glyph->width());
+ SkASSERT(skGlyph.fHeight == glyph->height());
+
+ bool isDFT = maskStyle == GrGlyph::kDistance_MaskStyle;
+
+ SkRect glyphRect = rect_to_draw(skGlyph, origin, textRatio, isDFT);
+ if (!glyphRect.isEmpty()) {
+ // TODO4F: Preserve float colors
+ GrColor color = color4f.toBytes_RGBA();
+
+ GrMaskFormat format = glyph->fMaskFormat;
+
+ Run::SubRunInfo* subRun = &fSubRunInfo.back();
+ if (fInitialized && subRun->maskFormat() != format) {
+ subRun = &pushBackSubRun();
+ subRun->setStrike(strike);
+ } else if (!fInitialized) {
+ subRun->setStrike(strike);
+ }
+
+ fInitialized = true;
+
+ bool hasW = subRun->hasWCoord();
+ // glyphs drawn in perspective must always have a w coord.
+ SkASSERT(hasW || !blob->fInitialViewMatrix.hasPerspective());
+
+ size_t vertexStride = GetVertexStride(format, hasW);
+
+ subRun->setMaskFormat(format);
+
+ subRun->joinGlyphBounds(glyphRect);
+ subRun->setColor(color);
+
+ intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices + subRun->vertexEndIndex());
+
+ // We always write the third position component used by SDFs. If it is unused it gets
+ // overwritten. Similarly, we always write the color and the blob will later overwrite it
+ // with texture coords if it is unused.
+ size_t colorOffset = hasW ? sizeof(SkPoint3) : sizeof(SkPoint);
+ // V0
+ *reinterpret_cast<SkPoint3*>(vertex) = {glyphRect.fLeft, glyphRect.fTop, 1.f};
+ *reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
+ vertex += vertexStride;
+
+ // V1
+ *reinterpret_cast<SkPoint3*>(vertex) = {glyphRect.fLeft, glyphRect.fBottom, 1.f};
+ *reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
+ vertex += vertexStride;
+
+ // V2
+ *reinterpret_cast<SkPoint3*>(vertex) = {glyphRect.fRight, glyphRect.fTop, 1.f};
+ *reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
+ vertex += vertexStride;
+
+ // V3
+ *reinterpret_cast<SkPoint3*>(vertex) = {glyphRect.fRight, glyphRect.fBottom, 1.f};
+ *reinterpret_cast<GrColor*>(vertex + colorOffset) = color;
+
+ subRun->appendVertices(vertexStride);
+ blob->fGlyphs[subRun->glyphEndIndex()] = glyph;
+ subRun->glyphAppended();
+ subRun->setNeedsTransform(needsTransform);
+ }
+}
+
+void GrTextBlob::Run::appendPathGlyph(const SkPath& path, SkPoint position,
SkScalar scale, bool preTransformed) {
- Run& run = fRuns[runIndex];
- run.fPathGlyphs.push_back(GrTextBlob::Run::PathGlyph(path, x, y, scale, preTransformed));
+ fPathGlyphs.push_back(PathGlyph(path, position.x(), position.y(), scale, preTransformed));
}
bool GrTextBlob::mustRegenerate(const SkPaint& paint, bool anyRunHasSubpixelPosition,
@@ -294,7 +331,7 @@
// GrTextBlob::makeOp only takes uint16_t values for run and subRun indices.
// Encountering something larger than this is highly unlikely, so we'll just not draw it.
- int lastRun = SkTMin(fRunCount, (1 << 16)) - 1;
+ int lastRun = SkTMin(fRunCountLimit, (1 << 16)) - 1;
// For each run in the GrTextBlob we're going to churn through all the glyphs.
// Each run is broken into a path part and a Mask / DFT / ARGB part.
for (int runIndex = 0; runIndex <= lastRun; runIndex++) {
@@ -465,8 +502,8 @@
SkASSERT_RELEASE(l.fMinMaxScale == r.fMinMaxScale);
SkASSERT_RELEASE(l.fTextType == r.fTextType);
- SkASSERT_RELEASE(l.fRunCount == r.fRunCount);
- for (int i = 0; i < l.fRunCount; i++) {
+ SkASSERT_RELEASE(l.fRunCountLimit == r.fRunCountLimit);
+ for (int i = 0; i < l.fRunCountLimit; i++) {
const Run& lRun = l.fRuns[i];
const Run& rRun = r.fRuns[i];