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