OLD | NEW |
1 | 1 |
2 /* | 2 /* |
3 * Copyright 2014 Google Inc. | 3 * Copyright 2014 Google Inc. |
4 * | 4 * |
5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
7 */ | 7 */ |
8 | 8 |
9 #include "GrAADistanceFieldPathRenderer.h" | 9 #include "GrAADistanceFieldPathRenderer.h" |
10 | 10 |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 dfpr->fPathList.remove(pathData); | 55 dfpr->fPathList.remove(pathData); |
56 SkDELETE(pathData); | 56 SkDELETE(pathData); |
57 #ifdef DF_PATH_TRACKING | 57 #ifdef DF_PATH_TRACKING |
58 ++g_NumFreedPaths; | 58 ++g_NumFreedPaths; |
59 #endif | 59 #endif |
60 } | 60 } |
61 } | 61 } |
62 } | 62 } |
63 | 63 |
64 //////////////////////////////////////////////////////////////////////////////// | 64 //////////////////////////////////////////////////////////////////////////////// |
65 GrAADistanceFieldPathRenderer::GrAADistanceFieldPathRenderer(GrContext* context) | 65 GrAADistanceFieldPathRenderer::GrAADistanceFieldPathRenderer() : fAtlas(NULL) {} |
66 : fContext(context) | |
67 , fAtlas(NULL) { | |
68 } | |
69 | 66 |
70 GrAADistanceFieldPathRenderer::~GrAADistanceFieldPathRenderer() { | 67 GrAADistanceFieldPathRenderer::~GrAADistanceFieldPathRenderer() { |
71 PathDataList::Iter iter; | 68 PathDataList::Iter iter; |
72 iter.init(fPathList, PathDataList::Iter::kHead_IterStart); | 69 iter.init(fPathList, PathDataList::Iter::kHead_IterStart); |
73 PathData* pathData; | 70 PathData* pathData; |
74 while ((pathData = iter.get())) { | 71 while ((pathData = iter.get())) { |
75 iter.next(); | 72 iter.next(); |
76 fPathList.remove(pathData); | 73 fPathList.remove(pathData); |
77 SkDELETE(pathData); | 74 SkDELETE(pathData); |
78 } | 75 } |
79 SkDELETE(fAtlas); | 76 SkDELETE(fAtlas); |
80 | 77 |
81 #ifdef DF_PATH_TRACKING | 78 #ifdef DF_PATH_TRACKING |
82 SkDebugf("Cached paths: %d, freed paths: %d\n", g_NumCachedPaths, g_NumFreed
Paths); | 79 SkDebugf("Cached paths: %d, freed paths: %d\n", g_NumCachedPaths, g_NumFreed
Paths); |
83 #endif | 80 #endif |
84 } | 81 } |
85 | 82 |
86 //////////////////////////////////////////////////////////////////////////////// | 83 //////////////////////////////////////////////////////////////////////////////// |
87 bool GrAADistanceFieldPathRenderer::canDrawPath(const GrDrawTarget* target, | 84 bool GrAADistanceFieldPathRenderer::onCanDrawPath(const CanDrawPathArgs& args) c
onst { |
88 const GrPipelineBuilder* pipelin
eBuilder, | |
89 const SkMatrix& viewMatrix, | |
90 const SkPath& path, | |
91 const GrStrokeInfo& stroke, | |
92 bool antiAlias) const { | |
93 | 85 |
94 // TODO: Support inverse fill | 86 // TODO: Support inverse fill |
95 // TODO: Support strokes | 87 // TODO: Support strokes |
96 if (!target->caps()->shaderCaps()->shaderDerivativeSupport() || !antiAlias | 88 if (!args.fTarget->caps()->shaderCaps()->shaderDerivativeSupport() || !args.
fAntiAlias || |
97 || path.isInverseFillType() || path.isVolatile() || !stroke.isFillStyle(
)) { | 89 args.fPath->isInverseFillType() || args.fPath->isVolatile() || |
| 90 !args.fStroke->isFillStyle()) { |
98 return false; | 91 return false; |
99 } | 92 } |
100 | 93 |
101 // currently don't support perspective | 94 // currently don't support perspective |
102 if (viewMatrix.hasPerspective()) { | 95 if (args.fViewMatrix->hasPerspective()) { |
103 return false; | 96 return false; |
104 } | 97 } |
105 | 98 |
106 // only support paths smaller than 64x64, scaled to less than 256x256 | 99 // only support paths smaller than 64x64, scaled to less than 256x256 |
107 // the goal is to accelerate rendering of lots of small paths that may be sc
aling | 100 // the goal is to accelerate rendering of lots of small paths that may be sc
aling |
108 SkScalar maxScale = viewMatrix.getMaxScale(); | 101 SkScalar maxScale = args.fViewMatrix->getMaxScale(); |
109 const SkRect& bounds = path.getBounds(); | 102 const SkRect& bounds = args.fPath->getBounds(); |
110 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); | 103 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); |
111 return maxDim < 64.f && maxDim * maxScale < 256.f; | 104 return maxDim < 64.f && maxDim * maxScale < 256.f; |
112 } | 105 } |
113 | 106 |
114 | |
115 GrPathRenderer::StencilSupport | 107 GrPathRenderer::StencilSupport |
116 GrAADistanceFieldPathRenderer::onGetStencilSupport(const GrDrawTarget*, | 108 GrAADistanceFieldPathRenderer::onGetStencilSupport(const GrDrawTarget*, |
117 const GrPipelineBuilder*, | 109 const GrPipelineBuilder*, |
118 const SkPath&, | 110 const SkPath&, |
119 const GrStrokeInfo&) const { | 111 const GrStrokeInfo&) const { |
120 return GrPathRenderer::kNoSupport_StencilSupport; | 112 return GrPathRenderer::kNoSupport_StencilSupport; |
121 } | 113 } |
122 | 114 |
123 //////////////////////////////////////////////////////////////////////////////// | 115 //////////////////////////////////////////////////////////////////////////////// |
124 | 116 |
(...skipping 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 bool fCoverageIgnored; | 522 bool fCoverageIgnored; |
531 }; | 523 }; |
532 | 524 |
533 BatchTracker fBatch; | 525 BatchTracker fBatch; |
534 SkSTArray<1, Geometry, true> fGeoData; | 526 SkSTArray<1, Geometry, true> fGeoData; |
535 GrBatchAtlas* fAtlas; | 527 GrBatchAtlas* fAtlas; |
536 PathCache* fPathCache; | 528 PathCache* fPathCache; |
537 PathDataList* fPathList; | 529 PathDataList* fPathList; |
538 }; | 530 }; |
539 | 531 |
540 static GrBatchAtlas* create_atlas(GrContext* context, GrBatchAtlas::EvictionFunc
func, void* data) { | 532 static GrBatchAtlas* create_atlas(GrTextureProvider* provider, GrBatchAtlas::Evi
ctionFunc func, void* data) { |
541 GrBatchAtlas* atlas; | 533 GrBatchAtlas* atlas; |
542 // Create a new atlas | 534 // Create a new atlas |
543 GrSurfaceDesc desc; | 535 GrSurfaceDesc desc; |
544 desc.fFlags = kNone_GrSurfaceFlags; | 536 desc.fFlags = kNone_GrSurfaceFlags; |
545 desc.fWidth = ATLAS_TEXTURE_WIDTH; | 537 desc.fWidth = ATLAS_TEXTURE_WIDTH; |
546 desc.fHeight = ATLAS_TEXTURE_HEIGHT; | 538 desc.fHeight = ATLAS_TEXTURE_HEIGHT; |
547 desc.fConfig = kAlpha_8_GrPixelConfig; | 539 desc.fConfig = kAlpha_8_GrPixelConfig; |
548 | 540 |
549 // We don't want to flush the context so we claim we're in the middle of flu
shing so as to | 541 // We don't want to flush the context so we claim we're in the middle of flu
shing so as to |
550 // guarantee we do not recieve a texture with pending IO | 542 // guarantee we do not recieve a texture with pending IO |
551 GrTexture* texture = context->textureProvider()->refScratchTexture( | 543 GrTexture* texture = provider->refScratchTexture( |
552 desc, GrTextureProvider::kApprox_ScratchTexMatch, true); | 544 desc, GrTextureProvider::kApprox_ScratchTexMatch, true); |
553 if (texture) { | 545 if (texture) { |
554 atlas = SkNEW_ARGS(GrBatchAtlas, (texture, NUM_PLOTS_X, NUM_PLOTS_Y)); | 546 atlas = SkNEW_ARGS(GrBatchAtlas, (texture, NUM_PLOTS_X, NUM_PLOTS_Y)); |
555 } else { | 547 } else { |
556 return NULL; | 548 return NULL; |
557 } | 549 } |
558 atlas->registerEvictionCallback(func, data); | 550 atlas->registerEvictionCallback(func, data); |
559 return atlas; | 551 return atlas; |
560 } | 552 } |
561 | 553 |
562 bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target, | 554 bool GrAADistanceFieldPathRenderer::onDrawPath(const DrawPathArgs& args) { |
563 GrPipelineBuilder* pipelineBuilde
r, | |
564 GrColor color, | |
565 const SkMatrix& viewMatrix, | |
566 const SkPath& path, | |
567 const GrStrokeInfo& stroke, | |
568 bool antiAlias) { | |
569 // we've already bailed on inverse filled paths, so this is safe | 555 // we've already bailed on inverse filled paths, so this is safe |
570 if (path.isEmpty()) { | 556 if (args.fPath->isEmpty()) { |
571 return true; | 557 return true; |
572 } | 558 } |
573 | 559 |
574 SkASSERT(fContext); | |
575 | |
576 if (!fAtlas) { | 560 if (!fAtlas) { |
577 fAtlas = create_atlas(fContext, &GrAADistanceFieldPathRenderer::HandleEv
iction, | 561 fAtlas = create_atlas(args.fResourceProvider, |
578 (void*)this); | 562 &GrAADistanceFieldPathRenderer::HandleEviction, (v
oid*)this); |
579 if (!fAtlas) { | 563 if (!fAtlas) { |
580 return false; | 564 return false; |
581 } | 565 } |
582 } | 566 } |
583 | 567 |
584 AADistanceFieldPathBatch::Geometry geometry(stroke); | 568 AADistanceFieldPathBatch::Geometry geometry(*args.fStroke); |
585 geometry.fPath = path; | 569 geometry.fPath = *args.fPath; |
586 geometry.fAntiAlias = antiAlias; | 570 geometry.fAntiAlias = args.fAntiAlias; |
587 | 571 |
588 SkAutoTUnref<GrBatch> batch(AADistanceFieldPathBatch::Create(geometry, color
, viewMatrix, | 572 SkAutoTUnref<GrBatch> batch(AADistanceFieldPathBatch::Create(geometry, args.
fColor, |
589 fAtlas, &fPathC
ache, &fPathList)); | 573 *args.fViewMatr
ix, fAtlas, |
590 target->drawBatch(*pipelineBuilder, batch); | 574 &fPathCache, &f
PathList)); |
| 575 args.fTarget->drawBatch(*args.fPipelineBuilder, batch); |
591 | 576 |
592 return true; | 577 return true; |
593 } | 578 } |
594 | 579 |
595 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 580 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
596 | 581 |
597 #ifdef GR_TEST_UTILS | 582 #ifdef GR_TEST_UTILS |
598 | 583 |
599 struct PathTestStruct { | 584 struct PathTestStruct { |
600 typedef GrAADistanceFieldPathRenderer::PathCache PathCache; | 585 typedef GrAADistanceFieldPathRenderer::PathCache PathCache; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 PathCache fPathCache; | 622 PathCache fPathCache; |
638 PathDataList fPathList; | 623 PathDataList fPathList; |
639 }; | 624 }; |
640 | 625 |
641 BATCH_TEST_DEFINE(AADistanceFieldPathBatch) { | 626 BATCH_TEST_DEFINE(AADistanceFieldPathBatch) { |
642 static PathTestStruct gTestStruct; | 627 static PathTestStruct gTestStruct; |
643 | 628 |
644 if (context->uniqueID() != gTestStruct.fContextID) { | 629 if (context->uniqueID() != gTestStruct.fContextID) { |
645 gTestStruct.fContextID = context->uniqueID(); | 630 gTestStruct.fContextID = context->uniqueID(); |
646 gTestStruct.reset(); | 631 gTestStruct.reset(); |
647 gTestStruct.fAtlas = create_atlas(context, &PathTestStruct::HandleEvicti
on, | 632 gTestStruct.fAtlas = create_atlas(context->resourceProvider(), |
648 (void*)&gTestStruct); | 633 &PathTestStruct::HandleEviction, (void
*)&gTestStruct); |
649 } | 634 } |
650 | 635 |
651 SkMatrix viewMatrix = GrTest::TestMatrix(random); | 636 SkMatrix viewMatrix = GrTest::TestMatrix(random); |
652 GrColor color = GrRandomColor(random); | 637 GrColor color = GrRandomColor(random); |
653 | 638 |
654 AADistanceFieldPathBatch::Geometry geometry(GrTest::TestStrokeRec(random)); | 639 AADistanceFieldPathBatch::Geometry geometry(GrTest::TestStrokeRec(random)); |
655 geometry.fPath = GrTest::TestPath(random); | 640 geometry.fPath = GrTest::TestPath(random); |
656 geometry.fAntiAlias = random->nextBool(); | 641 geometry.fAntiAlias = random->nextBool(); |
657 | 642 |
658 return AADistanceFieldPathBatch::Create(geometry, color, viewMatrix, | 643 return AADistanceFieldPathBatch::Create(geometry, color, viewMatrix, |
659 gTestStruct.fAtlas, | 644 gTestStruct.fAtlas, |
660 &gTestStruct.fPathCache, | 645 &gTestStruct.fPathCache, |
661 &gTestStruct.fPathList); | 646 &gTestStruct.fPathList); |
662 } | 647 } |
663 | 648 |
664 #endif | 649 #endif |
OLD | NEW |