Draw glyphs as paths directly.

Change-Id: I31733d19fa65da29a0a0276681647e7cfc593c06
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/499754
Reviewed-by: Herb Derby <herb@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
diff --git a/experimental/graphite/src/Device.h b/experimental/graphite/src/Device.h
index 49504d0..461062c 100644
--- a/experimental/graphite/src/Device.h
+++ b/experimental/graphite/src/Device.h
@@ -116,11 +116,11 @@
     void drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count, sk_sp<SkBlender>,
                    const SkPaint&) override {}
 
-    void drawDrawable(SkDrawable*, const SkMatrix*, SkCanvas*) override {}
+    void drawDrawable(SkCanvas*, SkDrawable*, const SkMatrix*) override {}
     void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&) override {}
     void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override {}
     void drawShadow(const SkPath&, const SkDrawShadowRec&) override {}
-    void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) override {}
+    void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override {}
 
     void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override {}
     void drawSpecial(SkSpecialImage*, const SkMatrix& localToDevice,
diff --git a/src/core/SkBitmapDevice.cpp b/src/core/SkBitmapDevice.cpp
index d8d3de8..a5efca9 100644
--- a/src/core/SkBitmapDevice.cpp
+++ b/src/core/SkBitmapDevice.cpp
@@ -521,9 +521,11 @@
     this->drawRect(*dstPtr, paintWithShader);
 }
 
-void SkBitmapDevice::onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) {
+void SkBitmapDevice::onDrawGlyphRunList(SkCanvas* canvas,
+                                        const SkGlyphRunList& glyphRunList,
+                                        const SkPaint& paint) {
     SkASSERT(!glyphRunList.hasRSXForm());
-    LOOP_TILER( drawGlyphRunList(glyphRunList, paint, &fGlyphPainter), nullptr )
+    LOOP_TILER( drawGlyphRunList(canvas, &fGlyphPainter, glyphRunList, paint), nullptr )
 }
 
 void SkBitmapDevice::drawVertices(const SkVertices* vertices,
diff --git a/src/core/SkBitmapDevice.h b/src/core/SkBitmapDevice.h
index 2f88fa0..47880a4 100644
--- a/src/core/SkBitmapDevice.h
+++ b/src/core/SkBitmapDevice.h
@@ -107,7 +107,7 @@
 
     ///////////////////////////////////////////////////////////////////////////
 
-    void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) override;
+    void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override;
     bool onReadPixels(const SkPixmap&, int x, int y) override;
     bool onWritePixels(const SkPixmap&, int, int) override;
     bool onPeekPixels(SkPixmap*) override;
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index f2a80ee..7c9efcc 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -2295,7 +2295,7 @@
     }
     auto layer = this->aboutToDraw(this, paint, &bounds);
     if (layer) {
-        this->topDevice()->drawGlyphRunList(glyphRunList, layer->paint());
+        this->topDevice()->drawGlyphRunList(this, glyphRunList, layer->paint());
     }
 }
 
@@ -2334,7 +2334,7 @@
         return;
     }
 
-    this->topDevice()->drawSlug(slug);
+    this->topDevice()->drawSlug(this, slug);
 }
 #endif
 
@@ -2528,7 +2528,7 @@
     // drawable bounds are no longer reliable (e.g. android displaylist)
     // so don't use them for quick-reject
     if (this->predrawNotify()) {
-        this->topDevice()->drawDrawable(dr, matrix, this);
+        this->topDevice()->drawDrawable(this, dr, matrix);
     }
 }
 
diff --git a/src/core/SkChromeRemoteGlyphCache.cpp b/src/core/SkChromeRemoteGlyphCache.cpp
index 4ddf253..a352e19 100644
--- a/src/core/SkChromeRemoteGlyphCache.cpp
+++ b/src/core/SkChromeRemoteGlyphCache.cpp
@@ -772,7 +772,9 @@
     }
 
 protected:
