| 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 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 219 &vertexBuffer, | 219 &vertexBuffer, |
| 220 &flushInfo.fVertexOffset); | 220 &flushInfo.fVertexOffset); |
| 221 flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer)); | 221 flushInfo.fVertexBuffer.reset(SkRef(vertexBuffer)); |
| 222 flushInfo.fIndexBuffer.reset(target->resourceProvider()->refQuadIndexBuf
fer()); | 222 flushInfo.fIndexBuffer.reset(target->resourceProvider()->refQuadIndexBuf
fer()); |
| 223 if (!vertices || !flushInfo.fIndexBuffer) { | 223 if (!vertices || !flushInfo.fIndexBuffer) { |
| 224 SkDebugf("Could not allocate vertices\n"); | 224 SkDebugf("Could not allocate vertices\n"); |
| 225 return; | 225 return; |
| 226 } | 226 } |
| 227 | 227 |
| 228 flushInfo.fInstancesToFlush = 0; | 228 flushInfo.fInstancesToFlush = 0; |
| 229 // Pointer to the next set of vertices to write. |
| 230 intptr_t offset = reinterpret_cast<intptr_t>(vertices); |
| 229 for (int i = 0; i < instanceCount; i++) { | 231 for (int i = 0; i < instanceCount; i++) { |
| 230 const Geometry& args = fGeoData[i]; | 232 const Geometry& args = fGeoData[i]; |
| 231 | 233 |
| 232 // get mip level | 234 // get mip level |
| 233 SkScalar maxScale = this->viewMatrix().getMaxScale(); | 235 SkScalar maxScale = this->viewMatrix().getMaxScale(); |
| 234 const SkRect& bounds = args.fShape.bounds(); | 236 const SkRect& bounds = args.fShape.bounds(); |
| 235 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); | 237 SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height()); |
| 236 SkScalar size = maxScale * maxDim; | 238 SkScalar size = maxScale * maxDim; |
| 237 uint32_t desiredDimension; | 239 uint32_t desiredDimension; |
| 238 if (size <= kSmallMIP) { | 240 if (size <= kSmallMIP) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 256 SkScalar scale = desiredDimension/maxDim; | 258 SkScalar scale = desiredDimension/maxDim; |
| 257 shapeData = new ShapeData; | 259 shapeData = new ShapeData; |
| 258 if (!this->addPathToAtlas(target, | 260 if (!this->addPathToAtlas(target, |
| 259 &flushInfo, | 261 &flushInfo, |
| 260 atlas, | 262 atlas, |
| 261 shapeData, | 263 shapeData, |
| 262 args.fShape, | 264 args.fShape, |
| 263 args.fAntiAlias, | 265 args.fAntiAlias, |
| 264 desiredDimension, | 266 desiredDimension, |
| 265 scale)) { | 267 scale)) { |
| 268 delete shapeData; |
| 266 SkDebugf("Can't rasterize path\n"); | 269 SkDebugf("Can't rasterize path\n"); |
| 267 return; | 270 continue; |
| 268 } | 271 } |
| 269 } | 272 } |
| 270 | 273 |
| 271 atlas->setLastUseToken(shapeData->fID, target->nextDrawToken()); | 274 atlas->setLastUseToken(shapeData->fID, target->nextDrawToken()); |
| 272 | 275 |
| 273 // Now set vertices | |
| 274 intptr_t offset = reinterpret_cast<intptr_t>(vertices); | |
| 275 offset += i * kVerticesPerQuad * vertexStride; | |
| 276 this->writePathVertices(target, | 276 this->writePathVertices(target, |
| 277 atlas, | 277 atlas, |
| 278 offset, | 278 offset, |
| 279 args.fColor, | 279 args.fColor, |
| 280 vertexStride, | 280 vertexStride, |
| 281 this->viewMatrix(), | 281 this->viewMatrix(), |
| 282 args.fShape, | |
| 283 shapeData); | 282 shapeData); |
| 283 offset += kVerticesPerQuad * vertexStride; |
| 284 flushInfo.fInstancesToFlush++; | 284 flushInfo.fInstancesToFlush++; |
| 285 } | 285 } |
| 286 | 286 |
| 287 this->flush(target, &flushInfo); | 287 this->flush(target, &flushInfo); |
| 288 } | 288 } |
| 289 | 289 |
| 290 bool addPathToAtlas(GrVertexBatch::Target* target, | 290 bool addPathToAtlas(GrVertexBatch::Target* target, |
| 291 FlushInfo* flushInfo, | 291 FlushInfo* flushInfo, |
| 292 GrBatchAtlas* atlas, | 292 GrBatchAtlas* atlas, |
| 293 ShapeData* shapeData, | 293 ShapeData* shapeData, |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 SkAutoSMalloc<1024> dfStorage(width * height * sizeof(unsigned char)); | 364 SkAutoSMalloc<1024> dfStorage(width * height * sizeof(unsigned char)); |
| 365 | 365 |
| 366 // Generate signed distance field | 366 // Generate signed distance field |
| 367 SkGenerateDistanceFieldFromA8Image((unsigned char*)dfStorage.get(), | 367 SkGenerateDistanceFieldFromA8Image((unsigned char*)dfStorage.get(), |
| 368 (const unsigned char*)dst.addr(), | 368 (const unsigned char*)dst.addr(), |
| 369 dst.width(), dst.height(), dst.rowByt
es()); | 369 dst.width(), dst.height(), dst.rowByt
es()); |
| 370 | 370 |
| 371 // add to atlas | 371 // add to atlas |
| 372 SkIPoint16 atlasLocation; | 372 SkIPoint16 atlasLocation; |
| 373 GrBatchAtlas::AtlasID id; | 373 GrBatchAtlas::AtlasID id; |
| 374 bool success = atlas->addToAtlas(&id, target, width, height, dfStorage.g
et(), | 374 if (!atlas->addToAtlas(&id, target, width, height, dfStorage.get(), &atla
sLocation)) { |
| 375 &atlasLocation); | |
| 376 if (!success) { | |
| 377 this->flush(target, flushInfo); | 375 this->flush(target, flushInfo); |
| 378 | 376 if (!atlas->addToAtlas(&id, target, width, height, dfStorage.get(),
&atlasLocation)) { |
| 379 SkDEBUGCODE(success =) atlas->addToAtlas(&id, target, width, height, | 377 return false; |
| 380 dfStorage.get(), &atlasLoca
tion); | 378 } |
| 381 SkASSERT(success); | |
| 382 | |
| 383 } | 379 } |
| 384 | 380 |
| 385 // add to cache | 381 // add to cache |
| 386 shapeData->fKey.set(shape, dimension); | 382 shapeData->fKey.set(shape, dimension); |
| 387 shapeData->fScale = scale; | 383 shapeData->fScale = scale; |
| 388 shapeData->fID = id; | 384 shapeData->fID = id; |
| 389 // change the scaled rect to match the size of the inset distance field | 385 // change the scaled rect to match the size of the inset distance field |
| 390 scaledBounds.fRight = scaledBounds.fLeft + | 386 scaledBounds.fRight = scaledBounds.fLeft + |
| 391 SkIntToScalar(devPathBounds.width() - 2*SK_DistanceFieldInset); | 387 SkIntToScalar(devPathBounds.width() - 2*SK_DistanceFieldInset); |
| 392 scaledBounds.fBottom = scaledBounds.fTop + | 388 scaledBounds.fBottom = scaledBounds.fTop + |
| (...skipping 15 matching lines...) Expand all Loading... |
| 408 #endif | 404 #endif |
| 409 return true; | 405 return true; |
| 410 } | 406 } |
| 411 | 407 |
| 412 void writePathVertices(GrDrawBatch::Target* target, | 408 void writePathVertices(GrDrawBatch::Target* target, |
| 413 GrBatchAtlas* atlas, | 409 GrBatchAtlas* atlas, |
| 414 intptr_t offset, | 410 intptr_t offset, |
| 415 GrColor color, | 411 GrColor color, |
| 416 size_t vertexStride, | 412 size_t vertexStride, |
| 417 const SkMatrix& viewMatrix, | 413 const SkMatrix& viewMatrix, |
| 418 const GrShape& shape, | |
| 419 const ShapeData* shapeData) const { | 414 const ShapeData* shapeData) const { |
| 420 GrTexture* texture = atlas->getTexture(); | 415 GrTexture* texture = atlas->getTexture(); |
| 421 | 416 |
| 422 SkScalar dx = shapeData->fBounds.fLeft; | 417 SkScalar dx = shapeData->fBounds.fLeft; |
| 423 SkScalar dy = shapeData->fBounds.fTop; | 418 SkScalar dy = shapeData->fBounds.fTop; |
| 424 SkScalar width = shapeData->fBounds.width(); | 419 SkScalar width = shapeData->fBounds.width(); |
| 425 SkScalar height = shapeData->fBounds.height(); | 420 SkScalar height = shapeData->fBounds.height(); |
| 426 | 421 |
| 427 SkScalar invScale = 1.0f / shapeData->fScale; | 422 SkScalar invScale = 1.0f / shapeData->fScale; |
| 428 dx *= invScale; | 423 dx *= invScale; |
| (...skipping 20 matching lines...) Expand all Loading... |
| 449 // vertex texture coords | 444 // vertex texture coords |
| 450 SkPoint* textureCoords = (SkPoint*)(offset + sizeof(SkPoint) + sizeof(Gr
Color)); | 445 SkPoint* textureCoords = (SkPoint*)(offset + sizeof(SkPoint) + sizeof(Gr
Color)); |
| 451 textureCoords->setRectFan(tx / texture->width(), | 446 textureCoords->setRectFan(tx / texture->width(), |
| 452 ty / texture->height(), | 447 ty / texture->height(), |
| 453 (tx + shapeData->fBounds.width()) / texture->w
idth(), | 448 (tx + shapeData->fBounds.width()) / texture->w
idth(), |
| 454 (ty + shapeData->fBounds.height()) / texture-
>height(), | 449 (ty + shapeData->fBounds.height()) / texture-
>height(), |
| 455 vertexStride); | 450 vertexStride); |
| 456 } | 451 } |
| 457 | 452 |
| 458 void flush(GrVertexBatch::Target* target, FlushInfo* flushInfo) const { | 453 void flush(GrVertexBatch::Target* target, FlushInfo* flushInfo) const { |
| 459 GrMesh mesh; | 454 if (flushInfo->fInstancesToFlush) { |
| 460 int maxInstancesPerDraw = | 455 GrMesh mesh; |
| 461 static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / sizeof(u
int16_t) / 6); | 456 int maxInstancesPerDraw = |
| 462 mesh.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuffer, | 457 static_cast<int>(flushInfo->fIndexBuffer->gpuMemorySize() / size
of(uint16_t) / 6); |
| 463 flushInfo->fIndexBuffer, flushInfo->fVertexOffset, kVerticesPerQuad, | 458 mesh.initInstanced(kTriangles_GrPrimitiveType, flushInfo->fVertexBuf
fer, |
| 464 kIndicesPerQuad, flushInfo->fInstancesToFlush, maxInstancesPerDraw); | 459 flushInfo->fIndexBuffer, flushInfo->fVertexOffset, kVerticesPerQ
uad, |
| 465 target->draw(flushInfo->fGeometryProcessor.get(), mesh); | 460 kIndicesPerQuad, flushInfo->fInstancesToFlush, maxInstancesPerDr
aw); |
| 466 flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstancesToFl
ush; | 461 target->draw(flushInfo->fGeometryProcessor.get(), mesh); |
| 467 flushInfo->fInstancesToFlush = 0; | 462 flushInfo->fVertexOffset += kVerticesPerQuad * flushInfo->fInstances
ToFlush; |
| 463 flushInfo->fInstancesToFlush = 0; |
| 464 } |
| 468 } | 465 } |
| 469 | 466 |
| 470 GrColor color() const { return fGeoData[0].fColor; } | 467 GrColor color() const { return fGeoData[0].fColor; } |
| 471 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } | 468 const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; } |
| 472 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } | 469 bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } |
| 473 | 470 |
| 474 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { | 471 bool onCombineIfPossible(GrBatch* t, const GrCaps& caps) override { |
| 475 AADistanceFieldPathBatch* that = t->cast<AADistanceFieldPathBatch>(); | 472 AADistanceFieldPathBatch* that = t->cast<AADistanceFieldPathBatch>(); |
| 476 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), | 473 if (!GrPipeline::CanCombine(*this->pipeline(), this->bounds(), *that->pi
peline(), |
| 477 that->bounds(), caps)) { | 474 that->bounds(), caps)) { |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 shape, | 613 shape, |
| 617 antiAlias, | 614 antiAlias, |
| 618 viewMatrix, | 615 viewMatrix, |
| 619 gTestStruct.fAtlas, | 616 gTestStruct.fAtlas, |
| 620 &gTestStruct.fShapeCache, | 617 &gTestStruct.fShapeCache, |
| 621 &gTestStruct.fShapeList, | 618 &gTestStruct.fShapeList, |
| 622 gammaCorrect); | 619 gammaCorrect); |
| 623 } | 620 } |
| 624 | 621 |
| 625 #endif | 622 #endif |
| OLD | NEW |