Find a maximum dimension give a list of SkGlyphIDs

In order to simplify buffer and strike handling eventually,
add a routine that will allow finding the maximum dimension of a
list of glyphs. In a future CL, I will use this to simplify
handling calculating the scale factor needed in the drawing of
last resort.

Change-Id: I8ac47328e1dfe59ea80499a83253bb166172a6b0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/552684
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Jim Van Verth <jvanverth@google.com>
diff --git a/src/core/SkChromeRemoteGlyphCache.cpp b/src/core/SkChromeRemoteGlyphCache.cpp
index 9a683ce..6bc011c 100644
--- a/src/core/SkChromeRemoteGlyphCache.cpp
+++ b/src/core/SkChromeRemoteGlyphCache.cpp
@@ -7,6 +7,7 @@
 
 #include "include/private/chromium/SkChromeRemoteGlyphCache.h"
 
+#include <algorithm>
 #include <bitset>
 #include <iterator>
 #include <memory>
@@ -22,6 +23,7 @@
 #include "src/core/SkDevice.h"
 #include "src/core/SkDraw.h"
 #include "src/core/SkEnumerate.h"
+#include "src/core/SkGlyph.h"
 #include "src/core/SkReadBuffer.h"
 #include "src/core/SkScalerCache.h"
 #include "src/core/SkStrikeCache.h"
@@ -186,6 +188,8 @@
     void prepareForDrawableDrawing(
             SkDrawableGlyphBuffer* accepted, SkSourceGlyphBuffer* rejected) override;
 
+    SkScalar findMaximumGlyphDimension(SkSpan<const SkGlyphID> glyphs) override;
+
     void onAboutToExitScope() override {}
 
     sk_sp<SkStrike> getUnderlyingStrike() const override { return nullptr; }
@@ -415,6 +419,16 @@
     return *digest;
 }
 
+SkScalar RemoteStrike::findMaximumGlyphDimension(SkSpan<const SkGlyphID> glyphs) {
+    SkScalar maxDimension = 0;
+    for (SkGlyphID glyphID : glyphs) {
+        SkGlyphDigest digest = this->digest(SkPackedGlyphID{glyphID});
+        maxDimension = std::max(static_cast<SkScalar>(digest.maxDimension()), maxDimension);
+    }
+
+    return maxDimension;
+}
+
 template <typename Rejector>
 void RemoteStrike::commonMaskLoop(
         SkDrawableGlyphBuffer* accepted, SkSourceGlyphBuffer* rejected, Rejector&& reject) {
diff --git a/src/core/SkScalerCache.cpp b/src/core/SkScalerCache.cpp
index f087fa1..133f1ba 100644
--- a/src/core/SkScalerCache.cpp
+++ b/src/core/SkScalerCache.cpp
@@ -203,6 +203,19 @@
     return {{results, glyphIDs.size()}, delta};
 }
 
+std::tuple<SkScalar, size_t> SkScalerCache::findMaximumGlyphDimension(
+        SkSpan<const SkGlyphID> glyphs) {
+    size_t totalIncrease = 0;
+    SkScalar maxDimension = 0;
+    SkAutoMutexExclusive lock{fMu};
+    for (SkGlyphID glyphID : glyphs) {
+        auto [digest, increase] = this->digest(SkPackedGlyphID{glyphID});
+        totalIncrease += increase;
+        maxDimension = std::max(static_cast<SkScalar>(digest.maxDimension()), maxDimension);
+    }
+    return {maxDimension, totalIncrease};
+}
+
 template <typename Fn>
 size_t SkScalerCache::commonFilterLoop(SkDrawableGlyphBuffer* accepted, Fn&& fn) {
     size_t total = 0;
diff --git a/src/core/SkScalerCache.h b/src/core/SkScalerCache.h
index ba538c8..f1068ca 100644
--- a/src/core/SkScalerCache.h
+++ b/src/core/SkScalerCache.h
@@ -87,6 +87,9 @@
     size_t prepareForDrawableDrawing(
             SkDrawableGlyphBuffer* accepted, SkSourceGlyphBuffer* rejected) SK_EXCLUDES(fMu);
 
+    std::tuple<SkScalar, size_t>
+            findMaximumGlyphDimension(SkSpan<const SkGlyphID> glyphs) SK_EXCLUDES(fMu);
+
     void dump() const SK_EXCLUDES(fMu);
 
     SkScalerContext* getScalerContext() const { return fScalerContext.get(); }
diff --git a/src/core/SkStrikeCache.h b/src/core/SkStrikeCache.h
index be26b9a..111c083 100644
--- a/src/core/SkStrikeCache.h
+++ b/src/core/SkStrikeCache.h
@@ -160,6 +160,12 @@
         this->updateDelta(increase);
     }
 
+    SkScalar findMaximumGlyphDimension(SkSpan<const SkGlyphID> glyphs) override {
+        auto [maxDimension, increase] = fScalerCache.findMaximumGlyphDimension(glyphs);
+        this->updateDelta(increase);
+        return maxDimension;
+    }
+
     void onAboutToExitScope() override {
         this->unref();
     }
diff --git a/src/core/SkStrikeForGPU.h b/src/core/SkStrikeForGPU.h
index 757fb49..80712b4 100644
--- a/src/core/SkStrikeForGPU.h
+++ b/src/core/SkStrikeForGPU.h
@@ -52,6 +52,9 @@
     // Return underlying SkStrike for building SubRuns while processing glyph runs.
     virtual sk_sp<SkStrike> getUnderlyingStrike() const = 0;
 
+    // Return the maximum dimension of a span of glyphs.
+    virtual SkScalar findMaximumGlyphDimension(SkSpan<const SkGlyphID> glyphs) = 0;
+
     // Common categories for glyph types used by GPU.
     static bool CanDrawAsMask(const SkGlyph& glyph);
     static bool CanDrawAsSDFT(const SkGlyph& glyph);