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

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

Powered by Google App Engine
This is Rietveld 408576698