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 |