Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/gpu/GrStencilAndCoverTextContext.cpp

Issue 1381073002: Implement cached nvpr text blobs (Closed) Base URL: https://skia.googlesource.com/skia.git@upload3_fallbackblob
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrStencilAndCoverTextContext.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrStencilAndCoverTextContext.h" 8 #include "GrStencilAndCoverTextContext.h"
9 #include "GrAtlasTextContext.h" 9 #include "GrAtlasTextContext.h"
10 #include "GrDrawContext.h" 10 #include "GrDrawContext.h"
11 #include "GrDrawTarget.h" 11 #include "GrDrawTarget.h"
12 #include "GrPath.h" 12 #include "GrPath.h"
13 #include "GrPathRange.h" 13 #include "GrPathRange.h"
14 #include "GrResourceProvider.h" 14 #include "GrResourceProvider.h"
15 #include "SkAutoKern.h" 15 #include "SkAutoKern.h"
16 #include "SkDraw.h" 16 #include "SkDraw.h"
17 #include "SkDrawProcs.h" 17 #include "SkDrawProcs.h"
18 #include "SkGlyphCache.h" 18 #include "SkGlyphCache.h"
19 #include "SkGpuDevice.h" 19 #include "SkGpuDevice.h"
20 #include "SkGrPriv.h"
20 #include "SkPath.h" 21 #include "SkPath.h"
21 #include "SkTextMapStateProc.h" 22 #include "SkTextMapStateProc.h"
22 #include "SkTextFormatParams.h" 23 #include "SkTextFormatParams.h"
23 24
24 #include "batches/GrDrawPathBatch.h" 25 #include "batches/GrDrawPathBatch.h"
25 26
27 template<typename Key, typename Val> static void delete_hash_map_entry(const Key &, Val* val) {
28 SkASSERT(*val);
29 delete *val;
30 }
31
32 template<typename T> static void delete_hash_table_entry(T* val) {
33 SkASSERT(*val);
34 delete *val;
35 }
36
26 GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(GrContext* context, 37 GrStencilAndCoverTextContext::GrStencilAndCoverTextContext(GrContext* context,
27 const SkSurfaceProps& surfaceProps) 38 const SkSurfaceProps& surfaceProps)
28 : INHERITED(context, surfaceProps) { 39 : INHERITED(context, surfaceProps),
40 fCacheSize(0) {
29 } 41 }
30 42
31 GrStencilAndCoverTextContext* 43 GrStencilAndCoverTextContext*
32 GrStencilAndCoverTextContext::Create(GrContext* context, const SkSurfaceProps& s urfaceProps) { 44 GrStencilAndCoverTextContext::Create(GrContext* context, const SkSurfaceProps& s urfaceProps) {
33 GrStencilAndCoverTextContext* textContext = 45 GrStencilAndCoverTextContext* textContext =
34 new GrStencilAndCoverTextContext(context, surfaceProps); 46 new GrStencilAndCoverTextContext(context, surfaceProps);
35 textContext->fFallbackTextContext = GrAtlasTextContext::Create(context, surf aceProps); 47 textContext->fFallbackTextContext = GrAtlasTextContext::Create(context, surf aceProps);
36 48
37 return textContext; 49 return textContext;
38 } 50 }
39 51
40 GrStencilAndCoverTextContext::~GrStencilAndCoverTextContext() { 52 GrStencilAndCoverTextContext::~GrStencilAndCoverTextContext() {
53 fBlobIdCache.foreach(delete_hash_map_entry<uint32_t, TextBlob*>);
54 fBlobKeyCache.foreach(delete_hash_table_entry<TextBlob*>);
41 } 55 }
42 56
43 bool GrStencilAndCoverTextContext::canDraw(const GrRenderTarget* rt, 57 bool GrStencilAndCoverTextContext::internalCanDraw(const SkPaint& skPaint) {
44 const GrClip& clip,
45 const GrPaint& paint,
46 const SkPaint& skPaint,
47 const SkMatrix& viewMatrix) {
48 if (skPaint.getRasterizer()) { 58 if (skPaint.getRasterizer()) {
49 return false; 59 return false;
50 } 60 }
51 if (skPaint.getMaskFilter()) { 61 if (skPaint.getMaskFilter()) {
52 return false; 62 return false;
53 } 63 }
54 if (SkPathEffect* pe = skPaint.getPathEffect()) { 64 if (SkPathEffect* pe = skPaint.getPathEffect()) {
55 if (pe->asADash(nullptr) != SkPathEffect::kDash_DashType) { 65 if (pe->asADash(nullptr) != SkPathEffect::kDash_DashType) {
56 return false; 66 return false;
57 } 67 }
58 } 68 }
59 // No hairlines. They would require new paths with customized strokes for ev ery new draw matrix. 69 // No hairlines. They would require new paths with customized strokes for ev ery new draw matrix.
60 return SkPaint::kStroke_Style != skPaint.getStyle() || 0 != skPaint.getStrok eWidth(); 70 return SkPaint::kStroke_Style != skPaint.getStyle() || 0 != skPaint.getStrok eWidth();
61 } 71 }
62 72
63 void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget* rt, 73 void GrStencilAndCoverTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget* rt,
64 const GrClip& clip, 74 const GrClip& clip,
65 const GrPaint& paint, 75 const GrPaint& paint,
66 const SkPaint& skPaint, 76 const SkPaint& skPaint,
67 const SkMatrix& viewMatrix, 77 const SkMatrix& viewMatrix,
68 const char text[], 78 const char text[],
69 size_t byteLength, 79 size_t byteLength,
70 SkScalar x, SkScalar y, 80 SkScalar x, SkScalar y,
71 const SkIRect& regionClipBounds) { 81 const SkIRect& clipBounds) {
72 TextRun run(skPaint); 82 TextRun run(skPaint);
83 GrPipelineBuilder pipelineBuilder(paint, rt, clip);
73 run.setText(text, byteLength, x, y, fContext, &fSurfaceProps); 84 run.setText(text, byteLength, x, y, fContext, &fSurfaceProps);
74 run.draw(dc, rt, clip, paint, viewMatrix, regionClipBounds, fFallbackTextCon text, skPaint); 85 run.draw(dc, &pipelineBuilder, paint.getColor(), viewMatrix, 0, 0, clipBound s,
86 fFallbackTextContext, skPaint);
75 } 87 }
76 88
77 void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* dc, GrRenderTarg et* rt, 89 void GrStencilAndCoverTextContext::onDrawPosText(GrDrawContext* dc, GrRenderTarg et* rt,
78 const GrClip& clip, 90 const GrClip& clip,
79 const GrPaint& paint, 91 const GrPaint& paint,
80 const SkPaint& skPaint, 92 const SkPaint& skPaint,
81 const SkMatrix& viewMatrix, 93 const SkMatrix& viewMatrix,
82 const char text[], 94 const char text[],
83 size_t byteLength, 95 size_t byteLength,
84 const SkScalar pos[], 96 const SkScalar pos[],
85 int scalarsPerPosition, 97 int scalarsPerPosition,
86 const SkPoint& offset, 98 const SkPoint& offset,
87 const SkIRect& regionClipBounds ) { 99 const SkIRect& clipBounds) {
88 TextRun run(skPaint); 100 TextRun run(skPaint);
101 GrPipelineBuilder pipelineBuilder(paint, rt, clip);
89 run.setPosText(text, byteLength, pos, scalarsPerPosition, offset, fContext, &fSurfaceProps); 102 run.setPosText(text, byteLength, pos, scalarsPerPosition, offset, fContext, &fSurfaceProps);
90 run.draw(dc, rt, clip, paint, viewMatrix, regionClipBounds, fFallbackTextCon text, skPaint); 103 run.draw(dc, &pipelineBuilder, paint.getColor(), viewMatrix, 0, 0, clipBound s,
104 fFallbackTextContext, skPaint);
105 }
106
107 void GrStencilAndCoverTextContext::drawTextBlob(GrDrawContext* dc, GrRenderTarge t* rt,
108 const GrClip& clip, const SkPain t& skPaint,
109 const SkMatrix& viewMatrix,
110 const SkTextBlob* skBlob, SkScal ar x, SkScalar y,
111 SkDrawFilter* drawFilter,
112 const SkIRect& clipBounds) {
113 if (!this->internalCanDraw(skPaint)) {
114 fFallbackTextContext->drawTextBlob(dc, rt, clip, skPaint, viewMatrix, sk Blob, x, y,
115 drawFilter, clipBounds);
116 return;
117 }
118
119 if (drawFilter || skPaint.getPathEffect()) {
120 // This draw can't be cached.
121 INHERITED::drawTextBlob(dc, rt, clip, skPaint, viewMatrix, skBlob, x, y, drawFilter,
122 clipBounds);
123 return;
124 }
125
126 if (fContext->abandoned()) {
127 return;
128 }
129
130 GrPaint paint;
131 if (!SkPaintToGrPaint(fContext, skPaint, viewMatrix, &paint)) {
132 return;
133 }
134
135 const TextBlob& blob = this->findOrCreateTextBlob(skBlob, skPaint);
136 GrPipelineBuilder pipelineBuilder(paint, rt, clip);
137
138 TextBlob::Iter iter(blob);
139 for (TextRun* run = iter.get(); run; run = iter.next()) {
140 run->draw(dc, &pipelineBuilder, paint.getColor(), viewMatrix, x, y, clip Bounds,
141 fFallbackTextContext, skPaint);
142 }
143 }
144
145 const GrStencilAndCoverTextContext::TextBlob&
146 GrStencilAndCoverTextContext::findOrCreateTextBlob(const SkTextBlob* skBlob,
147 const SkPaint& skPaint) {
148 // The font-related parameters are baked into the text blob and will overrid e this skPaint, so
149 // the only remaining properties that can affect a TextBlob are the ones rel ated to stroke.
150 if (SkPaint::kFill_Style == skPaint.getStyle()) { // Fast path.
151 if (TextBlob** found = fBlobIdCache.find(skBlob->uniqueID())) {
152 fLRUList.remove(*found);
153 fLRUList.addToTail(*found);
154 return **found;
155 }
156 TextBlob* blob = new TextBlob(skBlob->uniqueID(), skBlob, skPaint, fCont ext,
157 &fSurfaceProps);
158 this->purgeToFit(*blob);
159 fBlobIdCache.set(skBlob->uniqueID(), blob);
160 fLRUList.addToTail(blob);
161 fCacheSize += blob->cpuMemorySize();
162 return *blob;
163 } else {
164 GrStrokeInfo stroke(skPaint);
165 SkSTArray<4, uint32_t, true> key;
166 key.reset(1 + stroke.computeUniqueKeyFragmentData32Cnt());
167 key[0] = skBlob->uniqueID();
168 stroke.asUniqueKeyFragment(&key[1]);
169 if (TextBlob** found = fBlobKeyCache.find(key)) {
170 fLRUList.remove(*found);
171 fLRUList.addToTail(*found);
172 return **found;
173 }
174 TextBlob* blob = new TextBlob(key, skBlob, skPaint, fContext, &fSurfaceP rops);
175 this->purgeToFit(*blob);
176 fBlobKeyCache.set(blob);
177 fLRUList.addToTail(blob);
178 fCacheSize += blob->cpuMemorySize();
179 return *blob;
180 }
181 }
182
183 void GrStencilAndCoverTextContext::purgeToFit(const TextBlob& blob) {
184 static const int maxCacheSize = 4 * 1024 * 1024; // Allow up to 4 MB for cac hing text blobs.
185
186 int maxSizeForNewBlob = maxCacheSize - blob.cpuMemorySize();
187 while (fCacheSize && fCacheSize > maxSizeForNewBlob) {
188 TextBlob* lru = fLRUList.head();
189 if (1 == lru->key().count()) {
190 // 1-length keys are unterstood to be the blob id.
191 fBlobIdCache.remove(lru->key()[0]);
192 } else {
193 fBlobKeyCache.remove(lru->key());
194 }
195 fLRUList.remove(lru);
196 fCacheSize -= lru->cpuMemorySize();
197 delete lru;
198 }
91 } 199 }
92 200
93 //////////////////////////////////////////////////////////////////////////////// //////////////////// 201 //////////////////////////////////////////////////////////////////////////////// ////////////////////
202
203 void GrStencilAndCoverTextContext::TextBlob::init(const SkTextBlob* skBlob, cons t SkPaint& skPaint,
204 GrContext* ctx, const SkSurfac eProps* props) {
205 fCpuMemorySize = sizeof(TextBlob);
206 SkPaint runPaint(skPaint);
207 for (SkTextBlob::RunIterator iter(skBlob); !iter.done(); iter.next()) {
208 iter.applyFontToPaint(&runPaint); // No need to re-seed the paint.
209 TextRun* run = SkNEW_INSERT_AT_LLIST_TAIL(this, TextRun, (runPaint));
210
211 const char* text = reinterpret_cast<const char*>(iter.glyphs());
212 size_t byteLength = sizeof(uint16_t) * iter.glyphCount();
213 const SkPoint& runOffset = iter.offset();
214
215 switch (iter.positioning()) {
216 case SkTextBlob::kDefault_Positioning:
217 run->setText(text, byteLength, runOffset.fX, runOffset.fY, ctx, props);
218 break;
219 case SkTextBlob::kHorizontal_Positioning:
220 run->setPosText(text, byteLength, iter.pos(), 1, SkPoint::Make(0 , runOffset.fY),
221 ctx, props);
222 break;
223 case SkTextBlob::kFull_Positioning:
224 run->setPosText(text, byteLength, iter.pos(), 2, SkPoint::Make(0 , 0), ctx, props);
225 break;
226 }
227
228 fCpuMemorySize += run->cpuMemorySize();
229 }
230 }
231
232 //////////////////////////////////////////////////////////////////////////////// ////////////////////
94 233
95 class GrStencilAndCoverTextContext::FallbackBlobBuilder { 234 class GrStencilAndCoverTextContext::FallbackBlobBuilder {
96 public: 235 public:
97 FallbackBlobBuilder() : fBuffIdx(0) {} 236 FallbackBlobBuilder() : fBuffIdx(0) {}
98 237
99 bool isInitialized() const { return fBuilder; } 238 bool isInitialized() const { return fBuilder; }
100 239
101 void init(const SkPaint& font, SkScalar textRatio); 240 void init(const SkPaint& font, SkScalar textRatio);
102 241
103 void appendGlyph(uint16_t glyphId, const SkPoint& pos); 242 void appendGlyph(uint16_t glyphId, const SkPoint& pos);
104 243
105 const SkTextBlob* buildIfInitialized(); 244 const SkTextBlob* buildIfInitialized();
106 245
107 private: 246 private:
108 enum { kWriteBufferSize = 1024 }; 247 enum { kWriteBufferSize = 1024 };
109 248
110 void flush(); 249 void flush();
111 250
112 SkAutoTDelete<SkTextBlobBuilder> fBuilder; 251 SkAutoTDelete<SkTextBlobBuilder> fBuilder;
113 SkPaint fFont; 252 SkPaint fFont;
114 int fBuffIdx; 253 int fBuffIdx;
115 uint16_t fGlyphIds[kWriteBufferSize]; 254 uint16_t fGlyphIds[kWriteBufferSize];
116 SkPoint fPositions[kWriteBufferSize]; 255 SkPoint fPositions[kWriteBufferSize];
117 }; 256 };
118 257
119 //////////////////////////////////////////////////////////////////////////////// //////////////////// 258 //////////////////////////////////////////////////////////////////////////////// ////////////////////
120 259
121 GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke) 260 GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke)
122 : fStroke(fontAndStroke), 261 : fStroke(fontAndStroke),
123 fFont(fontAndStroke) { 262 fFont(fontAndStroke),
263 fTotalGlyphCount(0) {
124 SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported. 264 SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported.
125 265
126 // Setting to "fill" ensures that no strokes get baked into font outlines. ( We use the GPU path 266 // Setting to "fill" ensures that no strokes get baked into font outlines. ( We use the GPU path
127 // rendering API for stroking). 267 // rendering API for stroking).
128 fFont.setStyle(SkPaint::kFill_Style); 268 fFont.setStyle(SkPaint::kFill_Style);
129 269
130 if (fFont.isFakeBoldText() && SkStrokeRec::kStroke_Style != fStroke.getStyle ()) { 270 if (fFont.isFakeBoldText() && SkStrokeRec::kStroke_Style != fStroke.getStyle ()) {
131 // Instead of letting fake bold get baked into the glyph outlines, do it with GPU stroke. 271 // Instead of letting fake bold get baked into the glyph outlines, do it with GPU stroke.
132 SkScalar fakeBoldScale = SkScalarInterpFunc(fFont.getTextSize(), 272 SkScalar fakeBoldScale = SkScalarInterpFunc(fFont.getTextSize(),
133 kStdFakeBoldInterpKeys, 273 kStdFakeBoldInterpKeys,
(...skipping 27 matching lines...) Expand all
161 fUsingRawGlyphPaths = SK_Scalar1 == fFont.getTextScaleX() && 301 fUsingRawGlyphPaths = SK_Scalar1 == fFont.getTextScaleX() &&
162 0 == fFont.getTextSkewX() && 302 0 == fFont.getTextSkewX() &&
163 !fFont.isFakeBoldText() && 303 !fFont.isFakeBoldText() &&
164 !fFont.isVerticalText(); 304 !fFont.isVerticalText();
165 } else { 305 } else {
166 fTextRatio = fTextInverseRatio = 1.0f; 306 fTextRatio = fTextInverseRatio = 1.0f;
167 fUsingRawGlyphPaths = false; 307 fUsingRawGlyphPaths = false;
168 } 308 }
169 309
170 // When drawing from canonically sized paths, the actual local coords are fT extRatio * coords. 310 // When drawing from canonically sized paths, the actual local coords are fT extRatio * coords.
171 fLocalMatrix.setScale(fTextRatio, fTextRatio); 311 fLocalMatrixTemplate.setScale(fTextRatio, fTextRatio);
172 } 312 }
173 313
174 GrStencilAndCoverTextContext::TextRun::~TextRun() { 314 GrStencilAndCoverTextContext::TextRun::~TextRun() {
175 } 315 }
176 316
177 void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by teLength, 317 void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by teLength,
178 SkScalar x, SkScalar y, GrCo ntext* ctx, 318 SkScalar x, SkScalar y, GrCo ntext* ctx,
179 const SkSurfaceProps* surfac eProps) { 319 const SkSurfaceProps* surfac eProps) {
180 SkASSERT(byteLength == 0 || text != nullptr); 320 SkASSERT(byteLength == 0 || text != nullptr);
181 321
182 SkAutoGlyphCacheNoGamma autoGlyphCache(fFont, surfaceProps, nullptr); 322 SkAutoGlyphCacheNoGamma autoGlyphCache(fFont, surfaceProps, nullptr);
183 SkGlyphCache* glyphCache = autoGlyphCache.getCache(); 323 SkGlyphCache* glyphCache = autoGlyphCache.getCache();
184 324
325 fTotalGlyphCount = fFont.countText(text, byteLength);
185 fDraw.reset(GrPathRangeDraw::Create(this->createGlyphs(ctx, glyphCache), 326 fDraw.reset(GrPathRangeDraw::Create(this->createGlyphs(ctx, glyphCache),
186 GrPathRendering::kTranslate_PathTransfor mType, 327 GrPathRendering::kTranslate_PathTransfor mType,
187 fFont.countText(text, byteLength))); 328 fTotalGlyphCount));
188 329
189 SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc(); 330 SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();
190 331
191 const char* stop = text + byteLength; 332 const char* stop = text + byteLength;
192 333
193 // Measure first if needed. 334 // Measure first if needed.
194 if (fFont.getTextAlign() != SkPaint::kLeft_Align) { 335 if (fFont.getTextAlign() != SkPaint::kLeft_Align) {
195 SkFixed stopX = 0; 336 SkFixed stopX = 0;
196 SkFixed stopY = 0; 337 SkFixed stopY = 0;
197 338
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength, 384 void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength,
244 const SkScalar pos[], int scalarsPerPosition, 385 const SkScalar pos[], int scalarsPerPosition,
245 const SkPoint& offset, Gr Context* ctx, 386 const SkPoint& offset, Gr Context* ctx,
246 const SkSurfaceProps* sur faceProps) { 387 const SkSurfaceProps* sur faceProps) {
247 SkASSERT(byteLength == 0 || text != nullptr); 388 SkASSERT(byteLength == 0 || text != nullptr);
248 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); 389 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
249 390
250 SkAutoGlyphCacheNoGamma autoGlyphCache(fFont, surfaceProps, nullptr); 391 SkAutoGlyphCacheNoGamma autoGlyphCache(fFont, surfaceProps, nullptr);
251 SkGlyphCache* glyphCache = autoGlyphCache.getCache(); 392 SkGlyphCache* glyphCache = autoGlyphCache.getCache();
252 393
394 fTotalGlyphCount = fFont.countText(text, byteLength);
253 fDraw.reset(GrPathRangeDraw::Create(this->createGlyphs(ctx, glyphCache), 395 fDraw.reset(GrPathRangeDraw::Create(this->createGlyphs(ctx, glyphCache),
254 GrPathRendering::kTranslate_PathTransfor mType, 396 GrPathRendering::kTranslate_PathTransfor mType,
255 fFont.countText(text, byteLength))); 397 fTotalGlyphCount));
256 398
257 SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc(); 399 SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();
258 400
259 const char* stop = text + byteLength; 401 const char* stop = text + byteLength;
260 402
261 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); 403 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
262 SkTextAlignProc alignProc(fFont.getTextAlign()); 404 SkTextAlignProc alignProc(fFont.getTextAlign());
263 FallbackBlobBuilder fallback; 405 FallbackBlobBuilder fallback;
264 while (text < stop) { 406 while (text < stop) {
265 const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0); 407 const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 fallback->init(fFont, fTextRatio); 458 fallback->init(fFont, fTextRatio);
317 } 459 }
318 fallback->appendGlyph(glyph.getGlyphID(), pos); 460 fallback->appendGlyph(glyph.getGlyphID(), pos);
319 } else { 461 } else {
320 float translate[] = { fTextInverseRatio * pos.x(), fTextInverseRatio * p os.y() }; 462 float translate[] = { fTextInverseRatio * pos.x(), fTextInverseRatio * p os.y() };
321 fDraw->append(glyph.getGlyphID(), translate); 463 fDraw->append(glyph.getGlyphID(), translate);
322 } 464 }
323 } 465 }
324 466
325 void GrStencilAndCoverTextContext::TextRun::draw(GrDrawContext* dc, 467 void GrStencilAndCoverTextContext::TextRun::draw(GrDrawContext* dc,
326 GrRenderTarget* rt, 468 GrPipelineBuilder* pipelineBuil der,
327 const GrClip& clip, 469 GrColor color,
328 const GrPaint& paint,
329 const SkMatrix& viewMatrix, 470 const SkMatrix& viewMatrix,
330 const SkIRect& regionClipBounds , 471 SkScalar x, SkScalar y,
472 const SkIRect& clipBounds,
331 GrTextContext* fallbackTextCont ext, 473 GrTextContext* fallbackTextCont ext,
332 const SkPaint& originalSkPaint) const { 474 const SkPaint& originalSkPaint) const {
333 SkASSERT(fDraw); 475 SkASSERT(fDraw);
476 SkASSERT(pipelineBuilder->getRenderTarget()->isStencilBufferMultisampled() | |
477 !fFont.isAntiAlias());
334 478
335 if (fDraw->count()) { 479 if (fDraw->count()) {
336 GrPipelineBuilder pipelineBuilder(paint, rt, clip); 480 pipelineBuilder->setState(GrPipelineBuilder::kHWAntialias_Flag, fFont.is AntiAlias());
337 SkASSERT(rt->isStencilBufferMultisampled() || !paint.isAntiAlias());
338 pipelineBuilder.setState(GrPipelineBuilder::kHWAntialias_Flag, paint.isA ntiAlias());
339 481
340 GR_STATIC_CONST_SAME_STENCIL(kStencilPass, 482 GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
341 kZero_StencilOp, 483 kZero_StencilOp,
342 kKeep_StencilOp, 484 kKeep_StencilOp,
343 kNotEqual_StencilFunc, 485 kNotEqual_StencilFunc,
344 0xffff, 486 0xffff,
345 0x0000, 487 0x0000,
346 0xffff); 488 0xffff);
347 489
348 *pipelineBuilder.stencil() = kStencilPass; 490 *pipelineBuilder->stencil() = kStencilPass;
349 491
350 SkMatrix drawMatrix(viewMatrix); 492 SkMatrix drawMatrix(viewMatrix);
493 drawMatrix.preTranslate(x, y);
351 drawMatrix.preScale(fTextRatio, fTextRatio); 494 drawMatrix.preScale(fTextRatio, fTextRatio);
352 495
353 dc->drawPathsFromRange(&pipelineBuilder, drawMatrix, fLocalMatrix, paint .getColor(), fDraw, 496 SkMatrix& localMatrix = fLocalMatrixTemplate;
497 localMatrix.setTranslateX(x);
498 localMatrix.setTranslateY(y);
499
500 dc->drawPathsFromRange(pipelineBuilder, drawMatrix, localMatrix, color, fDraw,
354 GrPathRendering::kWinding_FillType); 501 GrPathRendering::kWinding_FillType);
355 } 502 }
356 503
357 if (fFallbackTextBlob) { 504 if (fFallbackTextBlob) {
358 SkPaint fallbackSkPaint(originalSkPaint); 505 SkPaint fallbackSkPaint(originalSkPaint);
359 fStroke.applyToPaint(&fallbackSkPaint); 506 fStroke.applyToPaint(&fallbackSkPaint);
360 if (!fStroke.isFillStyle()) { 507 if (!fStroke.isFillStyle()) {
361 fallbackSkPaint.setStrokeWidth(fStroke.getWidth() * fTextRatio); 508 fallbackSkPaint.setStrokeWidth(fStroke.getWidth() * fTextRatio);
362 } 509 }
363 510
364 fallbackTextContext->drawTextBlob(dc, rt, clip, fallbackSkPaint, viewMat rix, 511 fallbackTextContext->drawTextBlob(dc, pipelineBuilder->getRenderTarget() ,
365 fFallbackTextBlob, 0, 0, nullptr, regi onClipBounds); 512 pipelineBuilder->clip(), fallbackSkPai nt, viewMatrix,
513 fFallbackTextBlob, x, y, nullptr, clip Bounds);
366 } 514 }
367 } 515 }
368 516
517 int GrStencilAndCoverTextContext::TextRun::cpuMemorySize() const {
518 int size = sizeof(TextRun) + fTotalGlyphCount * (sizeof(uint16_t) + 2 * size of(float));
519 if (fDraw) {
520 size += sizeof(GrPathRangeDraw);
521 }
522 if (fFallbackTextBlob) {
523 size += sizeof(SkTextBlob);
524 }
525 return size;
526 }
527
369 //////////////////////////////////////////////////////////////////////////////// //////////////////// 528 //////////////////////////////////////////////////////////////////////////////// ////////////////////
370 529
371 void GrStencilAndCoverTextContext::FallbackBlobBuilder::init(const SkPaint& font , 530 void GrStencilAndCoverTextContext::FallbackBlobBuilder::init(const SkPaint& font ,
372 SkScalar textRatio) { 531 SkScalar textRatio) {
373 SkASSERT(!this->isInitialized()); 532 SkASSERT(!this->isInitialized());
374 fBuilder.reset(new SkTextBlobBuilder); 533 fBuilder.reset(new SkTextBlobBuilder);
375 fFont = font; 534 fFont = font;
376 fFont.setTextAlign(SkPaint::kLeft_Align); // The glyph positions will alread y account for align. 535 fFont.setTextAlign(SkPaint::kLeft_Align); // The glyph positions will alread y account for align.
377 fFont.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 536 fFont.setTextEncoding(SkPaint::kGlyphID_TextEncoding);
378 // No need for subpixel positioning with bitmap glyphs. TODO: revisit if non -bitmap color glyphs 537 // No need for subpixel positioning with bitmap glyphs. TODO: revisit if non -bitmap color glyphs
(...skipping 27 matching lines...) Expand all
406 fBuffIdx = 0; 565 fBuffIdx = 0;
407 } 566 }
408 567
409 const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfInit ialized() { 568 const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfInit ialized() {
410 if (!this->isInitialized()) { 569 if (!this->isInitialized()) {
411 return nullptr; 570 return nullptr;
412 } 571 }
413 this->flush(); 572 this->flush();
414 return fBuilder->build(); 573 return fBuilder->build();
415 } 574 }
OLDNEW
« no previous file with comments | « src/gpu/GrStencilAndCoverTextContext.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698