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 "GrBlurUtils.h" | 9 #include "GrBlurUtils.h" |
10 #include "GrDrawContext.h" | 10 #include "GrDrawContext.h" |
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 bool GrAtlasTextContext::HasLCD(const SkTextBlob* blob) { | 181 bool GrAtlasTextContext::HasLCD(const SkTextBlob* blob) { |
182 SkTextBlobRunIterator it(blob); | 182 SkTextBlobRunIterator it(blob); |
183 for (; !it.done(); it.next()) { | 183 for (; !it.done(); it.next()) { |
184 if (it.isLCD()) { | 184 if (it.isLCD()) { |
185 return true; | 185 return true; |
186 } | 186 } |
187 } | 187 } |
188 return false; | 188 return false; |
189 } | 189 } |
190 | 190 |
191 bool GrAtlasTextContext::MustRegenerateBlob(SkScalar* outTransX, SkScalar* outTr
ansY, | |
192 const GrAtlasTextBlob& blob, const S
kPaint& paint, | |
193 GrColor color, const SkMaskFilter::B
lurRec& blurRec, | |
194 const SkMatrix& viewMatrix, SkScalar
x, SkScalar y) { | |
195 // If we have LCD text then our canonical color will be set to transparent,
in this case we have | |
196 // to regenerate the blob on any color change | |
197 // We use the grPaint to get any color filter effects | |
198 if (blob.fKey.fCanonicalColor == SK_ColorTRANSPARENT && | |
199 blob.fPaintColor != color) { | |
200 return true; | |
201 } | |
202 | |
203 if (blob.fViewMatrix.hasPerspective() != viewMatrix.hasPerspective()) { | |
204 return true; | |
205 } | |
206 | |
207 if (blob.fViewMatrix.hasPerspective() && !blob.fViewMatrix.cheapEqualTo(view
Matrix)) { | |
208 return true; | |
209 } | |
210 | |
211 // We only cache one masked version | |
212 if (blob.fKey.fHasBlur && | |
213 (blob.fBlurRec.fSigma != blurRec.fSigma || | |
214 blob.fBlurRec.fStyle != blurRec.fStyle || | |
215 blob.fBlurRec.fQuality != blurRec.fQuality)) { | |
216 return true; | |
217 } | |
218 | |
219 // Similarly, we only cache one version for each style | |
220 if (blob.fKey.fStyle != SkPaint::kFill_Style && | |
221 (blob.fStrokeInfo.fFrameWidth != paint.getStrokeWidth() || | |
222 blob.fStrokeInfo.fMiterLimit != paint.getStrokeMiter() || | |
223 blob.fStrokeInfo.fJoin != paint.getStrokeJoin())) { | |
224 return true; | |
225 } | |
226 | |
227 // Mixed blobs must be regenerated. We could probably figure out a way to d
o integer scrolls | |
228 // for mixed blobs if this becomes an issue. | |
229 if (blob.hasBitmap() && blob.hasDistanceField()) { | |
230 // Identical viewmatrices and we can reuse in all cases | |
231 if (blob.fViewMatrix.cheapEqualTo(viewMatrix) && x == blob.fX && y == bl
ob.fY) { | |
232 return false; | |
233 } | |
234 return true; | |
235 } | |
236 | |
237 if (blob.hasBitmap()) { | |
238 if (blob.fViewMatrix.getScaleX() != viewMatrix.getScaleX() || | |
239 blob.fViewMatrix.getScaleY() != viewMatrix.getScaleY() || | |
240 blob.fViewMatrix.getSkewX() != viewMatrix.getSkewX() || | |
241 blob.fViewMatrix.getSkewY() != viewMatrix.getSkewY()) { | |
242 return true; | |
243 } | |
244 | |
245 // We can update the positions in the cachedtextblobs without regenerati
ng the whole blob, | |
246 // but only for integer translations. | |
247 // This cool bit of math will determine the necessary translation to app
ly to the already | |
248 // generated vertex coordinates to move them to the correct position | |
249 SkScalar transX = viewMatrix.getTranslateX() + | |
250 viewMatrix.getScaleX() * (x - blob.fX) + | |
251 viewMatrix.getSkewX() * (y - blob.fY) - | |
252 blob.fViewMatrix.getTranslateX(); | |
253 SkScalar transY = viewMatrix.getTranslateY() + | |
254 viewMatrix.getSkewY() * (x - blob.fX) + | |
255 viewMatrix.getScaleY() * (y - blob.fY) - | |
256 blob.fViewMatrix.getTranslateY(); | |
257 if (!SkScalarIsInt(transX) || !SkScalarIsInt(transY) ) { | |
258 return true; | |
259 } | |
260 | |
261 (*outTransX) = transX; | |
262 (*outTransY) = transY; | |
263 } else if (blob.hasDistanceField()) { | |
264 // A scale outside of [blob.fMaxMinScale, blob.fMinMaxScale] would resul
t in a different | |
265 // distance field being generated, so we have to regenerate in those cas
es | |
266 SkScalar newMaxScale = viewMatrix.getMaxScale(); | |
267 SkScalar oldMaxScale = blob.fViewMatrix.getMaxScale(); | |
268 SkScalar scaleAdjust = newMaxScale / oldMaxScale; | |
269 if (scaleAdjust < blob.fMaxMinScale || scaleAdjust > blob.fMinMaxScale)
{ | |
270 return true; | |
271 } | |
272 | |
273 (*outTransX) = x - blob.fX; | |
274 (*outTransY) = y - blob.fY; | |
275 } | |
276 | |
277 // It is possible that a blob has neither distanceField nor bitmaptext. Thi
s is in the case | |
278 // when all of the runs inside the blob are drawn as paths. In this case, w
e always regenerate | |
279 // the blob anyways at flush time, so no need to regenerate explicitly | |
280 return false; | |
281 } | |
282 | |
283 | |
284 inline SkGlyphCache* GrAtlasTextContext::setupCache(GrAtlasTextBlob::Run* run, | 191 inline SkGlyphCache* GrAtlasTextContext::setupCache(GrAtlasTextBlob::Run* run, |
285 const SkPaint& skPaint, | 192 const SkPaint& skPaint, |
286 const SkMatrix* viewMatrix, | 193 const SkMatrix* viewMatrix, |
287 bool noGamma) { | 194 bool noGamma) { |
288 skPaint.getScalerContextDescriptor(&run->fDescriptor, fSurfaceProps, viewMat
rix, noGamma); | 195 skPaint.getScalerContextDescriptor(&run->fDescriptor, fSurfaceProps, viewMat
rix, noGamma); |
289 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); | 196 run->fTypeface.reset(SkSafeRef(skPaint.getTypeface())); |
290 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc())
; | 197 return SkGlyphCache::DetachCache(run->fTypeface, run->fDescriptor.getDesc())
; |
291 } | 198 } |
292 | 199 |
293 void GrAtlasTextContext::drawTextBlob(GrDrawContext* dc, | 200 void GrAtlasTextContext::drawTextBlob(GrDrawContext* dc, |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
335 SkScalar transY = 0.f; | 242 SkScalar transY = 0.f; |
336 | 243 |
337 // Though for the time being runs in the textblob can override the paint, th
ey only touch font | 244 // Though for the time being runs in the textblob can override the paint, th
ey only touch font |
338 // info. | 245 // info. |
339 GrPaint grPaint; | 246 GrPaint grPaint; |
340 if (!SkPaintToGrPaint(fContext, skPaint, viewMatrix, &grPaint)) { | 247 if (!SkPaintToGrPaint(fContext, skPaint, viewMatrix, &grPaint)) { |
341 return; | 248 return; |
342 } | 249 } |
343 | 250 |
344 if (cacheBlob) { | 251 if (cacheBlob) { |
345 if (MustRegenerateBlob(&transX, &transY, *cacheBlob, skPaint, grPaint.ge
tColor(), blurRec, | 252 if (cacheBlob->mustRegenerate(&transX, &transY, skPaint, grPaint.getColo
r(), blurRec, |
346 viewMatrix, x, y)) { | 253 viewMatrix, x, y)) { |
347 // We have to remake the blob because changes may invalidate our mas
ks. | 254 // We have to remake the blob because changes may invalidate our mas
ks. |
348 // TODO we could probably get away reuse most of the time if the poi
nter is unique, | 255 // TODO we could probably get away reuse most of the time if the poi
nter is unique, |
349 // but we'd have to clear the subrun information | 256 // but we'd have to clear the subrun information |
350 fCache->remove(cacheBlob); | 257 fCache->remove(cacheBlob); |
351 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, | 258 cacheBlob.reset(SkRef(fCache->createCachedBlob(blob, key, blurRec, s
kPaint, |
352 GrAtlasTextBlob::kGra
yTextVASize))); | 259 GrAtlasTextBlob::kGra
yTextVASize))); |
353 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), vie
wMatrix, | 260 this->regenerateTextBlob(cacheBlob, skPaint, grPaint.getColor(), vie
wMatrix, |
354 blob, x, y, drawFilter, clip); | 261 blob, x, y, drawFilter, clip); |
355 } else { | 262 } else { |
356 // If we can reuse the blob, then make sure we update the blob's vie
wmatrix, and x/y | |
357 // offsets. Note, we offset the vertex bounds right before flushing | |
358 cacheBlob->fViewMatrix = viewMatrix; | |
359 cacheBlob->fX = x; | |
360 cacheBlob->fY = y; | |
361 fCache->makeMRU(cacheBlob); | 263 fCache->makeMRU(cacheBlob); |
362 #ifdef CACHE_SANITY_CHECK | 264 #ifdef CACHE_SANITY_CHECK |
363 { | 265 { |
364 int glyphCount = 0; | 266 int glyphCount = 0; |
365 int runCount = 0; | 267 int runCount = 0; |
366 GrTextBlobCache::BlobGlyphCount(&glyphCount, &runCount, blob); | 268 GrTextBlobCache::BlobGlyphCount(&glyphCount, &runCount, blob); |
367 SkAutoTUnref<GrAtlasTextBlob> sanityBlob(fCache->createBlob(glyp
hCount, runCount, | 269 SkAutoTUnref<GrAtlasTextBlob> sanityBlob(fCache->createBlob(glyp
hCount, runCount, |
368 kGra
yTextVASize)); | 270 kGra
yTextVASize)); |
369 GrTextBlobCache::SetupCacheBlobKey(sanityBlob, key, blurRec, skP
aint); | 271 GrTextBlobCache::SetupCacheBlobKey(sanityBlob, key, blurRec, skP
aint); |
370 this->regenerateTextBlob(sanityBlob, skPaint, grPaint.getColor()
, viewMatrix, | 272 this->regenerateTextBlob(sanityBlob, skPaint, grPaint.getColor()
, viewMatrix, |
(...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1284 gTextContext->createDrawTextBlob(clip, grPaint, skPaint, viewMatrix,
text, | 1186 gTextContext->createDrawTextBlob(clip, grPaint, skPaint, viewMatrix,
text, |
1285 static_cast<size_t>(textLen), 0, 0,
noClip)); | 1187 static_cast<size_t>(textLen), 0, 0,
noClip)); |
1286 | 1188 |
1287 SkScalar transX = static_cast<SkScalar>(random->nextU()); | 1189 SkScalar transX = static_cast<SkScalar>(random->nextU()); |
1288 SkScalar transY = static_cast<SkScalar>(random->nextU()); | 1190 SkScalar transY = static_cast<SkScalar>(random->nextU()); |
1289 const GrAtlasTextBlob::Run::SubRunInfo& info = blob->fRuns[0].fSubRunInfo[0]
; | 1191 const GrAtlasTextBlob::Run::SubRunInfo& info = blob->fRuns[0].fSubRunInfo[0]
; |
1290 return gTextContext->createBatch(blob, info, textLen, 0, 0, color, transX, t
ransY, skPaint); | 1192 return gTextContext->createBatch(blob, info, textLen, 0, 0, color, transX, t
ransY, skPaint); |
1291 } | 1193 } |
1292 | 1194 |
1293 #endif | 1195 #endif |
OLD | NEW |