-    void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) override {
+    void onDrawGlyphRunList(SkCanvas*,
+                            const SkGlyphRunList& glyphRunList,
+                            const SkPaint& paint) override {
         #if SK_SUPPORT_GPU
         GrContextOptions ctxOptions;
         GrSDFTControl control =
@@ -785,11 +787,11 @@
         drawMatrix.preTranslate(glyphRunList.origin().x(), glyphRunList.origin().y());
         const uint64_t uniqueID = glyphRunList.uniqueID();
         for (auto& glyphRun : glyphRunList) {
-            fPainter.processGlyphRun(glyphRun,
+            fPainter.processGlyphRun(nullptr,
+                                     glyphRun,
                                      drawMatrix,
                                      paint,
                                      control,
-                                     nullptr,
                                      "Cache Diff",
                                      uniqueID);
         }
diff --git a/src/core/SkDevice.cpp b/src/core/SkDevice.cpp
index 797f562..d114b58 100644
--- a/src/core/SkDevice.cpp
+++ b/src/core/SkDevice.cpp
@@ -294,7 +294,7 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-void SkBaseDevice::drawDrawable(SkDrawable* drawable, const SkMatrix* matrix, SkCanvas* canvas) {
+void SkBaseDevice::drawDrawable(SkCanvas* canvas, SkDrawable* drawable, const SkMatrix* matrix) {
     drawable->draw(canvas, matrix);
 }
 
@@ -423,23 +423,27 @@
     return shader->makeWithLocalMatrix(lm_inv * inverse * lm * outer_lm);
 }
 
-void SkBaseDevice::drawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) {
+void SkBaseDevice::drawGlyphRunList(SkCanvas* canvas,
+                                    const SkGlyphRunList& glyphRunList,
+                                    const SkPaint& paint) {
     if (!this->localToDevice().isFinite()) {
         return;
     }
 
     if (!glyphRunList.hasRSXForm()) {
-        this->onDrawGlyphRunList(glyphRunList, paint);
+        this->onDrawGlyphRunList(canvas, glyphRunList, paint);
     } else {
-        this->simplifyGlyphRunRSXFormAndRedraw(glyphRunList, paint);
+        this->simplifyGlyphRunRSXFormAndRedraw(canvas, glyphRunList, paint);
     }
 }
 
-void SkBaseDevice::simplifyGlyphRunRSXFormAndRedraw(const SkGlyphRunList& glyphRunList,
+void SkBaseDevice::simplifyGlyphRunRSXFormAndRedraw(SkCanvas* canvas,
+                                                    const SkGlyphRunList& glyphRunList,
                                                     const SkPaint& paint) {
     for (const SkGlyphRun& run : glyphRunList) {
         if (run.scaledRotations().empty()) {
-            this->drawGlyphRunList(SkGlyphRunList{run, run.sourceBounds(paint), {0, 0}}, paint);
+            SkGlyphRunList subList{run, run.sourceBounds(paint), {0, 0}};
+            this->drawGlyphRunList(canvas, subList, paint);
         } else {
             SkPoint origin = glyphRunList.origin();
             SkPoint sharedPos{0, 0};    // we're at the origin
@@ -453,7 +457,6 @@
                     SkSpan<const SkVector>{}
             };
 
-            const SkM44 originalLocalToDevice = this->localToDevice44();
             for (auto [i, glyphID, pos] : SkMakeEnumerate(run.source())) {
                 sharedGlyphID = glyphID;
                 auto [scos, ssin] = run.scaledRotations()[i];
@@ -467,11 +470,11 @@
                 // change to the ctm.
                 SkPaint invertingPaint{paint};
                 invertingPaint.setShader(make_post_inverse_lm(paint.getShader(), glyphToLocal));
-                this->setLocalToDevice(originalLocalToDevice * SkM44(glyphToLocal));
-                this->drawGlyphRunList(
-                    SkGlyphRunList{glyphRun, glyphRun.sourceBounds(paint), {0, 0}}, invertingPaint);
+                SkAutoCanvasRestore acr(canvas, true);
+                canvas->concat(SkM44(glyphToLocal));
+                SkGlyphRunList subList{glyphRun, glyphRun.sourceBounds(paint), {0, 0}};
+                this->drawGlyphRunList(canvas, subList, invertingPaint);
             }
-            this->setLocalToDevice(originalLocalToDevice);
         }
     }
 }
@@ -483,7 +486,7 @@
     return nullptr;
 }
 
-void SkBaseDevice::drawSlug(GrSlug* slug) {
+void SkBaseDevice::drawSlug(SkCanvas*, GrSlug*) {
     SK_ABORT("GrSlug drawing not supported.");
 }
 #endif
diff --git a/src/core/SkDevice.h b/src/core/SkDevice.h
index 51f681f..ba5b99d 100644
--- a/src/core/SkDevice.h
+++ b/src/core/SkDevice.h
@@ -191,7 +191,7 @@
     virtual skgpu::BaseDevice* asGpuDevice() { return nullptr; }
 
     // Ensure that non-RSXForm runs are passed to onDrawGlyphRunList.
-    void drawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint);
+    void drawGlyphRunList(SkCanvas*, const SkGlyphRunList& glyphRunList, const SkPaint& paint);
 
 protected:
     enum TileUsage {
@@ -293,17 +293,17 @@
                                     const SkSamplingOptions&, const SkPaint&,
                                     SkCanvas::SrcRectConstraint);
 
-    virtual void drawDrawable(SkDrawable*, const SkMatrix*, SkCanvas*);
+    virtual void drawDrawable(SkCanvas*, SkDrawable*, const SkMatrix*);
 
     // Only called with glyphRunLists that do not contain RSXForm.
-    virtual void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) = 0;
+    virtual void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) = 0;
 
     // GrSlug handling routines.
 #if SK_SUPPORT_GPU
     virtual sk_sp<GrSlug> convertGlyphRunListToSlug(
             const SkGlyphRunList& glyphRunList,
             const SkPaint& paint) const;
