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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 GrDrawTarget* target, | 68 bool GrAADistanceFieldPathRenderer::canDrawPath(const GrDrawTarget* target, |
69 const GrDrawState* drawState, | 69 const GrDrawState* drawState, |
| 70 const SkMatrix& viewMatrix, |
70 const SkPath& path, | 71 const SkPath& path, |
71 const SkStrokeRec& stroke, | 72 const SkStrokeRec& stroke, |
72 bool antiAlias) const { | 73 bool antiAlias) const { |
73 | 74 |
74 // TODO: Support inverse fill | 75 // TODO: Support inverse fill |
75 // TODO: Support strokes | 76 // TODO: Support strokes |
76 if (!target->caps()->shaderDerivativeSupport() || !antiAlias || path.isInver
seFillType() | 77 if (!target->caps()->shaderDerivativeSupport() || !antiAlias || path.isInver
seFillType() |
77 || path.isVolatile() || SkStrokeRec::kFill_Style != stroke.getStyle()) { | 78 || path.isVolatile() || SkStrokeRec::kFill_Style != stroke.getStyle()) { |
78 return false; | 79 return false; |
79 } | 80 } |
80 | 81 |
81 // currently don't support perspective | 82 // currently don't support perspective |
82 const SkMatrix& vm = drawState->getViewMatrix(); | 83 if (viewMatrix.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 = viewMatrix.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 | 96 GrPathRenderer::StencilSupport |
97 GrAADistanceFieldPathRenderer::onGetStencilSupport(const GrDrawTarget*, | 97 GrAADistanceFieldPathRenderer::onGetStencilSupport(const GrDrawTarget*, |
98 const GrDrawState*, | 98 const GrDrawState*, |
99 const SkPath&, | 99 const SkPath&, |
100 const SkStrokeRec&) const { | 100 const SkStrokeRec&) const { |
101 return GrPathRenderer::kNoSupport_StencilSupport; | 101 return GrPathRenderer::kNoSupport_StencilSupport; |
102 } | 102 } |
103 | 103 |
104 //////////////////////////////////////////////////////////////////////////////// | 104 //////////////////////////////////////////////////////////////////////////////// |
105 | 105 |
106 bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target, | 106 bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target, |
107 GrDrawState* drawState, | 107 GrDrawState* drawState, |
108 GrColor color, | 108 GrColor color, |
| 109 const SkMatrix& viewMatrix, |
109 const SkPath& path, | 110 const SkPath& path, |
110 const SkStrokeRec& stroke, | 111 const SkStrokeRec& stroke, |
111 bool antiAlias) { | 112 bool antiAlias) { |
112 // we've already bailed on inverse filled paths, so this is safe | 113 // we've already bailed on inverse filled paths, so this is safe |
113 if (path.isEmpty()) { | 114 if (path.isEmpty()) { |
114 return true; | 115 return true; |
115 } | 116 } |
116 | 117 |
117 SkASSERT(fContext); | 118 SkASSERT(fContext); |
118 | 119 |
119 // get mip level | 120 // get mip level |
120 const SkMatrix& vm = drawState->getViewMatrix(); | 121 SkScalar maxScale = viewMatrix.getMaxScale(); |
121 SkScalar maxScale = vm.getMaxScale(); | |
122 const SkRect& bounds = path.getBounds(); | 122 const SkRect& bounds = path.getBounds(); |
123 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); | 123 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); |
124 SkScalar size = maxScale*maxDim; | 124 SkScalar size = maxScale*maxDim; |
125 uint32_t desiredDimension; | 125 uint32_t desiredDimension; |
126 if (size <= kSmallMIP) { | 126 if (size <= kSmallMIP) { |
127 desiredDimension = kSmallMIP; | 127 desiredDimension = kSmallMIP; |
128 } else if (size <= kMediumMIP) { | 128 } else if (size <= kMediumMIP) { |
129 desiredDimension = kMediumMIP; | 129 desiredDimension = kMediumMIP; |
130 } else { | 130 } else { |
131 desiredDimension = kLargeMIP; | 131 desiredDimension = kLargeMIP; |
132 } | 132 } |
133 | 133 |
134 // check to see if path is cached | 134 // check to see if path is cached |
135 // TODO: handle stroked vs. filled version of same path | 135 // TODO: handle stroked vs. filled version of same path |
136 PathData::Key key = { path.getGenerationID(), desiredDimension }; | 136 PathData::Key key = { path.getGenerationID(), desiredDimension }; |
137 PathData* pathData = fPathCache.find(key); | 137 PathData* pathData = fPathCache.find(key); |
138 if (NULL == pathData) { | 138 if (NULL == pathData) { |
139 SkScalar scale = desiredDimension/maxDim; | 139 SkScalar scale = desiredDimension/maxDim; |
140 pathData = this->addPathToAtlas(path, stroke, antiAlias, desiredDimensio
n, scale); | 140 pathData = this->addPathToAtlas(path, stroke, antiAlias, desiredDimensio
n, scale); |
141 if (NULL == pathData) { | 141 if (NULL == pathData) { |
142 return false; | 142 return false; |
143 } | 143 } |
144 } | 144 } |
145 | 145 |
146 // use signed distance field to render | 146 // use signed distance field to render |
147 return this->internalDrawPath(target, drawState, color, path, pathData); | 147 return this->internalDrawPath(target, drawState, color, viewMatrix, path, pa
thData); |
148 } | 148 } |
149 | 149 |
150 // padding around path bounds to allow for antialiased pixels | 150 // padding around path bounds to allow for antialiased pixels |
151 const SkScalar kAntiAliasPad = 1.0f; | 151 const SkScalar kAntiAliasPad = 1.0f; |
152 | 152 |
153 GrAADistanceFieldPathRenderer::PathData* GrAADistanceFieldPathRenderer::addPathT
oAtlas( | 153 GrAADistanceFieldPathRenderer::PathData* GrAADistanceFieldPathRenderer::addPathT
oAtlas( |
154 const Sk
Path& path, | 154 const Sk
Path& path, |
155 const Sk
StrokeRec& stroke, | 155 const Sk
StrokeRec& stroke, |
156 bool ant
iAlias, | 156 bool ant
iAlias, |
157 uint32_t
dimension, | 157 uint32_t
dimension, |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 | 301 |
302 // tell the atlas to free the plot | 302 // tell the atlas to free the plot |
303 GrAtlas::RemovePlot(&fPlotUsage, plot); | 303 GrAtlas::RemovePlot(&fPlotUsage, plot); |
304 | 304 |
305 return true; | 305 return true; |
306 } | 306 } |
307 | 307 |
308 bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target, | 308 bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target, |
309 GrDrawState* drawState, | 309 GrDrawState* drawState, |
310 GrColor color, | 310 GrColor color, |
| 311 const SkMatrix& viewMatrix, |
311 const SkPath& path, | 312 const SkPath& path, |
312 const PathData* pathData) { | 313 const PathData* pathData) { |
313 GrTexture* texture = fAtlas->getTexture(); | 314 GrTexture* texture = fAtlas->getTexture(); |
314 GrDrawState::AutoRestoreEffects are(drawState); | 315 GrDrawState::AutoRestoreEffects are(drawState); |
315 | 316 |
316 SkASSERT(pathData->fPlot); | 317 SkASSERT(pathData->fPlot); |
317 GrDrawTarget::DrawToken drawToken = target->getCurrentDrawToken(); | 318 GrDrawTarget::DrawToken drawToken = target->getCurrentDrawToken(); |
318 pathData->fPlot->setDrawToken(drawToken); | 319 pathData->fPlot->setDrawToken(drawToken); |
319 | 320 |
320 // set up any flags | 321 // set up any flags |
321 uint32_t flags = 0; | 322 uint32_t flags = 0; |
322 const SkMatrix& vm = drawState->getViewMatrix(); | 323 flags |= viewMatrix.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0
; |
323 flags |= vm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0; | |
324 | 324 |
325 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_
FilterMode); | 325 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBilerp_
FilterMode); |
326 if (flags != fEffectFlags || fCachedGeometryProcessor->color() != color) { | 326 if (flags != fEffectFlags || fCachedGeometryProcessor->color() != color || |
| 327 !fCachedGeometryProcessor->viewMatrix().cheapEqualTo(viewMatrix)) { |
327 fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Crea
te(color, | 328 fCachedGeometryProcessor.reset(GrDistanceFieldNoGammaTextureEffect::Crea
te(color, |
| 329
viewMatrix, |
328
texture, | 330
texture, |
329
params, | 331
params, |
330
flags, | 332
flags, |
331
false)); | 333
false)); |
332 fEffectFlags = flags; | 334 fEffectFlags = flags; |
333 } | 335 } |
334 | 336 |
335 void* vertices = NULL; | 337 void* vertices = NULL; |
336 bool success = target->reserveVertexAndIndexSpace(4, | 338 bool success = target->reserveVertexAndIndexSpace(4, |
337 fCachedGeometryProcessor->
getVertexStride(), | 339 fCachedGeometryProcessor->
getVertexStride(), |
(...skipping 25 matching lines...) Expand all Loading... |
363 | 365 |
364 // vertex texture coords | 366 // vertex texture coords |
365 intptr_t intPtr = reinterpret_cast<intptr_t>(positions); | 367 intptr_t intPtr = reinterpret_cast<intptr_t>(positions); |
366 SkPoint* textureCoords = reinterpret_cast<SkPoint*>(intPtr + vertSize - size
of(SkPoint)); | 368 SkPoint* textureCoords = reinterpret_cast<SkPoint*>(intPtr + vertSize - size
of(SkPoint)); |
367 textureCoords->setRectFan(SkFixedToFloat(texture->texturePriv().normalizeFix
edX(tx)), | 369 textureCoords->setRectFan(SkFixedToFloat(texture->texturePriv().normalizeFix
edX(tx)), |
368 SkFixedToFloat(texture->texturePriv().normalizeFix
edY(ty)), | 370 SkFixedToFloat(texture->texturePriv().normalizeFix
edY(ty)), |
369 SkFixedToFloat(texture->texturePriv().normalizeFix
edX(tx + tw)), | 371 SkFixedToFloat(texture->texturePriv().normalizeFix
edX(tx + tw)), |
370 SkFixedToFloat(texture->texturePriv().normalizeFix
edY(ty + th)), | 372 SkFixedToFloat(texture->texturePriv().normalizeFix
edY(ty + th)), |
371 vertSize); | 373 vertSize); |
372 | 374 |
373 vm.mapRect(&r); | 375 viewMatrix.mapRect(&r); |
374 target->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); | 376 target->setIndexSourceToBuffer(fContext->getQuadIndexBuffer()); |
375 target->drawIndexedInstances(drawState, fCachedGeometryProcessor.get(), | 377 target->drawIndexedInstances(drawState, fCachedGeometryProcessor.get(), |
376 kTriangles_GrPrimitiveType, 1, 4, 6, &r); | 378 kTriangles_GrPrimitiveType, 1, 4, 6, &r); |
377 target->resetVertexSource(); | 379 target->resetVertexSource(); |
378 | 380 |
379 return true; | 381 return true; |
380 } | 382 } |
381 | 383 |
OLD | NEW |