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

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

Issue 1458233003: Factor out GrAtlasTextBatch fromt GrAtlasTextContext (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: remove newline Created 5 years, 1 month 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
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 "GrBatchFontCache.h"
10 #include "GrBatchFlushState.h"
11 #include "GrBatchTest.h"
12 #include "GrBlurUtils.h" 9 #include "GrBlurUtils.h"
13 #include "GrDefaultGeoProcFactory.h"
14 #include "GrDrawContext.h" 10 #include "GrDrawContext.h"
15 #include "GrDrawTarget.h" 11 #include "GrDrawTarget.h"
16 #include "GrFontScaler.h" 12 #include "GrFontScaler.h"
17 #include "GrResourceProvider.h"
18 #include "GrStrokeInfo.h" 13 #include "GrStrokeInfo.h"
19 #include "GrTextBlobCache.h" 14 #include "GrTextBlobCache.h"
20 #include "GrTexturePriv.h" 15 #include "GrTexturePriv.h"
21 #include "GrVertexBuffer.h" 16 #include "GrVertexBuffer.h"
22 17
23 #include "SkAutoKern.h" 18 #include "SkAutoKern.h"
24 #include "SkColorPriv.h" 19 #include "SkColorPriv.h"
25 #include "SkColorFilter.h" 20 #include "SkColorFilter.h"
26 #include "SkDistanceFieldGen.h" 21 #include "SkDistanceFieldGen.h"
27 #include "SkDraw.h" 22 #include "SkDraw.h"
28 #include "SkDrawFilter.h" 23 #include "SkDrawFilter.h"
29 #include "SkDrawProcs.h" 24 #include "SkDrawProcs.h"
30 #include "SkFindAndPlaceGlyph.h" 25 #include "SkFindAndPlaceGlyph.h"
31 #include "SkGlyphCache.h" 26 #include "SkGlyphCache.h"
32 #include "SkGpuDevice.h" 27 #include "SkGpuDevice.h"
33 #include "SkGrPriv.h" 28 #include "SkGrPriv.h"
34 #include "SkPath.h" 29 #include "SkPath.h"
35 #include "SkRTConf.h" 30 #include "SkRTConf.h"
36 #include "SkStrokeRec.h" 31 #include "SkStrokeRec.h"
37 #include "SkTextBlob.h" 32 #include "SkTextBlob.h"
38 #include "SkTextMapStateProc.h" 33 #include "SkTextMapStateProc.h"
39 34
40 #include "batches/GrVertexBatch.h" 35 #include "batches/GrAtlasTextBatch.h"
41
42 #include "effects/GrBitmapTextGeoProc.h"
43 #include "effects/GrDistanceFieldGeoProc.h"
44 36
45 namespace { 37 namespace {
46 static const size_t kLCDTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16);
47
48 // position + local coord
49 static const size_t kColorTextVASize = sizeof(SkPoint) + sizeof(SkIPoint16);
50
51 static const size_t kGrayTextVASize = sizeof(SkPoint) + sizeof(GrColor) + sizeof (SkIPoint16);
52
53 static const int kMinDFFontSize = 18; 38 static const int kMinDFFontSize = 18;
54 static const int kSmallDFFontSize = 32; 39 static const int kSmallDFFontSize = 32;
55 static const int kSmallDFFontLimit = 32; 40 static const int kSmallDFFontLimit = 32;
56 static const int kMediumDFFontSize = 72; 41 static const int kMediumDFFontSize = 72;
57 static const int kMediumDFFontLimit = 72; 42 static const int kMediumDFFontLimit = 72;
58 static const int kLargeDFFontSize = 162; 43 static const int kLargeDFFontSize = 162;
59 #ifdef SK_BUILD_FOR_ANDROID 44 #ifdef SK_BUILD_FOR_ANDROID
60 static const int kLargeDFFontLimit = 384; 45 static const int kLargeDFFontLimit = 384;
61 #else 46 #else
62 static const int kLargeDFFontLimit = 2 * kLargeDFFontSize; 47 static const int kLargeDFFontLimit = 2 * kLargeDFFontSize;
63 #endif 48 #endif
64 49
65 SkDEBUGCODE(static const int kExpectedDistanceAdjustTableSize = 8;) 50 SkDEBUGCODE(static const int kExpectedDistanceAdjustTableSize = 8;)
66 static const int kDistanceAdjustLumShift = 5;
67
68 static const int kVerticesPerGlyph = 4;
69 static const int kIndicesPerGlyph = 6;
70
71 static size_t get_vertex_stride(GrMaskFormat maskFormat) {
72 switch (maskFormat) {
73 case kA8_GrMaskFormat:
74 return kGrayTextVASize;
75 case kARGB_GrMaskFormat:
76 return kColorTextVASize;
77 default:
78 return kLCDTextVASize;
79 }
80 }
81
82 static size_t get_vertex_stride_df(GrMaskFormat maskFormat, bool useLCDText) {
83 SkASSERT(maskFormat == kA8_GrMaskFormat);
84 if (useLCDText) {
85 return kLCDTextVASize;
86 } else {
87 return kGrayTextVASize;
88 }
89 }
90
91 static inline GrColor skcolor_to_grcolor_nopremultiply(SkColor c) {
92 unsigned r = SkColorGetR(c);
93 unsigned g = SkColorGetG(c);
94 unsigned b = SkColorGetB(c);
95 return GrColorPackRGBA(r, g, b, 0xff);
96 }
97
98 }; 51 };
99 52
100 GrAtlasTextContext::GrAtlasTextContext(GrContext* context, const SkSurfaceProps& surfaceProps) 53 GrAtlasTextContext::GrAtlasTextContext(GrContext* context, const SkSurfaceProps& surfaceProps)
101 : INHERITED(context, surfaceProps) 54 : INHERITED(context, surfaceProps)
102 , fDistanceAdjustTable(new DistanceAdjustTable) { 55 , fDistanceAdjustTable(new DistanceAdjustTable) {
103 // We overallocate vertices in our textblobs based on the assumption that A8 has the greatest 56 // We overallocate vertices in our textblobs based on the assumption that A8 has the greatest
104 // vertexStride 57 // vertexStride
105 static_assert(kGrayTextVASize >= kColorTextVASize && kGrayTextVASize >= kLCD TextVASize, 58 static_assert(GrAtlasTextBatch::kGrayTextVASize >= GrAtlasTextBatch::kColorT extVASize &&
59 GrAtlasTextBatch::kGrayTextVASize >= GrAtlasTextBatch::kLCDTex tVASize,
106 "vertex_attribute_changed"); 60 "vertex_attribute_changed");
107 fCurrStrike = nullptr; 61 fCurrStrike = nullptr;
108 fCache = context->getTextBlobCache(); 62 fCache = context->getTextBlobCache();
109 } 63 }
110 64
111 void GrAtlasTextContext::DistanceAdjustTable::buildDistanceAdjustTable() { 65 void GrAtlasTextContext::DistanceAdjustTable::buildDistanceAdjustTable() {
112 66
113 // This is used for an approximation of the mask gamma hack, used by raster and bitmap 67 // This is used for an approximation of the mask gamma hack, used by raster and bitmap
114 // text. The mask gamma hack is based off of guessing what the blend color i s going to 68 // text. The mask gamma hack is based off of guessing what the blend color i s going to
115 // be, and adjusting the mask so that when run through the linear blend will 69 // be, and adjusting the mask so that when run through the linear blend will
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
395 } 349 }
396 350
397 if (cacheBlob) { 351 if (cacheBlob) {
398 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, grPaint.ge tColor(), blurRec, 352 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, grPaint.ge tColor(), blurRec,
399 viewMatrix, x, y)) { 353 viewMatrix, x, y)) {
400 // We have to remake the blob because changes may invalidate our mas ks. 354 // We have to remake the blob because changes may invalidate our mas ks.
401 // TODO we could probably get away reuse most of the time if the poi nter is unique, 355 // TODO we could probably get away reuse most of the time if the poi nter is unique,
402 // but we'd have to clear the subrun information 356 // but we'd have to clear the subrun information
403 fCache->remove(cacheBlob); 357 fCache->remove(cacheBlob);
404 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s kPaint, 358 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s kPaint,
405 kGrayTextVASize))); 359 GrAtlasTextBatch::kGr ayTextVASize)));
406 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), vie wMatrix, 360 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), vie wMatrix,
407 blob, x, y, drawFilter, clipRect, rt, clip) ; 361 blob, x, y, drawFilter, clipRect, rt, clip) ;
408 } else { 362 } else {
409 // If we can reuse the blob, then make sure we update the blob's vie wmatrix, and x/y 363 // If we can reuse the blob, then make sure we update the blob's vie wmatrix, and x/y
410 // offsets. Note, we offset the vertex bounds right before flushing 364 // offsets. Note, we offset the vertex bounds right before flushing
411 cacheBlob->fViewMatrix = viewMatrix; 365 cacheBlob->fViewMatrix = viewMatrix;
412 cacheBlob->fX = x; 366 cacheBlob->fX = x;
413 cacheBlob->fY = y; 367 cacheBlob->fY = y;
414 fCache->makeMRU(cacheBlob); 368 fCache->makeMRU(cacheBlob);
415 #ifdef CACHE_SANITY_CHECK 369 #ifdef CACHE_SANITY_CHECK
416 { 370 {
417 int glyphCount = 0; 371 int glyphCount = 0;
418 int runCount = 0; 372 int runCount = 0;
419 GrTextBlobCache::BlobGlyphCount(&glyphCount, &runCount, blob); 373 GrTextBlobCache::BlobGlyphCount(&glyphCount, &runCount, blob);
420 SkAutoTUnref<GrAtlasTextBlob> sanityBlob(fCache->createBlob(glyp hCount, runCount, 374 SkAutoTUnref<GrAtlasTextBlob> sanityBlob(fCache->createBlob(glyp hCount, runCount,
421 kGra yTextVASize)); 375 kGra yTextVASize));
422 GrTextBlobCache::SetupCacheBlobKey(sanityBlob, key, blurRec, skP aint); 376 GrTextBlobCache::SetupCacheBlobKey(sanityBlob, key, blurRec, skP aint);
423 this->regenerateTextBlob(sanityBlob, skPaint, grPaint.getColor() , viewMatrix, 377 this->regenerateTextBlob(sanityBlob, skPaint, grPaint.getColor() , viewMatrix,
424 blob, x, y, drawFilter, clipRect, rt, c lip); 378 blob, x, y, drawFilter, clipRect, rt, c lip);
425 GrAtlasTextBlob::AssertEqual(*sanityBlob, *cacheBlob); 379 GrAtlasTextBlob::AssertEqual(*sanityBlob, *cacheBlob);
426 } 380 }
427 381
428 #endif 382 #endif
429 } 383 }
430 } else { 384 } else {
431 if (canCache) { 385 if (canCache) {
432 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s kPaint, 386 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s kPaint,
433 kGrayTextVASize))); 387 GrAtlasTextBatch::kGr ayTextVASize)));
434 } else { 388 } else {
435 cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize)); 389 cacheBlob.reset(fCache->createBlob(blob, GrAtlasTextBatch::kGrayText VASize));
436 } 390 }
437 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMat rix, 391 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), viewMat rix,
438 blob, x, y, drawFilter, clipRect, rt, clip); 392 blob, x, y, drawFilter, clipRect, rt, clip);
439 } 393 }
440 394
441 this->flush(blob, cacheBlob, dc, rt, skPaint, grPaint, drawFilter, 395 this->flush(blob, cacheBlob, dc, rt, skPaint, grPaint, drawFilter,
442 clip, viewMatrix, clipBounds, x, y, transX, transY); 396 clip, viewMatrix, clipBounds, x, y, transX, transY);
443 } 397 }
444 398
445 inline bool GrAtlasTextContext::canDrawAsDistanceFields(const SkPaint& skPaint, 399 inline bool GrAtlasTextContext::canDrawAsDistanceFields(const SkPaint& skPaint,
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
682 this->internalDrawBMPPosText(blob, runIndex, cache, skPaint, color, viewMatr ix, 636 this->internalDrawBMPPosText(blob, runIndex, cache, skPaint, color, viewMatr ix,
683 fallbackTxt.begin(), fallbackTxt.count(), 637 fallbackTxt.begin(), fallbackTxt.count(),
684 fallbackPos.begin(), scalarsPerPosition, offset , clipRect); 638 fallbackPos.begin(), scalarsPerPosition, offset , clipRect);
685 SkGlyphCache::AttachCache(cache); 639 SkGlyphCache::AttachCache(cache);
686 } 640 }
687 641
688 inline GrAtlasTextBlob* 642 inline GrAtlasTextBlob*
689 GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint, 643 GrAtlasTextContext::setupDFBlob(int glyphCount, const SkPaint& origPaint,
690 const SkMatrix& viewMatrix, SkPaint* dfPaint, 644 const SkMatrix& viewMatrix, SkPaint* dfPaint,
691 SkScalar* textRatio) { 645 SkScalar* textRatio) {
692 GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1, kGrayTextVASize); 646 GrAtlasTextBlob* blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBatch:: kGrayTextVASize);
693 647
694 *dfPaint = origPaint; 648 *dfPaint = origPaint;
695 this->initDistanceFieldPaint(blob, dfPaint, textRatio, viewMatrix); 649 this->initDistanceFieldPaint(blob, dfPaint, textRatio, viewMatrix);
696 blob->fViewMatrix = viewMatrix; 650 blob->fViewMatrix = viewMatrix;
697 Run& run = blob->fRuns[0]; 651 Run& run = blob->fRuns[0];
698 PerSubRunInfo& subRun = run.fSubRunInfo.back(); 652 PerSubRunInfo& subRun = run.fSubRunInfo.back();
699 subRun.fUseLCDText = origPaint.isLCDRenderText(); 653 subRun.fUseLCDText = origPaint.isLCDRenderText();
700 subRun.fDrawAsDistanceFields = true; 654 subRun.fDrawAsDistanceFields = true;
701 655
702 return blob; 656 return blob;
(...skipping 19 matching lines...) Expand all
722 SkTDArray<SkScalar> fallbackPos; 676 SkTDArray<SkScalar> fallbackPos;
723 SkPoint offset; 677 SkPoint offset;
724 this->internalDrawDFText(blob, 0, dfPaint, paint.getColor(), viewMatrix, text, 678 this->internalDrawDFText(blob, 0, dfPaint, paint.getColor(), viewMatrix, text,
725 byteLength, x, y, clipRect, textRatio, &fallbac kTxt, &fallbackPos, 679 byteLength, x, y, clipRect, textRatio, &fallbac kTxt, &fallbackPos,
726 &offset, skPaint); 680 &offset, skPaint);
727 if (fallbackTxt.count()) { 681 if (fallbackTxt.count()) {
728 this->fallbackDrawPosText(blob, 0, rt, clip, paint.getColor(), skPai nt, viewMatrix, 682 this->fallbackDrawPosText(blob, 0, rt, clip, paint.getColor(), skPai nt, viewMatrix,
729 fallbackTxt, fallbackPos, 2, offset, clipR ect); 683 fallbackTxt, fallbackPos, 2, offset, clipR ect);
730 } 684 }
731 } else { 685 } else {
732 blob = fCache->createBlob(glyphCount, 1, kGrayTextVASize); 686 blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBatch::kGrayTextVASi ze);
733 blob->fViewMatrix = viewMatrix; 687 blob->fViewMatrix = viewMatrix;
734 688
735 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa trix, false); 689 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa trix, false);
736 this->internalDrawBMPText(blob, 0, cache, skPaint, paint.getColor(), vie wMatrix, text, 690 this->internalDrawBMPText(blob, 0, cache, skPaint, paint.getColor(), vie wMatrix, text,
737 byteLength, x, y, clipRect); 691 byteLength, x, y, clipRect);
738 SkGlyphCache::AttachCache(cache); 692 SkGlyphCache::AttachCache(cache);
739 } 693 }
740 return blob; 694 return blob;
741 } 695 }
742 696
(...skipping 19 matching lines...) Expand all
762 SkTDArray<SkScalar> fallbackPos; 716 SkTDArray<SkScalar> fallbackPos;
763 this->internalDrawDFPosText(blob, 0, dfPaint, paint.getColor(), viewMatr ix, text, 717 this->internalDrawDFPosText(blob, 0, dfPaint, paint.getColor(), viewMatr ix, text,
764 byteLength, pos, scalarsPerPosition, offset, clipRect, 718 byteLength, pos, scalarsPerPosition, offset, clipRect,
765 textRatio, &fallbackTxt, &fallbackPos); 719 textRatio, &fallbackTxt, &fallbackPos);
766 if (fallbackTxt.count()) { 720 if (fallbackTxt.count()) {
767 this->fallbackDrawPosText(blob, 0, rt, clip, paint.getColor(), skPai nt, viewMatrix, 721 this->fallbackDrawPosText(blob, 0, rt, clip, paint.getColor(), skPai nt, viewMatrix,
768 fallbackTxt, fallbackPos, scalarsPerPositi on, offset, 722 fallbackTxt, fallbackPos, scalarsPerPositi on, offset,
769 clipRect); 723 clipRect);
770 } 724 }
771 } else { 725 } else {
772 blob = fCache->createBlob(glyphCount, 1, kGrayTextVASize); 726 blob = fCache->createBlob(glyphCount, 1, GrAtlasTextBatch::kGrayTextVASi ze);
773 blob->fViewMatrix = viewMatrix; 727 blob->fViewMatrix = viewMatrix;
774 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa trix, false); 728 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, &viewMa trix, false);
775 this->internalDrawBMPPosText(blob, 0, cache, skPaint, paint.getColor(), viewMatrix, text, 729 this->internalDrawBMPPosText(blob, 0, cache, skPaint, paint.getColor(), viewMatrix, text,
776 byteLength, pos, scalarsPerPosition, offset , clipRect); 730 byteLength, pos, scalarsPerPosition, offset , clipRect);
777 SkGlyphCache::AttachCache(cache); 731 SkGlyphCache::AttachCache(cache);
778 } 732 }
779 return blob; 733 return blob;
780 } 734 }
781 735
782 void GrAtlasTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget* rt, 736 void GrAtlasTextContext::onDrawText(GrDrawContext* dc, GrRenderTarget* rt,
(...skipping 300 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 PerSubRunInfo* subRun = &run.fSubRunInfo.back(); 1037 PerSubRunInfo* subRun = &run.fSubRunInfo.back();
1084 if (run.fInitialized && subRun->fMaskFormat != format) { 1038 if (run.fInitialized && subRun->fMaskFormat != format) {
1085 subRun = &run.push_back(); 1039 subRun = &run.push_back();
1086 subRun->fStrike.reset(SkRef(fCurrStrike)); 1040 subRun->fStrike.reset(SkRef(fCurrStrike));
1087 } else if (!run.fInitialized) { 1041 } else if (!run.fInitialized) {
1088 subRun->fStrike.reset(SkRef(fCurrStrike)); 1042 subRun->fStrike.reset(SkRef(fCurrStrike));
1089 } 1043 }
1090 1044
1091 run.fInitialized = true; 1045 run.fInitialized = true;
1092 1046
1093 size_t vertexStride = get_vertex_stride(format); 1047 size_t vertexStride = GrAtlasTextBatch::GetVertexStride(format);
1094 1048
1095 SkRect r; 1049 SkRect r;
1096 r.fLeft = SkIntToScalar(x); 1050 r.fLeft = SkIntToScalar(x);
1097 r.fTop = SkIntToScalar(y); 1051 r.fTop = SkIntToScalar(y);
1098 r.fRight = r.fLeft + SkIntToScalar(width); 1052 r.fRight = r.fLeft + SkIntToScalar(width);
1099 r.fBottom = r.fTop + SkIntToScalar(height); 1053 r.fBottom = r.fTop + SkIntToScalar(height);
1100 subRun->fMaskFormat = format; 1054 subRun->fMaskFormat = format;
1101 this->appendGlyphCommon(blob, &run, subRun, r, color, vertexStride, kA8_GrMa skFormat == format, 1055 this->appendGlyphCommon(blob, &run, subRun, r, color, vertexStride, kA8_GrMa skFormat == format,
1102 glyph); 1056 glyph);
1103 } 1057 }
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1161 } 1115 }
1162 1116
1163 PerSubRunInfo* subRun = &run.fSubRunInfo.back(); 1117 PerSubRunInfo* subRun = &run.fSubRunInfo.back();
1164 if (!run.fInitialized) { 1118 if (!run.fInitialized) {
1165 subRun->fStrike.reset(SkRef(fCurrStrike)); 1119 subRun->fStrike.reset(SkRef(fCurrStrike));
1166 } 1120 }
1167 run.fInitialized = true; 1121 run.fInitialized = true;
1168 SkASSERT(glyph->fMaskFormat == kA8_GrMaskFormat); 1122 SkASSERT(glyph->fMaskFormat == kA8_GrMaskFormat);
1169 subRun->fMaskFormat = kA8_GrMaskFormat; 1123 subRun->fMaskFormat = kA8_GrMaskFormat;
1170 1124
1171 size_t vertexStride = get_vertex_stride_df(kA8_GrMaskFormat, subRun->fUseLCD Text); 1125 size_t vertexStride = GrAtlasTextBatch::GetVertexStrideDf(kA8_GrMaskFormat,
1126 subRun->fUseLCDTex t);
1172 1127
1173 bool useColorVerts = !subRun->fUseLCDText; 1128 bool useColorVerts = !subRun->fUseLCDText;
1174 this->appendGlyphCommon(blob, &run, subRun, glyphRect, color, vertexStride, useColorVerts, 1129 this->appendGlyphCommon(blob, &run, subRun, glyphRect, color, vertexStride, useColorVerts,
1175 glyph); 1130 glyph);
1176 return true; 1131 return true;
1177 } 1132 }
1178 1133
1179 inline void GrAtlasTextContext::appendGlyphPath(GrAtlasTextBlob* blob, GrGlyph* glyph, 1134 inline void GrAtlasTextContext::appendGlyphPath(GrAtlasTextBlob* blob, GrGlyph* glyph,
1180 GrFontScaler* scaler, const SkGl yph& skGlyph, 1135 GrFontScaler* scaler, const SkGl yph& skGlyph,
1181 SkScalar x, SkScalar y, SkScalar scale, 1136 SkScalar x, SkScalar y, SkScalar scale,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1244 position = reinterpret_cast<SkPoint*>(vertex); 1199 position = reinterpret_cast<SkPoint*>(vertex);
1245 position->set(positions.fRight, positions.fBottom); 1200 position->set(positions.fRight, positions.fBottom);
1246 vertex += vertexStride; 1201 vertex += vertexStride;
1247 1202
1248 // V3 1203 // V3
1249 position = reinterpret_cast<SkPoint*>(vertex); 1204 position = reinterpret_cast<SkPoint*>(vertex);
1250 position->set(positions.fRight, positions.fTop); 1205 position->set(positions.fRight, positions.fTop);
1251 } 1206 }
1252 1207
1253 subRun->fGlyphEndIndex++; 1208 subRun->fGlyphEndIndex++;
1254 subRun->fVertexEndIndex += vertexStride * kVerticesPerGlyph; 1209 subRun->fVertexEndIndex += vertexStride * GrAtlasTextBatch::kVerticesPerGlyp h;
1255 } 1210 }
1256 1211
1257 class TextBatch : public GrVertexBatch {
1258 public:
1259 DEFINE_BATCH_CLASS_ID
1260
1261 typedef GrAtlasTextContext::DistanceAdjustTable DistanceAdjustTable;
1262 typedef GrAtlasTextBlob Blob;
1263 typedef Blob::Run Run;
1264 typedef Run::SubRunInfo TextInfo;
1265 struct Geometry {
1266 Blob* fBlob;
1267 int fRun;
1268 int fSubRun;
1269 GrColor fColor;
1270 SkScalar fTransX;
1271 SkScalar fTransY;
1272 };
1273
1274 static TextBatch* CreateBitmap(GrMaskFormat maskFormat, int glyphCount,
1275 GrBatchFontCache* fontCache) {
1276 TextBatch* batch = new TextBatch;
1277
1278 batch->fFontCache = fontCache;
1279 switch (maskFormat) {
1280 case kA8_GrMaskFormat:
1281 batch->fMaskType = kGrayscaleCoverageMask_MaskType;
1282 break;
1283 case kA565_GrMaskFormat:
1284 batch->fMaskType = kLCDCoverageMask_MaskType;
1285 break;
1286 case kARGB_GrMaskFormat:
1287 batch->fMaskType = kColorBitmapMask_MaskType;
1288 break;
1289 }
1290 batch->fBatch.fNumGlyphs = glyphCount;
1291 batch->fGeoCount = 1;
1292 batch->fFilteredColor = 0;
1293 batch->fFontCache = fontCache;
1294 batch->fUseBGR = false;
1295 return batch;
1296 }
1297
1298 static TextBatch* CreateDistanceField(int glyphCount, GrBatchFontCache* font Cache,
1299 const DistanceAdjustTable* distanceAdj ustTable,
1300 SkColor filteredColor, bool isLCD,
1301 bool useBGR) {
1302 TextBatch* batch = new TextBatch;
1303
1304 batch->fFontCache = fontCache;
1305 batch->fMaskType = isLCD ? kLCDDistanceField_MaskType : kGrayscaleDistan ceField_MaskType;
1306 batch->fDistanceAdjustTable.reset(SkRef(distanceAdjustTable));
1307 batch->fFilteredColor = filteredColor;
1308 batch->fUseBGR = useBGR;
1309 batch->fBatch.fNumGlyphs = glyphCount;
1310 batch->fGeoCount = 1;
1311 return batch;
1312 }
1313
1314 // to avoid even the initial copy of the struct, we have a getter for the fi rst item which
1315 // is used to seed the batch with its initial geometry. After seeding, the client should call
1316 // init() so the Batch can initialize itself
1317 Geometry& geometry() { return fGeoData[0]; }
1318
1319 void init() {
1320 const Geometry& geo = fGeoData[0];
1321 fBatch.fColor = geo.fColor;
1322 fBatch.fViewMatrix = geo.fBlob->fViewMatrix;
1323
1324 // We don't yet position distance field text on the cpu, so we have to m ap the vertex bounds
1325 // into device space
1326 const Run& run = geo.fBlob->fRuns[geo.fRun];
1327 if (run.fSubRunInfo[geo.fSubRun].fDrawAsDistanceFields) {
1328 SkRect bounds = run.fVertexBounds;
1329 fBatch.fViewMatrix.mapRect(&bounds);
1330 this->setBounds(bounds);
1331 } else {
1332 this->setBounds(run.fVertexBounds);
1333 }
1334 }
1335
1336 const char* name() const override { return "TextBatch"; }
1337
1338 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
1339 if (kColorBitmapMask_MaskType == fMaskType) {
1340 out->setUnknownFourComponents();
1341 } else {
1342 out->setKnownFourComponents(fBatch.fColor);
1343 }
1344 }
1345
1346 void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
1347 switch (fMaskType) {
1348 case kGrayscaleDistanceField_MaskType:
1349 case kGrayscaleCoverageMask_MaskType:
1350 out->setUnknownSingleComponent();
1351 break;
1352 case kLCDCoverageMask_MaskType:
1353 case kLCDDistanceField_MaskType:
1354 out->setUnknownOpaqueFourComponents();
1355 out->setUsingLCDCoverage();
1356 break;
1357 case kColorBitmapMask_MaskType:
1358 out->setKnownSingleComponent(0xff);
1359 }
1360 }
1361
1362 private:
1363 void initBatchTracker(const GrPipelineOptimizations& opt) override {
1364 // Handle any color overrides
1365 if (!opt.readsColor()) {
1366 fGeoData[0].fColor = GrColor_ILLEGAL;
1367 }
1368 opt.getOverrideColorIfSet(&fGeoData[0].fColor);
1369
1370 // setup batch properties
1371 fBatch.fColorIgnored = !opt.readsColor();
1372 fBatch.fColor = fGeoData[0].fColor;
1373 fBatch.fUsesLocalCoords = opt.readsLocalCoords();
1374 fBatch.fCoverageIgnored = !opt.readsCoverage();
1375 }
1376
1377 struct FlushInfo {
1378 SkAutoTUnref<const GrVertexBuffer> fVertexBuffer;
1379 SkAutoTUnref<const GrIndexBuffer> fIndexBuffer;
1380 int fGlyphsToFlush;
1381 int fVertexOffset;
1382 };
1383
1384 void onPrepareDraws(Target* target) override {
1385 // if we have RGB, then we won't have any SkShaders so no need to use a localmatrix.
1386 // TODO actually only invert if we don't have RGBA
1387 SkMatrix localMatrix;
1388 if (this->usesLocalCoords() && !this->viewMatrix().invert(&localMatrix)) {
1389 SkDebugf("Cannot invert viewmatrix\n");
1390 return;
1391 }
1392
1393 GrTexture* texture = fFontCache->getTexture(this->maskFormat());
1394 if (!texture) {
1395 SkDebugf("Could not allocate backing texture for atlas\n");
1396 return;
1397 }
1398
1399 bool usesDistanceFields = this->usesDistanceFields();
1400 GrMaskFormat maskFormat = this->maskFormat();
1401 bool isLCD = this->isLCD();
1402
1403 SkAutoTUnref<const GrGeometryProcessor> gp;
1404 if (usesDistanceFields) {
1405 gp.reset(this->setupDfProcessor(this->viewMatrix(), fFilteredColor, this->color(),
1406 texture));
1407 } else {
1408 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::k None_FilterMode);
1409 gp.reset(GrBitmapTextGeoProc::Create(this->color(),
1410 texture,
1411 params,
1412 maskFormat,
1413 localMatrix,
1414 this->usesLocalCoords()));
1415 }
1416
1417 FlushInfo flushInfo;
1418 flushInfo.fGlyphsToFlush = 0;
1419 size_t vertexStride = gp->getVertexStride();
1420 SkASSERT(vertexStride == (usesDistanceFields ?
1421 get_vertex_stride_df(maskFormat, isLCD) :
1422 get_vertex_stride(maskFormat)));
1423
1424 target->initDraw(gp, this->pipeline());
1425
1426 int glyphCount = this->numGlyphs();
1427 const GrVertexBuffer* vertexBuffer;
1428
1429 void* vertices = target->makeVertexSpace(vertexStride,
1430 glyphCount * kVerticesPerGlyph,
1431 &vertexBuffer,
1432 &flushInfo.fVertexOffset);
1433 flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer));
1434 flushInfo.fIndexBuffer.reset(target->resourceProvider()->refQuadIndexBuf fer());
1435 if (!vertices || !flushInfo.fVertexBuffer) {
1436 SkDebugf("Could not allocate vertices\n");
1437 return;
1438 }
1439
1440 unsigned char* currVertex = reinterpret_cast<unsigned char*>(vertices);
1441
1442 // We cache some values to avoid going to the glyphcache for the same fo ntScaler twice
1443 // in a row
1444 const SkDescriptor* desc = nullptr;
1445 SkGlyphCache* cache = nullptr;
1446 GrFontScaler* scaler = nullptr;
1447 SkTypeface* typeface = nullptr;
1448
1449 for (int i = 0; i < fGeoCount; i++) {
1450 Geometry& args = fGeoData[i];
1451 Blob* blob = args.fBlob;
1452 Run& run = blob->fRuns[args.fRun];
1453 TextInfo& info = run.fSubRunInfo[args.fSubRun];
1454
1455 uint64_t currentAtlasGen = fFontCache->atlasGeneration(maskFormat);
1456 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas Gen ||
1457 info.fStrike->isAbandoned();
1458 bool regenerateColors;
1459 if (usesDistanceFields) {
1460 regenerateColors = !isLCD && run.fColor != args.fColor;
1461 } else {
1462 regenerateColors = kA8_GrMaskFormat == maskFormat && run.fColor != args.fColor;
1463 }
1464 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0. f;
1465 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex;
1466
1467 // We regenerate both texture coords and colors in the blob itself, and update the
1468 // atlas generation. If we don't end up purging any unused plots, w e can avoid
1469 // regenerating the coords. We could take a finer grained approach to updating texture
1470 // coords but its not clear if the extra bookkeeping would offset an y gains.
1471 // To avoid looping over the glyphs twice, we do one loop and condit ionally update color
1472 // or coords as needed. One final note, if we have to break a run f or an atlas eviction
1473 // then we can't really trust the atlas has all of the correct data. Atlas evictions
1474 // should be pretty rare, so we just always regenerate in those case s
1475 if (regenerateTextureCoords || regenerateColors || regeneratePositio ns) {
1476 // first regenerate texture coordinates / colors if need be
1477 bool brokenRun = false;
1478
1479 // Because the GrBatchFontCache may evict the strike a blob depe nds on using for
1480 // generating its texture coords, we have to track whether or no t the strike has
1481 // been abandoned. If it hasn't been abandoned, then we can use the GrGlyph*s as is
1482 // otherwise we have to get the new strike, and use that to get the correct glyphs.
1483 // Because we do not have the packed ids, and thus can't look up our glyphs in the
1484 // new strike, we instead keep our ref to the old strike and use the packed ids from
1485 // it. These ids will still be valid as long as we hold the ref . When we are done
1486 // updating our cache of the GrGlyph*s, we drop our ref on the o ld strike
1487 bool regenerateGlyphs = false;
1488 GrBatchTextStrike* strike = nullptr;
1489 if (regenerateTextureCoords) {
1490 info.fBulkUseToken.reset();
1491
1492 // We can reuse if we have a valid strike and our descriptor s / typeface are the
1493 // same. The override descriptor is only for the non distan ce field text within
1494 // a run
1495 const SkDescriptor* newDesc = (run.fOverrideDescriptor && !u sesDistanceFields) ?
1496 run.fOverrideDescriptor->getDe sc() :
1497 run.fDescriptor.getDesc();
1498 if (!cache || !SkTypeface::Equal(typeface, run.fTypeface) ||
1499 !(desc->equals(*newDesc))) {
1500 if (cache) {
1501 SkGlyphCache::AttachCache(cache);
1502 }
1503 desc = newDesc;
1504 cache = SkGlyphCache::DetachCache(run.fTypeface, desc);
1505 scaler = GrTextContext::GetGrFontScaler(cache);
1506 strike = info.fStrike;
1507 typeface = run.fTypeface;
1508 }
1509
1510 if (info.fStrike->isAbandoned()) {
1511 regenerateGlyphs = true;
1512 strike = fFontCache->getStrike(scaler);
1513 } else {
1514 strike = info.fStrike;
1515 }
1516 }
1517
1518 for (int glyphIdx = 0; glyphIdx < glyphCount; glyphIdx++) {
1519 if (regenerateTextureCoords) {
1520 size_t glyphOffset = glyphIdx + info.fGlyphStartIndex;
1521
1522 GrGlyph* glyph = blob->fGlyphs[glyphOffset];
1523 GrGlyph::PackedID id = glyph->fPackedID;
1524 const SkGlyph& skGlyph = scaler->grToSkGlyph(id);
1525 if (regenerateGlyphs) {
1526 // Get the id from the old glyph, and use the new st rike to lookup
1527 // the glyph.
1528 blob->fGlyphs[glyphOffset] = strike->getGlyph(skGlyp h, id, maskFormat,
1529 scaler );
1530 }
1531 glyph = blob->fGlyphs[glyphOffset];
1532 SkASSERT(glyph);
1533 SkASSERT(id == glyph->fPackedID);
1534 // We want to be able to assert this but cannot for test ing purposes.
1535 // once skbug:4143 has landed we can revist this assert
1536 //SkASSERT(glyph->fMaskFormat == this->maskFormat());
1537
1538 if (!fFontCache->hasGlyph(glyph) &&
1539 !strike->addGlyphToAtlas(target, glyph, scaler, skGl yph, maskFormat)) {
1540 this->flush(target, &flushInfo);
1541 target->initDraw(gp, this->pipeline());
1542 brokenRun = glyphIdx > 0;
1543
1544 SkDEBUGCODE(bool success =) strike->addGlyphToAtlas( target,
1545 glyph,
1546 scaler,
1547 skGlyph,
1548 maskFormat);
1549 SkASSERT(success);
1550 }
1551 fFontCache->addGlyphToBulkAndSetUseToken(&info.fBulkUseT oken, glyph,
1552 target->current Token());
1553
1554 // Texture coords are the last vertex attribute so we ge t a pointer to the
1555 // first one and then map with stride in regenerateTextu reCoords
1556 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert ices);
1557 vertex += info.fVertexStartIndex;
1558 vertex += vertexStride * glyphIdx * kVerticesPerGlyph;
1559 vertex += vertexStride - sizeof(SkIPoint16);
1560
1561 this->regenerateTextureCoords(glyph, vertex, vertexStrid e);
1562 }
1563
1564 if (regenerateColors) {
1565 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert ices);
1566 vertex += info.fVertexStartIndex;
1567 vertex += vertexStride * glyphIdx * kVerticesPerGlyph + sizeof(SkPoint);
1568 this->regenerateColors(vertex, vertexStride, args.fColor );
1569 }
1570
1571 if (regeneratePositions) {
1572 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert ices);
1573 vertex += info.fVertexStartIndex;
1574 vertex += vertexStride * glyphIdx * kVerticesPerGlyph;
1575 SkScalar transX = args.fTransX;
1576 SkScalar transY = args.fTransY;
1577 this->regeneratePositions(vertex, vertexStride, transX, transY);
1578 }
1579 flushInfo.fGlyphsToFlush++;
1580 }
1581
1582 // We my have changed the color so update it here
1583 run.fColor = args.fColor;
1584 if (regenerateTextureCoords) {
1585 if (regenerateGlyphs) {
1586 info.fStrike.reset(SkRef(strike));
1587 }
1588 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt lasGeneration :
1589 fFontCache->atlasGenerat ion(maskFormat);
1590 }
1591 } else {
1592 flushInfo.fGlyphsToFlush += glyphCount;
1593
1594 // set use tokens for all of the glyphs in our subrun. This is only valid if we
1595 // have a valid atlas generation
1596 fFontCache->setUseTokenBulk(info.fBulkUseToken, target->currentT oken(), maskFormat);
1597 }
1598
1599 // now copy all vertices
1600 size_t byteCount = info.fVertexEndIndex - info.fVertexStartIndex;
1601 memcpy(currVertex, blob->fVertices + info.fVertexStartIndex, byteCou nt);
1602
1603 currVertex += byteCount;
1604 }
1605 // Make sure to attach the last cache if applicable
1606 if (cache) {
1607 SkGlyphCache::AttachCache(cache);
1608 }
1609 this->flush(target, &flushInfo);
1610 }
1611
1612 TextBatch() : INHERITED(ClassID()) {} // initialized in factory functions.
1613
1614 ~TextBatch() {
1615 for (int i = 0; i < fGeoCount; i++) {
1616 fGeoData[i].fBlob->unref();
1617 }
1618 }
1619
1620 GrMaskFormat maskFormat() const {
1621 switch (fMaskType) {
1622 case kLCDCoverageMask_MaskType:
1623 return kA565_GrMaskFormat;
1624 case kColorBitmapMask_MaskType:
1625 return kARGB_GrMaskFormat;
1626 case kGrayscaleCoverageMask_MaskType:
1627 case kGrayscaleDistanceField_MaskType:
1628 case kLCDDistanceField_MaskType:
1629 return kA8_GrMaskFormat;
1630 }
1631 return kA8_GrMaskFormat; // suppress warning
1632 }
1633
1634 bool usesDistanceFields() const {
1635 return kGrayscaleDistanceField_MaskType == fMaskType ||
1636 kLCDDistanceField_MaskType == fMaskType;
1637 }
1638
1639 bool isLCD() const {
1640 return kLCDCoverageMask_MaskType == fMaskType ||
1641 kLCDDistanceField_MaskType == fMaskType;
1642 }
1643
1644 void regenerateTextureCoords(GrGlyph* glyph, intptr_t vertex, size_t vertexS tride) {
1645 int width = glyph->fBounds.width();
1646 int height = glyph->fBounds.height();
1647
1648 int u0, v0, u1, v1;
1649 if (this->usesDistanceFields()) {
1650 u0 = glyph->fAtlasLocation.fX + SK_DistanceFieldInset;
1651 v0 = glyph->fAtlasLocation.fY + SK_DistanceFieldInset;
1652 u1 = u0 + width - 2 * SK_DistanceFieldInset;
1653 v1 = v0 + height - 2 * SK_DistanceFieldInset;
1654 } else {
1655 u0 = glyph->fAtlasLocation.fX;
1656 v0 = glyph->fAtlasLocation.fY;
1657 u1 = u0 + width;
1658 v1 = v0 + height;
1659 }
1660
1661 SkIPoint16* textureCoords;
1662 // V0
1663 textureCoords = reinterpret_cast<SkIPoint16*>(vertex);
1664 textureCoords->set(u0, v0);
1665 vertex += vertexStride;
1666
1667 // V1
1668 textureCoords = reinterpret_cast<SkIPoint16*>(vertex);
1669 textureCoords->set(u0, v1);
1670 vertex += vertexStride;
1671
1672 // V2
1673 textureCoords = reinterpret_cast<SkIPoint16*>(vertex);
1674 textureCoords->set(u1, v1);
1675 vertex += vertexStride;
1676
1677 // V3
1678 textureCoords = reinterpret_cast<SkIPoint16*>(vertex);
1679 textureCoords->set(u1, v0);
1680 }
1681
1682 void regenerateColors(intptr_t vertex, size_t vertexStride, GrColor color) {
1683 for (int i = 0; i < kVerticesPerGlyph; i++) {
1684 SkColor* vcolor = reinterpret_cast<SkColor*>(vertex);
1685 *vcolor = color;
1686 vertex += vertexStride;
1687 }
1688 }
1689
1690 void regeneratePositions(intptr_t vertex, size_t vertexStride, SkScalar tran sX,
1691 SkScalar transY) {
1692 for (int i = 0; i < kVerticesPerGlyph; i++) {
1693 SkPoint* point = reinterpret_cast<SkPoint*>(vertex);
1694 point->fX += transX;
1695 point->fY += transY;
1696 vertex += vertexStride;
1697 }
1698 }
1699
1700 void flush(GrVertexBatch::Target* target, FlushInfo* flushInfo) {
1701 GrVertices vertices;
1702 int maxGlyphsPerDraw = flushInfo->fIndexBuffer->maxQuads();
1703 vertices.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuf fer,
1704 flushInfo->fIndexBuffer, flushInfo->fVertexOffset ,
1705 kVerticesPerGlyph, kIndicesPerGlyph, flushInfo->f GlyphsToFlush,
1706 maxGlyphsPerDraw);
1707 target->draw(vertices);
1708 flushInfo->fVertexOffset += kVerticesPerGlyph * flushInfo->fGlyphsToFlus h;
1709 flushInfo->fGlyphsToFlush = 0;
1710 }
1711
1712 GrColor color() const { return fBatch.fColor; }
1713 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; }
1714 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
1715 int numGlyphs() const { return fBatch.fNumGlyphs; }
1716
1717 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override {
1718 TextBatch* that = t->cast<TextBatch>();
1719 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi peline(),
1720 that->bounds(), caps)) {
1721 return false;
1722 }
1723
1724 if (fMaskType != that->fMaskType) {
1725 return false;
1726 }
1727
1728 if (!this->usesDistanceFields()) {
1729 // TODO we can often batch across LCD text if we have dual source bl ending and don't
1730 // have to use the blend constant
1731 if (kGrayscaleCoverageMask_MaskType != fMaskType && this->color() != that->color()) {
1732 return false;
1733 }
1734 if (this->usesLocalCoords() && !this->viewMatrix().cheapEqualTo(that ->viewMatrix())) {
1735 return false;
1736 }
1737 } else {
1738 if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
1739 return false;
1740 }
1741
1742 if (fFilteredColor != that->fFilteredColor) {
1743 return false;
1744 }
1745
1746 if (fUseBGR != that->fUseBGR) {
1747 return false;
1748 }
1749
1750 // TODO see note above
1751 if (kLCDDistanceField_MaskType == fMaskType && this->color() != that ->color()) {
1752 return false;
1753 }
1754 }
1755
1756 fBatch.fNumGlyphs += that->numGlyphs();
1757
1758 // Reallocate space for geo data if necessary and then import that's geo data.
1759 int newGeoCount = that->fGeoCount + fGeoCount;
1760 // We assume (and here enforce) that the allocation size is the smallest power of two that
1761 // is greater than or equal to the number of geometries (and at least
1762 // kMinGeometryAllocated).
1763 int newAllocSize = GrNextPow2(newGeoCount);
1764 int currAllocSize = SkTMax<int>(kMinGeometryAllocated, GrNextPow2(fGeoCo unt));
1765
1766 if (newGeoCount > currAllocSize) {
1767 fGeoData.realloc(newAllocSize);
1768 }
1769
1770 memcpy(&fGeoData[fGeoCount], that->fGeoData.get(), that->fGeoCount * siz eof(Geometry));
1771 // We steal the ref on the blobs from the other TextBatch and set its co unt to 0 so that
1772 // it doesn't try to unref them.
1773 #ifdef SK_DEBUG
1774 for (int i = 0; i < that->fGeoCount; ++i) {
1775 that->fGeoData.get()[i].fBlob = (Blob*)0x1;
1776 }
1777 #endif
1778 that->fGeoCount = 0;
1779 fGeoCount = newGeoCount;
1780
1781 this->joinBounds(that->bounds());
1782 return true;
1783 }
1784
1785 // TODO just use class params
1786 // TODO trying to figure out why lcd is so whack
1787 GrGeometryProcessor* setupDfProcessor(const SkMatrix& viewMatrix, SkColor fi lteredColor,
1788 GrColor color, GrTexture* texture) {
1789 GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBile rp_FilterMode);
1790 bool isLCD = this->isLCD();
1791 // set up any flags
1792 uint32_t flags = viewMatrix.isSimilarity() ? kSimilarity_DistanceFieldEf fectFlag : 0;
1793
1794 // see if we need to create a new effect
1795 if (isLCD) {
1796 flags |= kUseLCD_DistanceFieldEffectFlag;
1797 flags |= viewMatrix.rectStaysRect() ? kRectToRect_DistanceFieldEffec tFlag : 0;
1798 flags |= fUseBGR ? kBGR_DistanceFieldEffectFlag : 0;
1799
1800 GrColor colorNoPreMul = skcolor_to_grcolor_nopremultiply(filteredCol or);
1801
1802 float redCorrection =
1803 (*fDistanceAdjustTable)[GrColorUnpackR(colorNoPreMul) >> kDistan ceAdjustLumShift];
1804 float greenCorrection =
1805 (*fDistanceAdjustTable)[GrColorUnpackG(colorNoPreMul) >> kDistan ceAdjustLumShift];
1806 float blueCorrection =
1807 (*fDistanceAdjustTable)[GrColorUnpackB(colorNoPreMul) >> kDistan ceAdjustLumShift];
1808 GrDistanceFieldLCDTextGeoProc::DistanceAdjust widthAdjust =
1809 GrDistanceFieldLCDTextGeoProc::DistanceAdjust::Make(redCorrectio n,
1810 greenCorrect ion,
1811 blueCorrecti on);
1812
1813 return GrDistanceFieldLCDTextGeoProc::Create(color,
1814 viewMatrix,
1815 texture,
1816 params,
1817 widthAdjust,
1818 flags,
1819 this->usesLocalCoords() );
1820 } else {
1821 flags |= kColorAttr_DistanceFieldEffectFlag;
1822 #ifdef SK_GAMMA_APPLY_TO_A8
1823 U8CPU lum = SkColorSpaceLuminance::computeLuminance(SK_GAMMA_EXPONEN T, filteredColor);
1824 float correction = (*fDistanceAdjustTable)[lum >> kDistanceAdjustLum Shift];
1825 return GrDistanceFieldA8TextGeoProc::Create(color,
1826 viewMatrix,
1827 texture,
1828 params,
1829 correction,
1830 flags,
1831 this->usesLocalCoords()) ;
1832 #else
1833 return GrDistanceFieldA8TextGeoProc::Create(color,
1834 viewMatrix,
1835 texture,
1836 params,
1837 flags,
1838 this->usesLocalCoords()) ;
1839 #endif
1840 }
1841
1842 }
1843
1844 struct BatchTracker {
1845 GrColor fColor;
1846 SkMatrix fViewMatrix;
1847 bool fUsesLocalCoords;
1848 bool fColorIgnored;
1849 bool fCoverageIgnored;
1850 int fNumGlyphs;
1851 };
1852
1853 BatchTracker fBatch;
1854 // The minimum number of Geometry we will try to allocate.
1855 enum { kMinGeometryAllocated = 4 };
1856 SkAutoSTMalloc<kMinGeometryAllocated, Geometry> fGeoData;
1857 int fGeoCount;
1858
1859 enum MaskType {
1860 kGrayscaleCoverageMask_MaskType,
1861 kLCDCoverageMask_MaskType,
1862 kColorBitmapMask_MaskType,
1863 kGrayscaleDistanceField_MaskType,
1864 kLCDDistanceField_MaskType,
1865 } fMaskType;
1866 bool fUseBGR; // fold this into the enum?
1867
1868 GrBatchFontCache* fFontCache;
1869
1870 // Distance field properties
1871 SkAutoTUnref<const DistanceAdjustTable> fDistanceAdjustTable;
1872 SkColor fFilteredColor;
1873
1874 typedef GrVertexBatch INHERITED;
1875 };
1876
1877 void GrAtlasTextContext::flushRunAsPaths(GrDrawContext* dc, GrRenderTarget* rt, 1212 void GrAtlasTextContext::flushRunAsPaths(GrDrawContext* dc, GrRenderTarget* rt,
1878 const SkTextBlobRunIterator& it, 1213 const SkTextBlobRunIterator& it,
1879 const GrClip& clip, const SkPaint& skPa int, 1214 const GrClip& clip, const SkPaint& skPa int,
1880 SkDrawFilter* drawFilter, const SkMatri x& viewMatrix, 1215 SkDrawFilter* drawFilter, const SkMatri x& viewMatrix,
1881 const SkIRect& clipBounds, SkScalar x, SkScalar y) { 1216 const SkIRect& clipBounds, SkScalar x, SkScalar y) {
1882 SkPaint runPaint = skPaint; 1217 SkPaint runPaint = skPaint;
1883 1218
1884 size_t textLen = it.glyphCount() * sizeof(uint16_t); 1219 size_t textLen = it.glyphCount() * sizeof(uint16_t);
1885 const SkPoint& offset = it.offset(); 1220 const SkPoint& offset = it.offset();
1886 1221
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1919 const SkPaint& skPaint) { 1254 const SkPaint& skPaint) {
1920 GrMaskFormat format = info.fMaskFormat; 1255 GrMaskFormat format = info.fMaskFormat;
1921 GrColor subRunColor; 1256 GrColor subRunColor;
1922 if (kARGB_GrMaskFormat == format) { 1257 if (kARGB_GrMaskFormat == format) {
1923 uint8_t paintAlpha = skPaint.getAlpha(); 1258 uint8_t paintAlpha = skPaint.getAlpha();
1924 subRunColor = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAl pha); 1259 subRunColor = SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAl pha);
1925 } else { 1260 } else {
1926 subRunColor = color; 1261 subRunColor = color;
1927 } 1262 }
1928 1263
1929 TextBatch* batch; 1264 GrAtlasTextBatch* batch;
1930 if (info.fDrawAsDistanceFields) { 1265 if (info.fDrawAsDistanceFields) {
1931 SkColor filteredColor; 1266 SkColor filteredColor;
1932 SkColorFilter* colorFilter = skPaint.getColorFilter(); 1267 SkColorFilter* colorFilter = skPaint.getColorFilter();
1933 if (colorFilter) { 1268 if (colorFilter) {
1934 filteredColor = colorFilter->filterColor(skPaint.getColor()); 1269 filteredColor = colorFilter->filterColor(skPaint.getColor());
1935 } else { 1270 } else {
1936 filteredColor = skPaint.getColor(); 1271 filteredColor = skPaint.getColor();
1937 } 1272 }
1938 bool useBGR = SkPixelGeometryIsBGR(fSurfaceProps.pixelGeometry()); 1273 bool useBGR = SkPixelGeometryIsBGR(fSurfaceProps.pixelGeometry());
1939 batch = TextBatch::CreateDistanceField(glyphCount, fContext->getBatchFon tCache(), 1274 batch = GrAtlasTextBatch::CreateDistanceField(glyphCount, fContext->getB atchFontCache(),
1940 fDistanceAdjustTable, filteredCol or, 1275 fDistanceAdjustTable, filt eredColor,
1941 info.fUseLCDText, useBGR); 1276 info.fUseLCDText, useBGR);
1942 } else { 1277 } else {
1943 batch = TextBatch::CreateBitmap(format, glyphCount, fContext->getBatchFo ntCache()); 1278 batch = GrAtlasTextBatch::CreateBitmap(format, glyphCount, fContext->get BatchFontCache());
1944 } 1279 }
1945 TextBatch::Geometry& geometry = batch->geometry(); 1280 GrAtlasTextBatch::Geometry& geometry = batch->geometry();
1946 geometry.fBlob = SkRef(cacheBlob); 1281 geometry.fBlob = SkRef(cacheBlob);
1947 geometry.fRun = run; 1282 geometry.fRun = run;
1948 geometry.fSubRun = subRun; 1283 geometry.fSubRun = subRun;
1949 geometry.fColor = subRunColor; 1284 geometry.fColor = subRunColor;
1950 geometry.fTransX = transX; 1285 geometry.fTransX = transX;
1951 geometry.fTransY = transY; 1286 geometry.fTransY = transY;
1952 batch->init(); 1287 batch->init();
1953 1288
1954 return batch; 1289 return batch;
1955 } 1290 }
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
2107 gTextContext->createDrawTextBlob(rt, clip, grPaint, skPaint, viewMat rix, text, 1442 gTextContext->createDrawTextBlob(rt, clip, grPaint, skPaint, viewMat rix, text,
2108 static_cast<size_t>(textLen), 0, 0, noClip)); 1443 static_cast<size_t>(textLen), 0, 0, noClip));
2109 1444
2110 SkScalar transX = static_cast<SkScalar>(random->nextU()); 1445 SkScalar transX = static_cast<SkScalar>(random->nextU());
2111 SkScalar transY = static_cast<SkScalar>(random->nextU()); 1446 SkScalar transY = static_cast<SkScalar>(random->nextU());
2112 const GrAtlasTextBlob::Run::SubRunInfo& info = blob->fRuns[0].fSubRunInfo[0] ; 1447 const GrAtlasTextBlob::Run::SubRunInfo& info = blob->fRuns[0].fSubRunInfo[0] ;
2113 return gTextContext->createBatch(blob, info, textLen, 0, 0, color, transX, t ransY, skPaint); 1448 return gTextContext->createBatch(blob, info, textLen, 0, 0, color, transX, t ransY, skPaint);
2114 } 1449 }
2115 1450
2116 #endif 1451 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698