New more efficient run builder

A system for building glyph runs. In the future the builder will
only live in canvas, but it's internal structures facilitate
interacting with the cache a single glyph at a time. When all
the bulk code is in place, only runs will be passed around.

Passing the builder down the text draw stack is temporary.

Change-Id: I6e3ed184b3f3a58b919377f2d31936e971bd8efa
Reviewed-on: https://skia-review.googlesource.com/132928
Reviewed-by: Herb Derby <herb@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Herb Derby <herb@google.com>
diff --git a/src/gpu/text/GrTextContext.cpp b/src/gpu/text/GrTextContext.cpp
index 9864d02..b8fe456 100644
--- a/src/gpu/text/GrTextContext.cpp
+++ b/src/gpu/text/GrTextContext.cpp
@@ -210,15 +210,18 @@
                                     shaderCaps.supportsDistanceFieldText(), fOptions)) {
             switch (it.positioning()) {
                 case SkTextBlob::kDefault_Positioning: {
-                    SkGlyphSet glyphSet;
                     auto origin = SkPoint::Make(x + offset.x(), y + offset.y());
-                    auto glyphRun =
-                            SkGlyphRun::MakeFromDrawText(runPaint.skPaint(),
-                                    (const char*)it.glyphs(), textLen, origin, &glyphSet);
+                    SkGlyphRunBuilder builder;
+                    builder.prepareDrawText(runPaint.skPaint(),
+                                            (const char*)it.glyphs(), textLen, origin);
 
-                    this->drawDFPosText(cacheBlob, run, glyphCache, props, runPaint,
-                                        scalerContextFlags, viewMatrix, (const char*)it.glyphs(),
-                                        textLen, glyphRun.getPositions(), 2, SkPoint::Make(0,0));
+                    builder.temporaryShuntToCallback(
+                            [&](size_t runSize, const char* glyphIDs, const SkScalar* pos) {
+                                this->drawDFPosText(
+                                    cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
+                                    viewMatrix, glyphIDs, 2 * runSize, pos, 2,
+                                    SkPoint::Make(0,0));
+                            });
                     break;
                 }
 
@@ -240,16 +243,18 @@
         } else {
             switch (it.positioning()) {
                 case SkTextBlob::kDefault_Positioning: {
-                    SkGlyphSet glyphSet;
                     auto origin = SkPoint::Make(x + offset.x(), y + offset.y());
-                    auto glyphRun =
-                            SkGlyphRun::MakeFromDrawText(
-                                    runPaint.skPaint(), (const char*) it.glyphs(), textLen, origin,
-                                    &glyphSet);
+                    SkGlyphRunBuilder builder;
+                    builder.prepareDrawText(runPaint.skPaint(),
+                                            (const char*)it.glyphs(), textLen, origin);
 
-                    this->DrawBmpPosText(cacheBlob, run, glyphCache, props, runPaint,
-                                         scalerContextFlags, viewMatrix, (const char*) it.glyphs(),
-                                         textLen, glyphRun.getPositions(), 2, SkPoint::Make(0, 0));
+                    builder.temporaryShuntToCallback(
+                            [&](size_t runSize, const char* glyphIDs, const SkScalar* pos) {
+                                this->DrawBmpPosText(
+                                    cacheBlob, run, glyphCache, props, runPaint, scalerContextFlags,
+                                    viewMatrix, glyphIDs, 2 * runSize,
+                                    pos, 2, SkPoint::Make(0, 0));
+                            });
                     break;
                 }
                 case SkTextBlob::kHorizontal_Positioning:
@@ -768,15 +773,20 @@
     // right now we don't handle textblobs, nor do we handle drawPosText. Since we only intend to
     // test the text op with this unit test, that is okay.
 
-    SkGlyphSet glyphSet;
     auto origin = SkPoint::Make(x, y);
-    auto glyphRun = SkGlyphRun::MakeFromDrawText(skPaint, text, textLen, origin, &glyphSet);
+    SkGlyphRunBuilder builder;
+    builder.prepareDrawText(skPaint, text, textLen, origin);
+    sk_sp<GrTextBlob> blob;
 
-    sk_sp<GrTextBlob> blob(textContext->makeDrawPosTextBlob(
-            context->contextPriv().getTextBlobCache(), glyphCache,
-            *context->contextPriv().caps()->shaderCaps(), utilsPaint,
-            GrTextContext::kTextBlobOpScalerContextFlags, viewMatrix, surfaceProps, text,
-            static_cast<size_t>(textLen), glyphRun.getPositions(), 2, origin));
+    // Use the text and textLen below, because we don't want to mess with the paint.
+    builder.temporaryShuntToCallback(
+            [&](size_t runSize, const char* glyphIDs, const SkScalar* pos) {
+                blob = textContext->makeDrawPosTextBlob(
+                    context->contextPriv().getTextBlobCache(), glyphCache,
+                    *context->contextPriv().caps()->shaderCaps(), utilsPaint,
+                    GrTextContext::kTextBlobOpScalerContextFlags, viewMatrix, surfaceProps, text,
+                    textLen, pos, 2, origin);
+            });
 
     return blob->test_makeOp(textLen, 0, 0, viewMatrix, x, y, utilsPaint, surfaceProps,
                              textContext->dfAdjustTable(), rtc->textTarget());