-    virtual void drawSlug(GrSlug* slug);
+    virtual void drawSlug(SkCanvas*, GrSlug* slug);
 #endif
 
     /**
@@ -414,7 +414,7 @@
     friend class SkSurface_Raster;
     friend class DeviceTestingAccess;
 
-    void simplifyGlyphRunRSXFormAndRedraw(const SkGlyphRunList& glyphRunList, const SkPaint& paint);
+    void simplifyGlyphRunRSXFormAndRedraw(SkCanvas*, const SkGlyphRunList&, const SkPaint&);
 
     // used to change the backend's pixels (and possibly config/rowbytes)
     // but cannot change the width/height, so there should be no change to
@@ -527,7 +527,7 @@
     void drawFilteredImage(const skif::Mapping&, SkSpecialImage* src, const SkImageFilter*,
                            const SkSamplingOptions&, const SkPaint&) override {}
 
-    void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) override {}
+    void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override {}
 
 
     bool isNoPixelsDevice() const override { return true; }
diff --git a/src/core/SkDraw.h b/src/core/SkDraw.h
index 03c5631..4cd1355 100644
--- a/src/core/SkDraw.h
+++ b/src/core/SkDraw.h
@@ -61,9 +61,10 @@
     void    drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull,
                        const SkSamplingOptions&, const SkPaint&) const override;
     void    drawSprite(const SkBitmap&, int x, int y, const SkPaint&) const;
-    void    drawGlyphRunList(const SkGlyphRunList& glyphRunList,
-                             const SkPaint& paint,
-                             SkGlyphRunListPainter* glyphPainter) const;
+    void    drawGlyphRunList(SkCanvas* canvas,
+                             SkGlyphRunListPainter* glyphPainter,
+                             const SkGlyphRunList& glyphRunList,
+                             const SkPaint& paint) const;
     void    drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&) const;
     void  drawAtlas(const SkRSXform[], const SkRect[], const SkColor[], int count,
                     sk_sp<SkBlender>, const SkPaint&);
@@ -81,11 +82,6 @@
         this->drawPath(src, paint, nullptr, false, !isHairline, customBlitter);
     }
 
-    void paintPaths(SkDrawableGlyphBuffer* drawables,
-                    SkScalar scale,
-                    SkPoint origin,
-                    const SkPaint& paint) const override;
-
     void paintMasks(SkDrawableGlyphBuffer* drawables, const SkPaint& paint) const override;
 
     static bool ComputeMaskBounds(const SkRect& devPathBounds, const SkIRect* clipBounds,
diff --git a/src/core/SkDraw_text.cpp b/src/core/SkDraw_text.cpp
index 2c5bff0..fba267a 100644
--- a/src/core/SkDraw_text.cpp
+++ b/src/core/SkDraw_text.cpp
@@ -105,22 +105,10 @@
     }
 }
 
-void SkDraw::paintPaths(SkDrawableGlyphBuffer* drawables,
-                        SkScalar scale,
-                        SkPoint origin,
-                        const SkPaint& paint) const {
-    for (auto [variant, pos] : drawables->drawable()) {
-        const SkPath* path = variant.path();
-        SkMatrix m;
-        SkPoint translate = origin + pos;
-        m.setScaleTranslate(scale, scale, translate.x(), translate.y());
-        this->drawPath(*path, paint, &m, false);
-    }
-}
-
-void SkDraw::drawGlyphRunList(const SkGlyphRunList& glyphRunList,
-                              const SkPaint& paint,
-                              SkGlyphRunListPainter* glyphPainter) const {
+void SkDraw::drawGlyphRunList(SkCanvas* canvas,
+                              SkGlyphRunListPainter* glyphPainter,
+                              const SkGlyphRunList& glyphRunList,
+                              const SkPaint& paint) const {
 
     SkDEBUGCODE(this->validate();)
 
@@ -128,7 +116,8 @@
         return;
     }
 
-    glyphPainter->drawForBitmapDevice(glyphRunList, paint, fMatrixProvider->localToDevice(), this);
+    glyphPainter->drawForBitmapDevice(canvas, this, glyphRunList, paint,
+                                      fMatrixProvider->localToDevice());
 }
 
 #if defined _WIN32
diff --git a/src/core/SkGlyphRun.h b/src/core/SkGlyphRun.h
index b2e77f9..1df972c 100644
--- a/src/core/SkGlyphRun.h
+++ b/src/core/SkGlyphRun.h
@@ -21,6 +21,7 @@
 #include "src/core/SkZip.h"
 
 class SkBaseDevice;
+class SkCanvas;
 class SkGlyph;
 class SkTextBlob;
 class SkTextBlobRunIterator;
diff --git a/src/core/SkGlyphRunPainter.cpp b/src/core/SkGlyphRunPainter.cpp
index 86f6441..9e857eb 100644
--- a/src/core/SkGlyphRunPainter.cpp
+++ b/src/core/SkGlyphRunPainter.cpp
@@ -79,8 +79,8 @@
 #endif // SK_SUPPORT_GPU
 
 void SkGlyphRunListPainter::drawForBitmapDevice(
-        const SkGlyphRunList& glyphRunList, const SkPaint& paint, const SkMatrix& deviceMatrix,
-        const BitmapDevicePainter* bitmapDevice) {
+        SkCanvas* canvas, const BitmapDevicePainter* bitmapDevice,
+        const SkGlyphRunList& glyphRunList, const SkPaint& paint, const SkMatrix& deviceMatrix) {
     ScopedBuffers _ = this->ensureBuffers(glyphRunList);
 
     // TODO: fStrikeCache is only used for GPU, and some compilers complain about it during the no
@@ -115,8 +115,37 @@
             SkPaint pathPaint = paint;
             pathPaint.setAntiAlias(runFont.hasSomeAntiAliasing());
 
-            bitmapDevice->paintPaths(
-                    &fDrawable, strikeToSourceScale, drawOrigin, pathPaint);
+            const bool stroking = pathPaint.getStyle() != SkPaint::kFill_Style;
+            const bool hairline = pathPaint.getStrokeWidth() == 0;
+            const bool needsExactCTM = pathPaint.getShader()
+                                    || pathPaint.getPathEffect()
+                                    || pathPaint.getMaskFilter()
+                                    || (stroking && !hairline);
+            if (!needsExactCTM) {
+                for (auto [variant, pos] : fDrawable.drawable()) {
+                    const SkPath* path = variant.path();
+                    SkMatrix m;
+                    SkPoint translate = drawOrigin + pos;
+                    m.setScaleTranslate(strikeToSourceScale, strikeToSourceScale,
+                                        translate.x(), translate.y());
+                    SkAutoCanvasRestore acr(canvas, true);
+                    canvas->concat(m);
+                    canvas->drawPath(*path, pathPaint);
+                }
+            } else {
+               for (auto [variant, pos] : fDrawable.drawable()) {
+                    const SkPath* path = variant.path();
+                    SkMatrix m;
+                    SkPoint translate = drawOrigin + pos;
+                    m.setScaleTranslate(strikeToSourceScale, strikeToSourceScale,
+                                        translate.x(), translate.y());
+
+                    SkPath deviceOutline;
+                    path->transform(m, &deviceOutline);
+                    deviceOutline.setIsVolatile(true);
+                    canvas->drawPath(deviceOutline, pathPaint);
+                }
+            }
         }
         if (!fRejects.source().empty() && !deviceMatrix.hasPerspective()) {
             SkStrikeSpec strikeSpec = SkStrikeSpec::MakeMask(
@@ -225,11 +254,11 @@
 // extra_cflags = ["-D", "SK_TRACE_GLYPH_RUN_PROCESS"]
 
 #if SK_SUPPORT_GPU
-void SkGlyphRunListPainter::processGlyphRun(const SkGlyphRun& glyphRun,
+void SkGlyphRunListPainter::processGlyphRun(SkGlyphRunPainterInterface* process,
+                                            const SkGlyphRun& glyphRun,
                                             const SkMatrix& drawMatrix,
                                             const SkPaint& runPaint,
                                             const GrSDFTControl& control,
-                                            SkGlyphRunPainterInterface* process,
                                             const char* tag,
                                             uint64_t uniqueID) {
     #if defined(SK_TRACE_GLYPH_RUN_PROCESS)
@@ -344,8 +373,7 @@
             if (process && !fDrawable.drawableIsEmpty()) {
                 // processSourcePaths must be called even if there are no glyphs to make sure
                 // runs are set correctly.
-                process->processSourcePaths(
-                        fDrawable.drawable(), runFont, strikeToSourceScale);
+                process->processSourcePaths(fDrawable.drawable(), runFont, strikeToSourceScale);
             }
         }
     }
diff --git a/src/core/SkGlyphRunPainter.h b/src/core/SkGlyphRunPainter.h
index a65b0d7..a52b88ca 100644
--- a/src/core/SkGlyphRunPainter.h
+++ b/src/core/SkGlyphRunPainter.h
@@ -71,27 +71,23 @@
         BitmapDevicePainter(const BitmapDevicePainter&) = default;
         virtual ~BitmapDevicePainter() = default;
 
-        virtual void paintPaths(
-                SkDrawableGlyphBuffer* drawables, SkScalar scale, SkPoint origin,
-                const SkPaint& paint) const = 0;
-
         virtual void paintMasks(SkDrawableGlyphBuffer* drawables, const SkPaint& paint) const = 0;
         virtual void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull,
                                 const SkSamplingOptions&, const SkPaint&) const = 0;
     };
 
     void drawForBitmapDevice(
-            const SkGlyphRunList& glyphRunList, const SkPaint& paint, const SkMatrix& deviceMatrix,
-            const BitmapDevicePainter* bitmapDevice);
+            SkCanvas* canvas, const BitmapDevicePainter* bitmapDevice,
+            const SkGlyphRunList& glyphRunList, const SkPaint& paint, const SkMatrix& deviceMatrix);
 
 #if SK_SUPPORT_GPU
     // A nullptr for process means that the calls to the cache will be performed, but none of the
     // callbacks will be called.
-    void processGlyphRun(const SkGlyphRun& glyphRun,
+    void processGlyphRun(SkGlyphRunPainterInterface* process,
+                         const SkGlyphRun& glyphRun,
                          const SkMatrix& drawMatrix,
                          const SkPaint& drawPaint,
                          const GrSDFTControl& control,
-                         SkGlyphRunPainterInterface* process,
                          const char* tag = nullptr,
                          uint64_t blobID = SK_InvalidUniqueID);
 #endif  // SK_SUPPORT_GPU
diff --git a/src/core/SkOverdrawCanvas.cpp b/src/core/SkOverdrawCanvas.cpp
index b6426ba..d88a808 100644
--- a/src/core/SkOverdrawCanvas.cpp
+++ b/src/core/SkOverdrawCanvas.cpp
@@ -50,8 +50,6 @@
               fOverdrawCanvas{overdrawCanvas},
               fPainter{props, kN32_SkColorType, nullptr, SkStrikeCache::GlobalStrikeCache()} {}
 
-    void paintPaths(SkDrawableGlyphBuffer*, SkScalar, SkPoint, const SkPaint&) const override {}
-
     void paintMasks(SkDrawableGlyphBuffer* drawables, const SkPaint& paint) const override {
         for (auto t : drawables->drawable()) {
             SkGlyphVariant glyph; SkPoint pos;
@@ -64,9 +62,11 @@
     void    drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull,
                        const SkSamplingOptions&, const SkPaint&) const override {}
 
-    void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) override {
+    void onDrawGlyphRunList(SkCanvas* canvas, const SkGlyphRunList& glyphRunList,
+                            const SkPaint& paint) override {
         SkASSERT(!glyphRunList.hasRSXForm());
-        fPainter.drawForBitmapDevice(glyphRunList, paint, fOverdrawCanvas->getTotalMatrix(), this);
+        fPainter.drawForBitmapDevice(canvas, this, glyphRunList, paint,
+                                     fOverdrawCanvas->getTotalMatrix());
     }
 
 private:
@@ -88,7 +88,7 @@
     this->getProps(&props);
     TextDevice device{this, props};
 
-    device.drawGlyphRunList(glyphRunList, paint);
+    device.drawGlyphRunList(this, glyphRunList, paint);
 }
 
 void SkOverdrawCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
diff --git a/src/gpu/text/GrTextBlob.cpp b/src/gpu/text/GrTextBlob.cpp
index 8c4821f..fdacc0d 100644
--- a/src/gpu/text/GrTextBlob.cpp
+++ b/src/gpu/text/GrTextBlob.cpp
@@ -364,7 +364,8 @@
                                 SkScalar strikeToSourceScale,
                                 GrSubRunAllocator* alloc);
 
-    void submitOps(const GrClip* clip,
+    void submitOps(SkCanvas*,
+                   const GrClip* clip,
                    const SkMatrixProvider& viewMatrix,
                    SkPoint drawOrigin,
                    const SkPaint& paint,
@@ -414,7 +415,8 @@
     return PathOpSubmitter{isAntiAliased, strikeToSourceScale, paths, std::move(pathData)};
 }
 
-void PathOpSubmitter::submitOps(const GrClip* clip,
+void PathOpSubmitter::submitOps(SkCanvas* canvas,
+                                const GrClip* clip,
                                 const SkMatrixProvider& viewMatrix,
                                 SkPoint drawOrigin,
                                 const SkPaint& paint,
@@ -437,14 +439,14 @@
     if (!needsExactCTM) {
         for (const auto& pathPos : fPaths) {
             const SkPath& path = pathPos.fPath;
-            const SkPoint pos = pathPos.fPosition;  // Transform the glyph to source space.
+            const SkPoint pos = pathPos.fPosition;
+            // Transform the glyph to source space.
             SkMatrix pathMatrix = strikeToSource;
             pathMatrix.postTranslate(pos.x(), pos.y());
-            SkPreConcatMatrixProvider strikeToDevice(viewMatrix, pathMatrix);
 
-            GrStyledShape shape(path, paint);
-            GrBlurUtils::drawShapeWithMaskFilter(
-                    sdc->recordingContext(), sdc, clip, runPaint, strikeToDevice, shape);
+            SkAutoCanvasRestore acr(canvas, true);
+            canvas->concat(pathMatrix);
+            canvas->drawPath(path, runPaint);
         }
     } else {
         // Transform the path to device because the deviceMatrix must be unchanged to
@@ -459,9 +461,7 @@
             SkPath deviceOutline;
             path.transform(pathMatrix, &deviceOutline);
             deviceOutline.setIsVolatile(true);
-            GrStyledShape shape(deviceOutline, paint);
-            GrBlurUtils::drawShapeWithMaskFilter(
-                    sdc->recordingContext(), sdc, clip, runPaint, viewMatrix, shape);
+            canvas->drawPath(deviceOutline, runPaint);
         }
     }
 }
@@ -480,12 +480,13 @@
 public:
     PathSubRunSlug(PathOpSubmitter&& pathDrawing) : fPathDrawing(std::move(pathDrawing)) {}
 
-    void draw(const GrClip* clip,
+    void draw(SkCanvas* canvas,
+              const GrClip* clip,
               const SkMatrixProvider& viewMatrix,
               SkPoint drawOrigin,
               const SkPaint& paint,
               skgpu::v1::SurfaceDrawContext* sdc) const override {
-        fPathDrawing.submitOps(clip, viewMatrix, drawOrigin, paint, sdc);
+        fPathDrawing.submitOps(canvas, clip, viewMatrix, drawOrigin, paint, sdc);
     }
 
 private:
@@ -663,7 +664,8 @@
                               GrTextBlob* blob,
                               GrSubRunAllocator* alloc);
 
-    void draw(const GrClip*,
+    void draw(SkCanvas*,
+              const GrClip*,
               const SkMatrixProvider& viewMatrix,
               SkPoint drawOrigin,
               const SkPaint& paint,
@@ -795,7 +797,8 @@
     return SkCount(fGlyphs.glyphs());
 }
 
-void DirectMaskSubRun::draw(const GrClip* clip,
+void DirectMaskSubRun::draw(SkCanvas*,
+                            const GrClip* clip,
                             const SkMatrixProvider& viewMatrix,
                             SkPoint drawOrigin,
                             const SkPaint& paint,
@@ -1060,7 +1063,8 @@
                               GrTextBlob* blob,
                               GrSubRunAllocator* alloc);
 
-    void draw(const GrClip*,
+    void draw(SkCanvas*,
+              const GrClip*,
               const SkMatrixProvider& viewMatrix,
               SkPoint drawOrigin,
               const SkPaint& paint,
@@ -1154,7 +1158,8 @@
             GlyphVector::Make(std::move(strike), drawables.get<0>(), alloc));
 }
 
-void TransformedMaskSubRun::draw(const GrClip* clip,
+void TransformedMaskSubRun::draw(SkCanvas*,
+                                 const GrClip* clip,
                                  const SkMatrixProvider& viewMatrix,
                                  SkPoint drawOrigin,
                                  const SkPaint& paint,
@@ -1284,7 +1289,8 @@
                               GrTextBlob* blob,
                               GrSubRunAllocator* alloc);
 
-    void draw(const GrClip*,
+    void draw(SkCanvas*,
+              const GrClip*,
               const SkMatrixProvider& viewMatrix,
               SkPoint drawOrigin,
               const SkPaint&,
@@ -1395,7 +1401,8 @@
             has_some_antialiasing(runFont));
 }
 
-void SDFTSubRun::draw(const GrClip* clip,
+void SDFTSubRun::draw(SkCanvas*,
+                      const GrClip* clip,
                       const SkMatrixProvider& viewMatrix,
                       SkPoint drawOrigin,
                       const SkPaint& paint,
@@ -1739,11 +1746,11 @@
 
     const uint64_t uniqueID = glyphRunList.uniqueID();
     for (auto& glyphRun : glyphRunList) {
-        painter->processGlyphRun(glyphRun,
+        painter->processGlyphRun(blob.get(),
+                                 glyphRun,
                                  positionMatrix,
                                  paint,
                                  control,
-                                 blob.get(),
                                  "GrTextBlob",
                                  uniqueID);
     }
@@ -1787,13 +1794,14 @@
 const GrTextBlob::Key& GrTextBlob::key() const { return fKey; }
 size_t GrTextBlob::size() const { return fSize; }
 
-void GrTextBlob::draw(const GrClip* clip,
+void GrTextBlob::draw(SkCanvas* canvas,
+                      const GrClip* clip,
                       const SkMatrixProvider& viewMatrix,
                       SkPoint drawOrigin,
                       const SkPaint& paint,
                       skgpu::v1::SurfaceDrawContext* sdc) {
     for (const GrSubRun& subRun : fSubRunList) {
-        subRun.draw(clip, viewMatrix, drawOrigin, paint, sdc);
+        subRun.draw(canvas, clip, viewMatrix, drawOrigin, paint, sdc);
     }
 }
 
@@ -2512,13 +2520,15 @@
 }
 }  // namespace
 
-GrSubRunNoCachePainter::GrSubRunNoCachePainter(skgpu::v1::SurfaceDrawContext* sdc,
+GrSubRunNoCachePainter::GrSubRunNoCachePainter(SkCanvas* canvas,
+                                               skgpu::v1::SurfaceDrawContext* sdc,
                                                GrSubRunAllocator* alloc,
                                                const GrClip* clip,
                                                const SkMatrixProvider& viewMatrix,
                                                const SkGlyphRunList& glyphRunList,
                                                const SkPaint& paint)
-            : fSDC{sdc}
+            : fCanvas{canvas}
+            , fSDC{sdc}
             , fAlloc{alloc}
             , fClip{clip}
             , fViewMatrix{viewMatrix}
@@ -2560,7 +2570,7 @@
                                   strikeToSourceScale,
                                   fAlloc);
 
-    pathDrawing.submitOps(fClip, fViewMatrix, fGlyphRunList.origin(), fPaint, fSDC);
+    pathDrawing.submitOps(fCanvas, fClip, fViewMatrix, fGlyphRunList.origin(), fPaint, fSDC);
 }
 
 void GrSubRunNoCachePainter::processSourceSDFT(const SkZip<SkGlyphVariant, SkPoint>& drawables,
@@ -2603,7 +2613,8 @@
          int allocSize);
     ~Slug() override = default;
 
-    void surfaceDraw(const GrClip* clip,
+    void surfaceDraw(SkCanvas*,
+                     const GrClip* clip,
                      const SkMatrixProvider& viewMatrix,
                      skgpu::v1::SurfaceDrawContext* sdc);
 
@@ -2653,10 +2664,10 @@
            , fOrigin{origin}
            , fAlloc {SkTAddOffset<char>(this, sizeof(Slug)), allocSize, allocSize/2} { }
 
-void Slug::surfaceDraw(const GrClip* clip, const SkMatrixProvider& viewMatrix,
+void Slug::surfaceDraw(SkCanvas* canvas, const GrClip* clip, const SkMatrixProvider& viewMatrix,
                        skgpu::v1::SurfaceDrawContext* sdc) {
     for (const GrSubRun& subRun : fSubRuns) {
-        subRun.draw(clip, viewMatrix, fOrigin, fPaint, sdc);
+        subRun.draw(canvas, clip, viewMatrix, fOrigin, fPaint, sdc);
     }
 }
 
@@ -2677,7 +2688,8 @@
                               GrMaskFormat format,
                               GrSubRunAllocator* alloc);
 
-    void draw(const GrClip* clip,
+    void draw(SkCanvas*,
+              const GrClip* clip,
               const SkMatrixProvider& viewMatrix,
               SkPoint drawOrigin,
               const SkPaint& paint,
@@ -3078,11 +3090,11 @@
 
     const uint64_t uniqueID = glyphRunList.uniqueID();
     for (auto& glyphRun : glyphRunList) {
-        painter->processGlyphRun(glyphRun,
+        painter->processGlyphRun(slug.get(),
+                                 glyphRun,
                                  positionMatrix,
                                  paint,
                                  control,
-                                 slug.get(),
                                  "Slug",
                                  uniqueID);
     }
@@ -3123,7 +3135,8 @@
                               SkScalar strikeToSourceScale,
                               GrSubRunAllocator* alloc);
 
-    void draw(const GrClip* clip,
+    void draw(SkCanvas*,
+              const GrClip* clip,
               const SkMatrixProvider& viewMatrix,
               SkPoint drawOrigin,
               const SkPaint& paint,
@@ -3223,11 +3236,12 @@
             has_some_antialiasing(runFont));
 }
 
-void SDFTSubRunSlug::draw(const GrClip* clip,
-                      const SkMatrixProvider& viewMatrix,
-                      SkPoint drawOrigin,
-                      const SkPaint& paint,
-                      skgpu::v1::SurfaceDrawContext* sdc) const {
+void SDFTSubRunSlug::draw(SkCanvas*,
+                          const GrClip* clip,
+                          const SkMatrixProvider& viewMatrix,
+                          SkPoint drawOrigin,
+                          const SkPaint& paint,
+                          skgpu::v1::SurfaceDrawContext* sdc) const {
     auto[drawingClip, op] = this->makeAtlasTextOp(
             clip, viewMatrix, drawOrigin, paint, sdc, nullptr);
     if (op != nullptr) {
@@ -3347,7 +3361,8 @@
                               GrMaskFormat format,
                               GrSubRunAllocator* alloc);
 
-    void draw(const GrClip*,
+    void draw(SkCanvas*,
+              const GrClip*,
               const SkMatrixProvider& viewMatrix,
               SkPoint drawOrigin,
               const SkPaint&,
@@ -3435,7 +3450,8 @@
             GlyphVector::Make(std::move(strike), drawables.get<0>(), alloc));
 }
 
-void TransformedMaskSubRunSlug::draw(const GrClip* clip,
+void TransformedMaskSubRunSlug::draw(SkCanvas*,
+                                     const GrClip* clip,
                                      const SkMatrixProvider& viewMatrix,
                                      SkPoint drawOrigin,
                                      const SkPaint& paint,
@@ -3552,8 +3568,8 @@
             this->asMatrixProvider(), glyphRunList, paint);
 }
 
-void Device::drawSlug(GrSlug* slug) {
-    fSurfaceDrawContext->drawSlug(this->clip(), this->asMatrixProvider(), slug);
+void Device::drawSlug(SkCanvas* canvas, GrSlug* slug) {
+    fSurfaceDrawContext->drawSlug(canvas, this->clip(), this->asMatrixProvider(), slug);
 }
 
 sk_sp<GrSlug>
@@ -3569,11 +3585,12 @@
     return Slug::Make(viewMatrix, glyphRunList, paint, control, &fGlyphPainter);
 }
 
-void SurfaceDrawContext::drawSlug(const GrClip* clip,
+void SurfaceDrawContext::drawSlug(SkCanvas* canvas,
+                                  const GrClip* clip,
                                   const SkMatrixProvider& viewMatrix,
                                   GrSlug* slugPtr) {
     Slug* slug = static_cast<Slug*>(slugPtr);
 
-    slug->surfaceDraw(clip, viewMatrix, this);
+    slug->surfaceDraw(canvas, clip, viewMatrix, this);
 }
 }  // namespace skgpu::v1
diff --git a/src/gpu/text/GrTextBlob.h b/src/gpu/text/GrTextBlob.h
index 99e0cda..bfd9b14 100644
--- a/src/gpu/text/GrTextBlob.h
+++ b/src/gpu/text/GrTextBlob.h
@@ -95,8 +95,9 @@
 class GrSubRun {
 public:
     virtual ~GrSubRun();
-    // Produce GPU ops for this subRun.
-    virtual void draw(const GrClip*,
+    // Produce GPU ops for this subRun or just draw them.
+    virtual void draw(SkCanvas*,
+                      const GrClip*,
                       const SkMatrixProvider& viewMatrix,
                       SkPoint drawOrigin,
                       const SkPaint&,
@@ -228,7 +229,8 @@
     const Key& key() const;
     size_t size() const;
 
-    void draw(const GrClip* clip,
+    void draw(SkCanvas*,
+              const GrClip* clip,
               const SkMatrixProvider& viewMatrix,
               SkPoint drawOrigin,
               const SkPaint& paint,
@@ -289,7 +291,8 @@
 
 class GrSubRunNoCachePainter : public SkGlyphRunPainterInterface {
 public:
-    GrSubRunNoCachePainter(skgpu::v1::SurfaceDrawContext*,
+    GrSubRunNoCachePainter(SkCanvas*,
+                           skgpu::v1::SurfaceDrawContext*,
                            GrSubRunAllocator*,
                            const GrClip*,
                            const SkMatrixProvider& viewMatrix,
@@ -314,6 +317,7 @@
     // Draw passes ownership of the sub run to the op.
     void draw(GrAtlasSubRunOwner subRun);
 
+    SkCanvas* fCanvas;
     skgpu::v1::SurfaceDrawContext* const fSDC;
     GrSubRunAllocator* const fAlloc;
     const GrClip* const fClip;
diff --git a/src/gpu/text/GrTextBlobRedrawCoordinator.cpp b/src/gpu/text/GrTextBlobRedrawCoordinator.cpp
index 6c3d314..eae4001 100644
--- a/src/gpu/text/GrTextBlobRedrawCoordinator.cpp
+++ b/src/gpu/text/GrTextBlobRedrawCoordinator.cpp
@@ -22,7 +22,8 @@
         , fMessageBusID(messageBusID)
         , fPurgeBlobInbox(messageBusID) { }
 
-void GrTextBlobRedrawCoordinator::drawGlyphRunList(const GrClip* clip,
+void GrTextBlobRedrawCoordinator::drawGlyphRunList(SkCanvas* canvas,
+                                                   const GrClip* clip,
                                                    const SkMatrixProvider& viewMatrix,
                                                    const SkGlyphRunList& glyphRunList,
                                                    const SkPaint& paint,
@@ -65,7 +66,7 @@
         }
     }
 
-    blob->draw(clip, viewMatrix, glyphRunList.origin(), paint, sdc);
+    blob->draw(canvas, clip, viewMatrix, glyphRunList.origin(), paint, sdc);
 }
 
 sk_sp<GrTextBlob> GrTextBlobRedrawCoordinator::addOrReturnExisting(
diff --git a/src/gpu/text/GrTextBlobRedrawCoordinator.h b/src/gpu/text/GrTextBlobRedrawCoordinator.h
index 29e181c..bf6a3fe 100644
--- a/src/gpu/text/GrTextBlobRedrawCoordinator.h
+++ b/src/gpu/text/GrTextBlobRedrawCoordinator.h
@@ -29,7 +29,8 @@
 public:
     GrTextBlobRedrawCoordinator(uint32_t messageBusID);
 
-    void drawGlyphRunList(const GrClip* clip,
+    void drawGlyphRunList(SkCanvas* canvas,
+                          const GrClip* clip,
                           const SkMatrixProvider& viewMatrix,
                           const SkGlyphRunList& glyphRunList,
                           const SkPaint& paint,
diff --git a/src/gpu/v1/Device.cpp b/src/gpu/v1/Device.cpp
index 33f0814..e467ca2 100644
--- a/src/gpu/v1/Device.cpp
+++ b/src/gpu/v1/Device.cpp
@@ -920,7 +920,9 @@
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void Device::onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) {
+void Device::onDrawGlyphRunList(SkCanvas* canvas,
+                                const SkGlyphRunList& glyphRunList,
+                                const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("skgpu::v1::Device", "drawGlyphRunList", fContext.get());
     SkASSERT(!glyphRunList.hasRSXForm());
@@ -934,12 +936,12 @@
     #endif
 
     fSurfaceDrawContext->drawGlyphRunList(
-        this->clip(), this->asMatrixProvider(), glyphRunList, paint);
+        canvas, this->clip(), this->asMatrixProvider(), glyphRunList, paint);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void Device::drawDrawable(SkDrawable* drawable, const SkMatrix* matrix, SkCanvas* canvas) {
+void Device::drawDrawable(SkCanvas* canvas, SkDrawable* drawable, const SkMatrix* matrix) {
     ASSERT_SINGLE_OWNER
 
     GrBackendApi api = this->recordingContext()->backend();
@@ -955,7 +957,7 @@
             return;
         }
     }
-    this->INHERITED::drawDrawable(drawable, matrix, canvas);
+    this->INHERITED::drawDrawable(canvas, drawable, matrix);
 }
 
 
diff --git a/src/gpu/v1/Device_v1.h b/src/gpu/v1/Device_v1.h
index 5d56e91..5822376 100644
--- a/src/gpu/v1/Device_v1.h
+++ b/src/gpu/v1/Device_v1.h
@@ -124,7 +124,7 @@
     void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
                           const SkRect& dst, SkFilterMode, const SkPaint&) override;
 
-    void drawDrawable(SkDrawable*, const SkMatrix*, SkCanvas* canvas) override;
+    void drawDrawable(SkCanvas*, SkDrawable*, const SkMatrix*) override;
 
     void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override;
     void drawSpecial(SkSpecialImage*, const SkMatrix& localToDevice, const SkSamplingOptions&,
@@ -151,13 +151,13 @@
     void onSave() override { fClip.save(); }
     void onRestore() override { fClip.restore(); }
 
-    void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) override;
+    void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override;
 
     sk_sp<GrSlug> convertGlyphRunListToSlug(
             const SkGlyphRunList& glyphRunList,
             const SkPaint& paint) const override;
 
-    void drawSlug(GrSlug* slug) override;
+    void drawSlug(SkCanvas*, GrSlug* slug) override;
 
     void onClipRect(const SkRect& rect, SkClipOp op, bool aa) override {
         SkASSERT(op == SkClipOp::kIntersect || op == SkClipOp::kDifference);
diff --git a/src/gpu/v1/SurfaceDrawContext.cpp b/src/gpu/v1/SurfaceDrawContext.cpp
index 54b7ef8..ae60262 100644
--- a/src/gpu/v1/SurfaceDrawContext.cpp
+++ b/src/gpu/v1/SurfaceDrawContext.cpp
@@ -326,7 +326,8 @@
 #endif
 }
 
-void SurfaceDrawContext::drawGlyphRunListNoCache(const GrClip* clip,
+void SurfaceDrawContext::drawGlyphRunListNoCache(SkCanvas* canvas,
+                                                 const GrClip* clip,
                                                  const SkMatrixProvider& viewMatrix,
                                                  const SkGlyphRunList& glyphRunList,
                                                  const SkPaint& paint) {
@@ -337,20 +338,21 @@
     drawMatrix.preTranslate(drawOrigin.x(), drawOrigin.y());
     GrSubRunAllocator* const alloc = this->subRunAlloc();
 
-    GrSubRunNoCachePainter painter{this, alloc, clip, viewMatrix, glyphRunList, paint};
+    GrSubRunNoCachePainter painter{canvas, this, alloc, clip, viewMatrix, glyphRunList, paint};
     for (auto& glyphRun : glyphRunList) {
         // Make and add the text ops.
-        fGlyphPainter.processGlyphRun(glyphRun,
+        fGlyphPainter.processGlyphRun(&painter,
+                                      glyphRun,
                                       drawMatrix,
                                       paint,
-                                      control,
-                                      &painter);
+                                      control);
     }
 }
 
 // choose to use the GrTextBlob cache or not.
 bool gGrDrawTextNoCache = false;
-void SurfaceDrawContext::drawGlyphRunList(const GrClip* clip,
+void SurfaceDrawContext::drawGlyphRunList(SkCanvas* canvas,
+                                          const GrClip* clip,
                                           const SkMatrixProvider& viewMatrix,
                                           const SkGlyphRunList& glyphRunList,
                                           const SkPaint& paint) {
@@ -370,10 +372,10 @@
         // If the glyphRunList does not have an associated text blob, then it was created by one of
         // the direct draw APIs (drawGlyphs, etc.). There is no need to create a GrTextBlob just
         // build the sub run directly and place it in the op.
-        this->drawGlyphRunListNoCache(clip, viewMatrix, glyphRunList, paint);
+        this->drawGlyphRunListNoCache(canvas, clip, viewMatrix, glyphRunList, paint);
     } else {
         GrTextBlobRedrawCoordinator* textBlobCache = fContext->priv().getTextBlobCache();
-        textBlobCache->drawGlyphRunList(clip, viewMatrix, glyphRunList, paint, this);
+        textBlobCache->drawGlyphRunList(canvas, clip, viewMatrix, glyphRunList, paint, this);
     }
 }
 
diff --git a/src/gpu/v1/SurfaceDrawContext_v1.h b/src/gpu/v1/SurfaceDrawContext_v1.h
index b382187..f0c5b88 100644
--- a/src/gpu/v1/SurfaceDrawContext_v1.h
+++ b/src/gpu/v1/SurfaceDrawContext_v1.h
@@ -487,7 +487,8 @@
      * @param viewMatrix      transformationMatrix
      * @param glyphRunList    text, text positions, and paint.
      */
