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

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

Issue 1098653005: A small patch to enable distance field text in textblobs (Closed) Base URL: https://skia.googlesource.com/skia.git@atdfnow2
Patch Set: windows warnings 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/GrAtlasTextContext.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 2015 Google Inc. 2 * Copyright 2015 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 "GrAtlasTextContext.h" 7 #include "GrAtlasTextContext.h"
8 8
9 #include "GrAtlas.h" 9 #include "GrAtlas.h"
10 #include "GrBatch.h" 10 #include "GrBatch.h"
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 } 253 }
254 254
255 if (blob.fViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) { 255 if (blob.fViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) {
256 return true; 256 return true;
257 } 257 }
258 258
259 if (blob.fViewMatrix.hasPerspective() && !blob.fViewMatrix.cheapEqualTo(view Matrix)) { 259 if (blob.fViewMatrix.hasPerspective() && !blob.fViewMatrix.cheapEqualTo(view Matrix)) {
260 return true; 260 return true;
261 } 261 }
262 262
263 if (blob.fViewMatrix.getScaleX() != viewMatrix.getScaleX() ||
264 blob.fViewMatrix.getScaleY() != viewMatrix.getScaleY() ||
265 blob.fViewMatrix.getSkewX() != viewMatrix.getSkewX() ||
266 blob.fViewMatrix.getSkewY() != viewMatrix.getSkewY()) {
267 return true;
268 }
269
270 // We only cache one masked version 263 // We only cache one masked version
271 if (blob.fKey.fHasBlur && 264 if (blob.fKey.fHasBlur &&
272 (blob.fBlurRec.fSigma != blurRec.fSigma || 265 (blob.fBlurRec.fSigma != blurRec.fSigma ||
273 blob.fBlurRec.fStyle != blurRec.fStyle || 266 blob.fBlurRec.fStyle != blurRec.fStyle ||
274 blob.fBlurRec.fQuality != blurRec.fQuality)) { 267 blob.fBlurRec.fQuality != blurRec.fQuality)) {
275 return true; 268 return true;
276 } 269 }
277 270
278 // Similarly, we only cache one version for each style 271 // Similarly, we only cache one version for each style
279 if (blob.fKey.fStyle != SkPaint::kFill_Style && 272 if (blob.fKey.fStyle != SkPaint::kFill_Style &&
280 (blob.fStrokeInfo.fFrameWidth != paint.getStrokeWidth() || 273 (blob.fStrokeInfo.fFrameWidth != paint.getStrokeWidth() ||
281 blob.fStrokeInfo.fMiterLimit != paint.getStrokeMiter() || 274 blob.fStrokeInfo.fMiterLimit != paint.getStrokeMiter() ||
282 blob.fStrokeInfo.fJoin != paint.getStrokeJoin())) { 275 blob.fStrokeInfo.fJoin != paint.getStrokeJoin())) {
283 return true; 276 return true;
284 } 277 }
285 278
286 // We can update the positions in the cachedtextblobs without regenerating t he whole blob, but 279 // Identical viewmatrices and we can reuse in all cases
287 // only for integer translations. 280 if (blob.fViewMatrix.cheapEqualTo(viewMatrix) && x == blob.fX && y == blob.f Y) {
288 // This cool bit of math will determine the necessary translation to apply t o the already 281 return false;
289 // generated vertex coordinates to move them to the correct position 282 }
290 SkScalar transX = viewMatrix.getTranslateX() + 283
291 viewMatrix.getScaleX() * (x - blob.fX) + 284 // Mixed blobs must be regenerated. We could probably figure out a way to d o integer scrolls
292 viewMatrix.getSkewX() * (y - blob.fY) - 285 // for mixed blobs if this becomes an issue.
293 blob.fViewMatrix.getTranslateX(); 286 if (blob.hasBitmap() && blob.hasDistanceField()) {
294 SkScalar transY = viewMatrix.getTranslateY() +
295 viewMatrix.getSkewY() * (x - blob.fX) +
296 viewMatrix.getScaleY() * (y - blob.fY) -
297 blob.fViewMatrix.getTranslateY();
298 if (SkScalarFraction(transX) > SK_ScalarNearlyZero ||
299 SkScalarFraction(transY) > SK_ScalarNearlyZero) {
300 return true; 287 return true;
301 } 288 }
302 289
290 // TODO distance fields can handle many of these conditions
291 if (blob.fViewMatrix.getScaleX() != viewMatrix.getScaleX() ||
292 blob.fViewMatrix.getScaleY() != viewMatrix.getScaleY() ||
293 blob.fViewMatrix.getSkewX() != viewMatrix.getSkewX() ||
294 blob.fViewMatrix.getSkewY() != viewMatrix.getSkewY()) {
295 return true;
296 }
297
298 if (blob.hasBitmap()) {
299 // We can update the positions in the cachedtextblobs without regenerati ng the whole blob,
300 // but only for integer translations.
301 // This cool bit of math will determine the necessary translation to app ly to the already
302 // generated vertex coordinates to move them to the correct position
303 SkScalar transX = viewMatrix.getTranslateX() +
304 viewMatrix.getScaleX() * (x - blob.fX) +
305 viewMatrix.getSkewX() * (y - blob.fY) -
306 blob.fViewMatrix.getTranslateX();
307 SkScalar transY = viewMatrix.getTranslateY() +
308 viewMatrix.getSkewY() * (x - blob.fX) +
309 viewMatrix.getScaleY() * (y - blob.fY) -
310 blob.fViewMatrix.getTranslateY();
311 if (SkScalarFraction(transX) > SK_ScalarNearlyZero ||
312 SkScalarFraction(transY) > SK_ScalarNearlyZero) {
313 return true;
314 }
315
303 #ifdef SK_DEBUG 316 #ifdef SK_DEBUG
304 static const SkScalar kMinDiscernableTranslation = 0.0625; 317 static const SkScalar kMinDiscernableTranslation = 0.0625;
305 // As a safeguard when debugging, we store the total error across all transl ations and print if 318 // As a safeguard when debugging, we store the total error across all tr anslations and print
306 // the error becomes discernable. This is pretty unlikely to occur given th e tight bounds above 319 // if the error becomes discernable. This is pretty unlikely to occur g iven the tight
307 // on translation 320 // bounds above on translation
308 blob.fTotalXError += SkScalarAbs(SkScalarFraction(transX)); 321 blob.fTotalXError += SkScalarAbs(SkScalarFraction(transX));
309 blob.fTotalYError += SkScalarAbs(SkScalarFraction(transY)); 322 blob.fTotalYError += SkScalarAbs(SkScalarFraction(transY));
310 if (blob.fTotalXError > kMinDiscernableTranslation || 323 if (blob.fTotalXError > kMinDiscernableTranslation ||
311 blob.fTotalYError > kMinDiscernableTranslation) { 324 blob.fTotalYError > kMinDiscernableTranslation) {
312 SkDebugf("Exceeding error threshold for bitmap text translation"); 325 SkDebugf("Exceeding error threshold for bitmap text translation");
326 }
327 #endif
328 (*outTransX) = transX;
329 (*outTransY) = transY;
330 } else {
331 // blob.hasDistanceField()
332 // TODO figure out the regen formula
333 return true;
313 } 334 }
314 #endif 335
315 (*outTransX) = transX;
316 (*outTransY) = transY;
317 return false; 336 return false;
318 } 337 }
319 338
320 339
321 inline SkGlyphCache* GrAtlasTextContext::setupCache(BitmapTextBlob::Run* run, 340 inline SkGlyphCache* GrAtlasTextContext::setupCache(BitmapTextBlob::Run* run,
322 const SkPaint& skPaint, 341 const SkPaint& skPaint,
323 const SkMatrix* viewMatrix, 342 const SkMatrix* viewMatrix,
324 bool noGamma) { 343 bool noGamma) {
325 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, vi ewMatrix, noGamma); 344 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, vi ewMatrix, noGamma);
326 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); 345 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface()));
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
371 390
372 if (cacheBlob) { 391 if (cacheBlob) {
373 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, blurRec, v iewMatrix, x, y)) { 392 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, blurRec, v iewMatrix, x, y)) {
374 // We have to remake the blob because changes may invalidate our mas ks. 393 // We have to remake the blob because changes may invalidate our mas ks.
375 // TODO we could probably get away reuse most of the time if the poi nter is unique, 394 // TODO we could probably get away reuse most of the time if the poi nter is unique,
376 // but we'd have to clear the subrun information 395 // but we'd have to clear the subrun information
377 fCache->remove(cacheBlob); 396 fCache->remove(cacheBlob);
378 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s kPaint, 397 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s kPaint,
379 kGrayTextVASize))); 398 kGrayTextVASize)));
380 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), vie wMatrix, blob, x, y, 399 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), vie wMatrix, blob, x, y,
381 drawFilter, clipRect); 400 drawFilter, clipRect, rt, clip, grPaint);
382 } else { 401 } else {
383 // If we can reuse the blob, then make sure we update the blob's vie wmatrix, and x/y 402 // If we can reuse the blob, then make sure we update the blob's vie wmatrix, and x/y
384 // offsets 403 // offsets
385 cacheBlob->fViewMatrix = viewMatrix; 404 cacheBlob->fViewMatrix = viewMatrix;
386 cacheBlob->fX = x; 405 cacheBlob->fX = x;
387 cacheBlob->fY = y; 406 cacheBlob->fY = y;
388 fCache->makeMRU(cacheBlob); 407 fCache->makeMRU(cacheBlob);
389 } 408 }
390 } else { 409 } else {
391 if (canCache) { 410 if (canCache) {
392 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s kPaint, 411 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s kPaint,
393 kGrayTextVASize))); 412 kGrayTextVASize)));
394 } else { 413 } else {
395 cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize)); 414 cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize));
396 } 415 }
397 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMat rix, blob, x, y, 416 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMat rix, blob, x, y,
398 drawFilter, clipRect); 417 drawFilter, clipRect, rt, clip, grPaint);
399 } 418 }
400 419
401 cacheBlob->fPaintColor = skPaint.getColor(); 420 cacheBlob->fPaintColor = skPaint.getColor();
402 this->flush(fContext->getTextTarget(), blob, cacheBlob, rt, skPaint, grPaint , drawFilter, 421 this->flush(fContext->getTextTarget(), blob, cacheBlob, rt, skPaint, grPaint , drawFilter,
403 clip, viewMatrix, clipBounds, x, y, transX, transY); 422 clip, viewMatrix, clipBounds, x, y, transX, transY);
404 } 423 }
405 424
406 inline bool GrAtlasTextContext::canDrawAsDistanceFields(const SkPaint& skPaint, 425 inline bool GrAtlasTextContext::canDrawAsDistanceFields(const SkPaint& skPaint,
407 const SkMatrix& viewMatr ix) { 426 const SkMatrix& viewMatr ix) {
408 // TODO: support perspective (need getMaxScale replacement) 427 // TODO: support perspective (need getMaxScale replacement)
(...skipping 26 matching lines...) Expand all
435 return false; 454 return false;
436 } 455 }
437 456
438 return true; 457 return true;
439 } 458 }
440 459
441 void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob, 460 void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob,
442 const SkPaint& skPaint, GrColor colo r, 461 const SkPaint& skPaint, GrColor colo r,
443 const SkMatrix& viewMatrix, 462 const SkMatrix& viewMatrix,
444 const SkTextBlob* blob, SkScalar x, SkScalar y, 463 const SkTextBlob* blob, SkScalar x, SkScalar y,
445 SkDrawFilter* drawFilter, const SkIR ect& clipRect) { 464 SkDrawFilter* drawFilter, const SkIR ect& clipRect,
465 GrRenderTarget* rt, const GrClip& cl ip,
466 const GrPaint& paint) {
446 cacheBlob->fViewMatrix = viewMatrix; 467 cacheBlob->fViewMatrix = viewMatrix;
447 cacheBlob->fX = x; 468 cacheBlob->fX = x;
448 cacheBlob->fY = y; 469 cacheBlob->fY = y;
449 470
450 // Regenerate textblob 471 // Regenerate textblob
451 SkPaint runPaint = skPaint; 472 SkPaint runPaint = skPaint;
452 SkTextBlob::RunIterator it(blob); 473 SkTextBlob::RunIterator it(blob);
453 for (int run = 0; !it.done(); it.next(), run++) { 474 for (int run = 0; !it.done(); it.next(), run++) {
454 int glyphCount = it.glyphCount(); 475 int glyphCount = it.glyphCount();
455 size_t textLen = glyphCount * sizeof(uint16_t); 476 size_t textLen = glyphCount * sizeof(uint16_t);
456 const SkPoint& offset = it.offset(); 477 const SkPoint& offset = it.offset();
457 // applyFontToPaint() always overwrites the exact same attributes, 478 // applyFontToPaint() always overwrites the exact same attributes,
458 // so it is safe to not re-seed the paint for this reason. 479 // so it is safe to not re-seed the paint for this reason.
459 it.applyFontToPaint(&runPaint); 480 it.applyFontToPaint(&runPaint);
460 481
461 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ e)) { 482 if (drawFilter && !drawFilter->filter(&runPaint, SkDrawFilter::kText_Typ e)) {
462 // A false return from filter() means we should abort the current dr aw. 483 // A false return from filter() means we should abort the current dr aw.
463 runPaint = skPaint; 484 runPaint = skPaint;
464 continue; 485 continue;
465 } 486 }
466 487
467 runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint)); 488 runPaint.setFlags(fGpuDevice->filterTextFlags(runPaint));
468 489
469 SkGlyphCache* cache = this->setupCache(&cacheBlob->fRuns[run], runPaint, &viewMatrix,
470 false);
471
472 // setup vertex / glyphIndex for the new run 490 // setup vertex / glyphIndex for the new run
473 if (run > 0) { 491 if (run > 0) {
474 PerSubRunInfo& newRun = cacheBlob->fRuns[run].fSubRunInfo.back(); 492 PerSubRunInfo& newRun = cacheBlob->fRuns[run].fSubRunInfo.back();
475 PerSubRunInfo& lastRun = cacheBlob->fRuns[run - 1].fSubRunInfo.back( ); 493 PerSubRunInfo& lastRun = cacheBlob->fRuns[run - 1].fSubRunInfo.back( );
476 494
477 newRun.fVertexStartIndex = lastRun.fVertexEndIndex; 495 newRun.fVertexStartIndex = lastRun.fVertexEndIndex;
478 newRun.fVertexEndIndex = lastRun.fVertexEndIndex; 496 newRun.fVertexEndIndex = lastRun.fVertexEndIndex;
479 497
480 newRun.fGlyphStartIndex = lastRun.fGlyphEndIndex; 498 newRun.fGlyphStartIndex = lastRun.fGlyphEndIndex;
481 newRun.fGlyphEndIndex = lastRun.fGlyphEndIndex; 499 newRun.fGlyphEndIndex = lastRun.fGlyphEndIndex;
482 } 500 }
483 501
484 if (SkDraw::ShouldDrawTextAsPaths(runPaint, viewMatrix)) { 502 if (this->canDrawAsDistanceFields(runPaint, viewMatrix)) {
503 cacheBlob->setHasDistanceField();
504 SkPaint dfPaint = runPaint;
505 SkScalar textRatio;
506 this->initDistanceFieldPaint(&dfPaint, &textRatio, viewMatrix);
507 Run& runIdx = cacheBlob->fRuns[run];
508 PerSubRunInfo& subRun = runIdx.fSubRunInfo.back();
509 subRun.fUseLCDText = runPaint.isLCDRenderText();
510 subRun.fDrawAsDistanceFields = true;
511
512 SkGlyphCache* cache = this->setupCache(&cacheBlob->fRuns[run], dfPai nt, NULL, true);
513
514 SkTDArray<char> fallbackTxt;
515 SkTDArray<SkScalar> fallbackPos;
516 SkPoint dfOffset;
517 int scalarsPerPosition = 2;
518 switch (it.positioning()) {
519 case SkTextBlob::kDefault_Positioning: {
520 this->internalDrawDFText(cacheBlob, run, cache, dfPaint, col or, viewMatrix,
521 (const char *)it.glyphs(), textLen,
522 x + offset.x(), y + offset.y(), cli pRect, textRatio,
523 &fallbackTxt, &fallbackPos, &dfOffs et, runPaint);
524 break;
525 }
526 case SkTextBlob::kHorizontal_Positioning: {
527 scalarsPerPosition = 1;
528 dfOffset = SkPoint::Make(x, y + offset.y());
529 this->internalDrawDFPosText(cacheBlob, run, cache, dfPaint, color, viewMatrix,
530 (const char*)it.glyphs(), textLe n, it.pos(),
531 scalarsPerPosition, dfOffset, cl ipRect, textRatio,
532 &fallbackTxt, &fallbackPos);
533 break;
534 }
535 case SkTextBlob::kFull_Positioning: {
536 dfOffset = SkPoint::Make(x, y);
537 this->internalDrawDFPosText(cacheBlob, run, cache, dfPaint, color, viewMatrix,
538 (const char*)it.glyphs(), textLe n, it.pos(),
539 scalarsPerPosition, dfOffset, cl ipRect, textRatio,
540 &fallbackTxt, &fallbackPos);
541 break;
542 }
543 }
544 if (fallbackTxt.count()) {
545 this->fallbackDrawPosText(cacheBlob, run, rt, clip, paint, runPa int, viewMatrix,
546 fallbackTxt, fallbackPos, scalarsPerPo sition, dfOffset,
547 clipRect);
548 }
549
550 SkGlyphCache::AttachCache(cache);
551 } else if (SkDraw::ShouldDrawTextAsPaths(runPaint, viewMatrix)) {
485 cacheBlob->fRuns[run].fDrawAsPaths = true; 552 cacheBlob->fRuns[run].fDrawAsPaths = true;
486 continue; 553 } else {
487 } 554 cacheBlob->setHasBitmap();
488 cacheBlob->fRuns[run].fDrawAsPaths = false; 555 SkGlyphCache* cache = this->setupCache(&cacheBlob->fRuns[run], runPa int, &viewMatrix,
489 556 false);
490 switch (it.positioning()) { 557 switch (it.positioning()) {
491 case SkTextBlob::kDefault_Positioning: 558 case SkTextBlob::kDefault_Positioning:
492 this->internalDrawBMPText(cacheBlob, run, cache, runPaint, color , viewMatrix, 559 this->internalDrawBMPText(cacheBlob, run, cache, runPaint, c olor, viewMatrix,
493 (const char *)it.glyphs(), textLen, 560 (const char *)it.glyphs(), textLen ,
494 x + offset.x(), y + offset.y(), clipRe ct); 561 x + offset.x(), y + offset.y(), cl ipRect);
495 break; 562 break;
496 case SkTextBlob::kHorizontal_Positioning: 563 case SkTextBlob::kHorizontal_Positioning:
497 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint, co lor, viewMatrix, 564 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint , color, viewMatrix,
498 (const char*)it.glyphs(), textLen, it.pos(), 1, 565 (const char*)it.glyphs(), textL en, it.pos(), 1,
499 SkPoint::Make(x, y + offset.y()), c lipRect); 566 SkPoint::Make(x, y + offset.y() ), clipRect);
500 break; 567 break;
501 case SkTextBlob::kFull_Positioning: 568 case SkTextBlob::kFull_Positioning:
502 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint, co lor, viewMatrix, 569 this->internalDrawBMPPosText(cacheBlob, run, cache, runPaint , color, viewMatrix,
503 (const char*)it.glyphs(), textLen, it.pos(), 2, 570 (const char*)it.glyphs(), textL en, it.pos(), 2,
504 SkPoint::Make(x, y), clipRect); 571 SkPoint::Make(x, y), clipRect);
505 break; 572 break;
573 }
574 SkGlyphCache::AttachCache(cache);
506 } 575 }
507 576
508 if (drawFilter) { 577 if (drawFilter) {
509 // A draw filter may change the paint arbitrarily, so we must re-see d in this case. 578 // A draw filter may change the paint arbitrarily, so we must re-see d in this case.
510 runPaint = skPaint; 579 runPaint = skPaint;
511 } 580 }
512
513 SkGlyphCache::AttachCache(cache);
514 } 581 }
515 } 582 }
516 583
517 inline void GrAtlasTextContext::initDistanceFieldPaint(SkPaint* skPaint, SkScala r* textRatio, 584 inline void GrAtlasTextContext::initDistanceFieldPaint(SkPaint* skPaint, SkScala r* textRatio,
518 const SkMatrix& viewMatri x) { 585 const SkMatrix& viewMatri x) {
519 // getMaxScale doesn't support perspective, so neither do we at the moment 586 // getMaxScale doesn't support perspective, so neither do we at the moment
520 SkASSERT(!viewMatrix.hasPerspective()); 587 SkASSERT(!viewMatrix.hasPerspective());
521 SkScalar maxScale = viewMatrix.getMaxScale(); 588 SkScalar maxScale = viewMatrix.getMaxScale();
522 SkScalar textSize = skPaint->getTextSize(); 589 SkScalar textSize = skPaint->getTextSize();
523 SkScalar scaledTextSize = textSize; 590 SkScalar scaledTextSize = textSize;
(...skipping 15 matching lines...) Expand all
539 skPaint->setTextSize(SkIntToScalar(kLargeDFFontSize)); 606 skPaint->setTextSize(SkIntToScalar(kLargeDFFontSize));
540 } 607 }
541 608
542 skPaint->setLCDRenderText(false); 609 skPaint->setLCDRenderText(false);
543 skPaint->setAutohinted(false); 610 skPaint->setAutohinted(false);
544 skPaint->setHinting(SkPaint::kNormal_Hinting); 611 skPaint->setHinting(SkPaint::kNormal_Hinting);
545 skPaint->setSubpixelText(true); 612 skPaint->setSubpixelText(true);
546 } 613 }
547 614
548 inline void GrAtlasTextContext::fallbackDrawPosText(BitmapTextBlob* blob, 615 inline void GrAtlasTextContext::fallbackDrawPosText(BitmapTextBlob* blob,
616 int runIndex,
549 GrRenderTarget* rt, const Gr Clip& clip, 617 GrRenderTarget* rt, const Gr Clip& clip,
550 const GrPaint& paint, 618 const GrPaint& paint,
551 const SkPaint& skPaint, 619 const SkPaint& skPaint,
552 const SkMatrix& viewMatrix, 620 const SkMatrix& viewMatrix,
553 const SkTDArray<char>& fallb ackTxt, 621 const SkTDArray<char>& fallb ackTxt,
554 const SkTDArray<SkScalar>& f allbackPos, 622 const SkTDArray<SkScalar>& f allbackPos,
555 int scalarsPerPosition, 623 int scalarsPerPosition,
556 const SkPoint& offset, 624 const SkPoint& offset,
557 const SkIRect& clipRect) { 625 const SkIRect& clipRect) {
558 SkASSERT(fallbackTxt.count()); 626 SkASSERT(fallbackTxt.count());
559 Run& run = blob->fRuns[0]; 627 blob->setHasBitmap();
628 Run& run = blob->fRuns[runIndex];
560 PerSubRunInfo& subRun = run.fSubRunInfo.push_back(); 629 PerSubRunInfo& subRun = run.fSubRunInfo.push_back();
561 subRun.fOverrideDescriptor.reset(SkNEW(SkAutoDescriptor)); 630 subRun.fOverrideDescriptor.reset(SkNEW(SkAutoDescriptor));
562 skPaint.getScalerContextDescriptor(subRun.fOverrideDescriptor, 631 skPaint.getScalerContextDescriptor(subRun.fOverrideDescriptor,
563 &fDeviceProperties, &viewMatrix, false); 632 &fDeviceProperties, &viewMatrix, false);
564 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface, 633 SkGlyphCache* cache = SkGlyphCache::DetachCache(run.fTypeface,
565 subRun.fOverrideDescriptor-> getDesc()); 634 subRun.fOverrideDescriptor-> getDesc());
566 this->internalDrawBMPPosText(blob, 0, cache, skPaint, paint.getColor(), view Matrix, 635 this->internalDrawBMPPosText(blob, runIndex, cache, skPaint, paint.getColor( ), viewMatrix,
567 fallbackTxt.begin(), fallbackTxt.count(), 636 fallbackTxt.begin(), fallbackTxt.count(),
568 fallbackPos.begin(), scalarsPerPosition, offset , clipRect); 637 fallbackPos.begin(), scalarsPerPosition, offset , clipRect);
569 SkGlyphCache::AttachCache(cache); 638 SkGlyphCache::AttachCache(cache);
570 } 639 }
571 640
572 inline GrAtlasTextContext::BitmapTextBlob* 641 inline GrAtlasTextContext::BitmapTextBlob*
573 GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint, 642 GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint,
574 const SkMatrix& viewMatrix, SkGlyphCache** cache , 643 const SkMatrix& viewMatrix, SkGlyphCache** cache ,
575 SkPaint* dfPaint, SkScalar* textRatio) { 644 SkPaint* dfPaint, SkScalar* textRatio) {
576 BitmapTextBlob* blob = fCache->createBlob(glyphCount, 1, kGrayTextVASize); 645 BitmapTextBlob* blob = fCache->createBlob(glyphCount, 1, kGrayTextVASize);
577 646
578 *dfPaint = origPaint; 647 *dfPaint = origPaint;
579 this->initDistanceFieldPaint(dfPaint, textRatio, viewMatrix); 648 this->initDistanceFieldPaint(dfPaint, textRatio, viewMatrix);
580 blob->fViewMatrix = viewMatrix; 649 blob->fViewMatrix = viewMatrix;
581 blob->fRuns[0].fSubRunInfo.back().fUseLCDText = origPaint.isLCDRenderText(); 650 Run& run = blob->fRuns[0];
582 blob->fRuns[0].fSubRunInfo.back().fDrawAsDistanceFields = true; 651 PerSubRunInfo& subRun = run.fSubRunInfo.back();
652 subRun.fUseLCDText = origPaint.isLCDRenderText();
653 subRun.fDrawAsDistanceFields = true;
583 654
584 *cache = this->setupCache(&blob->fRuns[0], *dfPaint, NULL, true); 655 *cache = this->setupCache(&blob->fRuns[0], *dfPaint, NULL, true);
585 return blob; 656 return blob;
586 } 657 }
587 658
588 void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip, 659 void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
589 const GrPaint& paint, const SkPaint& skPaint , 660 const GrPaint& paint, const SkPaint& skPaint ,
590 const SkMatrix& viewMatrix, 661 const SkMatrix& viewMatrix,
591 const char text[], size_t byteLength, 662 const char text[], size_t byteLength,
592 SkScalar x, SkScalar y, const SkIRect& regio nClipBounds) { 663 SkScalar x, SkScalar y, const SkIRect& regio nClipBounds) {
(...skipping 10 matching lines...) Expand all
603 &dfPaint, &textRatio )); 674 &dfPaint, &textRatio ));
604 675
605 SkTDArray<char> fallbackTxt; 676 SkTDArray<char> fallbackTxt;
606 SkTDArray<SkScalar> fallbackPos; 677 SkTDArray<SkScalar> fallbackPos;
607 SkPoint offset; 678 SkPoint offset;
608 this->internalDrawDFText(blob, 0, cache, dfPaint, paint.getColor(), view Matrix, text, 679 this->internalDrawDFText(blob, 0, cache, dfPaint, paint.getColor(), view Matrix, text,
609 byteLength, x, y, clipRect, textRatio, &fallbac kTxt, &fallbackPos, 680 byteLength, x, y, clipRect, textRatio, &fallbac kTxt, &fallbackPos,
610 &offset, skPaint); 681 &offset, skPaint);
611 SkGlyphCache::AttachCache(cache); 682 SkGlyphCache::AttachCache(cache);
612 if (fallbackTxt.count()) { 683 if (fallbackTxt.count()) {
613 this->fallbackDrawPosText(blob, rt, clip, paint, skPaint, viewMatrix , fallbackTxt, 684 this->fallbackDrawPosText(blob, 0, rt, clip, paint, skPaint, viewMat rix, fallbackTxt,
614 fallbackPos, 2, offset, clipRect); 685 fallbackPos, 2, offset, clipRect);
615 } 686 }
616 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip); 687 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip);
617 } else { 688 } else {
618 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGra yTextVASize)); 689 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGra yTextVASize));
619 blob->fViewMatrix = viewMatrix; 690 blob->fViewMatrix = viewMatrix;
620 691
621 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa trix, false); 692 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa trix, false);
622 this->internalDrawBMPText(blob, 0, cache, skPaint, paint.getColor(), vie wMatrix, text, 693 this->internalDrawBMPText(blob, 0, cache, skPaint, paint.getColor(), vie wMatrix, text,
623 byteLength, x, y, clipRect); 694 byteLength, x, y, clipRect);
(...skipping 20 matching lines...) Expand all
644 SkAutoTUnref<BitmapTextBlob> blob(this->setupDFBlob(glyphCount, skPaint, viewMatrix, &cache, 715 SkAutoTUnref<BitmapTextBlob> blob(this->setupDFBlob(glyphCount, skPaint, viewMatrix, &cache,
645 &dfPaint, &textRatio )); 716 &dfPaint, &textRatio ));
646 717
647 SkTDArray<char> fallbackTxt; 718 SkTDArray<char> fallbackTxt;
648 SkTDArray<SkScalar> fallbackPos; 719 SkTDArray<SkScalar> fallbackPos;
649 this->internalDrawDFPosText(blob, 0, cache, dfPaint, paint.getColor(), v iewMatrix, text, 720 this->internalDrawDFPosText(blob, 0, cache, dfPaint, paint.getColor(), v iewMatrix, text,
650 byteLength, pos, scalarsPerPosition, offset, clipRect, 721 byteLength, pos, scalarsPerPosition, offset, clipRect,
651 textRatio, &fallbackTxt, &fallbackPos); 722 textRatio, &fallbackTxt, &fallbackPos);
652 SkGlyphCache::AttachCache(cache); 723 SkGlyphCache::AttachCache(cache);
653 if (fallbackTxt.count()) { 724 if (fallbackTxt.count()) {
654 this->fallbackDrawPosText(blob, rt, clip, paint, skPaint, viewMatrix , fallbackTxt, 725 this->fallbackDrawPosText(blob, 0, rt, clip, paint, skPaint, viewMat rix, fallbackTxt,
655 fallbackPos, scalarsPerPosition, offset, c lipRect); 726 fallbackPos, scalarsPerPosition, offset, c lipRect);
656 } 727 }
657 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip); 728 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip);
658 } else { 729 } else {
659 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGra yTextVASize)); 730 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGra yTextVASize));
660 blob->fViewMatrix = viewMatrix; 731 blob->fViewMatrix = viewMatrix;
661 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa trix, false); 732 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa trix, false);
662 this->internalDrawBMPPosText(blob, 0, cache, skPaint, paint.getColor(), viewMatrix, text, 733 this->internalDrawBMPPosText(blob, 0, cache, skPaint, paint.getColor(), viewMatrix, text,
663 byteLength, pos, scalarsPerPosition, offset , clipRect); 734 byteLength, pos, scalarsPerPosition, offset , clipRect);
664 SkGlyphCache::AttachCache(cache); 735 SkGlyphCache::AttachCache(cache);
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
1436 for (int i = 0; i < instanceCount; i++) { 1507 for (int i = 0; i < instanceCount; i++) {
1437 Geometry& args = fGeoData[i]; 1508 Geometry& args = fGeoData[i];
1438 Blob* blob = args.fBlob; 1509 Blob* blob = args.fBlob;
1439 Run& run = blob->fRuns[args.fRun]; 1510 Run& run = blob->fRuns[args.fRun];
1440 TextInfo& info = run.fSubRunInfo[args.fSubRun]; 1511 TextInfo& info = run.fSubRunInfo[args.fSubRun];
1441 1512
1442 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); 1513 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat);
1443 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas Gen; 1514 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas Gen;
1444 bool regenerateColors; 1515 bool regenerateColors;
1445 if (fUseDistanceFields) { 1516 if (fUseDistanceFields) {
1446 regenerateColors = fUseLCDText && run.fColor != args.fColor; 1517 regenerateColors = !fUseLCDText && run.fColor != args.fColor;
1447 } else { 1518 } else {
1448 regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColor != args.fColor; 1519 regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColor != args.fColor;
1449 } 1520 }
1450 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0. f; 1521 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0. f;
1451 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; 1522 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex;
1452 1523
1453 // We regenerate both texture coords and colors in the blob itself, and update the 1524 // We regenerate both texture coords and colors in the blob itself, and update the
1454 // atlas generation. If we don't end up purging any unused plots, w e can avoid 1525 // atlas generation. If we don't end up purging any unused plots, w e can avoid
1455 // regenerating the coords. We could take a finer grained approach to updating texture 1526 // regenerating the coords. We could take a finer grained approach to updating texture
1456 // coords but its not clear if the extra bookkeeping would offset an y gains. 1527 // coords but its not clear if the extra bookkeeping would offset an y gains.
(...skipping 543 matching lines...) Expand 10 before | Expand all | Expand 10 after
2000 pipelineBuilder.setFromPaint(grPaint, rt, clip); 2071 pipelineBuilder.setFromPaint(grPaint, rt, clip);
2001 2072
2002 GrColor color = grPaint.getColor(); 2073 GrColor color = grPaint.getColor();
2003 for (int run = 0; run < cacheBlob->fRunCount; run++) { 2074 for (int run = 0; run < cacheBlob->fRunCount; run++) {
2004 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, 0, 0, sk Paint); 2075 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, 0, 0, sk Paint);
2005 } 2076 }
2006 2077
2007 // Now flush big glyphs 2078 // Now flush big glyphs
2008 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0); 2079 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0);
2009 } 2080 }
OLDNEW
« no previous file with comments | « src/gpu/GrAtlasTextContext.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698