OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2014 Google Inc. | 2 * Copyright 2014 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 #include "GrAADistanceFieldPathRenderer.h" | 8 #include "GrAADistanceFieldPathRenderer.h" |
9 | 9 |
10 #include "GrBatchFlushState.h" | 10 #include "GrBatchFlushState.h" |
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
169 } | 169 } |
170 overrides.getOverrideColorIfSet(&fGeoData[0].fColor); | 170 overrides.getOverrideColorIfSet(&fGeoData[0].fColor); |
171 | 171 |
172 // setup batch properties | 172 // setup batch properties |
173 fBatch.fColorIgnored = !overrides.readsColor(); | 173 fBatch.fColorIgnored = !overrides.readsColor(); |
174 fBatch.fUsesLocalCoords = overrides.readsLocalCoords(); | 174 fBatch.fUsesLocalCoords = overrides.readsLocalCoords(); |
175 fBatch.fCoverageIgnored = !overrides.readsCoverage(); | 175 fBatch.fCoverageIgnored = !overrides.readsCoverage(); |
176 } | 176 } |
177 | 177 |
178 struct FlushInfo { | 178 struct FlushInfo { |
179 SkAutoTUnref<const GrBuffer> fVertexBuffer; | 179 SkAutoTUnref<const GrBuffer> fVertexBuffer; |
180 SkAutoTUnref<const GrBuffer> fIndexBuffer; | 180 SkAutoTUnref<const GrBuffer> fIndexBuffer; |
| 181 SkAutoTUnref<const GrGeometryProcessor> fGeometryProcessor; |
181 int fVertexOffset; | 182 int fVertexOffset; |
182 int fInstancesToFlush; | 183 int fInstancesToFlush; |
183 }; | 184 }; |
184 | 185 |
185 void onPrepareDraws(Target* target) const override { | 186 void onPrepareDraws(Target* target) const override { |
186 int instanceCount = fGeoData.count(); | 187 int instanceCount = fGeoData.count(); |
187 | 188 |
188 SkMatrix invert; | 189 SkMatrix invert; |
189 if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { | 190 if (this->usesLocalCoords() && !this->viewMatrix().invert(&invert)) { |
190 SkDebugf("Could not invert viewmatrix\n"); | 191 SkDebugf("Could not invert viewmatrix\n"); |
191 return; | 192 return; |
192 } | 193 } |
193 | 194 |
194 const SkMatrix& ctm = this->viewMatrix(); | 195 const SkMatrix& ctm = this->viewMatrix(); |
195 uint32_t flags = 0; | 196 uint32_t flags = 0; |
196 flags |= ctm.isScaleTranslate() ? kScaleOnly_DistanceFieldEffectFlag : 0
; | 197 flags |= ctm.isScaleTranslate() ? kScaleOnly_DistanceFieldEffectFlag : 0
; |
197 flags |= ctm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0; | 198 flags |= ctm.isSimilarity() ? kSimilarity_DistanceFieldEffectFlag : 0; |
198 | 199 |
199 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBil
erp_FilterMode); | 200 GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kBil
erp_FilterMode); |
200 | 201 |
| 202 FlushInfo flushInfo; |
| 203 |
201 // Setup GrGeometryProcessor | 204 // Setup GrGeometryProcessor |
202 GrBatchAtlas* atlas = fAtlas; | 205 GrBatchAtlas* atlas = fAtlas; |
203 SkAutoTUnref<GrGeometryProcessor> dfProcessor( | 206 flushInfo.fGeometryProcessor.reset( |
204 GrDistanceFieldPathGeoProc::Create(this->color(), | 207 GrDistanceFieldPathGeoProc::Create(this->color(), |
205 this->viewMatrix(), | 208 this->viewMatrix(), |
206 atlas->getTexture(), | 209 atlas->getTexture(), |
207 params, | 210 params, |
208 flags, | 211 flags, |
209 this->usesLocalCoords())); | 212 this->usesLocalCoords())); |
210 | 213 |
211 target->initDraw(dfProcessor); | |
212 | |
213 FlushInfo flushInfo; | |
214 | |
215 // allocate vertices | 214 // allocate vertices |
216 size_t vertexStride = dfProcessor->getVertexStride(); | 215 size_t vertexStride = flushInfo.fGeometryProcessor->getVertexStride(); |
217 SkASSERT(vertexStride == 2 * sizeof(SkPoint) + sizeof(GrColor)); | 216 SkASSERT(vertexStride == 2 * sizeof(SkPoint) + sizeof(GrColor)); |
218 | 217 |
219 const GrBuffer* vertexBuffer; | 218 const GrBuffer* vertexBuffer; |
220 void* vertices = target->makeVertexSpace(vertexStride, | 219 void* vertices = target->makeVertexSpace(vertexStride, |
221 kVerticesPerQuad * instanceCoun
t, | 220 kVerticesPerQuad * instanceCoun
t, |
222 &vertexBuffer, | 221 &vertexBuffer, |
223 &flushInfo.fVertexOffset); | 222 &flushInfo.fVertexOffset); |
224 flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer)); | 223 flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer)); |
225 flushInfo.fIndexBuffer.reset(target->resourceProvider()->refQuadIndexBuf
fer()); | 224 flushInfo.fIndexBuffer.reset(target->resourceProvider()->refQuadIndexBuf
fer()); |
226 if (!vertices || !flushInfo.fIndexBuffer) { | 225 if (!vertices || !flushInfo.fIndexBuffer) { |
(...skipping 25 matching lines...) Expand all Loading... |
252 if (nullptr == pathData || !atlas->hasID(pathData->fID)) { | 251 if (nullptr == pathData || !atlas->hasID(pathData->fID)) { |
253 // Remove the stale cache entry | 252 // Remove the stale cache entry |
254 if (pathData) { | 253 if (pathData) { |
255 fPathCache->remove(pathData->fKey); | 254 fPathCache->remove(pathData->fKey); |
256 fPathList->remove(pathData); | 255 fPathList->remove(pathData); |
257 delete pathData; | 256 delete pathData; |
258 } | 257 } |
259 SkScalar scale = desiredDimension/maxDim; | 258 SkScalar scale = desiredDimension/maxDim; |
260 pathData = new PathData; | 259 pathData = new PathData; |
261 if (!this->addPathToAtlas(target, | 260 if (!this->addPathToAtlas(target, |
262 dfProcessor, | |
263 this->pipeline(), | |
264 &flushInfo, | 261 &flushInfo, |
265 atlas, | 262 atlas, |
266 pathData, | 263 pathData, |
267 args.fPath, | 264 args.fPath, |
268 args.fGenID, | 265 args.fGenID, |
269 args.fStroke, | 266 args.fStroke, |
270 args.fAntiAlias, | 267 args.fAntiAlias, |
271 desiredDimension, | 268 desiredDimension, |
272 scale)) { | 269 scale)) { |
273 SkDebugf("Can't rasterize path\n"); | 270 SkDebugf("Can't rasterize path\n"); |
274 return; | 271 return; |
275 } | 272 } |
276 } | 273 } |
277 | 274 |
278 atlas->setLastUseToken(pathData->fID, target->currentToken()); | 275 atlas->setLastUseToken(pathData->fID, target->nextDrawToken()); |
279 | 276 |
280 // Now set vertices | 277 // Now set vertices |
281 intptr_t offset = reinterpret_cast<intptr_t>(vertices); | 278 intptr_t offset = reinterpret_cast<intptr_t>(vertices); |
282 offset += i * kVerticesPerQuad * vertexStride; | 279 offset += i * kVerticesPerQuad * vertexStride; |
283 this->writePathVertices(target, | 280 this->writePathVertices(target, |
284 atlas, | 281 atlas, |
285 this->pipeline(), | |
286 dfProcessor, | |
287 offset, | 282 offset, |
288 args.fColor, | 283 args.fColor, |
289 vertexStride, | 284 vertexStride, |
290 this->viewMatrix(), | 285 this->viewMatrix(), |
291 args.fPath, | 286 args.fPath, |
292 pathData); | 287 pathData); |
293 flushInfo.fInstancesToFlush++; | 288 flushInfo.fInstancesToFlush++; |
294 } | 289 } |
295 | 290 |
296 this->flush(target, &flushInfo); | 291 this->flush(target, &flushInfo); |
(...skipping 12 matching lines...) Expand all Loading... |
309 fAtlas = atlas; | 304 fAtlas = atlas; |
310 fPathCache = pathCache; | 305 fPathCache = pathCache; |
311 fPathList = pathList; | 306 fPathList = pathList; |
312 | 307 |
313 // Compute bounds | 308 // Compute bounds |
314 fBounds = geometry.fPath.getBounds(); | 309 fBounds = geometry.fPath.getBounds(); |
315 viewMatrix.mapRect(&fBounds); | 310 viewMatrix.mapRect(&fBounds); |
316 } | 311 } |
317 | 312 |
318 bool addPathToAtlas(GrVertexBatch::Target* target, | 313 bool addPathToAtlas(GrVertexBatch::Target* target, |
319 const GrGeometryProcessor* dfProcessor, | |
320 const GrPipeline* pipeline, | |
321 FlushInfo* flushInfo, | 314 FlushInfo* flushInfo, |
322 GrBatchAtlas* atlas, | 315 GrBatchAtlas* atlas, |
323 PathData* pathData, | 316 PathData* pathData, |
324 const SkPath& path, | 317 const SkPath& path, |
325 uint32_t genID, | 318 uint32_t genID, |
326 const SkStrokeRec& stroke, | 319 const SkStrokeRec& stroke, |
327 bool antiAlias, | 320 bool antiAlias, |
328 uint32_t dimension, | 321 uint32_t dimension, |
329 SkScalar scale) const { | 322 SkScalar scale) const { |
330 const SkRect& bounds = path.getBounds(); | 323 const SkRect& bounds = path.getBounds(); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 (const unsigned char*)dst.addr(), | 392 (const unsigned char*)dst.addr(), |
400 dst.width(), dst.height(), dst.rowByt
es()); | 393 dst.width(), dst.height(), dst.rowByt
es()); |
401 | 394 |
402 // add to atlas | 395 // add to atlas |
403 SkIPoint16 atlasLocation; | 396 SkIPoint16 atlasLocation; |
404 GrBatchAtlas::AtlasID id; | 397 GrBatchAtlas::AtlasID id; |
405 bool success = atlas->addToAtlas(&id, target, width, height, dfStorage.g
et(), | 398 bool success = atlas->addToAtlas(&id, target, width, height, dfStorage.g
et(), |
406 &atlasLocation); | 399 &atlasLocation); |
407 if (!success) { | 400 if (!success) { |
408 this->flush(target, flushInfo); | 401 this->flush(target, flushInfo); |
409 target->initDraw(dfProcessor); | |
410 | 402 |
411 SkDEBUGCODE(success =) atlas->addToAtlas(&id, target, width, height, | 403 SkDEBUGCODE(success =) atlas->addToAtlas(&id, target, width, height, |
412 dfStorage.get(), &atlasLoca
tion); | 404 dfStorage.get(), &atlasLoca
tion); |
413 SkASSERT(success); | 405 SkASSERT(success); |
414 | 406 |
415 } | 407 } |
416 | 408 |
417 // add to cache | 409 // add to cache |
418 pathData->fKey = PathData::Key(genID, dimension, stroke); | 410 pathData->fKey = PathData::Key(genID, dimension, stroke); |
419 pathData->fScale = scale; | 411 pathData->fScale = scale; |
(...skipping 16 matching lines...) Expand all Loading... |
436 fPathCache->add(pathData); | 428 fPathCache->add(pathData); |
437 fPathList->addToTail(pathData); | 429 fPathList->addToTail(pathData); |
438 #ifdef DF_PATH_TRACKING | 430 #ifdef DF_PATH_TRACKING |
439 ++g_NumCachedPaths; | 431 ++g_NumCachedPaths; |
440 #endif | 432 #endif |
441 return true; | 433 return true; |
442 } | 434 } |
443 | 435 |
444 void writePathVertices(GrDrawBatch::Target* target, | 436 void writePathVertices(GrDrawBatch::Target* target, |
445 GrBatchAtlas* atlas, | 437 GrBatchAtlas* atlas, |
446 const GrPipeline* pipeline, | |
447 const GrGeometryProcessor* gp, | |
448 intptr_t offset, | 438 intptr_t offset, |
449 GrColor color, | 439 GrColor color, |
450 size_t vertexStride, | 440 size_t vertexStride, |
451 const SkMatrix& viewMatrix, | 441 const SkMatrix& viewMatrix, |
452 const SkPath& path, | 442 const SkPath& path, |
453 const PathData* pathData) const { | 443 const PathData* pathData) const { |
454 GrTexture* texture = atlas->getTexture(); | 444 GrTexture* texture = atlas->getTexture(); |
455 | 445 |
456 SkScalar dx = pathData->fBounds.fLeft; | 446 SkScalar dx = pathData->fBounds.fLeft; |
457 SkScalar dy = pathData->fBounds.fTop; | 447 SkScalar dy = pathData->fBounds.fTop; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
489 vertexStride); | 479 vertexStride); |
490 } | 480 } |
491 | 481 |
492 void flush(GrVertexBatch::Target* target, FlushInfo* flushInfo) const { | 482 void flush(GrVertexBatch::Target* target, FlushInfo* flushInfo) const { |
493 GrMesh mesh; | 483 GrMesh mesh; |
494 int maxInstancesPerDraw = | 484 int maxInstancesPerDraw = |
495 static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(u
int16_t) / 6); | 485 static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(u
int16_t) / 6); |
496 mesh.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer, | 486 mesh.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer, |
497 flushInfo->fIndexBuffer, flushInfo->fVertexOffset, kVerticesPerQuad, | 487 flushInfo->fIndexBuffer, flushInfo->fVertexOffset, kVerticesPerQuad, |
498 kIndicesPerQuad, flushInfo->fInstancesToFlush, maxInstancesPerDraw); | 488 kIndicesPerQuad, flushInfo->fInstancesToFlush, maxInstancesPerDraw); |
499 target->draw(mesh); | 489 target->draw(flushInfo->fGeometryProcessor, mesh); |
500 flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFl
ush; | 490 flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFl
ush; |
501 flushInfo->fInstancesToFlush = 0; | 491 flushInfo->fInstancesToFlush = 0; |
502 } | 492 } |
503 | 493 |
504 GrColor color() const { return fGeoData[0].fColor; } | 494 GrColor color() const { return fGeoData[0].fColor; } |
505 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } | 495 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } |
506 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 496 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
507 | 497 |
508 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 498 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
509 AADistanceFieldPathBatch* that = t->cast<AADistanceFieldPathBatch>(); | 499 AADistanceFieldPathBatch* that = t->cast<AADistanceFieldPathBatch>(); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
647 geometry.fAntiAlias = random->nextBool(); | 637 geometry.fAntiAlias = random->nextBool(); |
648 geometry.fGenID = random->nextU(); | 638 geometry.fGenID = random->nextU(); |
649 | 639 |
650 return AADistanceFieldPathBatch::Create(geometry, viewMatrix, | 640 return AADistanceFieldPathBatch::Create(geometry, viewMatrix, |
651 gTestStruct.fAtlas, | 641 gTestStruct.fAtlas, |
652 &gTestStruct.fPathCache, | 642 &gTestStruct.fPathCache, |
653 &gTestStruct.fPathList); | 643 &gTestStruct.fPathList); |
654 } | 644 } |
655 | 645 |
656 #endif | 646 #endif |
OLD | NEW |