| 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 79 #ifdef DF_PATH_TRACKING | 79 #ifdef DF_PATH_TRACKING |
| 80 SkDebugf("Cached paths: %d, freed paths: %d\n", g_NumCachedPaths, g_NumFreed
Paths); | 80 SkDebugf("Cached paths: %d, freed paths: %d\n", g_NumCachedPaths, g_NumFreed
Paths); |
| 81 #endif | 81 #endif |
| 82 } | 82 } |
| 83 | 83 |
| 84 //////////////////////////////////////////////////////////////////////////////// | 84 //////////////////////////////////////////////////////////////////////////////// |
| 85 bool GrAADistanceFieldPathRenderer::canDrawPath(const GrDrawTarget* target, | 85 bool GrAADistanceFieldPathRenderer::canDrawPath(const GrDrawTarget* target, |
| 86 const GrPipelineBuilder* pipelin
eBuilder, | 86 const GrPipelineBuilder* pipelin
eBuilder, |
| 87 const SkMatrix& viewMatrix, | 87 const SkMatrix& viewMatrix, |
| 88 const SkPath& path, | 88 const SkPath& path, |
| 89 const SkStrokeRec& stroke, | 89 const GrStrokeInfo& stroke, |
| 90 bool antiAlias) const { | 90 bool antiAlias) const { |
| 91 | 91 |
| 92 // TODO: Support inverse fill | 92 // TODO: Support inverse fill |
| 93 // TODO: Support strokes | 93 // TODO: Support strokes |
| 94 if (!target->caps()->shaderDerivativeSupport() || !antiAlias || path.isInver
seFillType() | 94 if (!target->caps()->shaderDerivativeSupport() || !antiAlias || path.isInver
seFillType() |
| 95 || path.isVolatile() || SkStrokeRec::kFill_Style != stroke.getStyle()) { | 95 || path.isVolatile() || !stroke.isFillStyle()) { |
| 96 return false; | 96 return false; |
| 97 } | 97 } |
| 98 | 98 |
| 99 // currently don't support perspective | 99 // currently don't support perspective |
| 100 if (viewMatrix.hasPerspective()) { | 100 if (viewMatrix.hasPerspective()) { |
| 101 return false; | 101 return false; |
| 102 } | 102 } |
| 103 | 103 |
| 104 // only support paths smaller than 64x64, scaled to less than 256x256 | 104 // only support paths smaller than 64x64, scaled to less than 256x256 |
| 105 // the goal is to accelerate rendering of lots of small paths that may be sc
aling | 105 // the goal is to accelerate rendering of lots of small paths that may be sc
aling |
| 106 SkScalar maxScale = viewMatrix.getMaxScale(); | 106 SkScalar maxScale = viewMatrix.getMaxScale(); |
| 107 const SkRect& bounds = path.getBounds(); | 107 const SkRect& bounds = path.getBounds(); |
| 108 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); | 108 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); |
| 109 return maxDim < 64.f && maxDim * maxScale < 256.f; | 109 return maxDim < 64.f && maxDim * maxScale < 256.f; |
| 110 } | 110 } |
| 111 | 111 |
| 112 | 112 |
| 113 GrPathRenderer::StencilSupport | 113 GrPathRenderer::StencilSupport |
| 114 GrAADistanceFieldPathRenderer::onGetStencilSupport(const GrDrawTarget*, | 114 GrAADistanceFieldPathRenderer::onGetStencilSupport(const GrDrawTarget*, |
| 115 const GrPipelineBuilder*, | 115 const GrPipelineBuilder*, |
| 116 const SkPath&, | 116 const SkPath&, |
| 117 const SkStrokeRec&) const { | 117 const GrStrokeInfo&) const { |
| 118 return GrPathRenderer::kNoSupport_StencilSupport; | 118 return GrPathRenderer::kNoSupport_StencilSupport; |
| 119 } | 119 } |
| 120 | 120 |
| 121 //////////////////////////////////////////////////////////////////////////////// | 121 //////////////////////////////////////////////////////////////////////////////// |
| 122 | 122 |
| 123 // padding around path bounds to allow for antialiased pixels | 123 // padding around path bounds to allow for antialiased pixels |
| 124 static const SkScalar kAntiAliasPad = 1.0f; | 124 static const SkScalar kAntiAliasPad = 1.0f; |
| 125 | 125 |
| 126 class AADistanceFieldPathBatch : public GrBatch { | 126 class AADistanceFieldPathBatch : public GrBatch { |
| 127 public: | 127 public: |
| (...skipping 435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 563 GrBatchAtlas* fAtlas; | 563 GrBatchAtlas* fAtlas; |
| 564 PathCache* fPathCache; | 564 PathCache* fPathCache; |
| 565 PathDataList* fPathList; | 565 PathDataList* fPathList; |
| 566 }; | 566 }; |
| 567 | 567 |
| 568 bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target, | 568 bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target, |
| 569 GrPipelineBuilder* pipelineBuilde
r, | 569 GrPipelineBuilder* pipelineBuilde
r, |
| 570 GrColor color, | 570 GrColor color, |
| 571 const SkMatrix& viewMatrix, | 571 const SkMatrix& viewMatrix, |
| 572 const SkPath& path, | 572 const SkPath& path, |
| 573 const SkStrokeRec& stroke, | 573 const GrStrokeInfo& stroke, |
| 574 bool antiAlias) { | 574 bool antiAlias) { |
| 575 // we've already bailed on inverse filled paths, so this is safe | 575 // we've already bailed on inverse filled paths, so this is safe |
| 576 if (path.isEmpty()) { | 576 if (path.isEmpty()) { |
| 577 return true; | 577 return true; |
| 578 } | 578 } |
| 579 | 579 |
| 580 SkASSERT(fContext); | 580 SkASSERT(fContext); |
| 581 | 581 |
| 582 if (!fAtlas) { | 582 if (!fAtlas) { |
| 583 // Create a new atlas | 583 // Create a new atlas |
| 584 GrSurfaceDesc desc; | 584 GrSurfaceDesc desc; |
| 585 desc.fFlags = kNone_GrSurfaceFlags; | 585 desc.fFlags = kNone_GrSurfaceFlags; |
| 586 desc.fWidth = ATLAS_TEXTURE_WIDTH; | 586 desc.fWidth = ATLAS_TEXTURE_WIDTH; |
| 587 desc.fHeight = ATLAS_TEXTURE_HEIGHT; | 587 desc.fHeight = ATLAS_TEXTURE_HEIGHT; |
| 588 desc.fConfig = kAlpha_8_GrPixelConfig; | 588 desc.fConfig = kAlpha_8_GrPixelConfig; |
| 589 | 589 |
| 590 // We don't want to flush the context so we claim we're in the middle of
flushing so as to | 590 // We don't want to flush the context so we claim we're in the middle of
flushing so as to |
| 591 // guarantee we do not recieve a texture with pending IO | 591 // guarantee we do not recieve a texture with pending IO |
| 592 GrTexture* texture = fContext->refScratchTexture(desc, GrContext::kAppro
x_ScratchTexMatch, | 592 GrTexture* texture = fContext->refScratchTexture(desc, GrContext::kAppro
x_ScratchTexMatch, |
| 593 true); | 593 true); |
| 594 if (texture) { | 594 if (texture) { |
| 595 fAtlas = SkNEW_ARGS(GrBatchAtlas, (texture, NUM_PLOTS_X, NUM_PLOTS_Y
)); | 595 fAtlas = SkNEW_ARGS(GrBatchAtlas, (texture, NUM_PLOTS_X, NUM_PLOTS_Y
)); |
| 596 } else { | 596 } else { |
| 597 return false; | 597 return false; |
| 598 } | 598 } |
| 599 fAtlas->registerEvictionCallback(&GrAADistanceFieldPathRenderer::HandleE
viction, | 599 fAtlas->registerEvictionCallback(&GrAADistanceFieldPathRenderer::HandleE
viction, |
| 600 (void*)this); | 600 (void*)this); |
| 601 } | 601 } |
| 602 | 602 |
| 603 AADistanceFieldPathBatch::Geometry geometry(stroke); | 603 AADistanceFieldPathBatch::Geometry geometry(stroke.getStrokeRec()); |
| 604 geometry.fPath = path; | 604 geometry.fPath = path; |
| 605 geometry.fAntiAlias = antiAlias; | 605 geometry.fAntiAlias = antiAlias; |
| 606 | 606 |
| 607 SkAutoTUnref<GrBatch> batch(AADistanceFieldPathBatch::Create(geometry, color
, viewMatrix, | 607 SkAutoTUnref<GrBatch> batch(AADistanceFieldPathBatch::Create(geometry, color
, viewMatrix, |
| 608 fAtlas, &fPathC
ache, &fPathList)); | 608 fAtlas, &fPathC
ache, &fPathList)); |
| 609 | 609 |
| 610 SkRect bounds = path.getBounds(); | 610 SkRect bounds = path.getBounds(); |
| 611 viewMatrix.mapRect(&bounds); | 611 viewMatrix.mapRect(&bounds); |
| 612 target->drawBatch(pipelineBuilder, batch, &bounds); | 612 target->drawBatch(pipelineBuilder, batch, &bounds); |
| 613 | 613 |
| 614 return true; | 614 return true; |
| 615 } | 615 } |
| 616 | 616 |
| OLD | NEW |