1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2015 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "src/text/gpu/TextBlob.h"
9*c8dee2aaSAndroid Build Coastguard Worker
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkScalar.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/SkColorData.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkCPUTypes.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkDevice.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkFontPriv.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkMaskFilterBase.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkPaintPriv.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkScalerContext.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "src/text/GlyphRun.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/text/gpu/SlugImpl.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/text/gpu/SubRunAllocator.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/text/gpu/SubRunContainer.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/text/gpu/SubRunControl.h"
27*c8dee2aaSAndroid Build Coastguard Worker
28*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
29*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
30*c8dee2aaSAndroid Build Coastguard Worker
31*c8dee2aaSAndroid Build Coastguard Worker class SkMaskFilter;
32*c8dee2aaSAndroid Build Coastguard Worker
33*c8dee2aaSAndroid Build Coastguard Worker using namespace sktext::gpu;
34*c8dee2aaSAndroid Build Coastguard Worker namespace {
35*c8dee2aaSAndroid Build Coastguard Worker
36*c8dee2aaSAndroid Build Coastguard Worker // Check for integer translate with the same 2x2 matrix.
37*c8dee2aaSAndroid Build Coastguard Worker // Returns the translation, and true if the change from initial matrix to the position matrix
38*c8dee2aaSAndroid Build Coastguard Worker // support using direct glyph masks.
can_use_direct(const SkMatrix & initialPositionMatrix,const SkMatrix & positionMatrix)39*c8dee2aaSAndroid Build Coastguard Worker std::tuple<bool, SkVector> can_use_direct(
40*c8dee2aaSAndroid Build Coastguard Worker const SkMatrix& initialPositionMatrix, const SkMatrix& positionMatrix) {
41*c8dee2aaSAndroid Build Coastguard Worker // The existing direct glyph info can be used if the initialPositionMatrix, and the
42*c8dee2aaSAndroid Build Coastguard Worker // positionMatrix have the same 2x2, and the translation between them is integer.
43*c8dee2aaSAndroid Build Coastguard Worker // Calculate the translation in source space to a translation in device space by mapping
44*c8dee2aaSAndroid Build Coastguard Worker // (0, 0) through both the initial position matrix and the position matrix; take the difference.
45*c8dee2aaSAndroid Build Coastguard Worker SkVector translation = positionMatrix.mapOrigin() - initialPositionMatrix.mapOrigin();
46*c8dee2aaSAndroid Build Coastguard Worker return {initialPositionMatrix.getScaleX() == positionMatrix.getScaleX() &&
47*c8dee2aaSAndroid Build Coastguard Worker initialPositionMatrix.getScaleY() == positionMatrix.getScaleY() &&
48*c8dee2aaSAndroid Build Coastguard Worker initialPositionMatrix.getSkewX() == positionMatrix.getSkewX() &&
49*c8dee2aaSAndroid Build Coastguard Worker initialPositionMatrix.getSkewY() == positionMatrix.getSkewY() &&
50*c8dee2aaSAndroid Build Coastguard Worker SkScalarIsInt(translation.x()) && SkScalarIsInt(translation.y()),
51*c8dee2aaSAndroid Build Coastguard Worker translation};
52*c8dee2aaSAndroid Build Coastguard Worker }
53*c8dee2aaSAndroid Build Coastguard Worker
54*c8dee2aaSAndroid Build Coastguard Worker
compute_canonical_color(const SkPaint & paint,bool lcd)55*c8dee2aaSAndroid Build Coastguard Worker static SkColor compute_canonical_color(const SkPaint& paint, bool lcd) {
56*c8dee2aaSAndroid Build Coastguard Worker SkColor canonicalColor = SkPaintPriv::ComputeLuminanceColor(paint);
57*c8dee2aaSAndroid Build Coastguard Worker if (lcd) {
58*c8dee2aaSAndroid Build Coastguard Worker // This is the correct computation for canonicalColor, but there are tons of cases where LCD
59*c8dee2aaSAndroid Build Coastguard Worker // can be modified. For now we just regenerate if any run in a textblob has LCD.
60*c8dee2aaSAndroid Build Coastguard Worker // TODO figure out where all of these modifications are and see if we can incorporate that
61*c8dee2aaSAndroid Build Coastguard Worker // logic at a higher level *OR* use sRGB
62*c8dee2aaSAndroid Build Coastguard Worker //canonicalColor = SkMaskGamma::CanonicalColor(canonicalColor);
63*c8dee2aaSAndroid Build Coastguard Worker
64*c8dee2aaSAndroid Build Coastguard Worker // TODO we want to figure out a way to be able to use the canonical color on LCD text,
65*c8dee2aaSAndroid Build Coastguard Worker // see the note above. We pick a placeholder value for LCD text to ensure we always match
66*c8dee2aaSAndroid Build Coastguard Worker // the same key
67*c8dee2aaSAndroid Build Coastguard Worker return SK_ColorTRANSPARENT;
68*c8dee2aaSAndroid Build Coastguard Worker } else {
69*c8dee2aaSAndroid Build Coastguard Worker // A8, though can have mixed BMP text but it shouldn't matter because BMP text won't have
70*c8dee2aaSAndroid Build Coastguard Worker // gamma corrected masks anyways, nor color
71*c8dee2aaSAndroid Build Coastguard Worker U8CPU lum = SkComputeLuminance(SkColorGetR(canonicalColor),
72*c8dee2aaSAndroid Build Coastguard Worker SkColorGetG(canonicalColor),
73*c8dee2aaSAndroid Build Coastguard Worker SkColorGetB(canonicalColor));
74*c8dee2aaSAndroid Build Coastguard Worker // reduce to our finite number of bits
75*c8dee2aaSAndroid Build Coastguard Worker canonicalColor = SkMaskGamma::CanonicalColor(SkColorSetRGB(lum, lum, lum));
76*c8dee2aaSAndroid Build Coastguard Worker }
77*c8dee2aaSAndroid Build Coastguard Worker return canonicalColor;
78*c8dee2aaSAndroid Build Coastguard Worker }
79*c8dee2aaSAndroid Build Coastguard Worker
80*c8dee2aaSAndroid Build Coastguard Worker } // namespace
81*c8dee2aaSAndroid Build Coastguard Worker
82*c8dee2aaSAndroid Build Coastguard Worker namespace sktext::gpu {
83*c8dee2aaSAndroid Build Coastguard Worker // -- TextBlob::Key ------------------------------------------------------------------------------
Make(const GlyphRunList & glyphRunList,const SkPaint & paint,const SkMatrix & drawMatrix,const SkStrikeDeviceInfo & strikeDevice)84*c8dee2aaSAndroid Build Coastguard Worker auto TextBlob::Key::Make(const GlyphRunList& glyphRunList,
85*c8dee2aaSAndroid Build Coastguard Worker const SkPaint& paint,
86*c8dee2aaSAndroid Build Coastguard Worker const SkMatrix& drawMatrix,
87*c8dee2aaSAndroid Build Coastguard Worker const SkStrikeDeviceInfo& strikeDevice) -> std::tuple<bool, Key> {
88*c8dee2aaSAndroid Build Coastguard Worker SkASSERT(strikeDevice.fSubRunControl != nullptr);
89*c8dee2aaSAndroid Build Coastguard Worker SkMaskFilterBase::BlurRec blurRec;
90*c8dee2aaSAndroid Build Coastguard Worker // It might be worth caching these things, but its not clear at this time
91*c8dee2aaSAndroid Build Coastguard Worker // TODO for animated mask filters, this will fill up our cache. We need a safeguard here
92*c8dee2aaSAndroid Build Coastguard Worker const SkMaskFilter* maskFilter = paint.getMaskFilter();
93*c8dee2aaSAndroid Build Coastguard Worker bool canCache = glyphRunList.canCache() &&
94*c8dee2aaSAndroid Build Coastguard Worker !(paint.getPathEffect() ||
95*c8dee2aaSAndroid Build Coastguard Worker (maskFilter && !as_MFB(maskFilter)->asABlur(&blurRec)));
96*c8dee2aaSAndroid Build Coastguard Worker
97*c8dee2aaSAndroid Build Coastguard Worker TextBlob::Key key;
98*c8dee2aaSAndroid Build Coastguard Worker if (canCache) {
99*c8dee2aaSAndroid Build Coastguard Worker bool hasLCD = glyphRunList.anyRunsLCD();
100*c8dee2aaSAndroid Build Coastguard Worker
101*c8dee2aaSAndroid Build Coastguard Worker // We canonicalize all non-lcd draws to use kUnknown_SkPixelGeometry
102*c8dee2aaSAndroid Build Coastguard Worker SkPixelGeometry pixelGeometry = hasLCD ? strikeDevice.fSurfaceProps.pixelGeometry()
103*c8dee2aaSAndroid Build Coastguard Worker : kUnknown_SkPixelGeometry;
104*c8dee2aaSAndroid Build Coastguard Worker
105*c8dee2aaSAndroid Build Coastguard Worker SkColor canonicalColor = compute_canonical_color(paint, hasLCD);
106*c8dee2aaSAndroid Build Coastguard Worker
107*c8dee2aaSAndroid Build Coastguard Worker key.fPixelGeometry = pixelGeometry;
108*c8dee2aaSAndroid Build Coastguard Worker key.fUniqueID = glyphRunList.uniqueID();
109*c8dee2aaSAndroid Build Coastguard Worker key.fStyle = paint.getStyle();
110*c8dee2aaSAndroid Build Coastguard Worker if (key.fStyle != SkPaint::kFill_Style) {
111*c8dee2aaSAndroid Build Coastguard Worker key.fFrameWidth = paint.getStrokeWidth();
112*c8dee2aaSAndroid Build Coastguard Worker key.fMiterLimit = paint.getStrokeMiter();
113*c8dee2aaSAndroid Build Coastguard Worker key.fJoin = paint.getStrokeJoin();
114*c8dee2aaSAndroid Build Coastguard Worker }
115*c8dee2aaSAndroid Build Coastguard Worker key.fHasBlur = maskFilter != nullptr;
116*c8dee2aaSAndroid Build Coastguard Worker if (key.fHasBlur) {
117*c8dee2aaSAndroid Build Coastguard Worker key.fBlurRec = blurRec;
118*c8dee2aaSAndroid Build Coastguard Worker }
119*c8dee2aaSAndroid Build Coastguard Worker key.fCanonicalColor = canonicalColor;
120*c8dee2aaSAndroid Build Coastguard Worker key.fScalerContextFlags = SkTo<uint32_t>(strikeDevice.fScalerContextFlags);
121*c8dee2aaSAndroid Build Coastguard Worker
122*c8dee2aaSAndroid Build Coastguard Worker // Do any runs use direct drawing types?.
123*c8dee2aaSAndroid Build Coastguard Worker key.fHasSomeDirectSubRuns = false;
124*c8dee2aaSAndroid Build Coastguard Worker SkPoint glyphRunListLocation = glyphRunList.sourceBoundsWithOrigin().center();
125*c8dee2aaSAndroid Build Coastguard Worker for (auto& run : glyphRunList) {
126*c8dee2aaSAndroid Build Coastguard Worker SkScalar approximateDeviceTextSize =
127*c8dee2aaSAndroid Build Coastguard Worker SkFontPriv::ApproximateTransformedTextSize(run.font(), drawMatrix,
128*c8dee2aaSAndroid Build Coastguard Worker glyphRunListLocation);
129*c8dee2aaSAndroid Build Coastguard Worker key.fHasSomeDirectSubRuns |=
130*c8dee2aaSAndroid Build Coastguard Worker strikeDevice.fSubRunControl->isDirect(approximateDeviceTextSize, paint,
131*c8dee2aaSAndroid Build Coastguard Worker drawMatrix);
132*c8dee2aaSAndroid Build Coastguard Worker }
133*c8dee2aaSAndroid Build Coastguard Worker
134*c8dee2aaSAndroid Build Coastguard Worker if (key.fHasSomeDirectSubRuns) {
135*c8dee2aaSAndroid Build Coastguard Worker // Store the fractional offset of the position. We know that the matrix can't be
136*c8dee2aaSAndroid Build Coastguard Worker // perspective at this point.
137*c8dee2aaSAndroid Build Coastguard Worker SkPoint mappedOrigin = drawMatrix.mapOrigin();
138*c8dee2aaSAndroid Build Coastguard Worker key.fPositionMatrix = drawMatrix;
139*c8dee2aaSAndroid Build Coastguard Worker key.fPositionMatrix.setTranslateX(
140*c8dee2aaSAndroid Build Coastguard Worker mappedOrigin.x() - SkScalarFloorToScalar(mappedOrigin.x()));
141*c8dee2aaSAndroid Build Coastguard Worker key.fPositionMatrix.setTranslateY(
142*c8dee2aaSAndroid Build Coastguard Worker mappedOrigin.y() - SkScalarFloorToScalar(mappedOrigin.y()));
143*c8dee2aaSAndroid Build Coastguard Worker } else {
144*c8dee2aaSAndroid Build Coastguard Worker // For path and SDFT, the matrix doesn't matter.
145*c8dee2aaSAndroid Build Coastguard Worker key.fPositionMatrix = SkMatrix::I();
146*c8dee2aaSAndroid Build Coastguard Worker }
147*c8dee2aaSAndroid Build Coastguard Worker }
148*c8dee2aaSAndroid Build Coastguard Worker
149*c8dee2aaSAndroid Build Coastguard Worker return {canCache, key};
150*c8dee2aaSAndroid Build Coastguard Worker }
151*c8dee2aaSAndroid Build Coastguard Worker
operator ==(const TextBlob::Key & that) const152*c8dee2aaSAndroid Build Coastguard Worker bool TextBlob::Key::operator==(const TextBlob::Key& that) const {
153*c8dee2aaSAndroid Build Coastguard Worker if (fUniqueID != that.fUniqueID) { return false; }
154*c8dee2aaSAndroid Build Coastguard Worker if (fCanonicalColor != that.fCanonicalColor) { return false; }
155*c8dee2aaSAndroid Build Coastguard Worker if (fStyle != that.fStyle) { return false; }
156*c8dee2aaSAndroid Build Coastguard Worker if (fStyle != SkPaint::kFill_Style) {
157*c8dee2aaSAndroid Build Coastguard Worker if (fFrameWidth != that.fFrameWidth ||
158*c8dee2aaSAndroid Build Coastguard Worker fMiterLimit != that.fMiterLimit ||
159*c8dee2aaSAndroid Build Coastguard Worker fJoin != that.fJoin) {
160*c8dee2aaSAndroid Build Coastguard Worker return false;
161*c8dee2aaSAndroid Build Coastguard Worker }
162*c8dee2aaSAndroid Build Coastguard Worker }
163*c8dee2aaSAndroid Build Coastguard Worker if (fPixelGeometry != that.fPixelGeometry) { return false; }
164*c8dee2aaSAndroid Build Coastguard Worker if (fHasBlur != that.fHasBlur) { return false; }
165*c8dee2aaSAndroid Build Coastguard Worker if (fHasBlur) {
166*c8dee2aaSAndroid Build Coastguard Worker if (fBlurRec.fStyle != that.fBlurRec.fStyle || fBlurRec.fSigma != that.fBlurRec.fSigma) {
167*c8dee2aaSAndroid Build Coastguard Worker return false;
168*c8dee2aaSAndroid Build Coastguard Worker }
169*c8dee2aaSAndroid Build Coastguard Worker }
170*c8dee2aaSAndroid Build Coastguard Worker
171*c8dee2aaSAndroid Build Coastguard Worker if (fScalerContextFlags != that.fScalerContextFlags) { return false; }
172*c8dee2aaSAndroid Build Coastguard Worker
173*c8dee2aaSAndroid Build Coastguard Worker // DirectSubRuns do not support perspective when used with a TextBlob. SDFT, Transformed,
174*c8dee2aaSAndroid Build Coastguard Worker // Path, and Drawable do support perspective.
175*c8dee2aaSAndroid Build Coastguard Worker if (fPositionMatrix.hasPerspective() && fHasSomeDirectSubRuns) { return false; }
176*c8dee2aaSAndroid Build Coastguard Worker
177*c8dee2aaSAndroid Build Coastguard Worker if (fHasSomeDirectSubRuns != that.fHasSomeDirectSubRuns) { return false; }
178*c8dee2aaSAndroid Build Coastguard Worker
179*c8dee2aaSAndroid Build Coastguard Worker if (fHasSomeDirectSubRuns) {
180*c8dee2aaSAndroid Build Coastguard Worker auto [compatible, _] = can_use_direct(fPositionMatrix, that.fPositionMatrix);
181*c8dee2aaSAndroid Build Coastguard Worker return compatible;
182*c8dee2aaSAndroid Build Coastguard Worker }
183*c8dee2aaSAndroid Build Coastguard Worker
184*c8dee2aaSAndroid Build Coastguard Worker return true;
185*c8dee2aaSAndroid Build Coastguard Worker }
186*c8dee2aaSAndroid Build Coastguard Worker
187*c8dee2aaSAndroid Build Coastguard Worker // -- TextBlob -----------------------------------------------------------------------------------
operator delete(void * p)188*c8dee2aaSAndroid Build Coastguard Worker void TextBlob::operator delete(void* p) { ::operator delete(p); }
operator new(size_t)189*c8dee2aaSAndroid Build Coastguard Worker void* TextBlob::operator new(size_t) { SK_ABORT("All blobs are created by placement new."); }
operator new(size_t,void * p)190*c8dee2aaSAndroid Build Coastguard Worker void* TextBlob::operator new(size_t, void* p) { return p; }
191*c8dee2aaSAndroid Build Coastguard Worker
192*c8dee2aaSAndroid Build Coastguard Worker TextBlob::~TextBlob() = default;
193*c8dee2aaSAndroid Build Coastguard Worker
Make(const GlyphRunList & glyphRunList,const SkPaint & paint,const SkMatrix & positionMatrix,SkStrikeDeviceInfo strikeDeviceInfo,StrikeForGPUCacheInterface * strikeCache)194*c8dee2aaSAndroid Build Coastguard Worker sk_sp<TextBlob> TextBlob::Make(const GlyphRunList& glyphRunList,
195*c8dee2aaSAndroid Build Coastguard Worker const SkPaint& paint,
196*c8dee2aaSAndroid Build Coastguard Worker const SkMatrix& positionMatrix,
197*c8dee2aaSAndroid Build Coastguard Worker SkStrikeDeviceInfo strikeDeviceInfo,
198*c8dee2aaSAndroid Build Coastguard Worker StrikeForGPUCacheInterface* strikeCache) {
199*c8dee2aaSAndroid Build Coastguard Worker size_t subRunSizeHint = SubRunContainer::EstimateAllocSize(glyphRunList);
200*c8dee2aaSAndroid Build Coastguard Worker auto [initializer, totalMemoryAllocated, alloc] =
201*c8dee2aaSAndroid Build Coastguard Worker SubRunAllocator::AllocateClassMemoryAndArena<TextBlob>(subRunSizeHint);
202*c8dee2aaSAndroid Build Coastguard Worker
203*c8dee2aaSAndroid Build Coastguard Worker auto container = SubRunContainer::MakeInAlloc(
204*c8dee2aaSAndroid Build Coastguard Worker glyphRunList, positionMatrix, paint,
205*c8dee2aaSAndroid Build Coastguard Worker strikeDeviceInfo, strikeCache, &alloc, SubRunContainer::kAddSubRuns, "TextBlob");
206*c8dee2aaSAndroid Build Coastguard Worker
207*c8dee2aaSAndroid Build Coastguard Worker SkColor initialLuminance = SkPaintPriv::ComputeLuminanceColor(paint);
208*c8dee2aaSAndroid Build Coastguard Worker sk_sp<TextBlob> blob = sk_sp<TextBlob>(initializer.initialize(std::move(alloc),
209*c8dee2aaSAndroid Build Coastguard Worker std::move(container),
210*c8dee2aaSAndroid Build Coastguard Worker totalMemoryAllocated,
211*c8dee2aaSAndroid Build Coastguard Worker initialLuminance));
212*c8dee2aaSAndroid Build Coastguard Worker return blob;
213*c8dee2aaSAndroid Build Coastguard Worker }
214*c8dee2aaSAndroid Build Coastguard Worker
addKey(const Key & key)215*c8dee2aaSAndroid Build Coastguard Worker void TextBlob::addKey(const Key& key) {
216*c8dee2aaSAndroid Build Coastguard Worker fKey = key;
217*c8dee2aaSAndroid Build Coastguard Worker }
218*c8dee2aaSAndroid Build Coastguard Worker
canReuse(const SkPaint & paint,const SkMatrix & positionMatrix) const219*c8dee2aaSAndroid Build Coastguard Worker bool TextBlob::canReuse(const SkPaint& paint, const SkMatrix& positionMatrix) const {
220*c8dee2aaSAndroid Build Coastguard Worker // A singular matrix will create a TextBlob with no SubRuns, but unknown glyphs can also
221*c8dee2aaSAndroid Build Coastguard Worker // cause empty runs. If there are no subRuns, then regenerate when the matrices don't match.
222*c8dee2aaSAndroid Build Coastguard Worker if (fSubRuns->isEmpty() && fSubRuns->initialPosition() != positionMatrix) {
223*c8dee2aaSAndroid Build Coastguard Worker return false;
224*c8dee2aaSAndroid Build Coastguard Worker }
225*c8dee2aaSAndroid Build Coastguard Worker
226*c8dee2aaSAndroid Build Coastguard Worker // If we have LCD text then our canonical color will be set to transparent, in this case we have
227*c8dee2aaSAndroid Build Coastguard Worker // to regenerate the blob on any color change
228*c8dee2aaSAndroid Build Coastguard Worker // We use the grPaint to get any color filter effects
229*c8dee2aaSAndroid Build Coastguard Worker if (fKey.fCanonicalColor == SK_ColorTRANSPARENT &&
230*c8dee2aaSAndroid Build Coastguard Worker fInitialLuminance != SkPaintPriv::ComputeLuminanceColor(paint)) {
231*c8dee2aaSAndroid Build Coastguard Worker return false;
232*c8dee2aaSAndroid Build Coastguard Worker }
233*c8dee2aaSAndroid Build Coastguard Worker
234*c8dee2aaSAndroid Build Coastguard Worker return fSubRuns->canReuse(paint, positionMatrix);
235*c8dee2aaSAndroid Build Coastguard Worker }
236*c8dee2aaSAndroid Build Coastguard Worker
key() const237*c8dee2aaSAndroid Build Coastguard Worker const TextBlob::Key& TextBlob::key() const { return fKey; }
238*c8dee2aaSAndroid Build Coastguard Worker
draw(SkCanvas * canvas,SkPoint drawOrigin,const SkPaint & paint,const AtlasDrawDelegate & atlasDelegate)239*c8dee2aaSAndroid Build Coastguard Worker void TextBlob::draw(SkCanvas* canvas,
240*c8dee2aaSAndroid Build Coastguard Worker SkPoint drawOrigin,
241*c8dee2aaSAndroid Build Coastguard Worker const SkPaint& paint,
242*c8dee2aaSAndroid Build Coastguard Worker const AtlasDrawDelegate& atlasDelegate) {
243*c8dee2aaSAndroid Build Coastguard Worker fSubRuns->draw(canvas, drawOrigin, paint, this, atlasDelegate);
244*c8dee2aaSAndroid Build Coastguard Worker }
245*c8dee2aaSAndroid Build Coastguard Worker
TextBlob(SubRunAllocator && alloc,SubRunContainerOwner subRuns,int totalMemorySize,SkColor initialLuminance)246*c8dee2aaSAndroid Build Coastguard Worker TextBlob::TextBlob(SubRunAllocator&& alloc,
247*c8dee2aaSAndroid Build Coastguard Worker SubRunContainerOwner subRuns,
248*c8dee2aaSAndroid Build Coastguard Worker int totalMemorySize,
249*c8dee2aaSAndroid Build Coastguard Worker SkColor initialLuminance)
250*c8dee2aaSAndroid Build Coastguard Worker : fAlloc{std::move(alloc)}
251*c8dee2aaSAndroid Build Coastguard Worker , fSubRuns{std::move(subRuns)}
252*c8dee2aaSAndroid Build Coastguard Worker , fSize(totalMemorySize)
253*c8dee2aaSAndroid Build Coastguard Worker , fInitialLuminance{initialLuminance} { }
254*c8dee2aaSAndroid Build Coastguard Worker
MakeSlug(const SkMatrix & drawMatrix,const sktext::GlyphRunList & glyphRunList,const SkPaint & paint,SkStrikeDeviceInfo strikeDeviceInfo,sktext::StrikeForGPUCacheInterface * strikeCache)255*c8dee2aaSAndroid Build Coastguard Worker sk_sp<Slug> MakeSlug(const SkMatrix& drawMatrix,
256*c8dee2aaSAndroid Build Coastguard Worker const sktext::GlyphRunList& glyphRunList,
257*c8dee2aaSAndroid Build Coastguard Worker const SkPaint& paint,
258*c8dee2aaSAndroid Build Coastguard Worker SkStrikeDeviceInfo strikeDeviceInfo,
259*c8dee2aaSAndroid Build Coastguard Worker sktext::StrikeForGPUCacheInterface* strikeCache) {
260*c8dee2aaSAndroid Build Coastguard Worker return SlugImpl::Make(drawMatrix, glyphRunList, paint, strikeDeviceInfo, strikeCache);
261*c8dee2aaSAndroid Build Coastguard Worker }
262*c8dee2aaSAndroid Build Coastguard Worker } // namespace sktext::gpu
263