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

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

Issue 1065293003: Start caching masks / stroke fills for textblobs (Closed) Base URL: https://skia.googlesource.com/skia.git@textblobloopergm
Patch Set: tweak 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
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 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 case kARGB_GrMaskFormat: 53 case kARGB_GrMaskFormat:
54 return kColorTextVASize; 54 return kColorTextVASize;
55 default: 55 default:
56 return kLCDTextVASize; 56 return kLCDTextVASize;
57 } 57 }
58 } 58 }
59 59
60 }; 60 };
61 61
62 // TODO 62 // TODO
63 // More tests 63 // Gamma slotting to preserve color
64 // move to SkCache 64 // Better reuse on regeneration
65 // handle textblobs where the whole run is larger than the cache size 65 // Telemetry tests
66 // TODO implement micro speedy hash map for fast refing of glyphs
67 66
68 GrAtlasTextContext::GrAtlasTextContext(GrContext* context, 67 GrAtlasTextContext::GrAtlasTextContext(GrContext* context,
69 SkGpuDevice* gpuDevice, 68 SkGpuDevice* gpuDevice,
70 const SkDeviceProperties& properties) 69 const SkDeviceProperties& properties)
71 : INHERITED(context, gpuDevice, properties) { 70 : INHERITED(context, gpuDevice, properties) {
72 // We overallocate vertices in our textblobs based on the assumption that A8 has the greatest 71 // We overallocate vertices in our textblobs based on the assumption that A8 has the greatest
73 // vertexStride 72 // vertexStride
74 SK_COMPILE_ASSERT(kGrayTextVASize >= kColorTextVASize && kGrayTextVASize >= kLCDTextVASize, 73 SK_COMPILE_ASSERT(kGrayTextVASize >= kColorTextVASize && kGrayTextVASize >= kLCDTextVASize,
75 vertex_attribute_changed); 74 vertex_attribute_changed);
76 fCurrStrike = NULL; 75 fCurrStrike = NULL;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
150 const SkMatrix& viewMatrix) { 149 const SkMatrix& viewMatrix) {
151 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, &v iewMatrix, false); 150 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, &v iewMatrix, false);
152 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); 151 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface()));
153 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc()) ; 152 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc()) ;
154 } 153 }
155 154
156 void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, 155 void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip,
157 const SkPaint& skPaint, const SkMatrix& vi ewMatrix, 156 const SkPaint& skPaint, const SkMatrix& vi ewMatrix,
158 const SkTextBlob* blob, SkScalar x, SkScal ar y, 157 const SkTextBlob* blob, SkScalar x, SkScal ar y,
159 SkDrawFilter* drawFilter, const SkIRect& c lipBounds) { 158 SkDrawFilter* drawFilter, const SkIRect& c lipBounds) {
160 uint32_t uniqueID = blob->uniqueID();
161 SkAutoTUnref<BitmapTextBlob> cacheBlob; 159 SkAutoTUnref<BitmapTextBlob> cacheBlob;
162 // TODO start caching these, mix bits into the key 160
161 BitmapTextBlob::Key key;
162 // It might be worth caching these things, but its not clear at this time
163 // TODO for animated mask filters, this will fill up our cache. We need a s afeguard here
164 const SkMaskFilter* mf = skPaint.getMaskFilter();
163 bool mustNotCache = skPaint.getPathEffect() || 165 bool mustNotCache = skPaint.getPathEffect() ||
164 skPaint.getMaskFilter() || 166 (mf && !mf->asABlur(&key.fBlurRec)) ||
165 skPaint.getColorFilter() ||
166 skPaint.getStyle() != SkPaint::kFill_Style ||
167 drawFilter; 167 drawFilter;
168 168
169 if (!mustNotCache) { 169 if (!mustNotCache) {
170 cacheBlob.reset(SkSafeRef(fCache->find(uniqueID))); 170 key.fUniqueID = blob->uniqueID();
171 key.fStyle = skPaint.getStyle();
172 if (key.fStyle != SkPaint::kFill_Style) {
173 key.fStrokeInfo.fFrameWidth = skPaint.getStrokeWidth();
174 key.fStrokeInfo.fMiterLimit = skPaint.getStrokeMiter();
175 key.fStrokeInfo.fStrokeJoin = SkToU8(skPaint.getStrokeJoin());
176 }
177 cacheBlob.reset(SkSafeRef(fCache->find(key)));
171 } 178 }
172 179
173 SkIRect clipRect; 180 SkIRect clipRect;
174 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); 181 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect);
175 182
176 SkScalar transX = 0.f; 183 SkScalar transX = 0.f;
177 SkScalar transY = 0.f; 184 SkScalar transY = 0.f;
178 185
179 if (cacheBlob) { 186 if (cacheBlob) {
180 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, viewMatrix , x, y)) { 187 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, viewMatrix , x, y)) {
181 // We have to remake the blob because changes may invalidate our mas ks. 188 // We have to remake the blob because changes may invalidate our mas ks.
182 // TODO we could probably get away reuse most of the time if the poi nter is unique, 189 // TODO we could probably get away reuse most of the time if the poi nter is unique,
183 // but we'd have to clear the subrun information 190 // but we'd have to clear the subrun information
184 fCache->remove(cacheBlob); 191 fCache->remove(cacheBlob);
185 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, kGrayTextVASize ))); 192 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, kGrayTextV ASize)));
186 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter, 193 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, drawFilter,
187 clipRect); 194 clipRect);
188 } else { 195 } else {
189 // If we can reuse the blob, then make sure we update the blob's vie wmatrix and x/y 196 // If we can reuse the blob, then make sure we update the blob's vie wmatrix and x/y
190 // offsets to reflect the results of any translations we may apply i n generateGeometry 197 // offsets to reflect the results of any translations we may apply i n generateGeometry
191 cacheBlob->fViewMatrix = viewMatrix; 198 cacheBlob->fViewMatrix = viewMatrix;
192 cacheBlob->fX = x; 199 cacheBlob->fX = x;
193 cacheBlob->fY = y; 200 cacheBlob->fY = y;
194 fCache->makeMRU(cacheBlob); 201 fCache->makeMRU(cacheBlob);
195 } 202 }
196 } else { 203 } else {
197 if (mustNotCache) { 204 if (mustNotCache) {
198 cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize)); 205 cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize));
199 } else { 206 } else {
200 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, kGrayTextVASize ))); 207 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, kGrayTextV ASize)));
201 } 208 }
202 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra wFilter, clipRect); 209 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra wFilter, clipRect);
203 } 210 }
204 211
205 // Though for the time being runs in the textblob can override the paint, th ey only touch font 212 // Though for the time being runs in the textblob can override the paint, th ey only touch font
206 // info. 213 // info.
207 GrPaint grPaint; 214 GrPaint grPaint;
208 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint); 215 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint);
209 216
210 this->flush(fContext->getTextTarget(), blob, cacheBlob, rt, skPaint, grPaint , drawFilter, 217 this->flush(fContext->getTextTarget(), blob, cacheBlob, rt, skPaint, grPaint , drawFilter,
211 clip, viewMatrix, clipBounds, x, y, transX, transY); 218 clip, viewMatrix, clipBounds, x, y, transX, transY);
212 } 219 }
213 220
214 void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob, 221 void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob,
215 const SkPaint& skPaint, const SkMatr ix& viewMatrix, 222 const SkPaint& skPaint, const SkMatr ix& viewMatrix,
216 const SkTextBlob* blob, SkScalar x, SkScalar y, 223 const SkTextBlob* blob, SkScalar x, SkScalar y,
217 SkDrawFilter* drawFilter, const SkIR ect& clipRect) { 224 SkDrawFilter* drawFilter, const SkIR ect& clipRect) {
218 cacheBlob->fViewMatrix = viewMatrix; 225 cacheBlob->fViewMatrix = viewMatrix;
219 cacheBlob->fX = x; 226 cacheBlob->fX = x;
220 cacheBlob->fY = y; 227 cacheBlob->fY = y;
221 cacheBlob->fColor = skPaint.getColor(); 228 cacheBlob->fColor = skPaint.getColor();
222 cacheBlob->fStyle = skPaint.getStyle();
223 229
224 // Regenerate textblob 230 // Regenerate textblob
225 SkPaint runPaint = skPaint; 231 SkPaint runPaint = skPaint;
226 SkTextBlob::RunIterator it(blob); 232 SkTextBlob::RunIterator it(blob);
227 for (int run = 0; !it.done(); it.next(), run++) { 233 for (int run = 0; !it.done(); it.next(), run++) {
228 int glyphCount = it.glyphCount(); 234 int glyphCount = it.glyphCount();
229 size_t textLen = glyphCount * sizeof(uint16_t); 235 size_t textLen = glyphCount * sizeof(uint16_t);
230 const SkPoint& offset = it.offset(); 236 const SkPoint& offset = it.offset();
231 // applyFontToPaint() always overwrites the exact same attributes, 237 // applyFontToPaint() always overwrites the exact same attributes,
232 // so it is safe to not re-seed the paint for this reason. 238 // so it is safe to not re-seed the paint for this reason.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip, 296 void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip,
291 const GrPaint& paint, const SkPaint& skPaint , 297 const GrPaint& paint, const SkPaint& skPaint ,
292 const SkMatrix& viewMatrix, 298 const SkMatrix& viewMatrix,
293 const char text[], size_t byteLength, 299 const char text[], size_t byteLength,
294 SkScalar x, SkScalar y, const SkIRect& regio nClipBounds) { 300 SkScalar x, SkScalar y, const SkIRect& regio nClipBounds) {
295 int glyphCount = skPaint.countText(text, byteLength); 301 int glyphCount = skPaint.countText(text, byteLength);
296 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTex tVASize)); 302 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTex tVASize));
297 blob->fViewMatrix = viewMatrix; 303 blob->fViewMatrix = viewMatrix;
298 blob->fX = x; 304 blob->fX = x;
299 blob->fY = y; 305 blob->fY = y;
300 blob->fStyle = skPaint.getStyle();
301 306
302 SkIRect clipRect; 307 SkIRect clipRect;
303 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); 308 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect);
304 309
305 // setup cache 310 // setup cache
306 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix) ; 311 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix) ;
307 this->internalDrawText(blob, 0, cache, skPaint, viewMatrix, text, byteLength , x, y, clipRect); 312 this->internalDrawText(blob, 0, cache, skPaint, viewMatrix, text, byteLength , x, y, clipRect);
308 SkGlyphCache::AttachCache(cache); 313 SkGlyphCache::AttachCache(cache);
309 314
310 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip, viewM atrix); 315 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip, viewM atrix);
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 } 406 }
402 407
403 void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, 408 void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip,
404 const GrPaint& paint, const SkPaint& skPa int, 409 const GrPaint& paint, const SkPaint& skPa int,
405 const SkMatrix& viewMatrix, 410 const SkMatrix& viewMatrix,
406 const char text[], size_t byteLength, 411 const char text[], size_t byteLength,
407 const SkScalar pos[], int scalarsPerPosit ion, 412 const SkScalar pos[], int scalarsPerPosit ion,
408 const SkPoint& offset, const SkIRect& reg ionClipBounds) { 413 const SkPoint& offset, const SkIRect& reg ionClipBounds) {
409 int glyphCount = skPaint.countText(text, byteLength); 414 int glyphCount = skPaint.countText(text, byteLength);
410 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTex tVASize)); 415 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTex tVASize));
411 blob->fStyle = skPaint.getStyle();
412 blob->fViewMatrix = viewMatrix; 416 blob->fViewMatrix = viewMatrix;
413 417
414 SkIRect clipRect; 418 SkIRect clipRect;
415 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); 419 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect);
416 420
417 // setup cache 421 // setup cache
418 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix) ; 422 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix) ;
419 this->internalDrawPosText(blob, 0, cache, skPaint, viewMatrix, text, byteLen gth, pos, 423 this->internalDrawPosText(blob, 0, cache, skPaint, viewMatrix, text, byteLen gth, pos,
420 scalarsPerPosition, offset, clipRect); 424 scalarsPerPosition, offset, clipRect);
421 SkGlyphCache::AttachCache(cache); 425 SkGlyphCache::AttachCache(cache);
(...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after
1188 1192
1189 GrColor color = grPaint.getColor(); 1193 GrColor color = grPaint.getColor();
1190 uint8_t paintAlpha = skPaint.getAlpha(); 1194 uint8_t paintAlpha = skPaint.getAlpha();
1191 for (int run = 0; run < cacheBlob->fRunCount; run++) { 1195 for (int run = 0; run < cacheBlob->fRunCount; run++) {
1192 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, paintAlp ha, 0, 0); 1196 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, paintAlp ha, 0, 0);
1193 } 1197 }
1194 1198
1195 // Now flush big glyphs 1199 // Now flush big glyphs
1196 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0); 1200 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0);
1197 } 1201 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698