Have GPU and RemoteGlyphCache share mask position code
Change-Id: I0d8a969107304883ccd71c9b35ade50e3ac5d341
Reviewed-on: https://skia-review.googlesource.com/149048
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Herb Derby <herb@google.com>
diff --git a/gn/core.gni b/gn/core.gni
index 69e4353..6696887 100644
--- a/gn/core.gni
+++ b/gn/core.gni
@@ -262,6 +262,7 @@
"$_src/core/SkRegion_path.cpp",
"$_src/core/SkRemoteGlyphCache.h",
"$_src/core/SkRemoteGlyphCache.cpp",
+ "$_src/core/SkRemoteGlyphCacheImpl.h",
"$_src/core/SkResourceCache.cpp",
"$_src/core/SkRRect.cpp",
"$_src/core/SkRRectPriv.h",
diff --git a/src/core/SkGlyph.h b/src/core/SkGlyph.h
index d527871..dc4d7db 100644
--- a/src/core/SkGlyph.h
+++ b/src/core/SkGlyph.h
@@ -116,6 +116,7 @@
struct SkPackedGlyphID : public SkPackedID {
SkPackedGlyphID(SkGlyphID code) : SkPackedID(code) { }
SkPackedGlyphID(SkGlyphID code, SkFixed x, SkFixed y) : SkPackedID(code, x, y) { }
+ SkPackedGlyphID(SkGlyphID code, SkIPoint pt) : SkPackedID(code, pt.x(), pt.y()) { }
SkPackedGlyphID() : SkPackedID() { }
SkGlyphID code() const {
return SkTo<SkGlyphID>(SkPackedID::code());
diff --git a/src/core/SkGlyphRun.cpp b/src/core/SkGlyphRun.cpp
index 11688ae..6734c90 100644
--- a/src/core/SkGlyphRun.cpp
+++ b/src/core/SkGlyphRun.cpp
@@ -32,7 +32,7 @@
#include "SkPaintPriv.h"
#include "SkPathEffect.h"
#include "SkRasterClip.h"
-#include "SkRemoteGlyphCache.h"
+#include "SkRemoteGlyphCacheImpl.h"
#include "SkStrikeCache.h"
#include "SkTextBlob.h"
#include "SkTextBlobPriv.h"
@@ -162,20 +162,7 @@
auto pt = origin + *ptCursor++;
if (SkScalarsAreFinite(mappedPt.x(), mappedPt.y())) {
const SkGlyph& glyph = cache->getGlyphMetrics(glyphID, mappedPt);
- if (!glyph.isEmpty()) {
- // Prevent glyphs from being drawn outside of or straddling the edge
- // of device space. Comparisons written a little weirdly so that NaN
- // coordinates are treated safely.
- auto le = [](float a, int b) { return a <= (float)b; };
- auto ge = [](float a, int b) { return a >= (float)b; };
- if (le(mappedPt.fX, INT_MAX - (INT16_MAX + SkTo<int>(UINT16_MAX))) &&
- ge(mappedPt.fX, INT_MIN - (INT16_MIN + 0 /*UINT16_MIN*/)) &&
- le(mappedPt.fY, INT_MAX - (INT16_MAX + SkTo<int>(UINT16_MAX))) &&
- ge(mappedPt.fY, INT_MIN - (INT16_MIN + 0 /*UINT16_MIN*/)))
- {
- eachGlyph(glyph, pt, mappedPt);
- }
- }
+ eachGlyph(glyph, pt, mappedPt);
}
}
}
@@ -879,43 +866,29 @@
}
}
-// -- SkRemoteGlyphCache ---------------------------------------------------------------------------
-
+// -- TrackLayerDevice -----------------------------------------------------------------------------
void SkTextBlobCacheDiffCanvas::TrackLayerDevice::processGlyphRunForMask(
const SkGlyphRun& glyphRun, const SkMatrix& runMatrix, SkPoint origin) {
TRACE_EVENT0("skia", "SkTextBlobCacheDiffCanvas::processGlyphRunForMask");
const SkPaint& runPaint = glyphRun.paint();
- SkSTArenaAlloc<120> arena;
- SkFindAndPlaceGlyph::MapperInterface* mapper =
- SkFindAndPlaceGlyph::CreateMapper(runMatrix, origin, 2, &arena);
-
SkScalerContextEffects effects;
auto* glyphCacheState = fStrikeServer->getOrCreateCache(
runPaint, &this->surfaceProps(), &runMatrix,
SkScalerContextFlags::kFakeGammaAndBoostContrast, &effects);
SkASSERT(glyphCacheState);
- const bool asPath = false;
- bool isSubpixel = glyphCacheState->isSubpixel();
- SkAxisAlignment axisAlignment = glyphCacheState->axisAlignmentForHText();
- auto glyphs = glyphRun.shuntGlyphsIDs();
- auto positions = glyphRun.positions();
- for (uint32_t index = 0; index < glyphRun.runSize(); index++) {
- SkIPoint subPixelPos{0, 0};
- if (isSubpixel) {
- SkPoint glyphPos = mapper->map(positions[index]);
- subPixelPos = SkFindAndPlaceGlyph::SubpixelAlignment(axisAlignment, glyphPos);
- }
+ auto perGlyph = [glyphCacheState] (const SkGlyph& glyph, SkPoint mappedPt) {
+ glyphCacheState->addGlyph(glyph.getPackedID(), false);
+ };
- glyphCacheState->addGlyph(
- SkPackedGlyphID(glyphs[index], subPixelPos.x(), subPixelPos.y()),
- asPath);
- }
+ auto perPath = [](const SkGlyph& glyph, SkPoint position) {};
+
+ fPainter.drawGlyphRunAsBMPWithPathFallback(
+ glyphCacheState, glyphRun, origin, runMatrix, perGlyph, perPath);
}
// -- GrTextContext --------------------------------------------------------------------------------
-
GrColor generate_filtered_color(const SkPaint& paint, const GrColorSpaceInfo& colorSpaceInfo) {
GrColor4f filteredColor = SkColorToUnpremulGrColor4f(paint.getColor(), colorSpaceInfo);
if (paint.getColorFilter() != nullptr) {
@@ -1176,13 +1149,15 @@
auto perGlyph =
[cacheBlob, runIndex, glyphCache, &currStrike, filteredColor, cache{cache.get()}]
(const SkGlyph& glyph, SkPoint mappedPt) {
- const void* glyphImage = cache->findImage(glyph);
- if (glyphImage != nullptr) {
- SkScalar sx = SkScalarFloorToScalar(mappedPt.fX),
- sy = SkScalarFloorToScalar(mappedPt.fY);
- AppendGlyph(cacheBlob, runIndex, glyphCache, &currStrike,
- glyph, GrGlyph::kCoverage_MaskStyle, sx, sy,
- filteredColor, cache, SK_Scalar1, false);
+ if (!glyph.isEmpty()) {
+ const void* glyphImage = cache->findImage(glyph);
+ if (glyphImage != nullptr) {
+ SkScalar sx = SkScalarFloorToScalar(mappedPt.fX),
+ sy = SkScalarFloorToScalar(mappedPt.fY);
+ AppendGlyph(cacheBlob, runIndex, glyphCache, &currStrike,
+ glyph, GrGlyph::kCoverage_MaskStyle, sx, sy,
+ filteredColor, cache, SK_Scalar1, false);
+ }
}
};
@@ -1192,7 +1167,7 @@
const SkPath* glyphPath = cache->findPath(glyph);
if (glyphPath != nullptr) {
SkScalar sx = SkScalarFloorToScalar(position.fX),
- sy = SkScalarFloorToScalar(position.fY);
+ sy = SkScalarFloorToScalar(position.fY);
cacheBlob->appendPathGlyph(
runIndex, *glyphPath, sx, sy, SK_Scalar1, true);
}
diff --git a/src/core/SkRemoteGlyphCache.cpp b/src/core/SkRemoteGlyphCache.cpp
index febc9d1..5417ea1 100644
--- a/src/core/SkRemoteGlyphCache.cpp
+++ b/src/core/SkRemoteGlyphCache.cpp
@@ -18,6 +18,7 @@
#include "SkFindAndPlaceGlyph.h"
#include "SkGlyphRun.h"
#include "SkPathEffect.h"
+#include "SkRemoteGlyphCacheImpl.h"
#include "SkStrikeCache.h"
#include "SkTraceEvent.h"
#include "SkTypeface_remote.h"
@@ -213,11 +214,24 @@
return *lhs == *rhs;
}
+struct StrikeSpec {
+ StrikeSpec() {}
+ StrikeSpec(SkFontID typefaceID_, SkDiscardableHandleId discardableHandleId_)
+ : typefaceID{typefaceID_}, discardableHandleId(discardableHandleId_) {}
+ SkFontID typefaceID = 0u;
+ SkDiscardableHandleId discardableHandleId = 0u;
+ /* desc */
+ /* n X (glyphs ids) */
+};
+
// -- TrackLayerDevice -----------------------------------------------------------------------------
SkTextBlobCacheDiffCanvas::TrackLayerDevice::TrackLayerDevice(
const SkIRect& bounds, const SkSurfaceProps& props, SkStrikeServer* server,
const SkTextBlobCacheDiffCanvas::Settings& settings)
- : SkNoPixelsDevice(bounds, props), fStrikeServer(server), fSettings(settings) {
+ : SkNoPixelsDevice(bounds, props)
+ , fStrikeServer(server)
+ , fSettings(settings)
+ , fPainter{props, kUnknown_SkColorType, SkScalerContextFlags::kFakeGammaAndBoostContrast} {
SkASSERT(fStrikeServer);
}
@@ -375,16 +389,6 @@
SkCanvas::onDrawTextBlob(blob, x, y, paint);
}
-struct StrikeSpec {
- StrikeSpec() {}
- StrikeSpec(SkFontID typefaceID_, SkDiscardableHandleId discardableHandleId_)
- : typefaceID{typefaceID_}, discardableHandleId(discardableHandleId_) {}
- SkFontID typefaceID = 0u;
- SkDiscardableHandleId discardableHandleId = 0u;
- /* desc */
- /* n X (glyphs ids) */
-};
-
struct WireTypeface {
WireTypeface() = default;
WireTypeface(SkFontID typeface_id, int glyph_count, SkFontStyle style, bool is_fixed)
@@ -429,33 +433,6 @@
fLockedDescs.clear();
}
-SkStrikeServer::SkGlyphCacheState::SkGlyphCacheState(
- std::unique_ptr<SkDescriptor> keyDescriptor, uint32_t discardableHandleId)
- : fKeyDescriptor(std::move(keyDescriptor))
- , fDiscardableHandleId(discardableHandleId) {
- SkASSERT(fKeyDescriptor);
-}
-
-SkStrikeServer::SkGlyphCacheState::~SkGlyphCacheState() = default;
-
-void SkStrikeServer::SkGlyphCacheState::ensureScalerContext(
- const SkPaint& paint,
- const SkSurfaceProps* props,
- const SkMatrix* matrix,
- SkScalerContextFlags flags,
- SkScalerContextEffects* effects) {
- if (fContext == nullptr || fDeviceDescriptor == nullptr) {
- SkScalerContextRec deviceRec;
- SkScalerContext::MakeRecAndEffects(paint, props, matrix, flags, &deviceRec, effects, true);
- auto deviceDesc = SkScalerContext::DescriptorGivenRecAndEffects(deviceRec, *effects);
- auto* tf = paint.getTypeface();
- fContext = tf->createScalerContext(*effects, deviceDesc.get(), false);
- fIsSubpixel = fContext->isSubpixel();
- fAxisAlignmentForHText = fContext->computeAxisAlignmentForHText();
- fDeviceDescriptor = std::move(deviceDesc);
- }
-}
-
SkStrikeServer::SkGlyphCacheState* SkStrikeServer::getOrCreateCache(
const SkPaint& paint,
const SkSurfaceProps* props,
@@ -518,6 +495,16 @@
return cacheStatePtr;
}
+// -- SkGlyphCacheState ----------------------------------------------------------------------------
+SkStrikeServer::SkGlyphCacheState::SkGlyphCacheState(
+ std::unique_ptr<SkDescriptor> keyDescriptor, uint32_t discardableHandleId)
+ : fKeyDescriptor(std::move(keyDescriptor))
+ , fDiscardableHandleId(discardableHandleId) {
+ SkASSERT(fKeyDescriptor);
+}
+
+SkStrikeServer::SkGlyphCacheState::~SkGlyphCacheState() = default;
+
void SkStrikeServer::SkGlyphCacheState::addGlyph(SkPackedGlyphID glyph, bool asPath) {
auto* cache = asPath ? &fCachedGlyphPaths : &fCachedGlyphImages;
auto* pending = asPath ? &fPendingGlyphPaths : &fPendingGlyphImages;
@@ -535,8 +522,6 @@
// TODO(khushalsagar): Write a strike only if it has any pending glyphs.
serializer->emplace<bool>(this->hasPendingGlyphs());
if (!this->hasPendingGlyphs()) {
- // See comment below for reset.
- fContext.reset();
return;
}
@@ -603,10 +588,6 @@
writeGlyphPath(glyphID, serializer);
}
fPendingGlyphPaths.clear();
-
- // Note that we reset the context after serializing pending glyphs since we
- // don't want to extend the lifetime of the typeface.
- fContext.reset();
}
const SkGlyph& SkStrikeServer::SkGlyphCacheState::findGlyph(SkPackedGlyphID glyphID) {
@@ -620,6 +601,37 @@
return *glyph;
}
+void SkStrikeServer::SkGlyphCacheState::ensureScalerContext(
+ const SkPaint& paint,
+ const SkSurfaceProps* props,
+ const SkMatrix* matrix,
+ SkScalerContextFlags flags,
+ SkScalerContextEffects* effects) {
+ if (fContext == nullptr || fDeviceDescriptor == nullptr) {
+ SkScalerContextRec deviceRec;
+ SkScalerContext::MakeRecAndEffects(paint, props, matrix, flags, &deviceRec, effects, true);
+ auto deviceDesc = SkScalerContext::DescriptorGivenRecAndEffects(deviceRec, *effects);
+ auto* tf = paint.getTypeface();
+ fContext = tf->createScalerContext(*effects, deviceDesc.get(), false);
+ fIsSubpixel = fContext->isSubpixel();
+ fAxisAlignmentForHText = fContext->computeAxisAlignmentForHText();
+ fDeviceDescriptor = std::move(deviceDesc);
+ }
+}
+
+SkVector SkStrikeServer::SkGlyphCacheState::rounding() const {
+ return SkGlyphCacheCommon::PixelRounding(fIsSubpixel, fAxisAlignmentForHText);
+}
+
+const SkGlyph& SkStrikeServer::SkGlyphCacheState::getGlyphMetrics(
+ SkGlyphID glyphID, SkPoint position) {
+ SkIPoint lookupPoint = SkGlyphCacheCommon::SubpixelLookup(fAxisAlignmentForHText, position);
+ SkPackedGlyphID packedGlyphID = fIsSubpixel ? SkPackedGlyphID{glyphID, lookupPoint}
+ : SkPackedGlyphID{glyphID};
+
+ return this->findGlyph(packedGlyphID);
+}
+
void SkStrikeServer::SkGlyphCacheState::writeGlyphPath(const SkPackedGlyphID& glyphID,
Serializer* serializer) const {
SkPath path;
@@ -634,7 +646,6 @@
}
// SkStrikeClient -----------------------------------------
-
class SkStrikeClient::DiscardableStrikePinner : public SkStrikePinner {
public:
DiscardableStrikePinner(SkDiscardableHandleId discardableHandleId,
diff --git a/src/core/SkRemoteGlyphCache.h b/src/core/SkRemoteGlyphCache.h
index ec8b0eb..d9abb7c 100644
--- a/src/core/SkRemoteGlyphCache.h
+++ b/src/core/SkRemoteGlyphCache.h
@@ -28,11 +28,8 @@
enum SkAxisAlignment : uint32_t;
class SkDescriptor;
class SkGlyphCache;
-class SkGlyphRun;
-class SkGlyphRunList;
struct SkPackedGlyphID;
enum SkScalerContextFlags : uint32_t;
-class SkScalerContextRecDescriptor;
class SkStrikeCache;
class SkTypefaceProxy;
struct WireTypeface;
@@ -80,31 +77,9 @@
const SkPaint& paint) override;
private:
- class TrackLayerDevice : public SkNoPixelsDevice {
- public:
- TrackLayerDevice(const SkIRect& bounds, const SkSurfaceProps& props, SkStrikeServer* server,
- const SkTextBlobCacheDiffCanvas::Settings& settings);
+ class TrackLayerDevice;
- SkBaseDevice* onCreateDevice(const CreateInfo& cinfo, const SkPaint*) override;
- protected:
- void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override;
-
- private:
- void processGlyphRun(const SkPoint& origin, const SkGlyphRun& glyphRun);
-
- void processGlyphRunForMask(
- const SkGlyphRun& glyphRun, const SkMatrix& runMatrix, SkPoint origin);
-
- void processGlyphRunForPaths(const SkGlyphRun& glyphRun, const SkMatrix& runMatrix);
-
-#if SK_SUPPORT_GPU
- bool maybeProcessGlyphRunForDFT(const SkGlyphRun& glyphRun, const SkMatrix& runMatrix);
-#endif
-
- SkStrikeServer* const fStrikeServer;
- const SkTextBlobCacheDiffCanvas::Settings fSettings;
- };
};
using SkDiscardableHandleId = uint32_t;
@@ -147,62 +122,7 @@
void writeStrikeData(std::vector<uint8_t>* memory);
// Methods used internally in skia ------------------------------------------
- class SkGlyphCacheState {
- public:
- // N.B. SkGlyphCacheState is not valid until ensureScalerContext is called.
- SkGlyphCacheState(std::unique_ptr<SkDescriptor> keyDescriptor,
- SkDiscardableHandleId discardableHandleId);
- ~SkGlyphCacheState();
-
- void addGlyph(SkPackedGlyphID, bool pathOnly);
- void writePendingGlyphs(Serializer* serializer);
- SkDiscardableHandleId discardableHandleId() const { return fDiscardableHandleId; }
- const SkDescriptor& getDeviceDescriptor() {
- return *fDeviceDescriptor;
- }
- bool isSubpixel() const { return fIsSubpixel; }
- SkAxisAlignment axisAlignmentForHText() const { return fAxisAlignmentForHText; }
-
- const SkDescriptor& getKeyDescriptor() {
- return *fKeyDescriptor;
- }
- const SkGlyph& findGlyph(SkPackedGlyphID);
- void ensureScalerContext(const SkPaint& paint,
- const SkSurfaceProps* props,
- const SkMatrix* matrix,
- SkScalerContextFlags flags,
- SkScalerContextEffects* effects);
-
- private:
- bool hasPendingGlyphs() const {
- return !fPendingGlyphImages.empty() || !fPendingGlyphPaths.empty();
- }
- void writeGlyphPath(const SkPackedGlyphID& glyphID, Serializer* serializer) const;
-
- // The set of glyphs cached on the remote client.
- SkTHashSet<SkPackedGlyphID> fCachedGlyphImages;
- SkTHashSet<SkPackedGlyphID> fCachedGlyphPaths;
-
- // The set of glyphs which has not yet been serialized and sent to the
- // remote client.
- std::vector<SkPackedGlyphID> fPendingGlyphImages;
- std::vector<SkPackedGlyphID> fPendingGlyphPaths;
-
- // The device descriptor is used to create the scaler context. The glyphs to have the
- // correct device rendering. The key descriptor is used for communication. The GPU side will
- // create descriptors with out the device filtering, thus matching the key descriptor.
- std::unique_ptr<SkDescriptor> fDeviceDescriptor;
- std::unique_ptr<SkDescriptor> fKeyDescriptor;
- const SkDiscardableHandleId fDiscardableHandleId;
- // The context built using fDeviceDescriptor
- std::unique_ptr<SkScalerContext> fContext;
- bool fIsSubpixel = true;
- SkAxisAlignment fAxisAlignmentForHText;
-
- // FallbackTextHelper cases require glyph metrics when analyzing a glyph run, in which case
- // we cache them here.
- SkTHashMap<SkPackedGlyphID, SkGlyph> fGlyphMap;
- };
+ class SkGlyphCacheState;
SkGlyphCacheState* getOrCreateCache(const SkPaint&, const SkSurfaceProps*, const SkMatrix*,
SkScalerContextFlags flags,
diff --git a/src/core/SkRemoteGlyphCacheImpl.h b/src/core/SkRemoteGlyphCacheImpl.h
new file mode 100644
index 0000000..865f37e
--- /dev/null
+++ b/src/core/SkRemoteGlyphCacheImpl.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef SkRemoteGlyphCacheImpl_DEFINED
+#define SkRemoteGlyphCacheImpl_DEFINED
+
+#include "SkRemoteGlyphCache.h"
+#include "SkGlyphRun.h"
+
+class SkStrikeServer::SkGlyphCacheState : public SkGlyphCacheInterface {
+public:
+ // N.B. SkGlyphCacheState is not valid until ensureScalerContext is called.
+ SkGlyphCacheState(std::unique_ptr<SkDescriptor> keyDescriptor,
+ SkDiscardableHandleId discardableHandleId);
+ ~SkGlyphCacheState() override;
+
+ void addGlyph(SkPackedGlyphID, bool pathOnly);
+ void writePendingGlyphs(Serializer* serializer);
+ SkDiscardableHandleId discardableHandleId() const { return fDiscardableHandleId; }
+ const SkDescriptor& getDeviceDescriptor() {
+ return *fDeviceDescriptor;
+ }
+ bool isSubpixel() const { return fIsSubpixel; }
+ SkAxisAlignment axisAlignmentForHText() const { return fAxisAlignmentForHText; }
+
+ const SkDescriptor& getKeyDescriptor() {
+ return *fKeyDescriptor;
+ }
+ const SkGlyph& findGlyph(SkPackedGlyphID);
+
+ void ensureScalerContext(const SkPaint& paint,
+ const SkSurfaceProps* props,
+ const SkMatrix* matrix,
+ SkScalerContextFlags flags,
+ SkScalerContextEffects* effects);
+
+ SkVector rounding() const override;
+
+ const SkGlyph& getGlyphMetrics(SkGlyphID glyphID, SkPoint position) override;
+
+private:
+ bool hasPendingGlyphs() const {
+ return !fPendingGlyphImages.empty() || !fPendingGlyphPaths.empty();
+ }
+ void writeGlyphPath(const SkPackedGlyphID& glyphID, Serializer* serializer) const;
+
+ // The set of glyphs cached on the remote client.
+ SkTHashSet<SkPackedGlyphID> fCachedGlyphImages;
+ SkTHashSet<SkPackedGlyphID> fCachedGlyphPaths;
+
+ // The set of glyphs which has not yet been serialized and sent to the
+ // remote client.
+ std::vector<SkPackedGlyphID> fPendingGlyphImages;
+ std::vector<SkPackedGlyphID> fPendingGlyphPaths;
+
+ // The device descriptor is used to create the scaler context. The glyphs to have the
+ // correct device rendering. The key descriptor is used for communication. The GPU side will
+ // create descriptors with out the device filtering, thus matching the key descriptor.
+ std::unique_ptr<SkDescriptor> fDeviceDescriptor;
+ std::unique_ptr<SkDescriptor> fKeyDescriptor;
+ const SkDiscardableHandleId fDiscardableHandleId;
+ // The context built using fDeviceDescriptor
+ std::unique_ptr<SkScalerContext> fContext;
+ bool fIsSubpixel;
+ SkAxisAlignment fAxisAlignmentForHText;
+
+ // FallbackTextHelper cases require glyph metrics when analyzing a glyph run, in which case
+ // we cache them here.
+ SkTHashMap<SkPackedGlyphID, SkGlyph> fGlyphMap;
+};
+
+class SkTextBlobCacheDiffCanvas::TrackLayerDevice : public SkNoPixelsDevice {
+public:
+ TrackLayerDevice(const SkIRect& bounds, const SkSurfaceProps& props, SkStrikeServer* server,
+ const SkTextBlobCacheDiffCanvas::Settings& settings);
+
+ SkBaseDevice* onCreateDevice(const CreateInfo& cinfo, const SkPaint*) override;
+
+protected:
+ void drawGlyphRunList(const SkGlyphRunList& glyphRunList) override;
+
+private:
+ void processGlyphRun(const SkPoint& origin, const SkGlyphRun& glyphRun);
+
+ void processGlyphRunForMask(
+ const SkGlyphRun& glyphRun, const SkMatrix& runMatrix, SkPoint origin);
+
+ void processGlyphRunForPaths(const SkGlyphRun& glyphRun, const SkMatrix& runMatrix);
+
+#if SK_SUPPORT_GPU
+ bool maybeProcessGlyphRunForDFT(const SkGlyphRun& glyphRun, const SkMatrix& runMatrix);
+#endif
+
+ SkStrikeServer* const fStrikeServer;
+ const SkTextBlobCacheDiffCanvas::Settings fSettings;
+ SkGlyphRunListPainter fPainter;
+};
+
+#endif // SkRemoteGlyphCacheImpl_DEFINED
diff --git a/tests/SkRemoteGlyphCacheTest.cpp b/tests/SkRemoteGlyphCacheTest.cpp
index fd6350e..60ef272 100644
--- a/tests/SkRemoteGlyphCacheTest.cpp
+++ b/tests/SkRemoteGlyphCacheTest.cpp
@@ -9,6 +9,7 @@
#include "SkGraphics.h"
#include "SkMutex.h"
#include "SkRemoteGlyphCache.h"
+#include "SkRemoteGlyphCacheImpl.h"
#include "SkStrikeCache.h"
#include "SkSurface.h"
#include "SkTextBlob.h"