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 | 7 |
8 #ifndef GrAtlasTextBlob_DEFINED | 8 #ifndef GrAtlasTextBlob_DEFINED |
9 #define GrAtlasTextBlob_DEFINED | 9 #define GrAtlasTextBlob_DEFINED |
10 | 10 |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 #ifdef CACHE_SANITY_CHECK | 203 #ifdef CACHE_SANITY_CHECK |
204 static void AssertEqual(const GrAtlasTextBlob&, const GrAtlasTextBlob&); | 204 static void AssertEqual(const GrAtlasTextBlob&, const GrAtlasTextBlob&); |
205 size_t fSize; | 205 size_t fSize; |
206 #endif | 206 #endif |
207 | 207 |
208 // The color here is the GrPaint color, and it is used to determine whether
we | 208 // The color here is the GrPaint color, and it is used to determine whether
we |
209 // have to regenerate LCD text blobs. | 209 // have to regenerate LCD text blobs. |
210 // We use this color vs the SkPaint color because it has the colorfilter app
lied. | 210 // We use this color vs the SkPaint color because it has the colorfilter app
lied. |
211 void initReusableBlob(GrColor color, const SkMatrix& viewMatrix, SkScalar x,
SkScalar y) { | 211 void initReusableBlob(GrColor color, const SkMatrix& viewMatrix, SkScalar x,
SkScalar y) { |
212 fPaintColor = color; | 212 fPaintColor = color; |
213 this->setupViewMatrix(viewMatrix, x, y); | 213 fViewMatrix = viewMatrix; |
| 214 fX = x; |
| 215 fY = y; |
214 } | 216 } |
215 | 217 |
216 void initThrowawayBlob(const SkMatrix& viewMatrix, SkScalar x, SkScalar y) { | 218 void initThrowawayBlob(const SkMatrix& viewMatrix) { |
217 this->setupViewMatrix(viewMatrix, x, y); | 219 fViewMatrix = viewMatrix; |
218 } | 220 } |
219 | 221 |
220 GrDrawBatch* test_createBatch(int glyphCount, int run, int subRun, | 222 GrDrawBatch* test_createBatch(int glyphCount, int run, int subRun, |
221 GrColor color, SkScalar transX, SkScalar trans
Y, | 223 GrColor color, SkScalar transX, SkScalar trans
Y, |
222 const SkPaint& skPaint, const SkSurfaceProps&
props, | 224 const SkPaint& skPaint, const SkSurfaceProps&
props, |
223 const GrDistanceFieldAdjustTable* distanceAdju
stTable, | 225 const GrDistanceFieldAdjustTable* distanceAdju
stTable, |
224 GrBatchFontCache* cache); | 226 GrBatchFontCache* cache); |
225 | 227 |
226 private: | 228 private: |
227 void appendLargeGlyph(GrGlyph* glyph, GrFontScaler* scaler, const SkGlyph& s
kGlyph, | 229 void appendLargeGlyph(GrGlyph* glyph, GrFontScaler* scaler, const SkGlyph& s
kGlyph, |
(...skipping 12 matching lines...) Expand all Loading... |
240 const SkIRect& clipBounds); | 242 const SkIRect& clipBounds); |
241 | 243 |
242 void flushRunAsPaths(GrContext* context, | 244 void flushRunAsPaths(GrContext* context, |
243 GrDrawContext* dc, | 245 GrDrawContext* dc, |
244 const SkSurfaceProps& props, | 246 const SkSurfaceProps& props, |
245 const SkTextBlobRunIterator& it, | 247 const SkTextBlobRunIterator& it, |
246 const GrClip& clip, const SkPaint& skPaint, | 248 const GrClip& clip, const SkPaint& skPaint, |
247 SkDrawFilter* drawFilter, const SkMatrix& viewMatrix, | 249 SkDrawFilter* drawFilter, const SkMatrix& viewMatrix, |
248 const SkIRect& clipBounds, SkScalar x, SkScalar y); | 250 const SkIRect& clipBounds, SkScalar x, SkScalar y); |
249 | 251 |
250 // This function will only be called when we are regenerating a blob from sc
ratch. We record the | |
251 // initial view matrix and initial offsets(x,y), because we record vertex bo
unds relative to | |
252 // these numbers. When blobs are reused with new matrices, we need to retur
n to model space so | |
253 // we can update the vertex bounds appropriately. | |
254 void setupViewMatrix(const SkMatrix& viewMatrix, SkScalar x, SkScalar y) { | |
255 fViewMatrix = viewMatrix; | |
256 if (!viewMatrix.invert(&fInitialViewMatrixInverse)) { | |
257 fInitialViewMatrixInverse = SkMatrix::I(); | |
258 SkDebugf("Could not invert viewmatrix\n"); | |
259 } | |
260 fX = fInitialX = x; | |
261 fY = fInitialY = y; | |
262 } | |
263 | |
264 /* | 252 /* |
265 * Each Run inside of the blob can have its texture coordinates regenerated
if required. | 253 * Each Run inside of the blob can have its texture coordinates regenerated
if required. |
266 * To determine if regeneration is necessary, fAtlasGeneration is used. If
there have been | 254 * To determine if regeneration is necessary, fAtlasGeneration is used. If
there have been |
267 * any evictions inside of the atlas, then we will simply regenerate Runs.
We could track | 255 * any evictions inside of the atlas, then we will simply regenerate Runs.
We could track |
268 * this at a more fine grained level, but its not clear if this is worth it,
as evictions | 256 * this at a more fine grained level, but its not clear if this is worth it,
as evictions |
269 * should be fairly rare. | 257 * should be fairly rare. |
270 * | 258 * |
271 * One additional point, each run can contain glyphs with any of the three m
ask formats. | 259 * One additional point, each run can contain glyphs with any of the three m
ask formats. |
272 * We call these SubRuns. Because a subrun must be a contiguous range, we h
ave to create | 260 * We call these SubRuns. Because a subrun must be a contiguous range, we h
ave to create |
273 * a new subrun each time the mask format changes in a run. In theory, a ru
n can have as | 261 * a new subrun each time the mask format changes in a run. In theory, a ru
n can have as |
274 * many SubRuns as it has glyphs, ie if a run alternates between color emoji
and A8. In | 262 * many SubRuns as it has glyphs, ie if a run alternates between color emoji
and A8. In |
275 * practice, the vast majority of runs have only a single subrun. | 263 * practice, the vast majority of runs have only a single subrun. |
276 * | 264 * |
277 * Finally, for runs where the entire thing is too large for the GrAtlasText
Context to | 265 * Finally, for runs where the entire thing is too large for the GrAtlasText
Context to |
278 * handle, we have a bit to mark the run as flusahable via rendering as path
s. It is worth | 266 * handle, we have a bit to mark the run as flusahable via rendering as path
s. It is worth |
279 * pointing. It would be a bit expensive to figure out ahead of time whether
or not a run | 267 * pointing. It would be a bit expensive to figure out ahead of time whether
or not a run |
280 * can flush in this manner, so we always allocate vertices for the run, reg
ardless of | 268 * can flush in this manner, so we always allocate vertices for the run, reg
ardless of |
281 * whether or not it is too large. The benefit of this strategy is that we
can always reuse | 269 * whether or not it is too large. The benefit of this strategy is that we
can always reuse |
282 * a blob allocation regardless of viewmatrix changes. We could store posit
ions for these | 270 * a blob allocation regardless of viewmatrix changes. We could store posit
ions for these |
283 * glyphs. However, its not clear if this is a win because we'd still have
to either go the | 271 * glyphs. However, its not clear if this is a win because we'd still have
to either go the |
284 * glyph cache to get the path at flush time, or hold onto the path in the c
ache, which | 272 * glyph cache to get the path at flush time, or hold onto the path in the c
ache, which |
285 * would greatly increase the memory of these cached items. | 273 * would greatly increase the memory of these cached items. |
286 */ | 274 */ |
287 struct Run { | 275 struct Run { |
288 Run() | 276 Run() |
289 : fInitialized(false) | 277 : fInitialized(false) |
290 , fDrawAsPaths(false) { | 278 , fDrawAsPaths(false) { |
| 279 fVertexBounds.setLargestInverted(); |
291 // To ensure we always have one subrun, we push back a fresh run her
e | 280 // To ensure we always have one subrun, we push back a fresh run her
e |
292 fSubRunInfo.push_back(); | 281 fSubRunInfo.push_back(); |
293 } | 282 } |
294 struct SubRunInfo { | 283 struct SubRunInfo { |
295 SubRunInfo() | 284 SubRunInfo() |
296 : fAtlasGeneration(GrBatchAtlas::kInvalidAtlasGeneration) | 285 : fAtlasGeneration(GrBatchAtlas::kInvalidAtlasGeneration) |
297 , fVertexStartIndex(0) | 286 , fVertexStartIndex(0) |
298 , fVertexEndIndex(0) | 287 , fVertexEndIndex(0) |
299 , fGlyphStartIndex(0) | 288 , fGlyphStartIndex(0) |
300 , fGlyphEndIndex(0) | 289 , fGlyphEndIndex(0) |
301 , fColor(GrColor_ILLEGAL) | 290 , fColor(GrColor_ILLEGAL) |
302 , fMaskFormat(kA8_GrMaskFormat) | 291 , fMaskFormat(kA8_GrMaskFormat) |
303 , fDrawAsDistanceFields(false) | 292 , fDrawAsDistanceFields(false) |
304 , fUseLCDText(false) { | 293 , fUseLCDText(false) {} |
305 fVertexBounds.setLargestInverted(); | |
306 } | |
307 SubRunInfo(const SubRunInfo& that) | 294 SubRunInfo(const SubRunInfo& that) |
308 : fBulkUseToken(that.fBulkUseToken) | 295 : fBulkUseToken(that.fBulkUseToken) |
309 , fStrike(SkSafeRef(that.fStrike.get())) | 296 , fStrike(SkSafeRef(that.fStrike.get())) |
310 , fVertexBounds(that.fVertexBounds) | |
311 , fAtlasGeneration(that.fAtlasGeneration) | 297 , fAtlasGeneration(that.fAtlasGeneration) |
312 , fVertexStartIndex(that.fVertexStartIndex) | 298 , fVertexStartIndex(that.fVertexStartIndex) |
313 , fVertexEndIndex(that.fVertexEndIndex) | 299 , fVertexEndIndex(that.fVertexEndIndex) |
314 , fGlyphStartIndex(that.fGlyphStartIndex) | 300 , fGlyphStartIndex(that.fGlyphStartIndex) |
315 , fGlyphEndIndex(that.fGlyphEndIndex) | 301 , fGlyphEndIndex(that.fGlyphEndIndex) |
316 , fColor(that.fColor) | 302 , fColor(that.fColor) |
317 , fMaskFormat(that.fMaskFormat) | 303 , fMaskFormat(that.fMaskFormat) |
318 , fDrawAsDistanceFields(that.fDrawAsDistanceFields) | 304 , fDrawAsDistanceFields(that.fDrawAsDistanceFields) |
319 , fUseLCDText(that.fUseLCDText) { | 305 , fUseLCDText(that.fUseLCDText) { |
320 } | 306 } |
(...skipping 24 matching lines...) Expand all Loading... |
345 GrMaskFormat maskFormat() const { return fMaskFormat; } | 331 GrMaskFormat maskFormat() const { return fMaskFormat; } |
346 | 332 |
347 void setAsSuccessor(const SubRunInfo& prev) { | 333 void setAsSuccessor(const SubRunInfo& prev) { |
348 fGlyphStartIndex = prev.glyphEndIndex(); | 334 fGlyphStartIndex = prev.glyphEndIndex(); |
349 fGlyphEndIndex = prev.glyphEndIndex(); | 335 fGlyphEndIndex = prev.glyphEndIndex(); |
350 | 336 |
351 fVertexStartIndex = prev.vertexEndIndex(); | 337 fVertexStartIndex = prev.vertexEndIndex(); |
352 fVertexEndIndex = prev.vertexEndIndex(); | 338 fVertexEndIndex = prev.vertexEndIndex(); |
353 } | 339 } |
354 | 340 |
355 const SkRect& vertexBounds() const { return fVertexBounds; } | |
356 void joinGlyphBounds(const SkRect& glyphBounds) { | |
357 fVertexBounds.joinNonEmptyArg(glyphBounds); | |
358 } | |
359 | |
360 // df properties | 341 // df properties |
361 void setUseLCDText(bool useLCDText) { fUseLCDText = useLCDText; } | 342 void setUseLCDText(bool useLCDText) { fUseLCDText = useLCDText; } |
362 bool hasUseLCDText() const { return fUseLCDText; } | 343 bool hasUseLCDText() const { return fUseLCDText; } |
363 void setDrawAsDistanceFields() { fDrawAsDistanceFields = true; } | 344 void setDrawAsDistanceFields() { fDrawAsDistanceFields = true; } |
364 bool drawAsDistanceFields() const { return fDrawAsDistanceFields; } | 345 bool drawAsDistanceFields() const { return fDrawAsDistanceFields; } |
365 | 346 |
366 private: | 347 private: |
367 GrBatchAtlas::BulkUseTokenUpdater fBulkUseToken; | 348 GrBatchAtlas::BulkUseTokenUpdater fBulkUseToken; |
368 SkAutoTUnref<GrBatchTextStrike> fStrike; | 349 SkAutoTUnref<GrBatchTextStrike> fStrike; |
369 SkRect fVertexBounds; | |
370 uint64_t fAtlasGeneration; | 350 uint64_t fAtlasGeneration; |
371 size_t fVertexStartIndex; | 351 size_t fVertexStartIndex; |
372 size_t fVertexEndIndex; | 352 size_t fVertexEndIndex; |
373 uint32_t fGlyphStartIndex; | 353 uint32_t fGlyphStartIndex; |
374 uint32_t fGlyphEndIndex; | 354 uint32_t fGlyphEndIndex; |
375 GrColor fColor; | 355 GrColor fColor; |
376 GrMaskFormat fMaskFormat; | 356 GrMaskFormat fMaskFormat; |
377 bool fDrawAsDistanceFields; // df property | 357 bool fDrawAsDistanceFields; // df property |
378 bool fUseLCDText; // df property | 358 bool fUseLCDText; // df property |
379 }; | 359 }; |
380 | 360 |
381 SubRunInfo& push_back() { | 361 SubRunInfo& push_back() { |
382 // Forward glyph / vertex information to seed the new sub run | 362 // Forward glyph / vertex information to seed the new sub run |
383 SubRunInfo& newSubRun = fSubRunInfo.push_back(); | 363 SubRunInfo& newSubRun = fSubRunInfo.push_back(); |
384 const SubRunInfo& prevSubRun = fSubRunInfo.fromBack(1); | 364 const SubRunInfo& prevSubRun = fSubRunInfo.fromBack(1); |
385 | 365 |
386 newSubRun.setAsSuccessor(prevSubRun); | 366 newSubRun.setAsSuccessor(prevSubRun); |
387 return newSubRun; | 367 return newSubRun; |
388 } | 368 } |
389 static const int kMinSubRuns = 1; | 369 static const int kMinSubRuns = 1; |
390 SkAutoTUnref<SkTypeface> fTypeface; | 370 SkAutoTUnref<SkTypeface> fTypeface; |
| 371 SkRect fVertexBounds; |
391 SkSTArray<kMinSubRuns, SubRunInfo> fSubRunInfo; | 372 SkSTArray<kMinSubRuns, SubRunInfo> fSubRunInfo; |
392 SkAutoDescriptor fDescriptor; | 373 SkAutoDescriptor fDescriptor; |
393 | 374 |
394 // Distance field text cannot draw coloremoji, and so has to fall back.
However, | 375 // Distance field text cannot draw coloremoji, and so has to fall back.
However, |
395 // though the distance field text and the coloremoji may share the same
run, they | 376 // though the distance field text and the coloremoji may share the same
run, they |
396 // will have different descriptors. If fOverrideDescriptor is non-nullp
tr, then it | 377 // will have different descriptors. If fOverrideDescriptor is non-nullp
tr, then it |
397 // will be used in place of the run's descriptor to regen texture coords | 378 // will be used in place of the run's descriptor to regen texture coords |
398 SkAutoTDelete<SkAutoDescriptor> fOverrideDescriptor; // df properties | 379 SkAutoTDelete<SkAutoDescriptor> fOverrideDescriptor; // df properties |
399 bool fInitialized; | 380 bool fInitialized; |
400 bool fDrawAsPaths; | 381 bool fDrawAsPaths; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
435 // all glyph / vertex offsets are into these pools. | 416 // all glyph / vertex offsets are into these pools. |
436 unsigned char* fVertices; | 417 unsigned char* fVertices; |
437 GrGlyph** fGlyphs; | 418 GrGlyph** fGlyphs; |
438 Run* fRuns; | 419 Run* fRuns; |
439 GrMemoryPool* fPool; | 420 GrMemoryPool* fPool; |
440 SkMaskFilter::BlurRec fBlurRec; | 421 SkMaskFilter::BlurRec fBlurRec; |
441 StrokeInfo fStrokeInfo; | 422 StrokeInfo fStrokeInfo; |
442 SkTArray<BigGlyph> fBigGlyphs; | 423 SkTArray<BigGlyph> fBigGlyphs; |
443 Key fKey; | 424 Key fKey; |
444 SkMatrix fViewMatrix; | 425 SkMatrix fViewMatrix; |
445 SkMatrix fInitialViewMatrixInverse; | |
446 GrColor fPaintColor; | 426 GrColor fPaintColor; |
447 SkScalar fInitialX; | |
448 SkScalar fInitialY; | |
449 SkScalar fX; | 427 SkScalar fX; |
450 SkScalar fY; | 428 SkScalar fY; |
451 | 429 |
452 // We can reuse distance field text, but only if the new viewmatrix would no
t result in | 430 // We can reuse distance field text, but only if the new viewmatrix would no
t result in |
453 // a mip change. Because there can be multiple runs in a blob, we track the
overall | 431 // a mip change. Because there can be multiple runs in a blob, we track the
overall |
454 // maximum minimum scale, and minimum maximum scale, we can support before w
e need to regen | 432 // maximum minimum scale, and minimum maximum scale, we can support before w
e need to regen |
455 SkScalar fMaxMinScale; | 433 SkScalar fMaxMinScale; |
456 SkScalar fMinMaxScale; | 434 SkScalar fMinMaxScale; |
457 int fRunCount; | 435 int fRunCount; |
458 uint8_t fTextType; | 436 uint8_t fTextType; |
459 | 437 |
460 friend class GrAtlasTextBatch; // We might be able to get rid of this friend
ing | 438 friend class GrAtlasTextBatch; // We might be able to get rid of this friend
ing |
461 friend class GrTextBlobCache; // Needs to access the key | 439 friend class GrTextBlobCache; // Needs to access the key |
462 }; | 440 }; |
463 | 441 |
464 #endif | 442 #endif |
OLD | NEW |