move blur and path attributes to key

Blur and stroke information were kept out of line with the key.
Make them part of the key, and update operator==.

Change-Id: I2e7669aae4e9c3243c078b039ae796a7e371ef8e
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/315282
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
diff --git a/src/gpu/GrRenderTargetContext.cpp b/src/gpu/GrRenderTargetContext.cpp
index f3b924b..32df05d 100644
--- a/src/gpu/GrRenderTargetContext.cpp
+++ b/src/gpu/GrRenderTargetContext.cpp
@@ -475,25 +475,35 @@
         key.fPixelGeometry = pixelGeometry;
         key.fUniqueID = glyphRunList.uniqueID();
         key.fStyle = blobPaint.getStyle();
+        if (key.fStyle != SkPaint::kFill_Style) {
+            key.fFrameWidth = blobPaint.getStrokeWidth();
+            key.fMiterLimit = blobPaint.getStrokeMiter();
+            key.fJoin = blobPaint.getStrokeJoin();
+        }
         key.fHasBlur = SkToBool(mf);
+        if (key.fHasBlur) {
+            key.fBlurRec = blurRec;
+        }
         key.fCanonicalColor = canonicalColor;
         key.fScalerContextFlags = scalerContextFlags;
         blob = textBlobCache->find(key);
     }
 
     const SkMatrix& drawMatrix(viewMatrix.localToDevice());
