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 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 } | 58 } |
59 | 59 |
60 SkDELETE(fAtlas); | 60 SkDELETE(fAtlas); |
61 | 61 |
62 #ifdef DF_PATH_TRACKING | 62 #ifdef DF_PATH_TRACKING |
63 SkDebugf("Cached paths: %d, freed paths: %d\n", g_NumCachedPaths, g_NumFreed
Paths); | 63 SkDebugf("Cached paths: %d, freed paths: %d\n", g_NumCachedPaths, g_NumFreed
Paths); |
64 #endif | 64 #endif |
65 } | 65 } |
66 | 66 |
67 //////////////////////////////////////////////////////////////////////////////// | 67 //////////////////////////////////////////////////////////////////////////////// |
68 bool GrAADistanceFieldPathRenderer::canDrawPath(const SkPath& path, | 68 bool GrAADistanceFieldPathRenderer::canDrawPath(const GrDrawTarget* target, |
| 69 const GrDrawState* drawState, |
| 70 const SkPath& path, |
69 const SkStrokeRec& stroke, | 71 const SkStrokeRec& stroke, |
70 const GrDrawTarget* target, | |
71 bool antiAlias) const { | 72 bool antiAlias) const { |
72 | 73 |
73 // TODO: Support inverse fill | 74 // TODO: Support inverse fill |
74 // TODO: Support strokes | 75 // TODO: Support strokes |
75 if (!target->caps()->shaderDerivativeSupport() || !antiAlias || path.isInver
seFillType() | 76 if (!target->caps()->shaderDerivativeSupport() || !antiAlias || path.isInver
seFillType() |
76 || path.isVolatile() || SkStrokeRec::kFill_Style != stroke.getStyle()) { | 77 || path.isVolatile() || SkStrokeRec::kFill_Style != stroke.getStyle()) { |
77 return false; | 78 return false; |
78 } | 79 } |
79 | 80 |
80 // currently don't support perspective | 81 // currently don't support perspective |
81 const GrDrawState& drawState = target->getDrawState(); | 82 const SkMatrix& vm = drawState->getViewMatrix(); |
82 const SkMatrix& vm = drawState.getViewMatrix(); | |
83 if (vm.hasPerspective()) { | 83 if (vm.hasPerspective()) { |
84 return false; | 84 return false; |
85 } | 85 } |
86 | 86 |
87 // only support paths smaller than 64x64, scaled to less than 256x256 | 87 // only support paths smaller than 64x64, scaled to less than 256x256 |
88 // the goal is to accelerate rendering of lots of small paths that may be sc
aling | 88 // the goal is to accelerate rendering of lots of small paths that may be sc
aling |
89 SkScalar maxScale = vm.getMaxScale(); | 89 SkScalar maxScale = vm.getMaxScale(); |
90 const SkRect& bounds = path.getBounds(); | 90 const SkRect& bounds = path.getBounds(); |
91 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); | 91 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); |
92 return maxDim < 64.f && maxDim*maxScale < 256.f; | 92 return maxDim < 64.f && maxDim*maxScale < 256.f; |
93 } | 93 } |
94 | 94 |
95 | 95 |
96 GrPathRenderer::StencilSupport GrAADistanceFieldPathRenderer::onGetStencilSuppor
t( | 96 GrPathRenderer::StencilSupport |
97 const SkP
ath&, | 97 GrAADistanceFieldPathRenderer::onGetStencilSupport(const GrDrawTarget*, |
98 const SkS
trokeRec&, | 98 const GrDrawState*, |
99 const GrD
rawTarget*) const { | 99 const SkPath&, |
| 100 const SkStrokeRec&) const { |
100 return GrPathRenderer::kNoSupport_StencilSupport; | 101 return GrPathRenderer::kNoSupport_StencilSupport; |
101 } | 102 } |
102 | 103 |
103 //////////////////////////////////////////////////////////////////////////////// | 104 //////////////////////////////////////////////////////////////////////////////// |
104 | 105 |
105 // position + texture coord | 106 // position + texture coord |
106 extern const GrVertexAttrib gSDFPathVertexAttribs[] = { | 107 extern const GrVertexAttrib gSDFPathVertexAttribs[] = { |
107 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, | 108 { kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding }, |
108 { kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAtt
ribBinding } | 109 { kVec2f_GrVertexAttribType, sizeof(SkPoint), kGeometryProcessor_GrVertexAtt
ribBinding } |
109 }; | 110 }; |
110 static const size_t kSDFPathVASize = 2 * sizeof(SkPoint); | 111 static const size_t kSDFPathVASize = 2 * sizeof(SkPoint); |
111 | 112 |
112 bool GrAADistanceFieldPathRenderer::onDrawPath(const SkPath& path, | 113 bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target, |
| 114 GrDrawState* drawState, |
| 115 const SkPath& path, |
113 const SkStrokeRec& stroke, | 116 const SkStrokeRec& stroke, |
114 GrDrawTarget* target, | |
115 bool antiAlias) { | 117 bool antiAlias) { |
116 // we've already bailed on inverse filled paths, so this is safe | 118 // we've already bailed on inverse filled paths, so this is safe |
117 if (path.isEmpty()) { | 119 if (path.isEmpty()) { |
118 return true; | 120 return true; |
119 } | 121 } |
120 | 122 |
121 SkASSERT(fContext); | 123 SkASSERT(fContext); |
122 | 124 |
123 // get mip level | 125 // get mip level |
124 const GrDrawState& drawState = target->getDrawState(); | 126 const SkMatrix& vm = drawState->getViewMatrix(); |
125 const SkMatrix& vm = drawState.getViewMatrix(); | |
126 SkScalar maxScale = vm.getMaxScale(); | 127 SkScalar maxScale = vm.getMaxScale(); |
127 const SkRect& bounds = path.getBounds(); | 128 const SkRect& bounds = path.getBounds(); |
128 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); | 129 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); |
129 SkScalar size = maxScale*maxDim; | 130 SkScalar size = maxScale*maxDim; |
130 uint32_t desiredDimension; | 131 uint32_t desiredDimension; |
131 if (size <= kSmallMIP) { | 132 if (size <= kSmallMIP) { |
132 desiredDimension = kSmallMIP; | 133 desiredDimension = kSmallMIP; |
133 } else if (size <= kMediumMIP) { | 134 } else if (size <= kMediumMIP) { |
134 desiredDimension = kMediumMIP; | 135 desiredDimension = kMediumMIP; |
135 } else { | 136 } else { |
136 desiredDimension = kLargeMIP; | 137 desiredDimension = kLargeMIP; |
137 } | 138 } |
138 | 139 |
139 // check to see if path is cached | 140 // check to see if path is cached |
140 // TODO: handle stroked vs. filled version of same path | 141 // TODO: handle stroked vs. filled version of same path |
141 PathData::Key key = { path.getGenerationID(), desiredDimension }; | 142 PathData::Key key = { path.getGenerationID(), desiredDimension }; |
142 PathData* pathData = fPathCache.find(key); | 143 PathData* pathData = fPathCache.find(key); |
143 if (NULL == pathData) { | 144 if (NULL == pathData) { |
144 SkScalar scale = desiredDimension/maxDim; | 145 SkScalar scale = desiredDimension/maxDim; |
145 pathData = this->addPathToAtlas(path, stroke, antiAlias, desiredDimensio
n, scale); | 146 pathData = this->addPathToAtlas(path, stroke, antiAlias, desiredDimensio
n, scale); |
146 if (NULL == pathData) { | 147 if (NULL == pathData) { |
147 return false; | 148 return false; |
148 } | 149 } |
149 } | 150 } |
150 | 151 |
151 // use signed distance field to render | 152 // use signed distance field to render |
152 return this->internalDrawPath(path, pathData, target); | 153 return this->internalDrawPath(target, drawState, path, pathData); |
153 } | 154 } |
154 | 155 |
155 // padding around path bounds to allow for antialiased pixels | 156 // padding around path bounds to allow for antialiased pixels |
156 const SkScalar kAntiAliasPad = 1.0f; | 157 const SkScalar kAntiAliasPad = 1.0f; |
157 | 158 |
158 GrAADistanceFieldPathRenderer::PathData* GrAADistanceFieldPathRenderer::addPathT
oAtlas( | 159 GrAADistanceFieldPathRenderer::PathData* GrAADistanceFieldPathRenderer::addPathT
oAtlas( |
159 const Sk
Path& path, | 160 const Sk
Path& path, |
160 const Sk
StrokeRec& stroke, | 161 const Sk
StrokeRec& stroke, |
161 bool ant
iAlias, | 162 bool ant
iAlias, |
162 uint32_t
dimension, | 163 uint32_t
dimension, |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 #endif | 304 #endif |
304 } | 305 } |
305 } | 306 } |
306 | 307 |
307 // tell the atlas to free the plot | 308 // tell the atlas to free the plot |
308 GrAtlas::RemovePlot(&fPlotUsage, plot); | 309 GrAtlas::RemovePlot(&fPlotUsage, plot); |
309 | 310 |
310 return true; | 311 return true; |
311 } | 312 } |
312 | 313 |
313 bool GrAADistanceFieldPathRenderer::internalDrawPath(const SkPath& path, | 314 bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target, |
314 const PathData* pathData, | 315 GrDrawState* drawState, |
315 GrDrawTarget* target) { | 316 const SkPath& path, |
| 317 const PathData* pathData) { |
316 GrTexture* texture = fAtlas->getTexture(); | 318 GrTexture* texture = fAtlas->getTexture(); |
317 GrDrawState* drawState = target->drawState(); | |
318 GrDrawState::AutoRestoreEffects are(drawState); | 319 GrDrawState::AutoRestoreEffects are(drawState); |
319 | 320 |
320 SkASSERT(pathData->fPlot); | 321 SkASSERT(pathData->fPlot); |
321 GrDrawTarget::DrawToken drawToken = target->getCurrentDrawToken(); | 322 GrDrawTarget::DrawToken drawToken = target->getCurrentDrawToken(); |
322 pathData->fPlot->setDrawToken(drawToken); | 323 pathData->fPlot->setDrawToken(drawToken); |
323 | 324 |
324 // make me some vertices | 325 // make me some vertices |
325 drawState->setVertexAttribs<gSDFPathVertexAttribs>(SK_ARRAY_COUNT(gSDFPathVe
rtexAttribs), | 326 drawState->setVertexAttribs<gSDFPathVertexAttribs>(SK_ARRAY_COUNT(gSDFPathVe
rtexAttribs), |
326 kSDFPathVASize); | 327 kSDFPathVASize); |
327 void* vertices = NULL; | 328 void* vertices = NULL; |
328 bool success = target->reserveVertexAndIndexSpace(4, 0, &vertices, NULL); | 329 bool success = target->reserveVertexAndIndexSpace(4, drawState->getVertexStr
ide(), 0, &vertices, |
| 330 NULL); |
329 GrAlwaysAssert(success); | 331 GrAlwaysAssert(success); |
330 | 332 |
331 SkScalar dx = pathData->fBounds.fLeft; | 333 SkScalar dx = pathData->fBounds.fLeft; |
332 SkScalar dy = pathData->fBounds.fTop; | 334 SkScalar dy = pathData->fBounds.fTop; |
333 SkScalar width = pathData->fBounds.width(); | 335 SkScalar width = pathData->fBounds.width(); |
334 SkScalar height = pathData->fBounds.height(); | 336 SkScalar height = pathData->fBounds.height(); |
335 | 337 |
336 SkScalar invScale = 1.0f/pathData->fScale; | 338 SkScalar invScale = 1.0f/pathData->fScale; |
337 dx *= invScale; | 339 dx *= invScale; |
338 dy *= invScale; | 340 dy *= invScale; |
(...skipping 29 matching lines...) Expand all Loading... |
368 if (flags != fEffectFlags) { | 370 if (flags != fEffectFlags) { |
369 fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Crea
te(texture, | 371 fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Crea
te(texture, |
370
params, | 372
params, |
371
flags)); | 373
flags)); |
372 fEffectFlags = flags; | 374 fEffectFlags = flags; |
373 } | 375 } |
374 drawState->setGeometryProcessor(fCachedGeometryProcessor.get()); | 376 drawState->setGeometryProcessor(fCachedGeometryProcessor.get()); |
375 | 377 |
376 vm.mapRect(&r); | 378 vm.mapRect(&r); |
377 target->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); | 379 target->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); |
378 target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &r); | 380 target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6,
&r); |
379 target->resetVertexSource(); | 381 target->resetVertexSource(); |
380 | 382 |
381 return true; | 383 return true; |
382 } | 384 } |
383 | 385 |
OLD | NEW |