OLD | NEW |
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 | 7 |
8 #include "GrAtlasTextBatch.h" | 8 #include "GrAtlasTextBatch.h" |
9 | 9 |
10 #include "GrBatchFontCache.h" | 10 #include "GrBatchFontCache.h" |
(...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
305 SkDebugf("Cannot invert viewmatrix\n"); | 305 SkDebugf("Cannot invert viewmatrix\n"); |
306 return; | 306 return; |
307 } | 307 } |
308 | 308 |
309 GrTexture* texture = fFontCache->getTexture(this->maskFormat()); | 309 GrTexture* texture = fFontCache->getTexture(this->maskFormat()); |
310 if (!texture) { | 310 if (!texture) { |
311 SkDebugf("Could not allocate backing texture for atlas\n"); | 311 SkDebugf("Could not allocate backing texture for atlas\n"); |
312 return; | 312 return; |
313 } | 313 } |
314 | 314 |
| 315 bool usesDistanceFields = this->usesDistanceFields(); |
315 GrMaskFormat maskFormat = this->maskFormat(); | 316 GrMaskFormat maskFormat = this->maskFormat(); |
| 317 bool isLCD = this->isLCD(); |
316 | 318 |
317 SkAutoTUnref<const GrGeometryProcessor> gp; | 319 SkAutoTUnref<const GrGeometryProcessor> gp; |
318 if (this->usesDistanceFields()) { | 320 if (usesDistanceFields) { |
319 gp.reset(this->setupDfProcessor(this->viewMatrix(), fFilteredColor, this
->color(), | 321 gp.reset(this->setupDfProcessor(this->viewMatrix(), fFilteredColor, this
->color(), |
320 texture)); | 322 texture)); |
321 } else { | 323 } else { |
322 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone
_FilterMode); | 324 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kNone
_FilterMode); |
323 gp.reset(GrBitmapTextGeoProc::Create(this->color(), | 325 gp.reset(GrBitmapTextGeoProc::Create(this->color(), |
324 texture, | 326 texture, |
325 params, | 327 params, |
326 maskFormat, | 328 maskFormat, |
327 localMatrix, | 329 localMatrix, |
328 this->usesLocalCoords())); | 330 this->usesLocalCoords())); |
329 } | 331 } |
330 | 332 |
331 FlushInfo flushInfo; | 333 FlushInfo flushInfo; |
332 flushInfo.fGlyphsToFlush = 0; | 334 flushInfo.fGlyphsToFlush = 0; |
333 size_t vertexStride = gp->getVertexStride(); | 335 size_t vertexStride = gp->getVertexStride(); |
334 SkASSERT(vertexStride == GetVertexStride(maskFormat)); | 336 SkASSERT(vertexStride == (usesDistanceFields ? |
| 337 GetVertexStrideDf(maskFormat, isLCD) : |
| 338 GetVertexStride(maskFormat))); |
335 | 339 |
336 target->initDraw(gp, this->pipeline()); | 340 target->initDraw(gp, this->pipeline()); |
337 | 341 |
338 int glyphCount = this->numGlyphs(); | 342 int glyphCount = this->numGlyphs(); |
339 const GrVertexBuffer* vertexBuffer; | 343 const GrVertexBuffer* vertexBuffer; |
340 | 344 |
341 void* vertices = target->makeVertexSpace(vertexStride, | 345 void* vertices = target->makeVertexSpace(vertexStride, |
342 glyphCount * kVerticesPerGlyph, | 346 glyphCount * kVerticesPerGlyph, |
343 &vertexBuffer, | 347 &vertexBuffer, |
344 &flushInfo.fVertexOffset); | 348 &flushInfo.fVertexOffset); |
(...skipping 25 matching lines...) Expand all Loading... |
370 // generating its texture coords, we have to track whether or not the st
rike has | 374 // generating its texture coords, we have to track whether or not the st
rike has |
371 // been abandoned. If it hasn't been abandoned, then we can use the GrG
lyph*s as is | 375 // been abandoned. If it hasn't been abandoned, then we can use the GrG
lyph*s as is |
372 // otherwise we have to get the new strike, and use that to get the corr
ect glyphs. | 376 // otherwise we have to get the new strike, and use that to get the corr
ect glyphs. |
373 // Because we do not have the packed ids, and thus can't look up our gly
phs in the | 377 // Because we do not have the packed ids, and thus can't look up our gly
phs in the |
374 // new strike, we instead keep our ref to the old strike and use the pac
ked ids from | 378 // new strike, we instead keep our ref to the old strike and use the pac
ked ids from |
375 // it. These ids will still be valid as long as we hold the ref. When
we are done | 379 // it. These ids will still be valid as long as we hold the ref. When
we are done |
376 // updating our cache of the GrGlyph*s, we drop our ref on the old strik
e | 380 // updating our cache of the GrGlyph*s, we drop our ref on the old strik
e |
377 bool regenerateGlyphs = info.strike()->isAbandoned(); | 381 bool regenerateGlyphs = info.strike()->isAbandoned(); |
378 bool regenerateTextureCoords = info.atlasGeneration() != currentAtlasGen
|| | 382 bool regenerateTextureCoords = info.atlasGeneration() != currentAtlasGen
|| |
379 regenerateGlyphs; | 383 regenerateGlyphs; |
380 bool regenerateColors = kARGB_GrMaskFormat != maskFormat && | 384 bool regenerateColors; |
381 run.fColor != args.fColor; | 385 if (usesDistanceFields) { |
| 386 regenerateColors = !isLCD && run.fColor != args.fColor; |
| 387 } else { |
| 388 regenerateColors = kA8_GrMaskFormat == maskFormat && run.fColor != a
rgs.fColor; |
| 389 } |
382 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0.f; | 390 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0.f; |
383 int glyphCount = info.glyphCount(); | 391 int glyphCount = info.glyphCount(); |
384 | 392 |
385 uint32_t regenMaskBits = kNoRegen; | 393 uint32_t regenMaskBits = kNoRegen; |
386 regenMaskBits |= regeneratePositions ? kRegenPos : 0; | 394 regenMaskBits |= regeneratePositions ? kRegenPos : 0; |
387 regenMaskBits |= regenerateColors ? kRegenCol : 0; | 395 regenMaskBits |= regenerateColors ? kRegenCol : 0; |
388 regenMaskBits |= regenerateTextureCoords ? kRegenTex : 0; | 396 regenMaskBits |= regenerateTextureCoords ? kRegenTex : 0; |
389 regenMaskBits |= regenerateGlyphs ? kRegenGlyph : 0; | 397 regenMaskBits |= regenerateGlyphs ? kRegenGlyph : 0; |
390 RegenMask regenMask = (RegenMask)regenMaskBits; | 398 RegenMask regenMask = (RegenMask)regenMaskBits; |
391 | 399 |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
444 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeli
ne(), | 452 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pipeli
ne(), |
445 that->bounds(), caps)) { | 453 that->bounds(), caps)) { |
446 return false; | 454 return false; |
447 } | 455 } |
448 | 456 |
449 if (fMaskType != that->fMaskType) { | 457 if (fMaskType != that->fMaskType) { |
450 return false; | 458 return false; |
451 } | 459 } |
452 | 460 |
453 if (!this->usesDistanceFields()) { | 461 if (!this->usesDistanceFields()) { |
454 if (kColorBitmapMask_MaskType == fMaskType && this->color() != that->col
or()) { | 462 // TODO we can often batch across LCD text if we have dual source blendi
ng and don't |
| 463 // have to use the blend constant |
| 464 if (kGrayscaleCoverageMask_MaskType != fMaskType && this->color() != tha
t->color()) { |
455 return false; | 465 return false; |
456 } | 466 } |
457 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi
ewMatrix())) { | 467 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that->vi
ewMatrix())) { |
458 return false; | 468 return false; |
459 } | 469 } |
460 } else { | 470 } else { |
461 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { | 471 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) { |
462 return false; | 472 return false; |
463 } | 473 } |
464 | 474 |
465 if (fFilteredColor != that->fFilteredColor) { | 475 if (fFilteredColor != that->fFilteredColor) { |
466 return false; | 476 return false; |
467 } | 477 } |
468 | 478 |
469 if (fUseBGR != that->fUseBGR) { | 479 if (fUseBGR != that->fUseBGR) { |
470 return false; | 480 return false; |
471 } | 481 } |
| 482 |
| 483 // TODO see note above |
| 484 if (kLCDDistanceField_MaskType == fMaskType && this->color() != that->co
lor()) { |
| 485 return false; |
| 486 } |
472 } | 487 } |
473 | 488 |
474 fBatch.fNumGlyphs += that->numGlyphs(); | 489 fBatch.fNumGlyphs += that->numGlyphs(); |
475 | 490 |
476 // Reallocate space for geo data if necessary and then import that's geo dat
a. | 491 // Reallocate space for geo data if necessary and then import that's geo dat
a. |
477 int newGeoCount = that->fGeoCount + fGeoCount; | 492 int newGeoCount = that->fGeoCount + fGeoCount; |
478 // We assume (and here enforce) that the allocation size is the smallest pow
er of two that | 493 // We assume (and here enforce) that the allocation size is the smallest pow
er of two that |
479 // is greater than or equal to the number of geometries (and at least | 494 // is greater than or equal to the number of geometries (and at least |
480 // kMinGeometryAllocated). | 495 // kMinGeometryAllocated). |
481 int newAllocSize = GrNextPow2(newGeoCount); | 496 int newAllocSize = GrNextPow2(newGeoCount); |
(...skipping 26 matching lines...) Expand all Loading... |
508 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_F
ilterMode); | 523 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_F
ilterMode); |
509 bool isLCD = this->isLCD(); | 524 bool isLCD = this->isLCD(); |
510 // set up any flags | 525 // set up any flags |
511 uint32_t flags = viewMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffect
Flag : 0; | 526 uint32_t flags = viewMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffect
Flag : 0; |
512 | 527 |
513 // see if we need to create a new effect | 528 // see if we need to create a new effect |
514 if (isLCD) { | 529 if (isLCD) { |
515 flags |= kUseLCD_DistanceFieldEffectFlag; | 530 flags |= kUseLCD_DistanceFieldEffectFlag; |
516 flags |= viewMatrix.rectStaysRect() ? kRectToRect_DistanceFieldEffectFla
g : 0; | 531 flags |= viewMatrix.rectStaysRect() ? kRectToRect_DistanceFieldEffectFla
g : 0; |
517 flags |= fUseBGR ? kBGR_DistanceFieldEffectFlag : 0; | 532 flags |= fUseBGR ? kBGR_DistanceFieldEffectFlag : 0; |
518 flags |= kColorAttr_DistanceFieldEffectFlag; | |
519 | 533 |
520 GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor); | 534 GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredColor); |
521 | 535 |
522 float redCorrection = | 536 float redCorrection = |
523 (*fDistanceAdjustTable)[GrColorUnpackR(colorNoPreMul) >> kDistanceAd
justLumShift]; | 537 (*fDistanceAdjustTable)[GrColorUnpackR(colorNoPreMul) >> kDistanceAd
justLumShift]; |
524 float greenCorrection = | 538 float greenCorrection = |
525 (*fDistanceAdjustTable)[GrColorUnpackG(colorNoPreMul) >> kDistanceAd
justLumShift]; | 539 (*fDistanceAdjustTable)[GrColorUnpackG(colorNoPreMul) >> kDistanceAd
justLumShift]; |
526 float blueCorrection = | 540 float blueCorrection = |
527 (*fDistanceAdjustTable)[GrColorUnpackB(colorNoPreMul) >> kDistanceAd
justLumShift]; | 541 (*fDistanceAdjustTable)[GrColorUnpackB(colorNoPreMul) >> kDistanceAd
justLumShift]; |
528 GrDistanceFieldLCDTextGeoProc::DistanceAdjust widthAdjust = | 542 GrDistanceFieldLCDTextGeoProc::DistanceAdjust widthAdjust = |
(...skipping 24 matching lines...) Expand all Loading... |
553 return GrDistanceFieldA8TextGeoProc::Create(color, | 567 return GrDistanceFieldA8TextGeoProc::Create(color, |
554 viewMatrix, | 568 viewMatrix, |
555 texture, | 569 texture, |
556 params, | 570 params, |
557 flags, | 571 flags, |
558 this->usesLocalCoords()); | 572 this->usesLocalCoords()); |
559 #endif | 573 #endif |
560 } | 574 } |
561 | 575 |
562 } | 576 } |
OLD | NEW |