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

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

Issue 1041953002: Switch to one single bitmap text blob cache allocation (Closed) Base URL: https://skia.googlesource.com/skia.git@bmptext2
Patch Set: more tidying Created 5 years, 8 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
« src/gpu/GrBitmapTextContext.h ('K') | « src/gpu/GrBitmapTextContext.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 2013 Google Inc. 2 * Copyright 2013 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 #include "GrBitmapTextContext.h" 7 #include "GrBitmapTextContext.h"
8 8
9 #include "GrAtlas.h" 9 #include "GrAtlas.h"
10 #include "GrBatch.h" 10 #include "GrBatch.h"
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 } 94 }
95 95
96 bool GrBitmapTextContextB::MustRegenerateBlob(const BitmapTextBlob& blob, const SkPaint& paint, 96 bool GrBitmapTextContextB::MustRegenerateBlob(const BitmapTextBlob& blob, const SkPaint& paint,
97 const SkMatrix& viewMatrix, SkScala r x, SkScalar y) { 97 const SkMatrix& viewMatrix, SkScala r x, SkScalar y) {
98 // We always regenerate blobs with patheffects or mask filters we could cach e these 98 // We always regenerate blobs with patheffects or mask filters we could cach e these
99 // TODO find some way to cache the maskfilter / patheffects on the textblob 99 // TODO find some way to cache the maskfilter / patheffects on the textblob
100 return !blob.fViewMatrix.cheapEqualTo(viewMatrix) || blob.fX != x || blob.fY != y || 100 return !blob.fViewMatrix.cheapEqualTo(viewMatrix) || blob.fX != x || blob.fY != y ||
101 paint.getMaskFilter() || paint.getPathEffect() || paint.getStyle() ! = blob.fStyle; 101 paint.getMaskFilter() || paint.getPathEffect() || paint.getStyle() ! = blob.fStyle;
102 } 102 }
103 103
104
105 inline SkGlyphCache* GrBitmapTextContextB::setupCache(BitmapTextBlob::Run* run,
106 const SkPaint& skPaint,
107 const SkMatrix& viewMatrix ) {
108 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, &v iewMatrix, false);
109 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface()));
110 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc()) ;
111 }
112
113 inline void GrBitmapTextContextB::BlobGlyphCount(int* glyphCount, int* runCount,
bsalomon 2015/03/31 21:19:10 if this only uses public interfaces on textblob, d
joshualitt 2015/04/01 13:21:18 see comment in header
114 const SkTextBlob* blob) {
115 SkTextBlob::RunIterator itCounter(blob);
116 for (; !itCounter.done(); itCounter.next(), (*runCount)++) {
117 *glyphCount += itCounter.glyphCount();
118 }
119 }
120
121 inline GrBitmapTextContextB::BitmapTextBlob*
bsalomon 2015/03/31 21:19:10 you really think this should be inlined?
joshualitt 2015/04/01 13:21:17 Acknowledged.
122 GrBitmapTextContextB::CreateBlob(int glyphCount, int runCount) {
123 // We allocate size for the BitmapTextBlob itself, plus size for the vertice s array,
124 // and size for the glyphIds array.
125 size_t verticesCount = glyphCount * kVerticesPerGlyph * kGrayTextVASize;
bsalomon 2015/03/31 21:19:10 static assert that kGrayTextVASize is the largest?
joshualitt 2015/04/01 13:21:18 Acknowledged.
126 size_t length = sizeof(BitmapTextBlob) +
127 verticesCount +
128 glyphCount * sizeof(GrGlyph::PackedID) +
129 sizeof(BitmapTextBlob::Run) * runCount;
130
131 BitmapTextBlob* cacheBlob = SkNEW_PLACEMENT(sk_malloc_throw(length), BitmapT extBlob);
132
133 // setup offsets for vertices / glyphs
134 cacheBlob->fVertices = sizeof(BitmapTextBlob) + reinterpret_cast<unsigned ch ar*>(cacheBlob);
135 cacheBlob->fGlyphIDs =
136 reinterpret_cast<GrGlyph::PackedID*>(cacheBlob->fVertices + vertices Count);
137 cacheBlob->fRuns = reinterpret_cast<BitmapTextBlob::Run*>(cacheBlob->fGlyphI Ds + glyphCount);
138
139 // Initialize runs
140 for (int i = 0; i < runCount; i++) {
141 SkNEW_PLACEMENT(&cacheBlob->fRuns[i], BitmapTextBlob::Run);
142 }
143 cacheBlob->fRunCount = runCount;
144 return cacheBlob;
145 }
146
104 void GrBitmapTextContextB::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, 147 void GrBitmapTextContextB::drawTextBlob(GrRenderTarget* rt, const GrClip& clip,
105 const SkPaint& skPaint, const SkMatrix& viewMatrix, 148 const SkPaint& skPaint, const SkMatrix& viewMatrix,
106 const SkTextBlob* blob, SkScalar x, SkSc alar y, 149 const SkTextBlob* blob, SkScalar x, SkSc alar y,
107 SkDrawFilter* drawFilter, const SkIRect& clipBounds) { 150 SkDrawFilter* drawFilter, const SkIRect& clipBounds) {
108 BitmapTextBlob* cacheBlob; 151 BitmapTextBlob* cacheBlob;
109 BitmapTextBlob** foundBlob = fCache.find(blob->uniqueID()); 152 BitmapTextBlob** foundBlob = fCache.find(blob->uniqueID());
110
111 SkIRect clipRect; 153 SkIRect clipRect;
112 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); 154 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect);
113 155
114 if (foundBlob) { 156 if (foundBlob) {
115 cacheBlob = *foundBlob; 157 cacheBlob = *foundBlob;
116 if (MustRegenerateBlob(*cacheBlob, skPaint, viewMatrix, x, y)) { 158 if (MustRegenerateBlob(*cacheBlob, skPaint, viewMatrix, x, y)) {
117 // We can get away with reusing the blob if there are no outstanding refs on it. 159 // We have to remake the blob because changes may invalidate our mas ks.
118 // However, we still have to reset all of the runs. 160 // TODO we could probably get away reuse most of the time if the poi nter is unique,
119 if (!cacheBlob->unique()) { 161 // but we'd have to clear the subrun information
120 cacheBlob->unref(); 162 cacheBlob->unref();
121 cacheBlob = SkNEW(BitmapTextBlob); 163 int glyphCount = 0;
122 fCache.set(blob->uniqueID(), cacheBlob); 164 int runCount = 0;
123 } 165 BlobGlyphCount(&glyphCount, &runCount, blob);
166 cacheBlob = CreateBlob(glyphCount, runCount);
167 fCache.set(blob->uniqueID(), cacheBlob);
124 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter, 168 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter,
125 clipRect); 169 clipRect);
126 } 170 }
127 } else { 171 } else {
128 cacheBlob = SkNEW(BitmapTextBlob); 172 int glyphCount = 0;
173 int runCount = 0;
174 BlobGlyphCount(&glyphCount, &runCount, blob);
175 cacheBlob = CreateBlob(glyphCount, runCount);
129 fCache.set(blob->uniqueID(), cacheBlob); 176 fCache.set(blob->uniqueID(), cacheBlob);
130 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra wFilter, clipRect); 177 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra wFilter, clipRect);
131 } 178 }
132 179
133 // Though for the time being runs in the textblob can override the paint, th ey only touch font 180 // Though for the time being runs in the textblob can override the paint, th ey only touch font
134 // info. 181 // info.
135 GrPaint grPaint; 182 GrPaint grPaint;
136 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint); 183 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint);
137 184
138 this->flush(fContext->getTextTarget(), cacheBlob, rt, grPaint, clip, viewMat rix, 185 this->flush(fContext->getTextTarget(), cacheBlob, rt, grPaint, clip, viewMat rix,
139 fSkPaint.getAlpha()); 186 fSkPaint.getAlpha());
140 } 187 }
141 188
142 void GrBitmapTextContextB::regenerateTextBlob(BitmapTextBlob* cacheBlob, 189 void GrBitmapTextContextB::regenerateTextBlob(BitmapTextBlob* cacheBlob,
143 const SkPaint& skPaint, const SkMa trix& viewMatrix, 190 const SkPaint& skPaint, const SkMa trix& viewMatrix,
144 const SkTextBlob* blob, SkScalar x , SkScalar y, 191 const SkTextBlob* blob, SkScalar x , SkScalar y,
145 SkDrawFilter* drawFilter, const Sk IRect& clipRect) { 192 SkDrawFilter* drawFilter, const Sk IRect& clipRect) {
146 cacheBlob->fViewMatrix = viewMatrix; 193 cacheBlob->fViewMatrix = viewMatrix;
147 cacheBlob->fX = x; 194 cacheBlob->fX = x;
148 cacheBlob->fY = y; 195 cacheBlob->fY = y;
149 cacheBlob->fStyle = skPaint.getStyle(); 196 cacheBlob->fStyle = skPaint.getStyle();
150 cacheBlob->fRuns.reset(blob->fRunCount);
151 197
152 // Regenerate textblob 198 // Regenerate textblob
153 SkPaint runPaint = skPaint; 199 SkPaint runPaint = skPaint;
154 SkTextBlob::RunIterator it(blob); 200 SkTextBlob::RunIterator it(blob);
155 for (int run = 0; !it.done(); it.next(), run++) { 201 for (int run = 0; !it.done(); it.next(), run++) {
156 size_t textLen = it.glyphCount() * sizeof(uint16_t); 202 int glyphCount = it.glyphCount();
203 size_t textLen = glyphCount * sizeof(uint16_t);
157 const SkPoint& offset = it.offset(); 204 const SkPoint& offset = it.offset();
158 // applyFontToPaint() always overwrites the exact same attributes, 205 // applyFontToPaint() always overwrites the exact same attributes,
159 // so it is safe to not re-seed the paint for this reason. 206 // so it is safe to not re-seed the paint for this reason.
160 it.applyFontToPaint(&runPaint); 207 it.applyFontToPaint(&runPaint);
161 208
162 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ e)) { 209 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ e)) {
163 // A false return from filter() means we should abort the current dr aw. 210 // A false return from filter() means we should abort the current dr aw.
164 runPaint = skPaint; 211 runPaint = skPaint;
165 continue; 212 continue;
166 } 213 }
167 214
168 runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint)); 215 runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint));
169 216
217 SkGlyphCache* cache = setupCache(&cacheBlob->fRuns[run], runPaint, viewM atrix);
bsalomon 2015/03/31 21:19:10 this->
joshualitt 2015/04/01 13:21:17 Acknowledged.
218
219 // setup vertex / glyphIndex for the new run
220 if (run > 0) {
221 PerSubRunInfo& newRun = cacheBlob->fRuns[run].fSubRunInfo.back();
222 PerSubRunInfo& lastRun = cacheBlob->fRuns[run - 1].fSubRunInfo.back( );
223
224 newRun.fVertexStartIndex = lastRun.fVertexEndIndex;
225 newRun.fVertexEndIndex = lastRun.fVertexEndIndex;
226
227 newRun.fGlyphStartIndex = lastRun.fGlyphEndIndex;
228 newRun.fGlyphEndIndex = lastRun.fGlyphEndIndex;
229 }
230
170 switch (it.positioning()) { 231 switch (it.positioning()) {
171 case SkTextBlob::kDefault_Positioning: 232 case SkTextBlob::kDefault_Positioning:
172 this->internalDrawText(cacheBlob, run, runPaint, viewMatrix, 233 this->internalDrawText(cacheBlob, run, cache, runPaint, viewMatr ix,
173 (const char *)it.glyphs(), textLen, 234 (const char *)it.glyphs(), textLen,
174 x + offset.x(), y + offset.y(), clipRect) ; 235 x + offset.x(), y + offset.y(), clipRect) ;
175 break; 236 break;
176 case SkTextBlob::kHorizontal_Positioning: 237 case SkTextBlob::kHorizontal_Positioning:
177 this->internalDrawPosText(cacheBlob, run, runPaint, viewMatrix, 238 this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewM atrix,
178 (const char*)it.glyphs(), textLen, it. pos(), 1, 239 (const char*)it.glyphs(), textLen, it. pos(), 1,
179 SkPoint::Make(x, y + offset.y()), clip Rect); 240 SkPoint::Make(x, y + offset.y()), clip Rect);
180 break; 241 break;
181 case SkTextBlob::kFull_Positioning: 242 case SkTextBlob::kFull_Positioning:
182 this->internalDrawPosText(cacheBlob, run, runPaint, viewMatrix, 243 this->internalDrawPosText(cacheBlob, run, cache, runPaint, viewM atrix,
183 (const char*)it.glyphs(), textLen, it. pos(), 2, 244 (const char*)it.glyphs(), textLen, it. pos(), 2,
184 SkPoint::Make(x, y), clipRect); 245 SkPoint::Make(x, y), clipRect);
185 break; 246 break;
186 } 247 }
187 248
188 if (drawFilter) { 249 if (drawFilter) {
189 // A draw filter may change the paint arbitrarily, so we must re-see d in this case. 250 // A draw filter may change the paint arbitrarily, so we must re-see d in this case.
190 runPaint = skPaint; 251 runPaint = skPaint;
191 } 252 }
253
254 SkGlyphCache::AttachCache(cache);
192 } 255 }
193 } 256 }
194 257
195 void GrBitmapTextContextB::onDrawText(GrRenderTarget* rt, const GrClip& clip, 258 void GrBitmapTextContextB::onDrawText(GrRenderTarget* rt, const GrClip& clip,
196 const GrPaint& paint, const SkPaint& skPain t, 259 const GrPaint& paint, const SkPaint& skPain t,
197 const SkMatrix& viewMatrix, 260 const SkMatrix& viewMatrix,
198 const char text[], size_t byteLength, 261 const char text[], size_t byteLength,
199 SkScalar x, SkScalar y, const SkIRect& regi onClipBounds) { 262 SkScalar x, SkScalar y, const SkIRect& regi onClipBounds) {
200 SkAutoTUnref<BitmapTextBlob> blob(SkNEW(BitmapTextBlob)); 263 int glyphCount = skPaint.countText(text, byteLength);
264 SkAutoTUnref<BitmapTextBlob> blob(CreateBlob(glyphCount, 1));
201 blob->fViewMatrix = viewMatrix; 265 blob->fViewMatrix = viewMatrix;
202 blob->fX = x; 266 blob->fX = x;
203 blob->fY = y; 267 blob->fY = y;
204 blob->fStyle = skPaint.getStyle(); 268 blob->fStyle = skPaint.getStyle();
205 blob->fRuns.push_back();
206 269
207 SkIRect clipRect; 270 SkIRect clipRect;
208 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); 271 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect);
209 this->internalDrawText(blob, 0, skPaint, viewMatrix, text, byteLength, x, y, clipRect); 272
273 // setup cache
274 SkGlyphCache* cache = setupCache(&blob->fRuns[0], skPaint, viewMatrix);
bsalomon 2015/03/31 21:19:10 this->
joshualitt 2015/04/01 13:21:17 Acknowledged.
275 this->internalDrawText(blob, 0, cache, skPaint, viewMatrix, text, byteLength , x, y, clipRect);
276 SkGlyphCache::AttachCache(cache);
277
210 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, sk Paint.getAlpha()); 278 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, sk Paint.getAlpha());
211 } 279 }
212 280
213 void GrBitmapTextContextB::internalDrawText(BitmapTextBlob* blob, int runIndex, 281 void GrBitmapTextContextB::internalDrawText(BitmapTextBlob* blob, int runIndex,
214 const SkPaint& skPaint, 282 SkGlyphCache* cache, const SkPaint& skPaint,
215 const SkMatrix& viewMatrix, 283 const SkMatrix& viewMatrix,
216 const char text[], size_t byteLength, 284 const char text[], size_t byteLength,
217 SkScalar x, SkScalar y, const SkIRect & clipRect) { 285 SkScalar x, SkScalar y, const SkIRect & clipRect) {
218 SkASSERT(byteLength == 0 || text != NULL); 286 SkASSERT(byteLength == 0 || text != NULL);
219 287
220 // nothing to draw 288 // nothing to draw
221 if (text == NULL || byteLength == 0) { 289 if (text == NULL || byteLength == 0) {
222 return; 290 return;
223 } 291 }
224 292
225 fCurrStrike = NULL; 293 fCurrStrike = NULL;
226 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); 294 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc();
227 295
228 // Get GrFontScaler from cache 296 // Get GrFontScaler from cache
229 BitmapTextBlob::Run& run = blob->fRuns[runIndex];
230 run.fDescriptor.reset(skPaint.getScalerContextDescriptor(&fDeviceProperties, &viewMatrix,
231 false));
232 run.fTypeface.reset(SkSafeRef(skPaint.getTypeface()));
233 const SkDescriptor* desc = reinterpret_cast<const SkDescriptor*>(run.fDescri ptor->data());
234 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, desc);
235 GrFontScaler* fontScaler = GetGrFontScaler(cache); 297 GrFontScaler* fontScaler = GetGrFontScaler(cache);
236 298
237 // transform our starting point 299 // transform our starting point
238 { 300 {
239 SkPoint loc; 301 SkPoint loc;
240 viewMatrix.mapXY(x, y, &loc); 302 viewMatrix.mapXY(x, y, &loc);
241 x = loc.fX; 303 x = loc.fX;
242 y = loc.fY; 304 y = loc.fY;
243 } 305 }
244 306
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 GrGlyph::kCoverage_MaskStyle), 358 GrGlyph::kCoverage_MaskStyle),
297 Sk48Dot16FloorToInt(fx), 359 Sk48Dot16FloorToInt(fx),
298 Sk48Dot16FloorToInt(fy), 360 Sk48Dot16FloorToInt(fy),
299 fontScaler, 361 fontScaler,
300 clipRect); 362 clipRect);
301 } 363 }
302 364
303 fx += glyph.fAdvanceX; 365 fx += glyph.fAdvanceX;
304 fy += glyph.fAdvanceY; 366 fy += glyph.fAdvanceY;
305 } 367 }
306
307 SkGlyphCache::AttachCache(cache);
308 } 368 }
309 369
310 void GrBitmapTextContextB::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, 370 void GrBitmapTextContextB::onDrawPosText(GrRenderTarget* rt, const GrClip& clip,
311 const GrPaint& paint, const SkPaint& skP aint, 371 const GrPaint& paint, const SkPaint& skP aint,
312 const SkMatrix& viewMatrix, 372 const SkMatrix& viewMatrix,
313 const char text[], size_t byteLength, 373 const char text[], size_t byteLength,
314 const SkScalar pos[], int scalarsPerPosi tion, 374 const SkScalar pos[], int scalarsPerPosi tion,
315 const SkPoint& offset, const SkIRect& re gionClipBounds) { 375 const SkPoint& offset, const SkIRect& re gionClipBounds) {
316 SkAutoTUnref<BitmapTextBlob> blob(SkNEW(BitmapTextBlob)); 376 int glyphCount = skPaint.countText(text, byteLength);
377 SkAutoTUnref<BitmapTextBlob> blob(CreateBlob(glyphCount, 1));
317 blob->fStyle = skPaint.getStyle(); 378 blob->fStyle = skPaint.getStyle();
318 blob->fRuns.push_back();
319 blob->fViewMatrix = viewMatrix; 379 blob->fViewMatrix = viewMatrix;
320 380
321 SkIRect clipRect; 381 SkIRect clipRect;
322 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); 382 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect);
323 this->internalDrawPosText(blob, 0, skPaint, viewMatrix, text, byteLength, po s, 383
384 // setup cache
385 SkGlyphCache* cache = setupCache(&blob->fRuns[0], skPaint, viewMatrix);
bsalomon 2015/03/31 21:19:10 this->
joshualitt 2015/04/01 13:21:18 Acknowledged.
386 this->internalDrawPosText(blob, 0, cache, skPaint, viewMatrix, text, byteLen gth, pos,
324 scalarsPerPosition, offset, clipRect); 387 scalarsPerPosition, offset, clipRect);
388 SkGlyphCache::AttachCache(cache);
389
325 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, fS kPaint.getAlpha()); 390 this->flush(fContext->getTextTarget(), blob, rt, paint, clip, viewMatrix, fS kPaint.getAlpha());
326 } 391 }
327 392
328 void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runInde x, 393 void GrBitmapTextContextB::internalDrawPosText(BitmapTextBlob* blob, int runInde x,
329 const SkPaint& skPaint, 394 SkGlyphCache* cache, const SkPain t& skPaint,
330 const SkMatrix& viewMatrix, 395 const SkMatrix& viewMatrix,
331 const char text[], size_t byteLeng th, 396 const char text[], size_t byteLeng th,
332 const SkScalar pos[], int scalarsP erPosition, 397 const SkScalar pos[], int scalarsP erPosition,
333 const SkPoint& offset, const SkIRe ct& clipRect) { 398 const SkPoint& offset, const SkIRe ct& clipRect) {
334 SkASSERT(byteLength == 0 || text != NULL); 399 SkASSERT(byteLength == 0 || text != NULL);
335 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); 400 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
336 401
337 // nothing to draw 402 // nothing to draw
338 if (text == NULL || byteLength == 0) { 403 if (text == NULL || byteLength == 0) {
339 return; 404 return;
340 } 405 }
341 406
342 fCurrStrike = NULL; 407 fCurrStrike = NULL;
343 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc(); 408 SkDrawCacheProc glyphCacheProc = skPaint.getDrawCacheProc();
344 409
345 // Get GrFontScaler from cache 410 // Get GrFontScaler from cache
346 BitmapTextBlob::Run& run = blob->fRuns[runIndex];
347 run.fDescriptor.reset(skPaint.getScalerContextDescriptor(&fDeviceProperties, &viewMatrix,
348 false));
349 run.fTypeface.reset(SkSafeRef(skPaint.getTypeface()));
350 const SkDescriptor* desc = reinterpret_cast<const SkDescriptor*>(run.fDescri ptor->data());
351 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, desc);
352 GrFontScaler* fontScaler = GetGrFontScaler(cache); 411 GrFontScaler* fontScaler = GetGrFontScaler(cache);
353 412
354 const char* stop = text + byteLength; 413 const char* stop = text + byteLength;
355 SkTextAlignProc alignProc(skPaint.getTextAlign()); 414 SkTextAlignProc alignProc(skPaint.getTextAlign());
356 SkTextMapStateProc tmsProc(viewMatrix, offset, scalarsPerPosition); 415 SkTextMapStateProc tmsProc(viewMatrix, offset, scalarsPerPosition);
357 SkScalar halfSampleX = 0, halfSampleY = 0; 416 SkScalar halfSampleX = 0, halfSampleY = 0;
358 417
359 if (cache->isSubpixel()) { 418 if (cache->isSubpixel()) {
360 // maybe we should skip the rounding if linearText is set 419 // maybe we should skip the rounding if linearText is set
361 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix); 420 SkAxisAlignment baseline = SkComputeAxisAlignmentForHText(viewMatrix);
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
480 GrGlyph::kCoverage_MaskStyle ), 539 GrGlyph::kCoverage_MaskStyle ),
481 Sk48Dot16FloorToInt(fx), 540 Sk48Dot16FloorToInt(fx),
482 Sk48Dot16FloorToInt(fy), 541 Sk48Dot16FloorToInt(fy),
483 fontScaler, 542 fontScaler,
484 clipRect); 543 clipRect);
485 } 544 }
486 pos += scalarsPerPosition; 545 pos += scalarsPerPosition;
487 } 546 }
488 } 547 }
489 } 548 }
490 SkGlyphCache::AttachCache(cache);
491 } 549 }
492 550
493 static size_t get_vertex_stride(GrMaskFormat maskFormat) { 551 static size_t get_vertex_stride(GrMaskFormat maskFormat) {
494 switch (maskFormat) { 552 switch (maskFormat) {
495 case kA8_GrMaskFormat: 553 case kA8_GrMaskFormat:
496 return kGrayTextVASize; 554 return kGrayTextVASize;
497 case kARGB_GrMaskFormat: 555 case kARGB_GrMaskFormat:
498 return kColorTextVASize; 556 return kColorTextVASize;
499 default: 557 default:
500 return kLCDTextVASize; 558 return kLCDTextVASize;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 // flag the glyph as being dead? 591 // flag the glyph as being dead?
534 SkDELETE(path); 592 SkDELETE(path);
535 return; 593 return;
536 } 594 }
537 glyph->fPath = path; 595 glyph->fPath = path;
538 } 596 }
539 SkASSERT(glyph->fPath); 597 SkASSERT(glyph->fPath);
540 blob->fBigGlyphs.push_back(BitmapTextBlob::BigGlyph(*glyph->fPath, vx, v y)); 598 blob->fBigGlyphs.push_back(BitmapTextBlob::BigGlyph(*glyph->fPath, vx, v y));
541 return; 599 return;
542 } 600 }
601
602 Run& run = blob->fRuns[runIndex];
603
543 GrMaskFormat format = glyph->fMaskFormat; 604 GrMaskFormat format = glyph->fMaskFormat;
605
606 PerSubRunInfo* subRun = &run.fSubRunInfo.back();
607 if (run.fInitialized && subRun->fMaskFormat != format) {
608 PerSubRunInfo* newSubRun = &run.fSubRunInfo.push_back();
609 newSubRun->fGlyphStartIndex = subRun->fGlyphEndIndex;
610 newSubRun->fGlyphEndIndex = subRun->fGlyphEndIndex;
611
612 newSubRun->fVertexStartIndex = subRun->fVertexEndIndex;
613 newSubRun->fVertexEndIndex = subRun->fVertexEndIndex;
614
615 subRun = newSubRun;
616 }
617
618 run.fInitialized = true;
619 subRun->fMaskFormat = format;
620 blob->fGlyphIDs[subRun->fGlyphEndIndex] = packed;
621
544 size_t vertexStride = get_vertex_stride(format); 622 size_t vertexStride = get_vertex_stride(format);
545 623
546 BitmapTextBlob::Run& run = blob->fRuns[runIndex];
547 int glyphIdx = run.fInfos[format].fGlyphIDs.count();
548 *run.fInfos[format].fGlyphIDs.append() = packed;
549 run.fInfos[format].fVertices.append(static_cast<int>(vertexStride * kVertice sPerGlyph));
550
551 SkRect r; 624 SkRect r;
552 r.fLeft = SkIntToScalar(x); 625 r.fLeft = SkIntToScalar(x);
553 r.fTop = SkIntToScalar(y); 626 r.fTop = SkIntToScalar(y);
554 r.fRight = r.fLeft + SkIntToScalar(width); 627 r.fRight = r.fLeft + SkIntToScalar(width);
555 r.fBottom = r.fTop + SkIntToScalar(height); 628 r.fBottom = r.fTop + SkIntToScalar(height);
556 629
557 run.fVertexBounds.joinNonEmptyArg(r); 630 run.fVertexBounds.joinNonEmptyArg(r);
558 GrColor color = fPaint.getColor(); 631 GrColor color = fPaint.getColor();
559 run.fColor = color; 632 run.fColor = color;
560 633
561 intptr_t vertex = reinterpret_cast<intptr_t>(run.fInfos[format].fVertices.be gin()); 634 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices + subRun->fVert exEndIndex);
562 vertex += vertexStride * glyphIdx * kVerticesPerGlyph;
563 635
564 // V0 636 // V0
565 SkPoint* position = reinterpret_cast<SkPoint*>(vertex); 637 SkPoint* position = reinterpret_cast<SkPoint*>(vertex);
566 position->set(r.fLeft, r.fTop); 638 position->set(r.fLeft, r.fTop);
567 if (kA8_GrMaskFormat == format) { 639 if (kA8_GrMaskFormat == format) {
568 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)) ; 640 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)) ;
569 *colorPtr = color; 641 *colorPtr = color;
570 } 642 }
571 vertex += vertexStride; 643 vertex += vertexStride;
572 644
(...skipping 15 matching lines...) Expand all
588 } 660 }
589 vertex += vertexStride; 661 vertex += vertexStride;
590 662
591 // V3 663 // V3
592 position = reinterpret_cast<SkPoint*>(vertex); 664 position = reinterpret_cast<SkPoint*>(vertex);
593 position->set(r.fRight, r.fTop); 665 position->set(r.fRight, r.fTop);
594 if (kA8_GrMaskFormat == format) { 666 if (kA8_GrMaskFormat == format) {
595 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)) ; 667 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)) ;
596 *colorPtr = color; 668 *colorPtr = color;
597 } 669 }
670
671 subRun->fGlyphEndIndex++;
672 subRun->fVertexEndIndex += vertexStride * kVerticesPerGlyph;
598 } 673 }
599 674
600 class BitmapTextBatch : public GrBatch { 675 class BitmapTextBatch : public GrBatch {
601 public: 676 public:
602 typedef GrBitmapTextContextB::BitmapTextBlob Blob; 677 typedef GrBitmapTextContextB::BitmapTextBlob Blob;
603 typedef Blob::Run Run; 678 typedef Blob::Run Run;
604 typedef Run::PerFormatInfo TextInfo; 679 typedef Run::PerSubRunInfo TextInfo;
605 struct Geometry { 680 struct Geometry {
606 Geometry() {} 681 Geometry() {}
607 Geometry(const Geometry& geometry) 682 Geometry(const Geometry& geometry)
608 : fBlob(SkRef(geometry.fBlob.get())) 683 : fBlob(SkRef(geometry.fBlob.get()))
609 , fRun(geometry.fRun) 684 , fRun(geometry.fRun)
685 , fSubRun(geometry.fSubRun)
610 , fColor(geometry.fColor) {} 686 , fColor(geometry.fColor) {}
611 SkAutoTUnref<Blob> fBlob; 687 SkAutoTUnref<Blob> fBlob;
612 int fRun; 688 int fRun;
689 int fSubRun;
613 GrColor fColor; 690 GrColor fColor;
614 }; 691 };
615 692
616 static GrBatch* Create(const Geometry& geometry, GrColor color, GrMaskFormat maskFormat, 693 static GrBatch* Create(const Geometry& geometry, GrColor color, GrMaskFormat maskFormat,
617 GrBatchFontCache* fontCache) { 694 int glyphCount, GrBatchFontCache* fontCache) {
618 return SkNEW_ARGS(BitmapTextBatch, (geometry, color, maskFormat, fontCac he)); 695 return SkNEW_ARGS(BitmapTextBatch, (geometry, color, maskFormat, glyphCo unt, fontCache));
619 } 696 }
620 697
621 const char* name() const override { return "BitmapTextBatch"; } 698 const char* name() const override { return "BitmapTextBatch"; }
622 699
623 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 700 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
624 if (kARGB_GrMaskFormat == fMaskFormat) { 701 if (kARGB_GrMaskFormat == fMaskFormat) {
625 out->setUnknownFourComponents(); 702 out->setUnknownFourComponents();
626 } else { 703 } else {
627 out->setKnownFourComponents(fBatch.fColor); 704 out->setKnownFourComponents(fBatch.fColor);
628 } 705 }
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
711 drawInfo.setIndicesPerInstance(kIndicesPerGlyph); 788 drawInfo.setIndicesPerInstance(kIndicesPerGlyph);
712 drawInfo.adjustStartVertex(firstVertex); 789 drawInfo.adjustStartVertex(firstVertex);
713 drawInfo.setVertexBuffer(vertexBuffer); 790 drawInfo.setVertexBuffer(vertexBuffer);
714 drawInfo.setIndexBuffer(quadIndexBuffer); 791 drawInfo.setIndexBuffer(quadIndexBuffer);
715 792
716 int instancesToFlush = 0; 793 int instancesToFlush = 0;
717 for (int i = 0; i < instanceCount; i++) { 794 for (int i = 0; i < instanceCount; i++) {
718 Geometry& args = fGeoData[i]; 795 Geometry& args = fGeoData[i];
719 Blob* blob = args.fBlob; 796 Blob* blob = args.fBlob;
720 Run& run = blob->fRuns[args.fRun]; 797 Run& run = blob->fRuns[args.fRun];
721 TextInfo& info = run.fInfos[fMaskFormat]; 798 TextInfo& info = run.fSubRunInfo[args.fSubRun];
722 799
723 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); 800 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat);
724 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas Gen; 801 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas Gen;
725 bool regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColo r != args.fColor; 802 bool regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColo r != args.fColor;
726 int glyphCount = info.fGlyphIDs.count(); 803 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex;
727 804
728 // We regenerate both texture coords and colors in the blob itself, and update the 805 // We regenerate both texture coords and colors in the blob itself, and update the
729 // atlas generation. If we don't end up purging any unused plots, w e can avoid 806 // atlas generation. If we don't end up purging any unused plots, w e can avoid
730 // regenerating the coords. We could take a finer grained approach to updating texture 807 // regenerating the coords. We could take a finer grained approach to updating texture
731 // coords but its not clear if the extra bookkeeping would offset an y gains. 808 // coords but its not clear if the extra bookkeeping would offset an y gains.
732 // To avoid looping over the glyphs twice, we do one loop and condit ionally update color 809 // To avoid looping over the glyphs twice, we do one loop and condit ionally update color
733 // or coords as needed. One final note, if we have to break a run f or an atlas eviction 810 // or coords as needed. One final note, if we have to break a run f or an atlas eviction
734 // then we can't really trust the atlas has all of the correct data. Atlas evictions 811 // then we can't really trust the atlas has all of the correct data. Atlas evictions
735 // should be pretty rare, so we just always regenerate in those case s 812 // should be pretty rare, so we just always regenerate in those case s
736 if (regenerateTextureCoords || regenerateColors) { 813 if (regenerateTextureCoords || regenerateColors) {
737 // first regenerate texture coordinates / colors if need be 814 // first regenerate texture coordinates / colors if need be
738 const SkDescriptor* desc = NULL; 815 const SkDescriptor* desc = NULL;
739 SkGlyphCache* cache = NULL; 816 SkGlyphCache* cache = NULL;
740 GrFontScaler* scaler = NULL; 817 GrFontScaler* scaler = NULL;
741 GrBatchTextStrike* strike = NULL; 818 GrBatchTextStrike* strike = NULL;
742 bool brokenRun = false; 819 bool brokenRun = false;
743 if (regenerateTextureCoords) { 820 if (regenerateTextureCoords) {
744 desc = reinterpret_cast<const SkDescriptor*>(run.fDescriptor ->data()); 821 desc = run.fDescriptor.getDesc();
745 cache = SkGlyphCache::DetachCache(run.fTypeface, desc); 822 cache = SkGlyphCache::DetachCache(run.fTypeface, desc);
746 scaler = GrTextContext::GetGrFontScaler(cache); 823 scaler = GrTextContext::GetGrFontScaler(cache);
747 strike = fFontCache->getStrike(scaler); 824 strike = fFontCache->getStrike(scaler);
748 } 825 }
749 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) { 826 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) {
750 GrGlyph::PackedID glyphID = info.fGlyphIDs[glyphIdx]; 827 GrGlyph::PackedID glyphID = blob->fGlyphIDs[glyphIdx + info. fGlyphStartIndex];
751 828
752 if (regenerateTextureCoords) { 829 if (regenerateTextureCoords) {
753 // Upload the glyph only if needed 830 // Upload the glyph only if needed
754 GrGlyph* glyph = strike->getGlyph(glyphID, scaler); 831 GrGlyph* glyph = strike->getGlyph(glyphID, scaler);
755 SkASSERT(glyph); 832 SkASSERT(glyph);
756 833
757 if (!fFontCache->hasGlyph(glyph) && 834 if (!fFontCache->hasGlyph(glyph) &&
758 !strike->addGlyphToAtlas(batchTarget, glyph, scaler) ) { 835 !strike->addGlyphToAtlas(batchTarget, glyph, scaler) ) {
759 this->flush(batchTarget, &drawInfo, instancesToFlush , 836 this->flush(batchTarget, &drawInfo, instancesToFlush ,
760 maxInstancesPerDraw); 837 maxInstancesPerDraw);
761 this->initDraw(batchTarget, gp, pipeline); 838 this->initDraw(batchTarget, gp, pipeline);
762 instancesToFlush = 0; 839 instancesToFlush = 0;
763 brokenRun = glyphIdx > 0; 840 brokenRun = glyphIdx > 0;
764 841
765 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas( batchTarget, glyph, 842 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas( batchTarget, glyph,
766 scaler); 843 scaler);
767 SkASSERT(success); 844 SkASSERT(success);
768 } 845 }
769 846
770 fFontCache->setGlyphRefToken(glyph, batchTarget->current Token()); 847 fFontCache->setGlyphRefToken(glyph, batchTarget->current Token());
771 848
772 // Texture coords are the last vertex attribute so we ge t a pointer to the 849 // Texture coords are the last vertex attribute so we ge t a pointer to the
773 // first one and then map with stride in regenerateTextu reCoords 850 // first one and then map with stride in regenerateTextu reCoords
774 intptr_t vertex = reinterpret_cast<intptr_t>(info.fVerti ces.begin()); 851 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert ices);
852 vertex += info.fVertexStartIndex;
775 vertex += vertexStride * glyphIdx * kVerticesPerGlyph; 853 vertex += vertexStride * glyphIdx * kVerticesPerGlyph;
776 vertex += vertexStride - sizeof(SkIPoint16); 854 vertex += vertexStride - sizeof(SkIPoint16);
777 855
778 this->regenerateTextureCoords(glyph, vertex, vertexStrid e); 856 this->regenerateTextureCoords(glyph, vertex, vertexStrid e);
779 } 857 }
780 858
781 if (regenerateColors) { 859 if (regenerateColors) {
782 intptr_t vertex = reinterpret_cast<intptr_t>(info.fVerti ces.begin()); 860 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert ices);
861 vertex += info.fVertexStartIndex;
783 vertex += vertexStride * glyphIdx * kVerticesPerGlyph + sizeof(SkPoint); 862 vertex += vertexStride * glyphIdx * kVerticesPerGlyph + sizeof(SkPoint);
784 this->regenerateColors(vertex, vertexStride, args.fColor ); 863 this->regenerateColors(vertex, vertexStride, args.fColor );
785 } 864 }
786 865
787 instancesToFlush++; 866 instancesToFlush++;
788 } 867 }
789 868
790 if (regenerateTextureCoords) { 869 if (regenerateTextureCoords) {
791 SkGlyphCache::AttachCache(cache); 870 SkGlyphCache::AttachCache(cache);
792 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt lasGeneration : 871 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt lasGeneration :
793 fFontCache->atlasGenerat ion(fMaskFormat); 872 fFontCache->atlasGenerat ion(fMaskFormat);
794 } 873 }
795 } else { 874 } else {
796 instancesToFlush += glyphCount; 875 instancesToFlush += glyphCount;
797 } 876 }
798 877
799 // now copy all vertices 878 // now copy all vertices
800 int byteCount = info.fVertices.count(); 879 int byteCount = info.fVertexEndIndex - info.fVertexStartIndex;
801 memcpy(currVertex, info.fVertices.begin(), byteCount); 880 memcpy(currVertex, blob->fVertices + info.fVertexStartIndex, byteCou nt);
802 881
803 currVertex += byteCount; 882 currVertex += byteCount;
804 } 883 }
805 884
806 this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDra w); 885 this->flush(batchTarget, &drawInfo, instancesToFlush, maxInstancesPerDra w);
807 } 886 }
808 887
809 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } 888 SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
810 889
811 private: 890 private:
812 BitmapTextBatch(const Geometry& geometry, GrColor color, GrMaskFormat maskFo rmat, 891 BitmapTextBatch(const Geometry& geometry, GrColor color, GrMaskFormat maskFo rmat,
813 GrBatchFontCache* fontCache) 892 int glyphCount, GrBatchFontCache* fontCache)
814 : fMaskFormat(maskFormat) 893 : fMaskFormat(maskFormat)
815 , fPixelConfig(fontCache->getPixelConfig(maskFormat)) 894 , fPixelConfig(fontCache->getPixelConfig(maskFormat))
816 , fFontCache(fontCache) { 895 , fFontCache(fontCache) {
817 this->initClassID<BitmapTextBatch>(); 896 this->initClassID<BitmapTextBatch>();
818 fGeoData.push_back(geometry); 897 fGeoData.push_back(geometry);
819 fBatch.fColor = color; 898 fBatch.fColor = color;
820 fBatch.fViewMatrix = geometry.fBlob->fViewMatrix; 899 fBatch.fViewMatrix = geometry.fBlob->fViewMatrix;
821 int numGlyphs = geometry.fBlob->fRuns[geometry.fRun].fInfos[maskFormat]. fGlyphIDs.count(); 900 fBatch.fNumGlyphs = glyphCount;
822 fBatch.fNumGlyphs = numGlyphs;
823 } 901 }
824 902
825 void regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, size_t vertexS tride) { 903 void regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, size_t vertexS tride) {
826 int width = glyph->fBounds.width(); 904 int width = glyph->fBounds.width();
827 int height = glyph->fBounds.height(); 905 int height = glyph->fBounds.height();
828 int u0 = glyph->fAtlasLocation.fX; 906 int u0 = glyph->fAtlasLocation.fX;
829 int v0 = glyph->fAtlasLocation.fY; 907 int v0 = glyph->fAtlasLocation.fY;
830 int u1 = u0 + width; 908 int u1 = u0 + width;
831 int v1 = v0 + height; 909 int v1 = v0 + height;
832 910
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
925 int fNumGlyphs; 1003 int fNumGlyphs;
926 }; 1004 };
927 1005
928 BatchTracker fBatch; 1006 BatchTracker fBatch;
929 SkSTArray<1, Geometry, true> fGeoData; 1007 SkSTArray<1, Geometry, true> fGeoData;
930 GrMaskFormat fMaskFormat; 1008 GrMaskFormat fMaskFormat;
931 GrPixelConfig fPixelConfig; 1009 GrPixelConfig fPixelConfig;
932 GrBatchFontCache* fFontCache; 1010 GrBatchFontCache* fFontCache;
933 }; 1011 };
934 1012
935 void GrBitmapTextContextB::flushSubRun(GrDrawTarget* target, BitmapTextBlob* blo b, int i,
936 GrPipelineBuilder* pipelineBuilder, GrMas kFormat format,
937 GrColor color, int paintAlpha) {
938 if (0 == blob->fRuns[i].fInfos[format].fGlyphIDs.count()) {
939 return;
940 }
941
942 if (kARGB_GrMaskFormat == format) {
943 color = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAlpha);
944 }
945
946 BitmapTextBatch::Geometry geometry;
947 geometry.fBlob.reset(SkRef(blob));
948 geometry.fRun = i;
949 geometry.fColor = color;
950 SkAutoTUnref<GrBatch> batch(BitmapTextBatch::Create(geometry, color, format,
951 fContext->getBatchFontCa che()));
952
953 target->drawBatch(pipelineBuilder, batch, &blob->fRuns[i].fVertexBounds);
954 }
955
956 void GrBitmapTextContextB::flush(GrDrawTarget* target, BitmapTextBlob* blob, GrR enderTarget* rt, 1013 void GrBitmapTextContextB::flush(GrDrawTarget* target, BitmapTextBlob* blob, GrR enderTarget* rt,
957 const GrPaint& paint, const GrClip& clip, 1014 const GrPaint& paint, const GrClip& clip,
958 const SkMatrix& viewMatrix, int paintAlpha) { 1015 const SkMatrix& viewMatrix, int paintAlpha) {
959 GrPipelineBuilder pipelineBuilder; 1016 GrPipelineBuilder pipelineBuilder;
960 pipelineBuilder.setFromPaint(paint, rt, clip); 1017 pipelineBuilder.setFromPaint(paint, rt, clip);
961 1018
962 GrColor color = paint.getColor(); 1019 GrColor color = paint.getColor();
963 for (int i = 0; i < blob->fRuns.count(); i++) { 1020 for (uint32_t run = 0; run < blob->fRunCount; run++) {
964 this->flushSubRun(target, blob, i, &pipelineBuilder, kA8_GrMaskFormat, c olor, paintAlpha); 1021 for (int subRun = 0; subRun < blob->fRuns[run].fSubRunInfo.count(); subR un++) {
965 this->flushSubRun(target, blob, i, &pipelineBuilder, kA565_GrMaskFormat, color, paintAlpha); 1022 PerSubRunInfo& info = blob->fRuns[run].fSubRunInfo[subRun];
966 this->flushSubRun(target, blob, i, &pipelineBuilder, kARGB_GrMaskFormat, color, paintAlpha); 1023 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex;
1024 if (0 == glyphCount) {
1025 continue;
1026 }
1027
1028 GrMaskFormat format = info.fMaskFormat;
1029 if (kARGB_GrMaskFormat == format) {
1030 color = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paint Alpha);
1031 }
1032
1033 BitmapTextBatch::Geometry geometry;
1034 geometry.fBlob.reset(SkRef(blob));
1035 geometry.fRun = run;
1036 geometry.fSubRun = subRun;
1037 geometry.fColor = color;
1038 SkAutoTUnref<GrBatch> batch(BitmapTextBatch::Create(geometry, color, format, glyphCount,
1039 fContext->getBat chFontCache()));
1040
1041 target->drawBatch(&pipelineBuilder, batch, &blob->fRuns[run].fVertex Bounds);
1042 }
967 } 1043 }
968 1044
969 // Now flush big glyphs 1045 // Now flush big glyphs
970 for (int i = 0; i < blob->fBigGlyphs.count(); i++) { 1046 for (int i = 0; i < blob->fBigGlyphs.count(); i++) {
971 BitmapTextBlob::BigGlyph& bigGlyph = blob->fBigGlyphs[i]; 1047 BitmapTextBlob::BigGlyph& bigGlyph = blob->fBigGlyphs[i];
972 SkMatrix translate; 1048 SkMatrix translate;
973 translate.setTranslate(SkIntToScalar(bigGlyph.fVx), SkIntToScalar(bigGly ph.fVy)); 1049 translate.setTranslate(SkIntToScalar(bigGlyph.fVx), SkIntToScalar(bigGly ph.fVy));
974 SkPath tmpPath(bigGlyph.fPath); 1050 SkPath tmpPath(bigGlyph.fPath);
975 tmpPath.transform(translate); 1051 tmpPath.transform(translate);
976 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); 1052 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle);
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
1553 SkSafeSetNull(fCurrTexture); 1629 SkSafeSetNull(fCurrTexture);
1554 } 1630 }
1555 } 1631 }
1556 1632
1557 inline void GrBitmapTextContext::finish() { 1633 inline void GrBitmapTextContext::finish() {
1558 this->flush(); 1634 this->flush();
1559 fTotalVertexCount = 0; 1635 fTotalVertexCount = 0;
1560 1636
1561 GrTextContext::finish(); 1637 GrTextContext::finish();
1562 } 1638 }
OLDNEW
« src/gpu/GrBitmapTextContext.h ('K') | « src/gpu/GrBitmapTextContext.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698