| Index: src/gpu/GrOvalRenderer.cpp
|
| diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
|
| index 85a538973b844891df17b53f1942694bad425179..0622994186672d1974bf9c45e65cc0016a124a78 100644
|
| --- a/src/gpu/GrOvalRenderer.cpp
|
| +++ b/src/gpu/GrOvalRenderer.cpp
|
| @@ -26,7 +26,7 @@
|
| #include "effects/GrRRectEffect.h"
|
|
|
| namespace {
|
| -
|
| +// TODO(joshualitt) add per vertex colors
|
| struct CircleVertex {
|
| SkPoint fPos;
|
| SkPoint fOffset;
|
| @@ -478,13 +478,13 @@ bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, bo
|
| // we can draw circles
|
| if (SkScalarNearlyEqual(oval.width(), oval.height())
|
| && circle_stays_circle(vm)) {
|
| - this->drawCircle(target, useCoverageAA, oval, stroke);
|
| + this->drawCircle(target, context, useCoverageAA, oval, stroke);
|
| // if we have shader derivative support, render as device-independent
|
| } else if (target->caps()->shaderDerivativeSupport()) {
|
| - return this->drawDIEllipse(target, useCoverageAA, oval, stroke);
|
| + return this->drawDIEllipse(target, context, useCoverageAA, oval, stroke);
|
| // otherwise axis-aligned ellipses only
|
| } else if (vm.rectStaysRect()) {
|
| - return this->drawEllipse(target, useCoverageAA, oval, stroke);
|
| + return this->drawEllipse(target, context, useCoverageAA, oval, stroke);
|
| } else {
|
| return false;
|
| }
|
| @@ -501,6 +501,7 @@ extern const GrVertexAttrib gCircleVertexAttribs[] = {
|
| };
|
|
|
| void GrOvalRenderer::drawCircle(GrDrawTarget* target,
|
| + const GrContext* context,
|
| bool useCoverageAA,
|
| const SkRect& circle,
|
| const SkStrokeRec& stroke)
|
| @@ -572,22 +573,24 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target,
|
| verts[0].fOuterRadius = outerRadius;
|
| verts[0].fInnerRadius = innerRadius;
|
|
|
| - verts[1].fPos = SkPoint::Make(bounds.fRight, bounds.fTop);
|
| - verts[1].fOffset = SkPoint::Make(outerRadius, -outerRadius);
|
| + verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom);
|
| + verts[1].fOffset = SkPoint::Make(-outerRadius, outerRadius);
|
| verts[1].fOuterRadius = outerRadius;
|
| verts[1].fInnerRadius = innerRadius;
|
|
|
| - verts[2].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom);
|
| - verts[2].fOffset = SkPoint::Make(-outerRadius, outerRadius);
|
| + verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom);
|
| + verts[2].fOffset = SkPoint::Make(outerRadius, outerRadius);
|
| verts[2].fOuterRadius = outerRadius;
|
| verts[2].fInnerRadius = innerRadius;
|
|
|
| - verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom);
|
| - verts[3].fOffset = SkPoint::Make(outerRadius, outerRadius);
|
| + verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop);
|
| + verts[3].fOffset = SkPoint::Make(outerRadius, -outerRadius);
|
| verts[3].fOuterRadius = outerRadius;
|
| verts[3].fInnerRadius = innerRadius;
|
|
|
| - target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds);
|
| + target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
|
| + target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
|
| + target->resetIndexSource();
|
| }
|
|
|
| ///////////////////////////////////////////////////////////////////////////////
|
| @@ -607,6 +610,7 @@ extern const GrVertexAttrib gDIEllipseVertexAttribs[] = {
|
| };
|
|
|
| bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
|
| + const GrContext* context,
|
| bool useCoverageAA,
|
| const SkRect& ellipse,
|
| const SkStrokeRec& stroke)
|
| @@ -718,27 +722,30 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
|
| verts[0].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
|
| verts[0].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
|
|
|
| - verts[1].fPos = SkPoint::Make(bounds.fRight, bounds.fTop);
|
| - verts[1].fOffset = SkPoint::Make(xRadius, -yRadius);
|
| + verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom);
|
| + verts[1].fOffset = SkPoint::Make(-xRadius, yRadius);
|
| verts[1].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
|
| verts[1].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
|
|
|
| - verts[2].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom);
|
| - verts[2].fOffset = SkPoint::Make(-xRadius, yRadius);
|
| + verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom);
|
| + verts[2].fOffset = SkPoint::Make(xRadius, yRadius);
|
| verts[2].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
|
| verts[2].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
|
|
|
| - verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom);
|
| - verts[3].fOffset = SkPoint::Make(xRadius, yRadius);
|
| + verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop);
|
| + verts[3].fOffset = SkPoint::Make(xRadius, -yRadius);
|
| verts[3].fOuterRadii = SkPoint::Make(xRadRecip, yRadRecip);
|
| verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
|
|
|
| - target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds);
|
| + target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
|
| + target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
|
| + target->resetIndexSource();
|
|
|
| return true;
|
| }
|
|
|
| bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
|
| + const GrContext* context,
|
| bool useCoverageAA,
|
| const SkRect& ellipse,
|
| const SkStrokeRec& stroke)
|
| @@ -832,19 +839,21 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
|
| verts[0].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, -1.0f - offsetDy);
|
| verts[0].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, -innerRatioY - offsetDy);
|
|
|
| - verts[1].fPos = SkPoint::Make(bounds.fRight, bounds.fTop);
|
| - verts[1].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offsetDy);
|
| - verts[1].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY - offsetDy);
|
| + verts[1].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom);
|
| + verts[1].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, 1.0f + offsetDy);
|
| + verts[1].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, innerRatioY + offsetDy);
|
|
|
| - verts[2].fPos = SkPoint::Make(bounds.fLeft, bounds.fBottom);
|
| - verts[2].fOuterOffset = SkPoint::Make(-1.0f - offsetDx, 1.0f + offsetDy);
|
| - verts[2].fInnerOffset = SkPoint::Make(-innerRatioX - offsetDx, innerRatioY + offsetDy);
|
| + verts[2].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom);
|
| + verts[2].fOuterOffset = SkPoint::Make(1.0f + offsetDx, 1.0f + offsetDy);
|
| + verts[2].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, innerRatioY + offsetDy);
|
|
|
| - verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fBottom);
|
| - verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, 1.0f + offsetDy);
|
| - verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, innerRatioY + offsetDy);
|
| + verts[3].fPos = SkPoint::Make(bounds.fRight, bounds.fTop);
|
| + verts[3].fOuterOffset = SkPoint::Make(1.0f + offsetDx, -1.0f - offsetDy);
|
| + verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY - offsetDy);
|
|
|
| - target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, 4, &bounds);
|
| + target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
|
| + target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
|
| + target->resetIndexSource();
|
|
|
| return true;
|
| }
|
| @@ -869,21 +878,29 @@ static const uint16_t gRRectIndices[] = {
|
| 5, 6, 10, 5, 10, 9
|
| };
|
|
|
| -
|
| -GrIndexBuffer* GrOvalRenderer::rRectIndexBuffer(GrGpu* gpu) {
|
| - if (NULL == fRRectIndexBuffer) {
|
| - fRRectIndexBuffer =
|
| - gpu->createIndexBuffer(sizeof(gRRectIndices), false);
|
| - if (fRRectIndexBuffer) {
|
| -#ifdef SK_DEBUG
|
| - bool updated =
|
| -#endif
|
| - fRRectIndexBuffer->updateData(gRRectIndices,
|
| - sizeof(gRRectIndices));
|
| - GR_DEBUGASSERT(updated);
|
| +static const int kIndicesPerStrokeRRect = SK_ARRAY_COUNT(gRRectIndices) - 6;
|
| +static const int kIndicesPerRRect = SK_ARRAY_COUNT(gRRectIndices);
|
| +static const int kVertsPerRRect = 16;
|
| +static const int kNumRRectsInIndexBuffer = 256;
|
| +
|
| +GrIndexBuffer* GrOvalRenderer::rRectIndexBuffer(bool isStrokeOnly, GrGpu* gpu) {
|
| + if (isStrokeOnly) {
|
| + if (NULL == fStrokeRRectIndexBuffer) {
|
| + fStrokeRRectIndexBuffer = gpu->createInstancedIndexBuffer(gRRectIndices,
|
| + kIndicesPerStrokeRRect,
|
| + kNumRRectsInIndexBuffer,
|
| + kVertsPerRRect);
|
| + }
|
| + return fStrokeRRectIndexBuffer;
|
| + } else {
|
| + if (NULL == fRRectIndexBuffer) {
|
| + fRRectIndexBuffer = gpu->createInstancedIndexBuffer(gRRectIndices,
|
| + kIndicesPerRRect,
|
| + kNumRRectsInIndexBuffer,
|
| + kVertsPerRRect);
|
| }
|
| + return fRRectIndexBuffer;
|
| }
|
| - return fRRectIndexBuffer;
|
| }
|
|
|
| bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, GrContext* context, bool useAA,
|
| @@ -1018,7 +1035,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, GrContext* context, bool us
|
| return false;
|
| }
|
|
|
| - GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(context->getGpu());
|
| + GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly, context->getGpu());
|
| if (NULL == indexBuffer) {
|
| GrPrintf("Failed to create index buffer!\n");
|
| return false;
|
| @@ -1110,7 +1127,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, GrContext* context, bool us
|
| int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
|
| SK_ARRAY_COUNT(gRRectIndices);
|
| target->setIndexSourceToBuffer(indexBuffer);
|
| - target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bounds);
|
| + target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 16, indexCnt, &bounds);
|
|
|
| // otherwise we use the ellipse renderer
|
| } else {
|
| @@ -1217,8 +1234,9 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, GrContext* context, bool us
|
| int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
|
| SK_ARRAY_COUNT(gRRectIndices);
|
| target->setIndexSourceToBuffer(indexBuffer);
|
| - target->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 16, indexCnt, &bounds);
|
| + target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 16, indexCnt, &bounds);
|
| }
|
|
|
| + target->resetIndexSource();
|
| return true;
|
| }
|
|
|