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

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

Issue 1507203002: Improve nvpr glyph batching (Closed) Base URL: https://skia.googlesource.com/skia.git@upload_drawpathbatch
Patch Set: re-fix issue dependencies Created 5 years 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') | src/gpu/batches/GrDrawPathBatch.h » ('j') | 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"
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 } 226 }
227 227
228 fCpuMemorySize += run->computeSizeInCache(); 228 fCpuMemorySize += run->computeSizeInCache();
229 } 229 }
230 } 230 }
231 231
232 //////////////////////////////////////////////////////////////////////////////// //////////////////// 232 //////////////////////////////////////////////////////////////////////////////// ////////////////////
233 233
234 class GrStencilAndCoverTextContext::FallbackBlobBuilder { 234 class GrStencilAndCoverTextContext::FallbackBlobBuilder {
235 public: 235 public:
236 FallbackBlobBuilder() : fBuffIdx(0) {} 236 FallbackBlobBuilder() : fBuffIdx(0), fCount(0) {}
237 237
238 bool isInitialized() const { return SkToBool(fBuilder); } 238 bool isInitialized() const { return SkToBool(fBuilder); }
239 239
240 void init(const SkPaint& font, SkScalar textRatio); 240 void init(const SkPaint& font, SkScalar textRatio);
241 241
242 void appendGlyph(uint16_t glyphId, const SkPoint& pos); 242 void appendGlyph(uint16_t glyphId, const SkPoint& pos);
243 243
244 const SkTextBlob* buildIfInitialized(); 244 const SkTextBlob* buildIfNeeded(int* count);
245 245
246 private: 246 private:
247 enum { kWriteBufferSize = 1024 }; 247 enum { kWriteBufferSize = 1024 };
248 248
249 void flush(); 249 void flush();
250 250
251 SkAutoTDelete<SkTextBlobBuilder> fBuilder; 251 SkAutoTDelete<SkTextBlobBuilder> fBuilder;
252 SkPaint fFont; 252 SkPaint fFont;
253 int fBuffIdx; 253 int fBuffIdx;
254 int fCount;
254 uint16_t fGlyphIds[kWriteBufferSize]; 255 uint16_t fGlyphIds[kWriteBufferSize];
255 SkPoint fPositions[kWriteBufferSize]; 256 SkPoint fPositions[kWriteBufferSize];
256 }; 257 };
257 258
258 //////////////////////////////////////////////////////////////////////////////// //////////////////// 259 //////////////////////////////////////////////////////////////////////////////// ////////////////////
259 260
260 GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke) 261 GrStencilAndCoverTextContext::TextRun::TextRun(const SkPaint& fontAndStroke)
261 : fStroke(fontAndStroke), 262 : fStroke(fontAndStroke),
262 fFont(fontAndStroke), 263 fFont(fontAndStroke),
263 fTotalGlyphCount(0), 264 fTotalGlyphCount(0),
265 fFallbackGlyphCount(0),
264 fDetachedGlyphCache(nullptr), 266 fDetachedGlyphCache(nullptr),
265 fLastDrawnGlyphsID(SK_InvalidUniqueID) { 267 fLastDrawnGlyphsID(SK_InvalidUniqueID) {
266 SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported. 268 SkASSERT(!fStroke.isHairlineStyle()); // Hairlines are not supported.
267 269
268 // Setting to "fill" ensures that no strokes get baked into font outlines. ( We use the GPU path 270 // Setting to "fill" ensures that no strokes get baked into font outlines. ( We use the GPU path
269 // rendering API for stroking). 271 // rendering API for stroking).
270 fFont.setStyle(SkPaint::kFill_Style); 272 fFont.setStyle(SkPaint::kFill_Style);
271 273
272 if (fFont.isFakeBoldText() && SkStrokeRec::kStroke_Style != fStroke.getStyle ()) { 274 if (fFont.isFakeBoldText() && SkStrokeRec::kStroke_Style != fStroke.getStyle ()) {
273 // Instead of letting fake bold get baked into the glyph outlines, do it with GPU stroke. 275 // Instead of letting fake bold get baked into the glyph outlines, do it with GPU stroke.
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 const SkDescriptor* desc = &glyphCache->getDescriptor(); 334 const SkDescriptor* desc = &glyphCache->getDescriptor();
333 int descDataCount = (desc->getLength() + 3) / 4; 335 int descDataCount = (desc->getLength() + 3) / 4;
334 GrUniqueKey::Builder builder(&fGlyphPathsKey, kPathGlyphDomain, 336 GrUniqueKey::Builder builder(&fGlyphPathsKey, kPathGlyphDomain,
335 2 + strokeDataCount + descDataCount); 337 2 + strokeDataCount + descDataCount);
336 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqu eID() : 0; 338 reinterpret_cast<uint32_t&>(builder[0]) = typeface ? typeface->uniqu eID() : 0;
337 reinterpret_cast<uint32_t&>(builder[1]) = strokeDataCount | (descDat aCount << 16); 339 reinterpret_cast<uint32_t&>(builder[1]) = strokeDataCount | (descDat aCount << 16);
338 fStroke.asUniqueKeyFragment(&builder[2]); 340 fStroke.asUniqueKeyFragment(&builder[2]);
339 memcpy(&builder[2 + strokeDataCount], desc, desc->getLength()); 341 memcpy(&builder[2 + strokeDataCount], desc, desc->getLength());
340 } 342 }
341 } 343 }
342
343 // When drawing from canonically sized paths, the actual local coords are fT extRatio * coords.
344 fLocalMatrixTemplate.setScale(fTextRatio, fTextRatio);
345 } 344 }
346 345
347 GrStencilAndCoverTextContext::TextRun::~TextRun() { 346 GrStencilAndCoverTextContext::TextRun::~TextRun() {
348 this->releaseGlyphCache(); 347 this->releaseGlyphCache();
349 } 348 }
350 349
351 void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by teLength, 350 void GrStencilAndCoverTextContext::TextRun::setText(const char text[], size_t by teLength,
352 SkScalar x, SkScalar y) { 351 SkScalar x, SkScalar y) {
353 SkASSERT(byteLength == 0 || text != nullptr); 352 SkASSERT(byteLength == 0 || text != nullptr);
354 353
355 SkGlyphCache* glyphCache = this->getGlyphCache(); 354 SkGlyphCache* glyphCache = this->getGlyphCache();
356 SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc(); 355 SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();
357 356
358 fDraw.reset(GrPathRangeDraw::Create(GrPathRendering::kTranslate_PathTransfor mType, 357 fTotalGlyphCount = fFont.countText(text, byteLength);
359 fTotalGlyphCount = fFont.countText(text, byteLength))); 358 fInstanceData.reset(InstanceData::Alloc(GrPathRendering::kTranslate_PathTran sformType,
359 fTotalGlyphCount));
360 360
361 const char* stop = text + byteLength; 361 const char* stop = text + byteLength;
362 362
363 // Measure first if needed. 363 // Measure first if needed.
364 if (fFont.getTextAlign() != SkPaint::kLeft_Align) { 364 if (fFont.getTextAlign() != SkPaint::kLeft_Align) {
365 SkFixed stopX = 0; 365 SkFixed stopX = 0;
366 SkFixed stopY = 0; 366 SkFixed stopY = 0;
367 367
368 const char* textPtr = text; 368 const char* textPtr = text;
369 while (textPtr < stop) { 369 while (textPtr < stop) {
(...skipping 30 matching lines...) Expand all
400 fx += SkFixedMul(autokern.adjust(glyph), fixedSizeRatio); 400 fx += SkFixedMul(autokern.adjust(glyph), fixedSizeRatio);
401 if (glyph.fWidth) { 401 if (glyph.fWidth) {
402 this->appendGlyph(glyph, SkPoint::Make(SkFixedToScalar(fx), SkFixedT oScalar(fy)), 402 this->appendGlyph(glyph, SkPoint::Make(SkFixedToScalar(fx), SkFixedT oScalar(fy)),
403 &fallback); 403 &fallback);
404 } 404 }
405 405
406 fx += SkFixedMul(glyph.fAdvanceX, fixedSizeRatio); 406 fx += SkFixedMul(glyph.fAdvanceX, fixedSizeRatio);
407 fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio); 407 fy += SkFixedMul(glyph.fAdvanceY, fixedSizeRatio);
408 } 408 }
409 409
410 fFallbackTextBlob.reset(fallback.buildIfInitialized()); 410 fFallbackTextBlob.reset(fallback.buildIfNeeded(&fFallbackGlyphCount));
411 } 411 }
412 412
413 void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength, 413 void GrStencilAndCoverTextContext::TextRun::setPosText(const char text[], size_t byteLength,
414 const SkScalar pos[], int scalarsPerPosition, 414 const SkScalar pos[], int scalarsPerPosition,
415 const SkPoint& offset) { 415 const SkPoint& offset) {
416 SkASSERT(byteLength == 0 || text != nullptr); 416 SkASSERT(byteLength == 0 || text != nullptr);
417 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition); 417 SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
418 418
419 SkGlyphCache* glyphCache = this->getGlyphCache(); 419 SkGlyphCache* glyphCache = this->getGlyphCache();
420 SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc(); 420 SkDrawCacheProc glyphCacheProc = fFont.getDrawCacheProc();
421 421
422 fDraw.reset(GrPathRangeDraw::Create(GrPathRendering::kTranslate_PathTransfor mType, 422 fTotalGlyphCount = fFont.countText(text, byteLength);
423 fTotalGlyphCount = fFont.countText(text, byteLength))); 423 fInstanceData.reset(InstanceData::Alloc(GrPathRendering::kTranslate_PathTran sformType,
424 fTotalGlyphCount));
424 425
425 const char* stop = text + byteLength; 426 const char* stop = text + byteLength;
426 427
427 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition); 428 SkTextMapStateProc tmsProc(SkMatrix::I(), offset, scalarsPerPosition);
428 SkTextAlignProc alignProc(fFont.getTextAlign()); 429 SkTextAlignProc alignProc(fFont.getTextAlign());
429 FallbackBlobBuilder fallback; 430 FallbackBlobBuilder fallback;
430 while (text < stop) { 431 while (text < stop) {
431 const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0); 432 const SkGlyph& glyph = glyphCacheProc(glyphCache, &text, 0, 0);
432 if (glyph.fWidth) { 433 if (glyph.fWidth) {
433 SkPoint tmsLoc; 434 SkPoint tmsLoc;
434 tmsProc(pos, &tmsLoc); 435 tmsProc(pos, &tmsLoc);
435 SkPoint loc; 436 SkPoint loc;
436 alignProc(tmsLoc, glyph, &loc); 437 alignProc(tmsLoc, glyph, &loc);
437 438
438 this->appendGlyph(glyph, loc, &fallback); 439 this->appendGlyph(glyph, loc, &fallback);
439 } 440 }
440 pos += scalarsPerPosition; 441 pos += scalarsPerPosition;
441 } 442 }
442 443
443 fFallbackTextBlob.reset(fallback.buildIfInitialized()); 444 fFallbackTextBlob.reset(fallback.buildIfNeeded(&fFallbackGlyphCount));
444 } 445 }
445 446
446 GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx) const { 447 GrPathRange* GrStencilAndCoverTextContext::TextRun::createGlyphs(GrContext* ctx) const {
447 GrPathRange* glyphs = static_cast<GrPathRange*>( 448 GrPathRange* glyphs = static_cast<GrPathRange*>(
448 ctx->resourceProvider()->findAndRefResourceByUniqueKey(fGlyphPathsKe y)); 449 ctx->resourceProvider()->findAndRefResourceByUniqueKey(fGlyphPathsKe y));
449 if (nullptr == glyphs) { 450 if (nullptr == glyphs) {
450 if (fUsingRawGlyphPaths) { 451 if (fUsingRawGlyphPaths) {
451 glyphs = ctx->resourceProvider()->createGlyphs(fFont.getTypeface(), nullptr, fStroke); 452 glyphs = ctx->resourceProvider()->createGlyphs(fFont.getTypeface(), nullptr, fStroke);
452 } else { 453 } else {
453 SkGlyphCache* cache = this->getGlyphCache(); 454 SkGlyphCache* cache = this->getGlyphCache();
454 glyphs = ctx->resourceProvider()->createGlyphs(cache->getScalerConte xt()->getTypeface(), 455 glyphs = ctx->resourceProvider()->createGlyphs(cache->getScalerConte xt()->getTypeface(),
455 &cache->getDescriptor (), 456 &cache->getDescriptor (),
456 fStroke); 457 fStroke);
457 } 458 }
458 ctx->resourceProvider()->assignUniqueKeyToResource(fGlyphPathsKey, glyph s); 459 ctx->resourceProvider()->assignUniqueKeyToResource(fGlyphPathsKey, glyph s);
459 } 460 }
460 return glyphs; 461 return glyphs;
461 } 462 }
462 463
463 inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& gl yph, 464 inline void GrStencilAndCoverTextContext::TextRun::appendGlyph(const SkGlyph& gl yph,
464 const SkPoint& po s, 465 const SkPoint& po s,
465 FallbackBlobBuild er* fallback) { 466 FallbackBlobBuild er* fallback) {
466 // Stick the glyphs we can't draw into the fallback text blob. 467 // Stick the glyphs we can't draw into the fallback text blob.
467 if (SkMask::kARGB32_Format == glyph.fMaskFormat) { 468 if (SkMask::kARGB32_Format == glyph.fMaskFormat) {
468 if (!fallback->isInitialized()) { 469 if (!fallback->isInitialized()) {
469 fallback->init(fFont, fTextRatio); 470 fallback->init(fFont, fTextRatio);
470 } 471 }
471 fallback->appendGlyph(glyph.getGlyphID(), pos); 472 fallback->appendGlyph(glyph.getGlyphID(), pos);
472 } else { 473 } else {
473 float translate[] = { fTextInverseRatio * pos.x(), fTextInverseRatio * p os.y() }; 474 fInstanceData->append(glyph.getGlyphID(), fTextInverseRatio * pos.x(),
474 fDraw->append(glyph.getGlyphID(), translate); 475 fTextInverseRatio * pos.y());
475 } 476 }
476 } 477 }
477 478
478 void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx, 479 void GrStencilAndCoverTextContext::TextRun::draw(GrContext* ctx,
479 GrDrawContext* dc, 480 GrDrawContext* dc,
480 GrPipelineBuilder* pipelineBuil der, 481 GrPipelineBuilder* pipelineBuil der,
481 GrColor color, 482 GrColor color,
482 const SkMatrix& viewMatrix, 483 const SkMatrix& viewMatrix,
483 SkScalar x, SkScalar y, 484 SkScalar x, SkScalar y,
484 const SkIRect& clipBounds, 485 const SkIRect& clipBounds,
485 GrTextContext* fallbackTextCont ext, 486 GrTextContext* fallbackTextCont ext,
486 const SkPaint& originalSkPaint) const { 487 const SkPaint& originalSkPaint) const {
487 SkASSERT(fDraw); 488 SkASSERT(fInstanceData);
488 SkASSERT(dc->accessRenderTarget()->isStencilBufferMultisampled() || !fFont.i sAntiAlias()); 489 SkASSERT(dc->accessRenderTarget()->isStencilBufferMultisampled() || !fFont.i sAntiAlias());
489 490
490 if (fDraw->count()) { 491 if (fInstanceData->count()) {
491 pipelineBuilder->setState(GrPipelineBuilder::kHWAntialias_Flag, fFont.is AntiAlias()); 492 pipelineBuilder->setState(GrPipelineBuilder::kHWAntialias_Flag, fFont.is AntiAlias());
492 493
493 GR_STATIC_CONST_SAME_STENCIL(kStencilPass, 494 GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
494 kZero_StencilOp, 495 kZero_StencilOp,
495 kKeep_StencilOp, 496 kKeep_StencilOp,
496 kNotEqual_StencilFunc, 497 kNotEqual_StencilFunc,
497 0xffff, 498 0xffff,
498 0x0000, 499 0x0000,
499 0xffff); 500 0xffff);
500 501
501 *pipelineBuilder->stencil() = kStencilPass; 502 *pipelineBuilder->stencil() = kStencilPass;
502 503
503 SkAutoTUnref<GrPathRange> glyphs(this->createGlyphs(ctx)); 504 SkAutoTUnref<GrPathRange> glyphs(this->createGlyphs(ctx));
504 if (fLastDrawnGlyphsID != glyphs->getUniqueID()) { 505 if (fLastDrawnGlyphsID != glyphs->getUniqueID()) {
505 // Either this is the first draw or the glyphs object was purged sin ce last draw. 506 // Either this is the first draw or the glyphs object was purged sin ce last draw.
506 glyphs->loadPathsIfNeeded(fDraw->indices(), fDraw->count()); 507 glyphs->loadPathsIfNeeded(fInstanceData->indices(), fInstanceData->c ount());
507 fLastDrawnGlyphsID = glyphs->getUniqueID(); 508 fLastDrawnGlyphsID = glyphs->getUniqueID();
508 } 509 }
509 510
510 SkMatrix drawMatrix(viewMatrix);
511 drawMatrix.preTranslate(x, y);
512 drawMatrix.preScale(fTextRatio, fTextRatio);
513
514 SkMatrix& localMatrix = fLocalMatrixTemplate;
515 localMatrix.setTranslateX(x);
516 localMatrix.setTranslateY(y);
517
518 // Don't compute a bounding box. For dst copy texture, we'll opt instead for it to just copy 511 // Don't compute a bounding box. For dst copy texture, we'll opt instead for it to just copy
519 // the entire dst. Realistically this is a moot point, because any conte xt that supports 512 // the entire dst. Realistically this is a moot point, because any conte xt that supports
520 // NV_path_rendering will also support NV_blend_equation_advanced. 513 // NV_path_rendering will also support NV_blend_equation_advanced.
521 // For clipping we'll just skip any optimizations based on the bounds. T his does, however, 514 // For clipping we'll just skip any optimizations based on the bounds. T his does, however,
522 // hurt batching. 515 // hurt batching.
523 SkRect bounds = SkRect::MakeIWH(pipelineBuilder->getRenderTarget()->widt h(), 516 SkRect bounds = SkRect::MakeIWH(pipelineBuilder->getRenderTarget()->widt h(),
524 pipelineBuilder->getRenderTarget()->heig ht()); 517 pipelineBuilder->getRenderTarget()->heig ht());
525 518
526 SkAutoTUnref<GrDrawPathBatchBase> batch( 519 SkAutoTUnref<GrDrawPathBatchBase> batch(
527 GrDrawPathRangeBatch::Create(drawMatrix, localMatrix, color, 520 GrDrawPathRangeBatch::Create(viewMatrix, fTextRatio, fTextInverseRat io * x,
528 GrPathRendering::kWinding_FillType, gly phs, fDraw, 521 fTextInverseRatio * y, color,
522 GrPathRendering::kWinding_FillType, gly phs, fInstanceData,
529 bounds)); 523 bounds));
530 524
531 dc->drawPathBatch(*pipelineBuilder, batch); 525 dc->drawPathBatch(*pipelineBuilder, batch);
532 } 526 }
533 527
534 if (fFallbackTextBlob) { 528 if (fFallbackTextBlob) {
535 SkPaint fallbackSkPaint(originalSkPaint); 529 SkPaint fallbackSkPaint(originalSkPaint);
536 fStroke.applyToPaint(&fallbackSkPaint); 530 fStroke.applyToPaint(&fallbackSkPaint);
537 if (!fStroke.isFillStyle()) { 531 if (!fStroke.isFillStyle()) {
538 fallbackSkPaint.setStrokeWidth(fStroke.getWidth() * fTextRatio); 532 fallbackSkPaint.setStrokeWidth(fStroke.getWidth() * fTextRatio);
(...skipping 13 matching lines...) Expand all
552 546
553 547
554 void GrStencilAndCoverTextContext::TextRun::releaseGlyphCache() const { 548 void GrStencilAndCoverTextContext::TextRun::releaseGlyphCache() const {
555 if (fDetachedGlyphCache) { 549 if (fDetachedGlyphCache) {
556 SkGlyphCache::AttachCache(fDetachedGlyphCache); 550 SkGlyphCache::AttachCache(fDetachedGlyphCache);
557 fDetachedGlyphCache = nullptr; 551 fDetachedGlyphCache = nullptr;
558 } 552 }
559 } 553 }
560 554
561 size_t GrStencilAndCoverTextContext::TextRun::computeSizeInCache() const { 555 size_t GrStencilAndCoverTextContext::TextRun::computeSizeInCache() const {
562 size_t size = sizeof(TextRun) + 556 size_t size = sizeof(TextRun) + fGlyphPathsKey.size();
563 fGlyphPathsKey.size() + 557 // The instance data always reserves enough space for every glyph.
564 fTotalGlyphCount * (sizeof(uint16_t) + 2 * sizeof(float)); 558 size += (fTotalGlyphCount + fFallbackGlyphCount) * (sizeof(uint16_t) + 2 * s izeof(float));
565 if (fDraw) { 559 if (fInstanceData) {
566 size += sizeof(GrPathRangeDraw); 560 size += sizeof(InstanceData);
567 } 561 }
568 if (fFallbackTextBlob) { 562 if (fFallbackTextBlob) {
569 size += sizeof(SkTextBlob); 563 size += sizeof(SkTextBlob);
570 } 564 }
571 return size; 565 return size;
572 } 566 }
573 567
574 //////////////////////////////////////////////////////////////////////////////// //////////////////// 568 //////////////////////////////////////////////////////////////////////////////// ////////////////////
575 569
576 void GrStencilAndCoverTextContext::FallbackBlobBuilder::init(const SkPaint& font , 570 void GrStencilAndCoverTextContext::FallbackBlobBuilder::init(const SkPaint& font ,
(...skipping 12 matching lines...) Expand all
589 583
590 void GrStencilAndCoverTextContext::FallbackBlobBuilder::appendGlyph(uint16_t gly phId, 584 void GrStencilAndCoverTextContext::FallbackBlobBuilder::appendGlyph(uint16_t gly phId,
591 const SkPoin t& pos) { 585 const SkPoin t& pos) {
592 SkASSERT(this->isInitialized()); 586 SkASSERT(this->isInitialized());
593 if (fBuffIdx >= kWriteBufferSize) { 587 if (fBuffIdx >= kWriteBufferSize) {
594 this->flush(); 588 this->flush();
595 } 589 }
596 fGlyphIds[fBuffIdx] = glyphId; 590 fGlyphIds[fBuffIdx] = glyphId;
597 fPositions[fBuffIdx] = pos; 591 fPositions[fBuffIdx] = pos;
598 fBuffIdx++; 592 fBuffIdx++;
593 fCount++;
599 } 594 }
600 595
601 void GrStencilAndCoverTextContext::FallbackBlobBuilder::flush() { 596 void GrStencilAndCoverTextContext::FallbackBlobBuilder::flush() {
602 SkASSERT(this->isInitialized()); 597 SkASSERT(this->isInitialized());
603 SkASSERT(fBuffIdx <= kWriteBufferSize); 598 SkASSERT(fBuffIdx <= kWriteBufferSize);
604 if (!fBuffIdx) { 599 if (!fBuffIdx) {
605 return; 600 return;
606 } 601 }
607 // This will automatically merge with previous runs since we use the same fo nt. 602 // This will automatically merge with previous runs since we use the same fo nt.
608 const SkTextBlobBuilder::RunBuffer& buff = fBuilder->allocRunPos(fFont, fBuf fIdx); 603 const SkTextBlobBuilder::RunBuffer& buff = fBuilder->allocRunPos(fFont, fBuf fIdx);
609 memcpy(buff.glyphs, fGlyphIds, fBuffIdx * sizeof(uint16_t)); 604 memcpy(buff.glyphs, fGlyphIds, fBuffIdx * sizeof(uint16_t));
610 memcpy(buff.pos, fPositions[0].asScalars(), fBuffIdx * 2 * sizeof(SkScalar)) ; 605 memcpy(buff.pos, fPositions[0].asScalars(), fBuffIdx * 2 * sizeof(SkScalar)) ;
611 fBuffIdx = 0; 606 fBuffIdx = 0;
612 } 607 }
613 608
614 const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfInit ialized() { 609 const SkTextBlob* GrStencilAndCoverTextContext::FallbackBlobBuilder::buildIfNeed ed(int *count) {
615 if (!this->isInitialized()) { 610 *count = fCount;
616 return nullptr; 611 if (fCount) {
612 this->flush();
613 return fBuilder->build();
617 } 614 }
618 this->flush(); 615 return nullptr;
619 return fBuilder->build();
620 } 616 }
OLDNEW
« no previous file with comments | « src/gpu/GrStencilAndCoverTextContext.h ('k') | src/gpu/batches/GrDrawPathBatch.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698