-    void drawGlyphRunList(const GrClip*,
+    void drawGlyphRunList(SkCanvas*,
+                          const GrClip*,
                           const SkMatrixProvider& viewMatrix,
                           const SkGlyphRunList& glyphRunList,
                           const SkPaint& paint);
@@ -498,7 +499,8 @@
      * @param viewMatrix      transformationMatrix
      * @param glyphRunList    text, text positions, and paint.
      */
-    void drawGlyphRunListNoCache(const GrClip*,
+    void drawGlyphRunListNoCache(SkCanvas*,
+                                 const GrClip*,
                                  const SkMatrixProvider& viewMatrix,
                                  const SkGlyphRunList& glyphRunList,
                                  const SkPaint& paint);
@@ -513,7 +515,8 @@
     /**
      * Draw a slug.
      */
-    void drawSlug(const GrClip* clip,
+    void drawSlug(SkCanvas*,
+                  const GrClip* clip,
                   const SkMatrixProvider& viewMatrix,
                   GrSlug* slugPtr);
 
diff --git a/src/pdf/SkPDFDevice.cpp b/src/pdf/SkPDFDevice.cpp
index 9c21c34..11cdb0b 100644
--- a/src/pdf/SkPDFDevice.cpp
+++ b/src/pdf/SkPDFDevice.cpp
@@ -956,7 +956,9 @@
     }
 }
 
-void SkPDFDevice::onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) {
+void SkPDFDevice::onDrawGlyphRunList(SkCanvas*,
+                                     const SkGlyphRunList& glyphRunList,
+                                     const SkPaint& paint) {
     SkASSERT(!glyphRunList.hasRSXForm());
     for (const SkGlyphRun& glyphRun : glyphRunList) {
         this->internalDrawGlyphRun(glyphRun, glyphRunList.origin(), paint);
diff --git a/src/pdf/SkPDFDevice.h b/src/pdf/SkPDFDevice.h
index 4b4bcda..bad2cda 100644
--- a/src/pdf/SkPDFDevice.h
+++ b/src/pdf/SkPDFDevice.h
@@ -84,7 +84,7 @@
                        const SkSamplingOptions&,
                        const SkPaint&,
                        SkCanvas::SrcRectConstraint) override;
-    void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) override;
+    void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override;
     void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&) override;
     void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override;
 