-    if (blob == nullptr || !blob->canReuse(blobPaint, blurRec, drawMatrix, drawOrigin)) {
+    if (blob == nullptr || !blob->canReuse(blobPaint, drawMatrix, drawOrigin)) {
         if (blob != nullptr) {
             // We have to remake the blob because changes may invalidate our masks.
             // TODO we could probably get away with reuse most of the time if the pointer is unique,
             //      but we'd have to clear the SubRun information
             textBlobCache->remove(blob.get());
         }
+
+        blob = GrTextBlob::Make(glyphRunList, drawMatrix);
         if (canCache) {
-            blob = textBlobCache->makeCachedBlob(glyphRunList, key, blurRec, drawMatrix);
-        } else {
-            blob = GrTextBlob::Make(glyphRunList, drawMatrix);
+            blob->addKey(key);
+            textBlobCache->add(glyphRunList, blob);
         }
+
         bool supportsSDFT = fContext->priv().caps()->shaderCaps()->supportsDistanceFieldText();
         fGlyphPainter.processGlyphRunList(
                 glyphRunList, drawMatrix, fSurfaceProps, supportsSDFT, options, blob.get());
diff --git a/src/gpu/text/GrTextBlob.cpp b/src/gpu/text/GrTextBlob.cpp
index 0c691e5..6147b8d 100644
--- a/src/gpu/text/GrTextBlob.cpp
+++ b/src/gpu/text/GrTextBlob.cpp
@@ -103,9 +103,9 @@
     for (auto[quad, glyph, leftTop] : quadData) {
         auto[al, at, ar, ab] = glyph->fAtlasLocator.getUVs();
         SkScalar dl = leftTop.x() + deviceOrigin.x(),
-                dt = leftTop.y() + deviceOrigin.y(),
-                dr = dl + (ar - al),
-                db = dt + (ab - at);
+                 dt = leftTop.y() + deviceOrigin.y(),
+                 dr = dl + (ar - al),
+                 db = dt + (ab - at);
 
         quad[0] = {{dl, dt}, color, {al, at}};  // L,T
         quad[1] = {{dl, db}, color, {al, ab}};  // L,B
@@ -123,7 +123,7 @@
     for (auto[quad, glyph, leftTop] : quadData) {
         auto[al, at, ar, ab] = glyph->fAtlasLocator.getUVs();
         uint16_t w = ar - al,
-                h = ab - at;
+                 h = ab - at;
         auto[l, t] = leftTop + deviceOrigin;
         if (clip == nullptr) {
             auto[dl, dt, dr, db] = SkRect::MakeLTRB(l, t, l + w, t + h);
@@ -200,9 +200,9 @@
         SkPoint sLT = (SkPoint::Make(l, t) + inset) * strikeToSource + pos,
                 sRB = (SkPoint::Make(r, b) - inset) * strikeToSource + pos;
         SkPoint3 lt = mapXYZ(sLT.x(), sLT.y()),
-                lb = mapXYZ(sLT.x(), sRB.y()),
-                rt = mapXYZ(sRB.x(), sLT.y()),
-                rb = mapXYZ(sRB.x(), sRB.y());
+                 lb = mapXYZ(sLT.x(), sRB.y()),
+                 rt = mapXYZ(sRB.x(), sLT.y()),
+                 rb = mapXYZ(sRB.x(), sRB.y());
         auto[al, at, ar, ab] = glyph->fAtlasLocator.getUVs();
         quad[0] = {lt, color, {al, at}};  // L,T
         quad[1] = {lb, color, {al, ab}};  // L,B
@@ -215,8 +215,26 @@
 // -- GrTextBlob::Key ------------------------------------------------------------------------------
 GrTextBlob::Key::Key() { sk_bzero(this, sizeof(Key)); }
 
-bool GrTextBlob::Key::operator==(const GrTextBlob::Key& other) const {
-    return 0 == memcmp(this, &other, sizeof(Key));
+bool GrTextBlob::Key::operator==(const GrTextBlob::Key& that) const {
+    if (fUniqueID != that.fUniqueID) { return false; }
+    if (fCanonicalColor != that.fCanonicalColor) { return false; }
+    if (fStyle != that.fStyle) { return false; }
+    if (fStyle != SkPaint::kFill_Style) {
+        if (fFrameWidth != that.fFrameWidth ||
+            fMiterLimit != that.fMiterLimit ||
+            fJoin != that.fJoin) {
+                return false;
+        }
+    }
+    if (fPixelGeometry != that.fPixelGeometry) { return false; }
+    if (fHasBlur != that.fHasBlur) { return false; }
+    if (fHasBlur) {
+        if (fBlurRec.fStyle != that.fBlurRec.fStyle || fBlurRec.fSigma != that.fBlurRec.fSigma) {
+            return false;
+        }
+    }
+    if (fScalerContextFlags != that.fScalerContextFlags) { return false; }
+    return true;
 }
 
 // -- GrPathSubRun::PathGlyph ----------------------------------------------------------------------
@@ -997,21 +1015,12 @@
     return blob;
 }
 
-void GrTextBlob::setupKey(const GrTextBlob::Key& key, const SkMaskFilterBase::BlurRec& blurRec,
-                          const SkPaint& paint) {
-    fKey = key;
-    if (key.fHasBlur) {
-        fBlurRec = blurRec;
-    }
-    if (key.fStyle != SkPaint::kFill_Style) {
-        fStrokeInfo.fFrameWidth = paint.getStrokeWidth();
-        fStrokeInfo.fMiterLimit = paint.getStrokeMiter();
-        fStrokeInfo.fJoin = paint.getStrokeJoin();
-    }
-}
 const GrTextBlob::Key& GrTextBlob::GetKey(const GrTextBlob& blob) { return blob.fKey; }
 uint32_t GrTextBlob::Hash(const GrTextBlob::Key& key) { return SkOpts::hash(&key, sizeof(Key)); }
 
+void GrTextBlob::addKey(const Key& key) {
+    fKey = key;
+}
 bool GrTextBlob::hasDistanceField() const {
     return SkToBool(fTextType & kHasDistanceField_TextType);
 }
@@ -1027,7 +1036,6 @@
 }
 
 bool GrTextBlob::canReuse(const SkPaint& paint,
-                          const SkMaskFilterBase::BlurRec& blurRec,
                           const SkMatrix& drawMatrix,
                           SkPoint drawOrigin) {
     // A singular matrix will create a GrTextBlob with no SubRuns, but unknown glyphs can
@@ -1054,20 +1062,6 @@
         return false;
     }
 
-    // We only cache one masked version
-    if (fKey.fHasBlur &&
-        (fBlurRec.fSigma != blurRec.fSigma || fBlurRec.fStyle != blurRec.fStyle)) {
-        return false;
-    }
-
-    // Similarly, we only cache one version for each style
-    if (fKey.fStyle != SkPaint::kFill_Style &&
-        (fStrokeInfo.fFrameWidth != paint.getStrokeWidth() ||
-         fStrokeInfo.fMiterLimit != paint.getStrokeMiter() ||
-         fStrokeInfo.fJoin != paint.getStrokeJoin())) {
-        return false;
-    }
-
     // Mixed blobs must be regenerated.  We could probably figure out a way to do integer scrolls
     // for mixed blobs if this becomes an issue.
     if (this->hasBitmap() && this->hasDistanceField()) {
diff --git a/src/gpu/text/GrTextBlob.h b/src/gpu/text/GrTextBlob.h
index 28e8662..0817a69 100644
--- a/src/gpu/text/GrTextBlob.h
+++ b/src/gpu/text/GrTextBlob.h
@@ -66,8 +66,12 @@
         // represents the bucket.  This functionality is currently only supported for A8
         SkColor fCanonicalColor;
         SkPaint::Style fStyle;
+        SkScalar fFrameWidth;
+        SkScalar fMiterLimit;
+        SkPaint::Join fJoin;
         SkPixelGeometry fPixelGeometry;
         bool fHasBlur;
+        SkMaskFilterBase::BlurRec fBlurRec;
         uint32_t fScalerContextFlags;
 
         bool operator==(const Key& other) const;
@@ -88,13 +92,10 @@
     static sk_sp<GrTextBlob> Make(const SkGlyphRunList& glyphRunList,
                                   const SkMatrix& drawMatrix);
 
-    // Key manipulation functions
-    void setupKey(const GrTextBlob::Key& key,
-                  const SkMaskFilterBase::BlurRec& blurRec,
-                  const SkPaint& paint);
     static const Key& GetKey(const GrTextBlob& blob);
     static uint32_t Hash(const Key& key);
 
+    void addKey(const Key& key);
     bool hasDistanceField() const;
     bool hasBitmap() const;
     bool hasPerspective() const;
@@ -103,8 +104,7 @@
     void setHasBitmap();
     void setMinAndMaxScale(SkScalar scaledMin, SkScalar scaledMax);
 
-    bool canReuse(const SkPaint& paint, const SkMaskFilterBase::BlurRec& blurRec,
-                  const SkMatrix& drawMatrix, SkPoint drawOrigin);
+    bool canReuse(const SkPaint& paint, const SkMatrix& drawMatrix, SkPoint drawOrigin);
 
     const Key& key() const;
     size_t size() const;
@@ -124,12 +124,6 @@
         kHasBitmap_TextType = 0x2,
     };
 
-    struct StrokeInfo {
-        SkScalar fFrameWidth;
-        SkScalar fMiterLimit;
-        SkPaint::Join fJoin;
-    };
-
     GrTextBlob(size_t allocSize,
                const SkMatrix& drawMatrix,
                SkPoint origin,
@@ -167,8 +161,6 @@
 
     const SkColor fInitialLuminance;
 
-    SkMaskFilterBase::BlurRec fBlurRec;
-    StrokeInfo fStrokeInfo;
     Key fKey;
 
     // We can reuse distance field text, but only if the new view matrix would not result in
diff --git a/src/gpu/text/GrTextBlobCache.cpp b/src/gpu/text/GrTextBlobCache.cpp
index a7647be..815a775 100644
--- a/src/gpu/text/GrTextBlobCache.cpp
+++ b/src/gpu/text/GrTextBlobCache.cpp
@@ -20,16 +20,10 @@
         , fMessageBusID(messageBusID)
         , fPurgeBlobInbox(messageBusID) { }
 
-sk_sp<GrTextBlob>
-GrTextBlobCache::makeCachedBlob(const SkGlyphRunList& glyphRunList, const GrTextBlob::Key& key,
-                                const SkMaskFilterBase::BlurRec& blurRec,
-                                const SkMatrix& viewMatrix) {
-    sk_sp<GrTextBlob> cacheBlob(GrTextBlob::Make(glyphRunList, viewMatrix));
-    cacheBlob->setupKey(key, blurRec, glyphRunList.paint());
+void GrTextBlobCache::add(const SkGlyphRunList& glyphRunList, sk_sp<GrTextBlob> blob) {
     SkAutoSpinlock lock{fSpinLock};
-    this->internalAdd(cacheBlob);
+    this->internalAdd(std::move(blob));
     glyphRunList.temporaryShuntBlobNotifyAddedToCache(fMessageBusID);
-    return cacheBlob;
 }
 
 sk_sp<GrTextBlob> GrTextBlobCache::find(const GrTextBlob::Key& key) {
diff --git a/src/gpu/text/GrTextBlobCache.h b/src/gpu/text/GrTextBlobCache.h
index 1e6dd9e..c973384 100644
--- a/src/gpu/text/GrTextBlobCache.h
+++ b/src/gpu/text/GrTextBlobCache.h
@@ -22,10 +22,8 @@
 public:
     GrTextBlobCache(uint32_t messageBusID);
 
-    sk_sp<GrTextBlob> makeCachedBlob(const SkGlyphRunList& glyphRunList,
-                                     const GrTextBlob::Key& key,
-                                     const SkMaskFilterBase::BlurRec& blurRec,
-                                     const SkMatrix& viewMatrix) SK_EXCLUDES(fSpinLock);
+    void add(const SkGlyphRunList& glyphRunList,
+             sk_sp<GrTextBlob> blob) SK_EXCLUDES(fSpinLock);
 
     sk_sp<GrTextBlob> find(const GrTextBlob::Key& key) SK_EXCLUDES(fSpinLock);