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