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

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

Issue 1062863002: Avoid regenerating cached textblobs on integer scrolls (Closed) Base URL: https://skia.googlesource.com/skia.git@atlastextcache
Patch Set: feedback inc 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') | src/gpu/GrTextBlobCache.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 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 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
83 return SkNEW_ARGS(GrAtlasTextContext, (context, gpuDevice, props)); 83 return SkNEW_ARGS(GrAtlasTextContext, (context, gpuDevice, props));
84 } 84 }
85 85
86 bool GrAtlasTextContext::canDraw(const GrRenderTarget*, 86 bool GrAtlasTextContext::canDraw(const GrRenderTarget*,
87 const GrClip&, 87 const GrClip&,
88 const GrPaint&, 88 const GrPaint&,
89 const SkPaint& skPaint, 89 const SkPaint& skPaint,
90 const SkMatrix& viewMatrix) { 90 const SkMatrix& viewMatrix) {
91 return !SkDraw::ShouldDrawTextAsPaths(skPaint, viewMatrix); 91 return !SkDraw::ShouldDrawTextAsPaths(skPaint, viewMatrix);
92 } 92 }
93 93
robertphillips 2015/04/09 13:15:32 kMinDiscernableTranslation ? Can this be moved int
joshualitt 2015/04/09 14:59:00 Acknowledged.
94 bool GrAtlasTextContext::MustRegenerateBlob(const BitmapTextBlob& blob, const Sk Paint& paint, 94 static const SkScalar kThreshold = 0.0625;
95
96 bool GrAtlasTextContext::MustRegenerateBlob(SkScalar* transX, SkScalar* transY,
97 const BitmapTextBlob& blob, const Sk Paint& paint,
95 const SkMatrix& viewMatrix, SkScalar x, SkScalar y) { 98 const SkMatrix& viewMatrix, SkScalar x, SkScalar y) {
96 // We always regenerate blobs with patheffects or mask filters we could cach e these 99 // Color can affect the mask
97 // TODO find some way to cache the maskfilter / patheffects on the textblob 100 // TODO we can adjust the color within specific gamma slots
98 return !blob.fViewMatrix.cheapEqualTo(viewMatrix) || blob.fX != x || blob.fY != y || 101 if (blob.fColor != paint.getColor()) {
99 paint.getMaskFilter() || paint.getPathEffect() || paint.getStyle() ! = blob.fStyle; 102 return true;
103 }
104
105 if (blob.fViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) {
106 return true;
107 }
108
109 if (blob.fViewMatrix.hasPerspective() && !blob.fViewMatrix.cheapEqualTo(view Matrix)) {
110 return true;
111 }
112
113 if (blob.fViewMatrix.getScaleX() != viewMatrix.getScaleX() ||
114 blob.fViewMatrix.getScaleY() != viewMatrix.getScaleY() ||
115 blob.fViewMatrix.getSkewX() != viewMatrix.getSkewX() ||
116 blob.fViewMatrix.getSkewY() != viewMatrix.getSkewY()) {
117 return true;
118 }
119
120 // We can update the positions in the cachedtextblobs without regenerating t he whole blob, but
121 // only for integer translations.
robertphillips 2015/04/09 13:15:32 That's an ominous todo Shouldn't this be something
joshualitt 2015/04/09 14:59:00 I took another stab at it. I *think* I can allow
122 // TODO I think this is wrong
123 if (SkScalarFraction(blob.fViewMatrix.getTranslateX() -
124 viewMatrix.getTranslateX()) > kThreshold ||
125 SkScalarFraction(x - blob.fX) > kThreshold ||
126 SkScalarFraction(blob.fViewMatrix.getTranslateX() -
127 viewMatrix.getTranslateX()) > kThreshold ||
128 SkScalarFraction(y - blob.fY) > kThreshold) {
129 return true;
130 }
131
robertphillips 2015/04/09 13:15:32 // This cool math does the following ... ?
joshualitt 2015/04/09 14:59:00 Acknowledged.
132 (*transX) = viewMatrix.getTranslateX() +
133 viewMatrix.getScaleX() * (x - blob.fX) +
134 viewMatrix.getSkewX() * (y - blob.fY) -
135 blob.fViewMatrix.getTranslateX();
136
137 (*transY) = viewMatrix.getTranslateY() +
138 viewMatrix.getSkewY() * (x - blob.fX) +
139 viewMatrix.getScaleY() * (y - blob.fY) -
140 blob.fViewMatrix.getTranslateY();
141 return false;
100 } 142 }
101 143
102 144
103 inline SkGlyphCache* GrAtlasTextContext::setupCache(BitmapTextBlob::Run* run, 145 inline SkGlyphCache* GrAtlasTextContext::setupCache(BitmapTextBlob::Run* run,
104 const SkPaint& skPaint, 146 const SkPaint& skPaint,
105 const SkMatrix& viewMatrix) { 147 const SkMatrix& viewMatrix) {
106 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, &v iewMatrix, false); 148 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, &v iewMatrix, false);
107 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); 149 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface()));
108 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc()) ; 150 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc()) ;
109 } 151 }
110 152
111 void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, 153 void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip,
112 const SkPaint& skPaint, const SkMatrix& vi ewMatrix, 154 const SkPaint& skPaint, const SkMatrix& vi ewMatrix,
113 const SkTextBlob* blob, SkScalar x, SkScal ar y, 155 const SkTextBlob* blob, SkScalar x, SkScal ar y,
114 SkDrawFilter* drawFilter, const SkIRect& c lipBounds) { 156 SkDrawFilter* drawFilter, const SkIRect& c lipBounds) {
115 uint32_t uniqueID = blob->uniqueID(); 157 uint32_t uniqueID = blob->uniqueID();
116 BitmapTextBlob* cacheBlob = fCache->find(uniqueID); 158 SkAutoTUnref<BitmapTextBlob> cacheBlob;
159 // TODO start caching these, mix bits into the key
robertphillips 2015/04/09 13:15:32 Would this be more natural as "canCache" ?
joshualitt 2015/04/09 14:59:00 Acknowledged.
160 bool mustNotCache = skPaint.getPathEffect() ||
161 skPaint.getMaskFilter() ||
162 skPaint.getColorFilter() ||
163 skPaint.getStyle() != SkPaint::kFill_Style ||
164 drawFilter;
165
166 if (!mustNotCache) {
167 cacheBlob.reset(SkSafeRef(fCache->find(uniqueID)));
168 }
169
117 SkIRect clipRect; 170 SkIRect clipRect;
118 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); 171 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect);
119 172
173 SkScalar transX = 0.f;
174 SkScalar transY = 0.f;
175
120 if (cacheBlob) { 176 if (cacheBlob) {
121 if (MustRegenerateBlob(*cacheBlob, skPaint, viewMatrix, x, y)) { 177 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, viewMatrix , x, y)) {
122 // We have to remake the blob because changes may invalidate our mas ks. 178 // We have to remake the blob because changes may invalidate our mas ks.
123 // TODO we could probably get away reuse most of the time if the poi nter is unique, 179 // TODO we could probably get away reuse most of the time if the poi nter is unique,
124 // but we'd have to clear the subrun information 180 // but we'd have to clear the subrun information
125 fCache->remove(cacheBlob); 181 fCache->remove(cacheBlob);
126 cacheBlob = fCache->createCachedBlob(blob, kGrayTextVASize); 182 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, kGrayTextVASize )));
127 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter, 183 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter,
128 clipRect); 184 clipRect);
129 } else { 185 } else {
186 // If we can reuse the blob, then make sure we update the blob's vie wmatrix and x/y
187 // offsets to reflect the results of any translations we may apply i n generateGeometry
188 cacheBlob->fViewMatrix = viewMatrix;
189 cacheBlob->fX = x;
190 cacheBlob->fY = y;
130 fCache->makeMRU(cacheBlob); 191 fCache->makeMRU(cacheBlob);
131 } 192 }
132 } else { 193 } else {
133 cacheBlob = fCache->createCachedBlob(blob, kGrayTextVASize); 194 if (mustNotCache) {
195 cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize));
196 } else {
197 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, kGrayTextVASize )));
198 }
134 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra wFilter, clipRect); 199 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra wFilter, clipRect);
135 } 200 }
136 201
137 // Though for the time being runs in the textblob can override the paint, th ey only touch font 202 // Though for the time being runs in the textblob can override the paint, th ey only touch font
138 // info. 203 // info.
139 GrPaint grPaint; 204 GrPaint grPaint;
140 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint); 205 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint);
141 206
142 this->flush(fContext->getTextTarget(), blob, cacheBlob, rt, skPaint, grPaint , drawFilter, 207 this->flush(fContext->getTextTarget(), blob, cacheBlob, rt, skPaint, grPaint , drawFilter,
143 clip, viewMatrix, clipBounds, x, y); 208 clip, viewMatrix, clipBounds, x, y, transX, transY);
144 } 209 }
145 210
146 void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob, 211 void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob,
147 const SkPaint& skPaint, const SkMatr ix& viewMatrix, 212 const SkPaint& skPaint, const SkMatr ix& viewMatrix,
148 const SkTextBlob* blob, SkScalar x, SkScalar y, 213 const SkTextBlob* blob, SkScalar x, SkScalar y,
149 SkDrawFilter* drawFilter, const SkIR ect& clipRect) { 214 SkDrawFilter* drawFilter, const SkIR ect& clipRect) {
150 cacheBlob->fViewMatrix = viewMatrix; 215 cacheBlob->fViewMatrix = viewMatrix;
151 cacheBlob->fX = x; 216 cacheBlob->fX = x;
152 cacheBlob->fY = y; 217 cacheBlob->fY = y;
218 cacheBlob->fColor = skPaint.getColor();
153 cacheBlob->fStyle = skPaint.getStyle(); 219 cacheBlob->fStyle = skPaint.getStyle();
154 220
155 // Regenerate textblob 221 // Regenerate textblob
156 SkPaint runPaint = skPaint; 222 SkPaint runPaint = skPaint;
157 SkTextBlob::RunIterator it(blob); 223 SkTextBlob::RunIterator it(blob);
158 for (int run = 0; !it.done(); it.next(), run++) { 224 for (int run = 0; !it.done(); it.next(), run++) {
159 int glyphCount = it.glyphCount(); 225 int glyphCount = it.glyphCount();
160 size_t textLen = glyphCount * sizeof(uint16_t); 226 size_t textLen = glyphCount * sizeof(uint16_t);
161 const SkPoint& offset = it.offset(); 227 const SkPoint& offset = it.offset();
162 // applyFontToPaint() always overwrites the exact same attributes, 228 // applyFontToPaint() always overwrites the exact same attributes,
(...skipping 15 matching lines...) Expand all
178 PerSubRunInfo& newRun = cacheBlob->fRuns[run].fSubRunInfo.back(); 244 PerSubRunInfo& newRun = cacheBlob->fRuns[run].fSubRunInfo.back();
179 PerSubRunInfo& lastRun = cacheBlob->fRuns[run - 1].fSubRunInfo.back( ); 245 PerSubRunInfo& lastRun = cacheBlob->fRuns[run - 1].fSubRunInfo.back( );
180 246
181 newRun.fVertexStartIndex = lastRun.fVertexEndIndex; 247 newRun.fVertexStartIndex = lastRun.fVertexEndIndex;
182 newRun.fVertexEndIndex = lastRun.fVertexEndIndex; 248 newRun.fVertexEndIndex = lastRun.fVertexEndIndex;
183 249
184 newRun.fGlyphStartIndex = lastRun.fGlyphEndIndex; 250 newRun.fGlyphStartIndex = lastRun.fGlyphEndIndex;
185 newRun.fGlyphEndIndex = lastRun.fGlyphEndIndex; 251 newRun.fGlyphEndIndex = lastRun.fGlyphEndIndex;
186 } 252 }
187 253
188 if (SkDraw::ShouldDrawTextAsPaths(skPaint, viewMatrix)) { 254 if (SkDraw::ShouldDrawTextAsPaths(runPaint, viewMatrix)) {
189 cacheBlob->fRuns[run].fDrawAsPaths = true; 255 cacheBlob->fRuns[run].fDrawAsPaths = true;
190 continue; 256 continue;
191 } 257 }
192 cacheBlob->fRuns[run].fDrawAsPaths = false; 258 cacheBlob->fRuns[run].fDrawAsPaths = false;
193 259
194 switch (it.positioning()) { 260 switch (it.positioning()) {
195 case SkTextBlob::kDefault_Positioning: 261 case SkTextBlob::kDefault_Positioning:
196 this->internalDrawText(cacheBlob, run, cache, runPaint, viewMatr ix, 262 this->internalDrawText(cacheBlob, run, cache, runPaint, viewMatr ix,
197 (const char *)it.glyphs(), textLen, 263 (const char *)it.glyphs(), textLen,
198 x + offset.x(), y + offset.y(), clipRect) ; 264 x + offset.x(), y + offset.y(), clipRect) ;
(...skipping 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
529 return; 595 return;
530 } 596 }
531 597
532 int x = vx + glyph->fBounds.fLeft; 598 int x = vx + glyph->fBounds.fLeft;
533 int y = vy + glyph->fBounds.fTop; 599 int y = vy + glyph->fBounds.fTop;
534 600
535 // keep them as ints until we've done the clip-test 601 // keep them as ints until we've done the clip-test
536 int width = glyph->fBounds.width(); 602 int width = glyph->fBounds.width();
537 int height = glyph->fBounds.height(); 603 int height = glyph->fBounds.height();
538 604
539 // check if we clipped out
540 if (clipRect.quickReject(x, y, x + width, y + height)) {
541 return;
542 }
543
544 // If the glyph is too large we fall back to paths 605 // If the glyph is too large we fall back to paths
545 if (fCurrStrike->glyphTooLargeForAtlas(glyph)) { 606 if (fCurrStrike->glyphTooLargeForAtlas(glyph)) {
546 if (NULL == glyph->fPath) { 607 if (NULL == glyph->fPath) {
547 SkPath* path = SkNEW(SkPath); 608 SkPath* path = SkNEW(SkPath);
548 if (!scaler->getGlyphPath(glyph->glyphID(), path)) { 609 if (!scaler->getGlyphPath(glyph->glyphID(), path)) {
549 // flag the glyph as being dead? 610 // flag the glyph as being dead?
550 SkDELETE(path); 611 SkDELETE(path);
551 return; 612 return;
552 } 613 }
553 glyph->fPath = path; 614 glyph->fPath = path;
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
591 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices + subRun->fVert exEndIndex); 652 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVertices + subRun->fVert exEndIndex);
592 653
593 // V0 654 // V0
594 SkPoint* position = reinterpret_cast<SkPoint*>(vertex); 655 SkPoint* position = reinterpret_cast<SkPoint*>(vertex);
595 position->set(r.fLeft, r.fTop); 656 position->set(r.fLeft, r.fTop);
596 if (kA8_GrMaskFormat == format) { 657 if (kA8_GrMaskFormat == format) {
597 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)) ; 658 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)) ;
598 *colorPtr = color; 659 *colorPtr = color;
599 } 660 }
600 vertex += vertexStride; 661 vertex += vertexStride;
601
602 // V1 662 // V1
603 position = reinterpret_cast<SkPoint*>(vertex); 663 position = reinterpret_cast<SkPoint*>(vertex);
604 position->set(r.fLeft, r.fBottom); 664 position->set(r.fLeft, r.fBottom);
605 if (kA8_GrMaskFormat == format) { 665 if (kA8_GrMaskFormat == format) {
606 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)) ; 666 SkColor* colorPtr = reinterpret_cast<SkColor*>(vertex + sizeof(SkPoint)) ;
607 *colorPtr = color; 667 *colorPtr = color;
608 } 668 }
609 vertex += vertexStride; 669 vertex += vertexStride;
610 670
611 // V2 671 // V2
(...skipping 21 matching lines...) Expand all
633 public: 693 public:
634 typedef GrAtlasTextContext::BitmapTextBlob Blob; 694 typedef GrAtlasTextContext::BitmapTextBlob Blob;
635 typedef Blob::Run Run; 695 typedef Blob::Run Run;
636 typedef Run::SubRunInfo TextInfo; 696 typedef Run::SubRunInfo TextInfo;
637 struct Geometry { 697 struct Geometry {
638 Geometry() {} 698 Geometry() {}
639 Geometry(const Geometry& geometry) 699 Geometry(const Geometry& geometry)
640 : fBlob(SkRef(geometry.fBlob.get())) 700 : fBlob(SkRef(geometry.fBlob.get()))
641 , fRun(geometry.fRun) 701 , fRun(geometry.fRun)
642 , fSubRun(geometry.fSubRun) 702 , fSubRun(geometry.fSubRun)
643 , fColor(geometry.fColor) {} 703 , fColor(geometry.fColor)
704 , fTransX(geometry.fTransX)
705 , fTransY(geometry.fTransY) {}
644 SkAutoTUnref<Blob> fBlob; 706 SkAutoTUnref<Blob> fBlob;
645 int fRun; 707 int fRun;
646 int fSubRun; 708 int fSubRun;
647 GrColor fColor; 709 GrColor fColor;
710 SkScalar fTransX;
711 SkScalar fTransY;
648 }; 712 };
649 713
650 static GrBatch* Create(const Geometry& geometry, GrMaskFormat maskFormat, 714 static GrBatch* Create(const Geometry& geometry, GrMaskFormat maskFormat,
651 int glyphCount, GrBatchFontCache* fontCache) { 715 int glyphCount, GrBatchFontCache* fontCache) {
652 return SkNEW_ARGS(BitmapTextBatch, (geometry, maskFormat, glyphCount, fo ntCache)); 716 return SkNEW_ARGS(BitmapTextBatch, (geometry, maskFormat, glyphCount, fo ntCache));
653 } 717 }
654 718
655 const char* name() const override { return "BitmapTextBatch"; } 719 const char* name() const override { return "BitmapTextBatch"; }
656 720
657 void getInvariantOutputColor(GrInitInvariantOutput* out) const override { 721 void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
751 int instancesToFlush = 0; 815 int instancesToFlush = 0;
752 for (int i = 0; i < instanceCount; i++) { 816 for (int i = 0; i < instanceCount; i++) {
753 Geometry& args = fGeoData[i]; 817 Geometry& args = fGeoData[i];
754 Blob* blob = args.fBlob; 818 Blob* blob = args.fBlob;
755 Run& run = blob->fRuns[args.fRun]; 819 Run& run = blob->fRuns[args.fRun];
756 TextInfo& info = run.fSubRunInfo[args.fSubRun]; 820 TextInfo& info = run.fSubRunInfo[args.fSubRun];
757 821
758 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat); 822 uint64_t currentAtlasGen = fFontCache->atlasGeneration(fMaskFormat);
759 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas Gen; 823 bool regenerateTextureCoords = info.fAtlasGeneration != currentAtlas Gen;
760 bool regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColo r != args.fColor; 824 bool regenerateColors = kA8_GrMaskFormat == fMaskFormat && run.fColo r != args.fColor;
825 bool regeneratePositions = args.fTransX != 0.f || args.fTransY != 0. f;
761 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; 826 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex;
762 827
763 // We regenerate both texture coords and colors in the blob itself, and update the 828 // We regenerate both texture coords and colors in the blob itself, and update the
764 // atlas generation. If we don't end up purging any unused plots, w e can avoid 829 // atlas generation. If we don't end up purging any unused plots, w e can avoid
765 // regenerating the coords. We could take a finer grained approach to updating texture 830 // regenerating the coords. We could take a finer grained approach to updating texture
766 // coords but its not clear if the extra bookkeeping would offset an y gains. 831 // coords but its not clear if the extra bookkeeping would offset an y gains.
767 // To avoid looping over the glyphs twice, we do one loop and condit ionally update color 832 // To avoid looping over the glyphs twice, we do one loop and condit ionally update color
768 // or coords as needed. One final note, if we have to break a run f or an atlas eviction 833 // or coords as needed. One final note, if we have to break a run f or an atlas eviction
769 // then we can't really trust the atlas has all of the correct data. Atlas evictions 834 // then we can't really trust the atlas has all of the correct data. Atlas evictions
770 // should be pretty rare, so we just always regenerate in those case s 835 // should be pretty rare, so we just always regenerate in those case s
771 if (regenerateTextureCoords || regenerateColors) { 836 if (regenerateTextureCoords || regenerateColors || regeneratePositio ns) {
772 // first regenerate texture coordinates / colors if need be 837 // first regenerate texture coordinates / colors if need be
773 const SkDescriptor* desc = NULL; 838 const SkDescriptor* desc = NULL;
774 SkGlyphCache* cache = NULL; 839 SkGlyphCache* cache = NULL;
775 GrFontScaler* scaler = NULL; 840 GrFontScaler* scaler = NULL;
776 GrBatchTextStrike* strike = NULL; 841 GrBatchTextStrike* strike = NULL;
777 bool brokenRun = false; 842 bool brokenRun = false;
778 if (regenerateTextureCoords) { 843 if (regenerateTextureCoords) {
779 info.fBulkUseToken.reset(); 844 info.fBulkUseToken.reset();
780 desc = run.fDescriptor.getDesc(); 845 desc = run.fDescriptor.getDesc();
781 cache = SkGlyphCache::DetachCache(run.fTypeface, desc); 846 cache = SkGlyphCache::DetachCache(run.fTypeface, desc);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
815 this->regenerateTextureCoords(glyph, vertex, vertexStrid e); 880 this->regenerateTextureCoords(glyph, vertex, vertexStrid e);
816 } 881 }
817 882
818 if (regenerateColors) { 883 if (regenerateColors) {
819 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert ices); 884 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert ices);
820 vertex += info.fVertexStartIndex; 885 vertex += info.fVertexStartIndex;
821 vertex += vertexStride * glyphIdx * kVerticesPerGlyph + sizeof(SkPoint); 886 vertex += vertexStride * glyphIdx * kVerticesPerGlyph + sizeof(SkPoint);
822 this->regenerateColors(vertex, vertexStride, args.fColor ); 887 this->regenerateColors(vertex, vertexStride, args.fColor );
823 } 888 }
824 889
890 if (regeneratePositions) {
891 intptr_t vertex = reinterpret_cast<intptr_t>(blob->fVert ices);
892 vertex += info.fVertexStartIndex;
893 vertex += vertexStride * glyphIdx * kVerticesPerGlyph;
894 SkScalar transX = args.fTransX;
895 SkScalar transY = args.fTransY;
896 this->regeneratePositions(vertex, vertexStride, transX, transY);
897 }
825 instancesToFlush++; 898 instancesToFlush++;
826 } 899 }
827 900
901 // We my have changed the color so update it here
902 run.fColor = args.fColor;
828 if (regenerateTextureCoords) { 903 if (regenerateTextureCoords) {
829 SkGlyphCache::AttachCache(cache); 904 SkGlyphCache::AttachCache(cache);
830 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt lasGeneration : 905 info.fAtlasGeneration = brokenRun ? GrBatchAtlas::kInvalidAt lasGeneration :
831 fFontCache->atlasGenerat ion(fMaskFormat); 906 fFontCache->atlasGenerat ion(fMaskFormat);
832 } 907 }
833 } else { 908 } else {
834 instancesToFlush += glyphCount; 909 instancesToFlush += glyphCount;
835 910
836 // set use tokens for all of the glyphs in our subrun. This is only valid if we 911 // set use tokens for all of the glyphs in our subrun. This is only valid if we
837 // have a valid atlas generation 912 // have a valid atlas generation
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
897 } 972 }
898 973
899 void regenerateColors(intptr_t vertex, size_t vertexStride, GrColor color) { 974 void regenerateColors(intptr_t vertex, size_t vertexStride, GrColor color) {
900 for (int i = 0; i < kVerticesPerGlyph; i++) { 975 for (int i = 0; i < kVerticesPerGlyph; i++) {
901 SkColor* vcolor = reinterpret_cast<SkColor*>(vertex); 976 SkColor* vcolor = reinterpret_cast<SkColor*>(vertex);
902 *vcolor = color; 977 *vcolor = color;
903 vertex += vertexStride; 978 vertex += vertexStride;
904 } 979 }
905 } 980 }
906 981
982 void regeneratePositions(intptr_t vertex, size_t vertexStride, SkScalar tran sX,
983 SkScalar transY) {
984 for (int i = 0; i < kVerticesPerGlyph; i++) {
985 SkPoint* point = reinterpret_cast<SkPoint*>(vertex);
986 point->fX += transX;
987 point->fY += transY;
988 vertex += vertexStride;
989 }
990 }
991
907 void initDraw(GrBatchTarget* batchTarget, 992 void initDraw(GrBatchTarget* batchTarget,
908 const GrGeometryProcessor* gp, 993 const GrGeometryProcessor* gp,
909 const GrPipeline* pipeline) { 994 const GrPipeline* pipeline) {
910 batchTarget->initDraw(gp, pipeline); 995 batchTarget->initDraw(gp, pipeline);
911 996
912 // TODO remove this when batch is everywhere 997 // TODO remove this when batch is everywhere
913 GrPipelineInfo init; 998 GrPipelineInfo init;
914 init.fColorIgnored = fBatch.fColorIgnored; 999 init.fColorIgnored = fBatch.fColorIgnored;
915 init.fOverrideColor = GrColor_ILLEGAL; 1000 init.fOverrideColor = GrColor_ILLEGAL;
916 init.fCoverageIgnored = fBatch.fCoverageIgnored; 1001 init.fCoverageIgnored = fBatch.fCoverageIgnored;
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1003 break; 1088 break;
1004 case SkTextBlob::kFull_Positioning: 1089 case SkTextBlob::kFull_Positioning:
1005 this->drawPosTextAsPath(runPaint, viewMatrix, (const char*)it.glyphs (), 1090 this->drawPosTextAsPath(runPaint, viewMatrix, (const char*)it.glyphs (),
1006 textLen, it.pos(), 2, SkPoint::Make(x, y), c lipBounds); 1091 textLen, it.pos(), 2, SkPoint::Make(x, y), c lipBounds);
1007 break; 1092 break;
1008 } 1093 }
1009 } 1094 }
1010 1095
1011 inline void GrAtlasTextContext::flushRun(GrDrawTarget* target, GrPipelineBuilder * pipelineBuilder, 1096 inline void GrAtlasTextContext::flushRun(GrDrawTarget* target, GrPipelineBuilder * pipelineBuilder,
1012 BitmapTextBlob* cacheBlob, int run, GrC olor color, 1097 BitmapTextBlob* cacheBlob, int run, GrC olor color,
1013 uint8_t paintAlpha) { 1098 uint8_t paintAlpha, SkScalar transX, Sk Scalar transY) {
1014 for (int subRun = 0; subRun < cacheBlob->fRuns[run].fSubRunInfo.count(); sub Run++) { 1099 for (int subRun = 0; subRun < cacheBlob->fRuns[run].fSubRunInfo.count(); sub Run++) {
1015 const PerSubRunInfo& info = cacheBlob->fRuns[run].fSubRunInfo[subRun]; 1100 const PerSubRunInfo& info = cacheBlob->fRuns[run].fSubRunInfo[subRun];
1016 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex; 1101 int glyphCount = info.fGlyphEndIndex - info.fGlyphStartIndex;
1017 if (0 == glyphCount) { 1102 if (0 == glyphCount) {
1018 continue; 1103 continue;
1019 } 1104 }
1020 1105
1021 GrMaskFormat format = info.fMaskFormat; 1106 GrMaskFormat format = info.fMaskFormat;
1022 GrColor subRunColor = kARGB_GrMaskFormat == format ? 1107 GrColor subRunColor = kARGB_GrMaskFormat == format ?
1023 SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAlpha) : 1108 SkColorSetARGB(paintAlpha, paintAlpha, paintAlpha, paintAlpha) :
1024 color; 1109 color;
1025 1110
1026 BitmapTextBatch::Geometry geometry; 1111 BitmapTextBatch::Geometry geometry;
1027 geometry.fBlob.reset(SkRef(cacheBlob)); 1112 geometry.fBlob.reset(SkRef(cacheBlob));
1028 geometry.fRun = run; 1113 geometry.fRun = run;
1029 geometry.fSubRun = subRun; 1114 geometry.fSubRun = subRun;
1030 geometry.fColor = subRunColor; 1115 geometry.fColor = subRunColor;
1116 geometry.fTransX = transX;
1117 geometry.fTransY = transY;
1031 SkAutoTUnref<GrBatch> batch(BitmapTextBatch::Create(geometry, format, gl yphCount, 1118 SkAutoTUnref<GrBatch> batch(BitmapTextBatch::Create(geometry, format, gl yphCount,
1032 fContext->getBatchFo ntCache())); 1119 fContext->getBatchFo ntCache()));
1033 1120
1034 target->drawBatch(pipelineBuilder, batch, &cacheBlob->fRuns[run].fVertex Bounds); 1121 target->drawBatch(pipelineBuilder, batch, &cacheBlob->fRuns[run].fVertex Bounds);
1035 } 1122 }
1036 } 1123 }
1037 1124
1038 inline void GrAtlasTextContext::flushBigGlyphs(BitmapTextBlob* cacheBlob, GrRend erTarget* rt, 1125 inline void GrAtlasTextContext::flushBigGlyphs(BitmapTextBlob* cacheBlob, GrRend erTarget* rt,
1039 const GrPaint& grPaint, const GrC lip& clip) { 1126 const GrPaint& grPaint, const GrC lip& clip,
1127 SkScalar transX, SkScalar transY) {
1040 for (int i = 0; i < cacheBlob->fBigGlyphs.count(); i++) { 1128 for (int i = 0; i < cacheBlob->fBigGlyphs.count(); i++) {
1041 const BitmapTextBlob::BigGlyph& bigGlyph = cacheBlob->fBigGlyphs[i]; 1129 BitmapTextBlob::BigGlyph& bigGlyph = cacheBlob->fBigGlyphs[i];
1130 bigGlyph.fVx += transX;
1131 bigGlyph.fVy += transY;
1042 SkMatrix translate; 1132 SkMatrix translate;
1043 translate.setTranslate(SkIntToScalar(bigGlyph.fVx), SkIntToScalar(bigGly ph.fVy)); 1133 translate.setTranslate(SkIntToScalar(bigGlyph.fVx),
1134 SkIntToScalar(bigGlyph.fVy));
1044 SkPath tmpPath(bigGlyph.fPath); 1135 SkPath tmpPath(bigGlyph.fPath);
1045 tmpPath.transform(translate); 1136 tmpPath.transform(translate);
1046 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle); 1137 GrStrokeInfo strokeInfo(SkStrokeRec::kFill_InitStyle);
1047 fContext->drawPath(rt, clip, grPaint, SkMatrix::I(), tmpPath, strokeInfo ); 1138 fContext->drawPath(rt, clip, grPaint, SkMatrix::I(), tmpPath, strokeInfo );
1048 } 1139 }
1049 } 1140 }
1050 1141
1051 void GrAtlasTextContext::flush(GrDrawTarget* target, 1142 void GrAtlasTextContext::flush(GrDrawTarget* target,
1052 const SkTextBlob* blob, 1143 const SkTextBlob* blob,
1053 BitmapTextBlob* cacheBlob, 1144 BitmapTextBlob* cacheBlob,
1054 GrRenderTarget* rt, 1145 GrRenderTarget* rt,
1055 const SkPaint& skPaint, 1146 const SkPaint& skPaint,
1056 const GrPaint& grPaint, 1147 const GrPaint& grPaint,
1057 SkDrawFilter* drawFilter, 1148 SkDrawFilter* drawFilter,
1058 const GrClip& clip, 1149 const GrClip& clip,
1059 const SkMatrix& viewMatrix, 1150 const SkMatrix& viewMatrix,
1060 const SkIRect& clipBounds, 1151 const SkIRect& clipBounds,
1061 SkScalar x, 1152 SkScalar x, SkScalar y,
1062 SkScalar y) { 1153 SkScalar transX, SkScalar transY) {
1063 // We loop through the runs of the blob, flushing each. If any run is too l arge, then we flush 1154 // We loop through the runs of the blob, flushing each. If any run is too l arge, then we flush
1064 // it as paths 1155 // it as paths
1065 GrPipelineBuilder pipelineBuilder; 1156 GrPipelineBuilder pipelineBuilder;
1066 pipelineBuilder.setFromPaint(grPaint, rt, clip); 1157 pipelineBuilder.setFromPaint(grPaint, rt, clip);
1067 1158
1068 GrColor color = grPaint.getColor(); 1159 GrColor color = grPaint.getColor();
1069 uint8_t paintAlpha = skPaint.getAlpha(); 1160 uint8_t paintAlpha = skPaint.getAlpha();
1070 1161
1071 SkTextBlob::RunIterator it(blob); 1162 SkTextBlob::RunIterator it(blob);
1072 for (int run = 0; !it.done(); it.next(), run++) { 1163 for (int run = 0; !it.done(); it.next(), run++) {
1073 if (cacheBlob->fRuns[run].fDrawAsPaths) { 1164 if (cacheBlob->fRuns[run].fDrawAsPaths) {
1074 this->flushRunAsPaths(it, skPaint, drawFilter, viewMatrix, clipBound s, x, y); 1165 this->flushRunAsPaths(it, skPaint, drawFilter, viewMatrix, clipBound s, x, y);
1075 continue; 1166 continue;
1076 } 1167 }
1077 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, paintAlp ha); 1168 cacheBlob->fRuns[run].fVertexBounds.offset(transX, transY);
1169 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, paintAlp ha, transX, transY);
1078 } 1170 }
1079 1171
1080 // Now flush big glyphs 1172 // Now flush big glyphs
1081 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip); 1173 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, transX, transY);
1082 } 1174 }
1083 1175
1084 void GrAtlasTextContext::flush(GrDrawTarget* target, 1176 void GrAtlasTextContext::flush(GrDrawTarget* target,
1085 BitmapTextBlob* cacheBlob, 1177 BitmapTextBlob* cacheBlob,
1086 GrRenderTarget* rt, 1178 GrRenderTarget* rt,
1087 const SkPaint& skPaint, 1179 const SkPaint& skPaint,
1088 const GrPaint& grPaint, 1180 const GrPaint& grPaint,
1089 const GrClip& clip, 1181 const GrClip& clip,
1090 const SkMatrix& viewMatrix) { 1182 const SkMatrix& viewMatrix) {
1091 GrPipelineBuilder pipelineBuilder; 1183 GrPipelineBuilder pipelineBuilder;
1092 pipelineBuilder.setFromPaint(grPaint, rt, clip); 1184 pipelineBuilder.setFromPaint(grPaint, rt, clip);
1093 1185
1094 GrColor color = grPaint.getColor(); 1186 GrColor color = grPaint.getColor();
1095 uint8_t paintAlpha = skPaint.getAlpha(); 1187 uint8_t paintAlpha = skPaint.getAlpha();
1096 for (int run = 0; run < cacheBlob->fRunCount; run++) { 1188 for (int run = 0; run < cacheBlob->fRunCount; run++) {
1097 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, paintAlp ha); 1189 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, paintAlp ha, 0, 0);
1098 } 1190 }
1099 1191
1100 // Now flush big glyphs 1192 // Now flush big glyphs
1101 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip); 1193 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0);
1102 } 1194 }
OLDNEW
« no previous file with comments | « src/gpu/GrAtlasTextContext.h ('k') | src/gpu/GrTextBlobCache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698