diff --git a/src/svg/SkSVGDevice.cpp b/src/svg/SkSVGDevice.cpp
index 0b95b4a..ff5ea76 100644
--- a/src/svg/SkSVGDevice.cpp
+++ b/src/svg/SkSVGDevice.cpp
@@ -1071,7 +1071,9 @@
              fHasConstY             = true;
 };
 
-void SkSVGDevice::onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint)  {
+void SkSVGDevice::onDrawGlyphRunList(SkCanvas* canvas,
+                                     const SkGlyphRunList& glyphRunList,
+                                     const SkPaint& paint)  {
     SkASSERT(!glyphRunList.hasRSXForm());
     const auto draw_as_path = (fFlags & SkSVGCanvas::kConvertTextToPaths_Flag) ||
                                paint.getPathEffect();
diff --git a/src/svg/SkSVGDevice.h b/src/svg/SkSVGDevice.h
index df6b5d5..48a786b 100644
--- a/src/svg/SkSVGDevice.h
+++ b/src/svg/SkSVGDevice.h
@@ -35,7 +35,7 @@
                   const SkPaint& paint,
                   bool pathIsMutable = false) override;
 
-    void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) override;
+    void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override;
     void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&) override;
     void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override;
 
diff --git a/src/xps/SkXPSDevice.cpp b/src/xps/SkXPSDevice.cpp
index fd507cc..c9cb33d 100644
--- a/src/xps/SkXPSDevice.cpp
+++ b/src/xps/SkXPSDevice.cpp
@@ -1896,7 +1896,9 @@
     ;
 }
 
