| 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 |