| Index: src/gpu/GrOvalRenderer.cpp
|
| diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
|
| index 38efefa8570071157bbcb72a763ff3c7f5e9fa01..8723d70a58ba30944b1d036ecdb557f0c797db5a 100644
|
| --- a/src/gpu/GrOvalRenderer.cpp
|
| +++ b/src/gpu/GrOvalRenderer.cpp
|
| @@ -13,10 +13,10 @@
|
| #include "GrBufferAllocPool.h"
|
| #include "GrDrawTarget.h"
|
| #include "GrGeometryProcessor.h"
|
| +#include "GrGpu.h"
|
| #include "GrInvariantOutput.h"
|
| #include "GrPipelineBuilder.h"
|
| #include "GrProcessor.h"
|
| -#include "GrResourceProvider.h"
|
| #include "GrVertexBuffer.h"
|
| #include "SkRRect.h"
|
| #include "SkStrokeRec.h"
|
| @@ -646,6 +646,11 @@
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
|
|
| +void GrOvalRenderer::reset() {
|
| + SkSafeSetNull(fRRectIndexBuffer);
|
| + SkSafeSetNull(fStrokeRRectIndexBuffer);
|
| +}
|
| +
|
| bool GrOvalRenderer::drawOval(GrDrawTarget* target,
|
| GrPipelineBuilder* pipelineBuilder,
|
| GrColor color,
|
| @@ -654,7 +659,8 @@
|
| const SkRect& oval,
|
| const SkStrokeRec& stroke)
|
| {
|
| - bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isMultisampled();
|
| + bool useCoverageAA = useAA &&
|
| + !pipelineBuilder->getRenderTarget()->isMultisampled();
|
|
|
| if (!useCoverageAA) {
|
| return false;
|
| @@ -691,7 +697,9 @@
|
| SkRect fDevBounds;
|
| };
|
|
|
| - static GrBatch* Create(const Geometry& geometry) { return SkNEW_ARGS(CircleBatch, (geometry)); }
|
| + static GrBatch* Create(const Geometry& geometry) {
|
| + return SkNEW_ARGS(CircleBatch, (geometry));
|
| + }
|
|
|
| const char* name() const override { return "CircleBatch"; }
|
|
|
| @@ -748,8 +756,6 @@
|
| size_t vertexStride = gp->getVertexStride();
|
| SkASSERT(vertexStride == sizeof(CircleVertex));
|
|
|
| - SkAutoTUnref<const GrIndexBuffer> indexBuffer(
|
| - batchTarget->resourceProvider()->refQuadIndexBuffer());
|
| const GrVertexBuffer* vertexBuffer;
|
| int firstVertex;
|
|
|
| @@ -758,7 +764,7 @@
|
| &vertexBuffer,
|
| &firstVertex);
|
|
|
| - if (!vertices || !indexBuffer) {
|
| + if (!vertices || !batchTarget->quadIndexBuffer()) {
|
| SkDebugf("Could not allocate buffers\n");
|
| return;
|
| }
|
| @@ -797,6 +803,8 @@
|
|
|
| verts += kVertsPerCircle;
|
| }
|
| +
|
| + const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
|
|
|
| GrDrawTarget::DrawInfo drawInfo;
|
| drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
|
| @@ -806,9 +814,9 @@
|
| drawInfo.setIndicesPerInstance(kIndicesPerCircle);
|
| drawInfo.adjustStartVertex(firstVertex);
|
| drawInfo.setVertexBuffer(vertexBuffer);
|
| - drawInfo.setIndexBuffer(indexBuffer);
|
| -
|
| - int maxInstancesPerDraw = indexBuffer->maxQuads();
|
| + drawInfo.setIndexBuffer(quadIndexBuffer);
|
| +
|
| + int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
|
|
|
| while (instanceCount) {
|
| drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
|
| @@ -1014,8 +1022,6 @@
|
| SkASSERT(vertexStride == sizeof(EllipseVertex));
|
|
|
| const GrVertexBuffer* vertexBuffer;
|
| - SkAutoTUnref<const GrIndexBuffer> indexBuffer(
|
| - batchTarget->resourceProvider()->refQuadIndexBuffer());
|
| int firstVertex;
|
|
|
| void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
|
| @@ -1023,7 +1029,7 @@
|
| &vertexBuffer,
|
| &firstVertex);
|
|
|
| - if (!vertices || !indexBuffer) {
|
| + if (!vertices || !batchTarget->quadIndexBuffer()) {
|
| SkDebugf("Could not allocate buffers\n");
|
| return;
|
| }
|
| @@ -1067,6 +1073,8 @@
|
|
|
| verts += kVertsPerEllipse;
|
| }
|
| +
|
| + const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
|
|
|
| GrDrawTarget::DrawInfo drawInfo;
|
| drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
|
| @@ -1076,9 +1084,9 @@
|
| drawInfo.setIndicesPerInstance(kIndicesPerEllipse);
|
| drawInfo.adjustStartVertex(firstVertex);
|
| drawInfo.setVertexBuffer(vertexBuffer);
|
| - drawInfo.setIndexBuffer(indexBuffer);
|
| -
|
| - int maxInstancesPerDraw = indexBuffer->maxQuads();
|
| + drawInfo.setIndexBuffer(quadIndexBuffer);
|
| +
|
| + int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
|
|
|
| while (instanceCount) {
|
| drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
|
| @@ -1317,21 +1325,20 @@
|
| init.fUsesLocalCoords = this->usesLocalCoords();
|
| gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
|
|
|
| - SkAutoTUnref<const GrIndexBuffer> indexBuffer(
|
| - batchTarget->resourceProvider()->refQuadIndexBuffer());
|
| -
|
| int instanceCount = fGeoData.count();
|
| int vertexCount = kVertsPerEllipse * instanceCount;
|
| size_t vertexStride = gp->getVertexStride();
|
| SkASSERT(vertexStride == sizeof(DIEllipseVertex));
|
| +
|
| const GrVertexBuffer* vertexBuffer;
|
| int firstVertex;
|
| +
|
| void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
|
| vertexCount,
|
| &vertexBuffer,
|
| &firstVertex);
|
|
|
| - if (!vertices || !indexBuffer) {
|
| + if (!vertices || !batchTarget->quadIndexBuffer()) {
|
| SkDebugf("Could not allocate buffers\n");
|
| return;
|
| }
|
| @@ -1371,6 +1378,8 @@
|
|
|
| verts += kVertsPerEllipse;
|
| }
|
| +
|
| + const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
|
|
|
| GrDrawTarget::DrawInfo drawInfo;
|
| drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
|
| @@ -1380,9 +1389,9 @@
|
| drawInfo.setIndicesPerInstance(kIndicesPerEllipse);
|
| drawInfo.adjustStartVertex(firstVertex);
|
| drawInfo.setVertexBuffer(vertexBuffer);
|
| - drawInfo.setIndexBuffer(indexBuffer);
|
| -
|
| - int maxInstancesPerDraw = indexBuffer->maxQuads();
|
| + drawInfo.setIndexBuffer(quadIndexBuffer);
|
| +
|
| + int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
|
|
|
| while (instanceCount) {
|
| drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
|
| @@ -1569,24 +1578,6 @@
|
| static const int kIndicesPerRRect = SK_ARRAY_COUNT(gRRectIndices);
|
| static const int kVertsPerRRect = 16;
|
| static const int kNumRRectsInIndexBuffer = 256;
|
| -
|
| -GR_DECLARE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey);
|
| -GR_DECLARE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey);
|
| -static const GrIndexBuffer* ref_rrect_index_buffer(bool strokeOnly,
|
| - GrResourceProvider* resourceProvider) {
|
| - GR_DEFINE_STATIC_UNIQUE_KEY(gStrokeRRectOnlyIndexBufferKey);
|
| - GR_DEFINE_STATIC_UNIQUE_KEY(gRRectOnlyIndexBufferKey);
|
| - if (strokeOnly) {
|
| - return resourceProvider->refOrCreateInstancedIndexBuffer(
|
| - gRRectIndices, kIndicesPerStrokeRRect, kNumRRectsInIndexBuffer, kVertsPerRRect,
|
| - gStrokeRRectOnlyIndexBufferKey);
|
| - } else {
|
| - return resourceProvider->refOrCreateInstancedIndexBuffer(
|
| - gRRectIndices, kIndicesPerRRect, kNumRRectsInIndexBuffer, kVertsPerRRect,
|
| - gRRectOnlyIndexBufferKey);
|
| -
|
| - }
|
| -}
|
|
|
| bool GrOvalRenderer::drawDRRect(GrDrawTarget* target,
|
| GrPipelineBuilder* pipelineBuilder,
|
| @@ -1666,8 +1657,8 @@
|
| SkRect fDevBounds;
|
| };
|
|
|
| - static GrBatch* Create(const Geometry& geometry) {
|
| - return SkNEW_ARGS(RRectCircleRendererBatch, (geometry));
|
| + static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* indexBuffer) {
|
| + return SkNEW_ARGS(RRectCircleRendererBatch, (geometry, indexBuffer));
|
| }
|
|
|
| const char* name() const override { return "RRectCircleBatch"; }
|
| @@ -1727,8 +1718,6 @@
|
| SkASSERT(vertexStride == sizeof(CircleVertex));
|
|
|
| const GrVertexBuffer* vertexBuffer;
|
| - SkAutoTUnref<const GrIndexBuffer> indexBuffer(
|
| - ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider()));
|
| int firstVertex;
|
|
|
| void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
|
| @@ -1736,7 +1725,7 @@
|
| &vertexBuffer,
|
| &firstVertex);
|
|
|
| - if (!vertices || !indexBuffer) {
|
| + if (!vertices) {
|
| SkDebugf("Could not allocate vertices\n");
|
| return;
|
| }
|
| @@ -1791,6 +1780,7 @@
|
| int indexCnt = this->stroke() ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
|
| SK_ARRAY_COUNT(gRRectIndices);
|
|
|
| +
|
| GrDrawTarget::DrawInfo drawInfo;
|
| drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
|
| drawInfo.setStartVertex(0);
|
| @@ -1799,7 +1789,7 @@
|
| drawInfo.setIndicesPerInstance(indexCnt);
|
| drawInfo.adjustStartVertex(firstVertex);
|
| drawInfo.setVertexBuffer(vertexBuffer);
|
| - drawInfo.setIndexBuffer(indexBuffer);
|
| + drawInfo.setIndexBuffer(fIndexBuffer);
|
|
|
| int maxInstancesPerDraw = kNumRRectsInIndexBuffer;
|
|
|
| @@ -1818,7 +1808,8 @@
|
| SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
|
|
|
| private:
|
| - RRectCircleRendererBatch(const Geometry& geometry) {
|
| + RRectCircleRendererBatch(const Geometry& geometry, const GrIndexBuffer* indexBuffer)
|
| + : fIndexBuffer(indexBuffer) {
|
| this->initClassID<RRectCircleRendererBatch>();
|
| fGeoData.push_back(geometry);
|
|
|
| @@ -1862,6 +1853,7 @@
|
|
|
| BatchTracker fBatch;
|
| SkSTArray<1, Geometry, true> fGeoData;
|
| + const GrIndexBuffer* fIndexBuffer;
|
| };
|
|
|
| class RRectEllipseRendererBatch : public GrBatch {
|
| @@ -1877,8 +1869,8 @@
|
| SkRect fDevBounds;
|
| };
|
|
|
| - static GrBatch* Create(const Geometry& geometry) {
|
| - return SkNEW_ARGS(RRectEllipseRendererBatch, (geometry));
|
| + static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* indexBuffer) {
|
| + return SkNEW_ARGS(RRectEllipseRendererBatch, (geometry, indexBuffer));
|
| }
|
|
|
| const char* name() const override { return "RRectEllipseRendererBatch"; }
|
| @@ -1938,8 +1930,6 @@
|
| SkASSERT(vertexStride == sizeof(EllipseVertex));
|
|
|
| const GrVertexBuffer* vertexBuffer;
|
| - SkAutoTUnref<const GrIndexBuffer> indexBuffer(
|
| - ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider()));
|
| int firstVertex;
|
|
|
| void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
|
| @@ -1947,7 +1937,7 @@
|
| &vertexBuffer,
|
| &firstVertex);
|
|
|
| - if (!vertices || !indexBuffer) {
|
| + if (!vertices) {
|
| SkDebugf("Could not allocate vertices\n");
|
| return;
|
| }
|
| @@ -2021,7 +2011,7 @@
|
| drawInfo.setIndicesPerInstance(indexCnt);
|
| drawInfo.adjustStartVertex(firstVertex);
|
| drawInfo.setVertexBuffer(vertexBuffer);
|
| - drawInfo.setIndexBuffer(indexBuffer);
|
| + drawInfo.setIndexBuffer(fIndexBuffer);
|
|
|
| int maxInstancesPerDraw = kNumRRectsInIndexBuffer;
|
|
|
| @@ -2040,7 +2030,8 @@
|
| SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
|
|
|
| private:
|
| - RRectEllipseRendererBatch(const Geometry& geometry) {
|
| + RRectEllipseRendererBatch(const Geometry& geometry, const GrIndexBuffer* indexBuffer)
|
| + : fIndexBuffer(indexBuffer) {
|
| this->initClassID<RRectEllipseRendererBatch>();
|
| fGeoData.push_back(geometry);
|
|
|
| @@ -2084,13 +2075,40 @@
|
|
|
| BatchTracker fBatch;
|
| SkSTArray<1, Geometry, true> fGeoData;
|
| + const GrIndexBuffer* fIndexBuffer;
|
| };
|
| +
|
| +static GrIndexBuffer* create_rrect_indexbuffer(GrIndexBuffer** strokeRRectIndexBuffer,
|
| + GrIndexBuffer** rrectIndexBuffer,
|
| + bool isStrokeOnly,
|
| + GrGpu* gpu) {
|
| + if (isStrokeOnly) {
|
| + if (NULL == *strokeRRectIndexBuffer) {
|
| + *strokeRRectIndexBuffer = gpu->createInstancedIndexBuffer(gRRectIndices,
|
| + kIndicesPerStrokeRRect,
|
| + kNumRRectsInIndexBuffer,
|
| + kVertsPerRRect);
|
| + }
|
| + return *strokeRRectIndexBuffer;
|
| + } else {
|
| + if (NULL == *rrectIndexBuffer) {
|
| + *rrectIndexBuffer = gpu->createInstancedIndexBuffer(gRRectIndices,
|
| + kIndicesPerRRect,
|
| + kNumRRectsInIndexBuffer,
|
| + kVertsPerRRect);
|
| + }
|
| + return *rrectIndexBuffer;
|
| + }
|
| +}
|
|
|
| static GrBatch* create_rrect_batch(GrColor color,
|
| const SkMatrix& viewMatrix,
|
| const SkRRect& rrect,
|
| const SkStrokeRec& stroke,
|
| - SkRect* bounds) {
|
| + SkRect* bounds,
|
| + GrIndexBuffer** strokeRRectIndexBuffer,
|
| + GrIndexBuffer** rrectIndexBuffer,
|
| + GrGpu* gpu) {
|
| SkASSERT(viewMatrix.rectStaysRect());
|
| SkASSERT(rrect.isSimple());
|
| SkASSERT(!rrect.isOval());
|
| @@ -2138,6 +2156,15 @@
|
| // We could consider falling back to rect rendering here, since a tiny radius is
|
| // indistinguishable from a square corner.
|
| if (!isStrokeOnly && (SK_ScalarHalf > xRadius || SK_ScalarHalf > yRadius)) {
|
| + return NULL;
|
| + }
|
| +
|
| + GrIndexBuffer* indexBuffer = create_rrect_indexbuffer(strokeRRectIndexBuffer,
|
| + rrectIndexBuffer,
|
| + isStrokeOnly,
|
| + gpu);
|
| + if (NULL == indexBuffer) {
|
| + SkDebugf("Failed to create index buffer!\n");
|
| return NULL;
|
| }
|
|
|
| @@ -2181,7 +2208,8 @@
|
| geometry.fStroke = isStrokeOnly;
|
| geometry.fDevBounds = *bounds;
|
|
|
| - return RRectCircleRendererBatch::Create(geometry);
|
| + return RRectCircleRendererBatch::Create(geometry, indexBuffer);
|
| +
|
| // otherwise we use the ellipse renderer
|
| } else {
|
| SkScalar innerXRadius = 0.0f;
|
| @@ -2231,7 +2259,7 @@
|
| geometry.fStroke = isStrokeOnly;
|
| geometry.fDevBounds = *bounds;
|
|
|
| - return RRectEllipseRendererBatch::Create(geometry);
|
| + return RRectEllipseRendererBatch::Create(geometry, indexBuffer);
|
| }
|
| }
|
|
|
| @@ -2259,7 +2287,9 @@
|
| }
|
|
|
| SkRect bounds;
|
| - SkAutoTUnref<GrBatch> batch(create_rrect_batch(color, viewMatrix, rrect, stroke, &bounds));
|
| + SkAutoTUnref<GrBatch> batch(create_rrect_batch(color, viewMatrix, rrect, stroke, &bounds,
|
| + &fStrokeRRectIndexBuffer, &fRRectIndexBuffer,
|
| + fGpu));
|
| if (!batch) {
|
| return false;
|
| }
|
| @@ -2317,8 +2347,11 @@
|
| GrColor color = GrRandomColor(random);
|
| const SkRRect& rrect = GrTest::TestRRectSimple(random);
|
|
|
| + static GrIndexBuffer* gStrokeRRectIndexBuffer;
|
| + static GrIndexBuffer* gRRectIndexBuffer;
|
| SkRect bounds;
|
| - return create_rrect_batch(color, viewMatrix, rrect, random_strokerec(random), &bounds);
|
| + return create_rrect_batch(color, viewMatrix, rrect, random_strokerec(random), &bounds,
|
| + &gStrokeRRectIndexBuffer, &gRRectIndexBuffer, context->getGpu());
|
| }
|
|
|
| #endif
|
|
|