-void SkXPSDevice::onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) {
+void SkXPSDevice::onDrawGlyphRunList(SkCanvas*,
+                                     const SkGlyphRunList& glyphRunList,
+                                     const SkPaint& paint) {
     SkASSERT(!glyphRunList.hasRSXForm());
 
     for (const auto& run : glyphRunList) {
diff --git a/src/xps/SkXPSDevice.h b/src/xps/SkXPSDevice.h
index 5505021..e49f13f 100644
--- a/src/xps/SkXPSDevice.h
+++ b/src/xps/SkXPSDevice.h
@@ -92,7 +92,7 @@
                        const SkRect* srcOrNull, const SkRect& dst,
                        const SkSamplingOptions&, const SkPaint& paint,
                        SkCanvas::SrcRectConstraint) override;
-    void onDrawGlyphRunList(const SkGlyphRunList& glyphRunList, const SkPaint& paint) override;
+    void onDrawGlyphRunList(SkCanvas*, const SkGlyphRunList&, const SkPaint&) override;
     void drawVertices(const SkVertices*, sk_sp<SkBlender>, const SkPaint&) override;
     void drawCustomMesh(SkCustomMesh, sk_sp<SkBlender>, const SkPaint&) override;
     void drawDevice(SkBaseDevice*, const SkSamplingOptions&, const SkPaint&) override;