| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 #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 Loading... |
| 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 | 66 // possibly consider having a regeneration ratio on the textblob itself for anim
ated textblobs |
| 67 | 67 |
| 68 GrAtlasTextContext::GrAtlasTextContext(GrContext* context, | 68 GrAtlasTextContext::GrAtlasTextContext(GrContext* context, |
| 69 SkGpuDevice* gpuDevice, | 69 SkGpuDevice* gpuDevice, |
| 70 const SkDeviceProperties& properties) | 70 const SkDeviceProperties& properties) |
| 71 : INHERITED(context, gpuDevice, properties) { | 71 : INHERITED(context, gpuDevice, properties) { |
| 72 // We overallocate vertices in our textblobs based on the assumption that A8
has the greatest | 72 // We overallocate vertices in our textblobs based on the assumption that A8
has the greatest |
| 73 // vertexStride | 73 // vertexStride |
| 74 SK_COMPILE_ASSERT(kGrayTextVASize >= kColorTextVASize && kGrayTextVASize >=
kLCDTextVASize, | 74 SK_COMPILE_ASSERT(kGrayTextVASize >= kColorTextVASize && kGrayTextVASize >=
kLCDTextVASize, |
| 75 vertex_attribute_changed); | 75 vertex_attribute_changed); |
| 76 fCurrStrike = NULL; | 76 fCurrStrike = NULL; |
| 77 fCache = context->getTextBlobCache(); | 77 fCache = context->getTextBlobCache(); |
| 78 } | 78 } |
| 79 | 79 |
| 80 GrAtlasTextContext* GrAtlasTextContext::Create(GrContext* context, | 80 GrAtlasTextContext* GrAtlasTextContext::Create(GrContext* context, |
| 81 SkGpuDevice* gpuDevice, | 81 SkGpuDevice* gpuDevice, |
| 82 const SkDeviceProperties& props)
{ | 82 const SkDeviceProperties& props)
{ |
| 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 |
| 94 bool GrAtlasTextContext::MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTr
ansY, | 94 bool GrAtlasTextContext::MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTr
ansY, |
| 95 const BitmapTextBlob& blob, const Sk
Paint& paint, | 95 const BitmapTextBlob& blob, const Sk
Paint& paint, |
| 96 const SkMaskFilter::BlurRec& blurRec
, |
| 96 const SkMatrix& viewMatrix, SkScalar
x, SkScalar y) { | 97 const SkMatrix& viewMatrix, SkScalar
x, SkScalar y) { |
| 97 // Color can affect the mask | 98 // Color can affect the mask |
| 98 // TODO we can adjust the color within specific gamma slots | 99 // TODO we can adjust the color within specific gamma slots |
| 99 if (blob.fColor != paint.getColor()) { | 100 if (blob.fColor != paint.getColor()) { |
| 100 return true; | 101 return true; |
| 101 } | 102 } |
| 102 | 103 |
| 103 if (blob.fViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) { | 104 if (blob.fViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) { |
| 104 return true; | 105 return true; |
| 105 } | 106 } |
| 106 | 107 |
| 107 if (blob.fViewMatrix.hasPerspective() && !blob.fViewMatrix.cheapEqualTo(view
Matrix)) { | 108 if (blob.fViewMatrix.hasPerspective() && !blob.fViewMatrix.cheapEqualTo(view
Matrix)) { |
| 108 return true; | 109 return true; |
| 109 } | 110 } |
| 110 | 111 |
| 111 if (blob.fViewMatrix.getScaleX() != viewMatrix.getScaleX() || | 112 if (blob.fViewMatrix.getScaleX() != viewMatrix.getScaleX() || |
| 112 blob.fViewMatrix.getScaleY() != viewMatrix.getScaleY() || | 113 blob.fViewMatrix.getScaleY() != viewMatrix.getScaleY() || |
| 113 blob.fViewMatrix.getSkewX() != viewMatrix.getSkewX() || | 114 blob.fViewMatrix.getSkewX() != viewMatrix.getSkewX() || |
| 114 blob.fViewMatrix.getSkewY() != viewMatrix.getSkewY()) { | 115 blob.fViewMatrix.getSkewY() != viewMatrix.getSkewY()) { |
| 115 return true; | 116 return true; |
| 116 } | 117 } |
| 117 | 118 |
| 119 // We only cache one masked version |
| 120 if (blob.fKey.fHasBlur && |
| 121 (blob.fBlurRec.fSigma != blurRec.fSigma || |
| 122 blob.fBlurRec.fStyle != blurRec.fStyle || |
| 123 blob.fBlurRec.fQuality != blurRec.fQuality)) { |
| 124 return true; |
| 125 } |
| 126 |
| 127 // Similarly, we only cache one version for each style |
| 128 if (blob.fKey.fStyle != SkPaint::kFill_Style && |
| 129 (blob.fStrokeInfo.fFrameWidth != paint.getStrokeWidth() || |
| 130 blob.fStrokeInfo.fMiterLimit != paint.getStrokeMiter() || |
| 131 blob.fStrokeInfo.fJoin != paint.getStrokeJoin())) { |
| 132 return true; |
| 133 } |
| 134 |
| 118 // We can update the positions in the cachedtextblobs without regenerating t
he whole blob, but | 135 // We can update the positions in the cachedtextblobs without regenerating t
he whole blob, but |
| 119 // only for integer translations. | 136 // only for integer translations. |
| 120 // This cool bit of math will determine the necessary translation to apply t
o the already | 137 // This cool bit of math will determine the necessary translation to apply t
o the already |
| 121 // generated vertex coordinates to move them to the correct position | 138 // generated vertex coordinates to move them to the correct position |
| 122 SkScalar transX = viewMatrix.getTranslateX() + | 139 SkScalar transX = viewMatrix.getTranslateX() + |
| 123 viewMatrix.getScaleX() * (x - blob.fX) + | 140 viewMatrix.getScaleX() * (x - blob.fX) + |
| 124 viewMatrix.getSkewX() * (y - blob.fY) - | 141 viewMatrix.getSkewX() * (y - blob.fY) - |
| 125 blob.fViewMatrix.getTranslateX(); | 142 blob.fViewMatrix.getTranslateX(); |
| 126 SkScalar transY = viewMatrix.getTranslateY() + | 143 SkScalar transY = viewMatrix.getTranslateY() + |
| 127 viewMatrix.getSkewY() * (x - blob.fX) + | 144 viewMatrix.getSkewY() * (x - blob.fX) + |
| (...skipping 27 matching lines...) Expand all Loading... |
| 155 const SkMatrix& viewMatrix)
{ | 172 const SkMatrix& viewMatrix)
{ |
| 156 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, &v
iewMatrix, false); | 173 skPaint.getScalerContextDescriptor(&run->fDescriptor, &fDeviceProperties, &v
iewMatrix, false); |
| 157 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); | 174 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); |
| 158 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc())
; | 175 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc())
; |
| 159 } | 176 } |
| 160 | 177 |
| 161 void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, | 178 void GrAtlasTextContext::drawTextBlob(GrRenderTarget* rt, const GrClip& clip, |
| 162 const SkPaint& skPaint, const SkMatrix& vi
ewMatrix, | 179 const SkPaint& skPaint, const SkMatrix& vi
ewMatrix, |
| 163 const SkTextBlob* blob, SkScalar x, SkScal
ar y, | 180 const SkTextBlob* blob, SkScalar x, SkScal
ar y, |
| 164 SkDrawFilter* drawFilter, const SkIRect& c
lipBounds) { | 181 SkDrawFilter* drawFilter, const SkIRect& c
lipBounds) { |
| 165 uint32_t uniqueID = blob->uniqueID(); | |
| 166 SkAutoTUnref<BitmapTextBlob> cacheBlob; | 182 SkAutoTUnref<BitmapTextBlob> cacheBlob; |
| 167 // TODO start caching these, mix bits into the key | 183 |
| 184 SkMaskFilter::BlurRec blurRec; |
| 185 BitmapTextBlob::Key key; |
| 186 // It might be worth caching these things, but its not clear at this time |
| 187 // TODO for animated mask filters, this will fill up our cache. We need a s
afeguard here |
| 188 const SkMaskFilter* mf = skPaint.getMaskFilter(); |
| 168 bool canCache = !(skPaint.getPathEffect() || | 189 bool canCache = !(skPaint.getPathEffect() || |
| 169 skPaint.getMaskFilter() || | 190 (mf && !mf->asABlur(&blurRec)) || |
| 170 skPaint.getColorFilter() || | |
| 171 skPaint.getStyle() != SkPaint::kFill_Style || | |
| 172 drawFilter); | 191 drawFilter); |
| 173 | 192 |
| 174 if (canCache) { | 193 if (canCache) { |
| 175 cacheBlob.reset(SkSafeRef(fCache->find(uniqueID))); | 194 key.fUniqueID = blob->uniqueID(); |
| 195 key.fStyle = skPaint.getStyle(); |
| 196 key.fHasBlur = SkToBool(mf); |
| 197 cacheBlob.reset(SkSafeRef(fCache->find(key))); |
| 176 } | 198 } |
| 177 | 199 |
| 178 SkIRect clipRect; | 200 SkIRect clipRect; |
| 179 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 201 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
| 180 | 202 |
| 181 SkScalar transX = 0.f; | 203 SkScalar transX = 0.f; |
| 182 SkScalar transY = 0.f; | 204 SkScalar transY = 0.f; |
| 183 | 205 |
| 184 if (cacheBlob) { | 206 if (cacheBlob) { |
| 185 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, viewMatrix
, x, y)) { | 207 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, blurRec, v
iewMatrix, x, y)) { |
| 186 // We have to remake the blob because changes may invalidate our mas
ks. | 208 // We have to remake the blob because changes may invalidate our mas
ks. |
| 187 // TODO we could probably get away reuse most of the time if the poi
nter is unique, | 209 // TODO we could probably get away reuse most of the time if the poi
nter is unique, |
| 188 // but we'd have to clear the subrun information | 210 // but we'd have to clear the subrun information |
| 189 fCache->remove(cacheBlob); | 211 fCache->remove(cacheBlob); |
| 190 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, kGrayTextVASize
))); | 212 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, |
| 213 kGrayTextVASize))); |
| 191 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y,
drawFilter, | 214 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y,
drawFilter, |
| 192 clipRect); | 215 clipRect); |
| 193 } else { | 216 } else { |
| 194 // If we can reuse the blob, then make sure we update the blob's vie
wmatrix and x/y | 217 // If we can reuse the blob, then make sure we update the blob's vie
wmatrix and x/y |
| 195 // offsets to reflect the results of any translations we may apply i
n generateGeometry | 218 // offsets to reflect the results of any translations we may apply i
n generateGeometry |
| 196 cacheBlob->fViewMatrix = viewMatrix; | 219 cacheBlob->fViewMatrix = viewMatrix; |
| 197 cacheBlob->fX = x; | 220 cacheBlob->fX = x; |
| 198 cacheBlob->fY = y; | 221 cacheBlob->fY = y; |
| 199 fCache->makeMRU(cacheBlob); | 222 fCache->makeMRU(cacheBlob); |
| 200 } | 223 } |
| 201 } else { | 224 } else { |
| 202 if (canCache) { | 225 if (canCache) { |
| 203 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, kGrayTextVASize
))); | 226 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, |
| 227 kGrayTextVASize))); |
| 204 } else { | 228 } else { |
| 205 cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize)); | 229 cacheBlob.reset(fCache->createBlob(blob, kGrayTextVASize)); |
| 206 } | 230 } |
| 207 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra
wFilter, clipRect); | 231 this->regenerateTextBlob(cacheBlob, skPaint, viewMatrix, blob, x, y, dra
wFilter, clipRect); |
| 208 } | 232 } |
| 209 | 233 |
| 210 // Though for the time being runs in the textblob can override the paint, th
ey only touch font | 234 // Though for the time being runs in the textblob can override the paint, th
ey only touch font |
| 211 // info. | 235 // info. |
| 212 GrPaint grPaint; | 236 GrPaint grPaint; |
| 213 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint); | 237 SkPaint2GrPaintShader(fContext, rt, skPaint, viewMatrix, true, &grPaint); |
| 214 | 238 |
| 215 this->flush(fContext->getTextTarget(), blob, cacheBlob, rt, skPaint, grPaint
, drawFilter, | 239 this->flush(fContext->getTextTarget(), blob, cacheBlob, rt, skPaint, grPaint
, drawFilter, |
| 216 clip, viewMatrix, clipBounds, x, y, transX, transY); | 240 clip, viewMatrix, clipBounds, x, y, transX, transY); |
| 217 } | 241 } |
| 218 | 242 |
| 219 void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob, | 243 void GrAtlasTextContext::regenerateTextBlob(BitmapTextBlob* cacheBlob, |
| 220 const SkPaint& skPaint, const SkMatr
ix& viewMatrix, | 244 const SkPaint& skPaint, const SkMatr
ix& viewMatrix, |
| 221 const SkTextBlob* blob, SkScalar x,
SkScalar y, | 245 const SkTextBlob* blob, SkScalar x,
SkScalar y, |
| 222 SkDrawFilter* drawFilter, const SkIR
ect& clipRect) { | 246 SkDrawFilter* drawFilter, const SkIR
ect& clipRect) { |
| 223 cacheBlob->fViewMatrix = viewMatrix; | 247 cacheBlob->fViewMatrix = viewMatrix; |
| 224 cacheBlob->fX = x; | 248 cacheBlob->fX = x; |
| 225 cacheBlob->fY = y; | 249 cacheBlob->fY = y; |
| 226 cacheBlob->fColor = skPaint.getColor(); | 250 cacheBlob->fColor = skPaint.getColor(); |
| 227 cacheBlob->fStyle = skPaint.getStyle(); | |
| 228 | 251 |
| 229 // Regenerate textblob | 252 // Regenerate textblob |
| 230 SkPaint runPaint = skPaint; | 253 SkPaint runPaint = skPaint; |
| 231 SkTextBlob::RunIterator it(blob); | 254 SkTextBlob::RunIterator it(blob); |
| 232 for (int run = 0; !it.done(); it.next(), run++) { | 255 for (int run = 0; !it.done(); it.next(), run++) { |
| 233 int glyphCount = it.glyphCount(); | 256 int glyphCount = it.glyphCount(); |
| 234 size_t textLen = glyphCount * sizeof(uint16_t); | 257 size_t textLen = glyphCount * sizeof(uint16_t); |
| 235 const SkPoint& offset = it.offset(); | 258 const SkPoint& offset = it.offset(); |
| 236 // applyFontToPaint() always overwrites the exact same attributes, | 259 // applyFontToPaint() always overwrites the exact same attributes, |
| 237 // so it is safe to not re-seed the paint for this reason. | 260 // 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 Loading... |
| 295 void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip, | 318 void GrAtlasTextContext::onDrawText(GrRenderTarget* rt, const GrClip& clip, |
| 296 const GrPaint& paint, const SkPaint& skPaint
, | 319 const GrPaint& paint, const SkPaint& skPaint
, |
| 297 const SkMatrix& viewMatrix, | 320 const SkMatrix& viewMatrix, |
| 298 const char text[], size_t byteLength, | 321 const char text[], size_t byteLength, |
| 299 SkScalar x, SkScalar y, const SkIRect& regio
nClipBounds) { | 322 SkScalar x, SkScalar y, const SkIRect& regio
nClipBounds) { |
| 300 int glyphCount = skPaint.countText(text, byteLength); | 323 int glyphCount = skPaint.countText(text, byteLength); |
| 301 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTex
tVASize)); | 324 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTex
tVASize)); |
| 302 blob->fViewMatrix = viewMatrix; | 325 blob->fViewMatrix = viewMatrix; |
| 303 blob->fX = x; | 326 blob->fX = x; |
| 304 blob->fY = y; | 327 blob->fY = y; |
| 305 blob->fStyle = skPaint.getStyle(); | |
| 306 | 328 |
| 307 SkIRect clipRect; | 329 SkIRect clipRect; |
| 308 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 330 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
| 309 | 331 |
| 310 // setup cache | 332 // setup cache |
| 311 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix)
; | 333 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix)
; |
| 312 this->internalDrawText(blob, 0, cache, skPaint, viewMatrix, text, byteLength
, x, y, clipRect); | 334 this->internalDrawText(blob, 0, cache, skPaint, viewMatrix, text, byteLength
, x, y, clipRect); |
| 313 SkGlyphCache::AttachCache(cache); | 335 SkGlyphCache::AttachCache(cache); |
| 314 | 336 |
| 315 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip, viewM
atrix); | 337 this->flush(fContext->getTextTarget(), blob, rt, skPaint, paint, clip, viewM
atrix); |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 } | 428 } |
| 407 | 429 |
| 408 void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, | 430 void GrAtlasTextContext::onDrawPosText(GrRenderTarget* rt, const GrClip& clip, |
| 409 const GrPaint& paint, const SkPaint& skPa
int, | 431 const GrPaint& paint, const SkPaint& skPa
int, |
| 410 const SkMatrix& viewMatrix, | 432 const SkMatrix& viewMatrix, |
| 411 const char text[], size_t byteLength, | 433 const char text[], size_t byteLength, |
| 412 const SkScalar pos[], int scalarsPerPosit
ion, | 434 const SkScalar pos[], int scalarsPerPosit
ion, |
| 413 const SkPoint& offset, const SkIRect& reg
ionClipBounds) { | 435 const SkPoint& offset, const SkIRect& reg
ionClipBounds) { |
| 414 int glyphCount = skPaint.countText(text, byteLength); | 436 int glyphCount = skPaint.countText(text, byteLength); |
| 415 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTex
tVASize)); | 437 SkAutoTUnref<BitmapTextBlob> blob(fCache->createBlob(glyphCount, 1, kGrayTex
tVASize)); |
| 416 blob->fStyle = skPaint.getStyle(); | |
| 417 blob->fViewMatrix = viewMatrix; | 438 blob->fViewMatrix = viewMatrix; |
| 418 | 439 |
| 419 SkIRect clipRect; | 440 SkIRect clipRect; |
| 420 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); | 441 clip.getConservativeBounds(rt->width(), rt->height(), &clipRect); |
| 421 | 442 |
| 422 // setup cache | 443 // setup cache |
| 423 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix)
; | 444 SkGlyphCache* cache = this->setupCache(&blob->fRuns[0], skPaint, viewMatrix)
; |
| 424 this->internalDrawPosText(blob, 0, cache, skPaint, viewMatrix, text, byteLen
gth, pos, | 445 this->internalDrawPosText(blob, 0, cache, skPaint, viewMatrix, text, byteLen
gth, pos, |
| 425 scalarsPerPosition, offset, clipRect); | 446 scalarsPerPosition, offset, clipRect); |
| 426 SkGlyphCache::AttachCache(cache); | 447 SkGlyphCache::AttachCache(cache); |
| (...skipping 784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1211 | 1232 |
| 1212 GrColor color = grPaint.getColor(); | 1233 GrColor color = grPaint.getColor(); |
| 1213 uint8_t paintAlpha = skPaint.getAlpha(); | 1234 uint8_t paintAlpha = skPaint.getAlpha(); |
| 1214 for (int run = 0; run < cacheBlob->fRunCount; run++) { | 1235 for (int run = 0; run < cacheBlob->fRunCount; run++) { |
| 1215 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, paintAlp
ha, 0, 0); | 1236 this->flushRun(target, &pipelineBuilder, cacheBlob, run, color, paintAlp
ha, 0, 0); |
| 1216 } | 1237 } |
| 1217 | 1238 |
| 1218 // Now flush big glyphs | 1239 // Now flush big glyphs |
| 1219 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0); | 1240 this->flushBigGlyphs(cacheBlob, rt, grPaint, clip, 0, 0); |
| 1220 } | 1241 } |
| OLD | NEW |