Chromium Code Reviews| Index: src/gpu/GrOvalRenderer.cpp |
| diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp |
| index a1c80f5b8b8bc1fb83a87e726a4a0bda0478d779..bcc04ae56a1867d6b9631f7a39c18673acd928c7 100644 |
| --- a/src/gpu/GrOvalRenderer.cpp |
| +++ b/src/gpu/GrOvalRenderer.cpp |
| @@ -9,6 +9,7 @@ |
| #include "GrBatch.h" |
| #include "GrBatchTarget.h" |
| +#include "GrBatchTest.h" |
| #include "GrBufferAllocPool.h" |
| #include "GrDrawTarget.h" |
| #include "GrGeometryProcessor.h" |
| @@ -878,13 +879,12 @@ private: |
| SkSTArray<1, Geometry, true> fGeoData; |
| }; |
| -void GrOvalRenderer::drawCircle(GrDrawTarget* target, |
| - GrPipelineBuilder* pipelineBuilder, |
| - GrColor color, |
| - const SkMatrix& viewMatrix, |
| - bool useCoverageAA, |
| - const SkRect& circle, |
| - const SkStrokeRec& stroke) { |
| +static GrBatch* create_circle_batch(GrColor color, |
| + const SkMatrix& viewMatrix, |
| + bool useCoverageAA, |
| + const SkRect& circle, |
| + const SkStrokeRec& stroke, |
| + SkRect* bounds) { |
| SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY()); |
| viewMatrix.mapPoints(¢er, 1); |
| SkScalar radius = viewMatrix.mapRadius(SkScalarHalf(circle.width())); |
| @@ -918,7 +918,7 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target, |
| outerRadius += SK_ScalarHalf; |
| innerRadius -= SK_ScalarHalf; |
|
robertphillips
2015/04/30 14:07:32
bounds->setLTRB(... ?
also, just 2 lines ?
|
| - SkRect bounds = SkRect::MakeLTRB( |
| + *bounds = SkRect::MakeLTRB( |
| center.fX - outerRadius, |
| center.fY - outerRadius, |
| center.fX + outerRadius, |
| @@ -931,9 +931,21 @@ void GrOvalRenderer::drawCircle(GrDrawTarget* target, |
| geometry.fInnerRadius = innerRadius; |
| geometry.fOuterRadius = outerRadius; |
| geometry.fStroke = isStrokeOnly && innerRadius > 0; |
| - geometry.fDevBounds = bounds; |
| + geometry.fDevBounds = *bounds; |
| + |
| + return CircleBatch::Create(geometry); |
| +} |
| - SkAutoTUnref<GrBatch> batch(CircleBatch::Create(geometry)); |
| +void GrOvalRenderer::drawCircle(GrDrawTarget* target, |
| + GrPipelineBuilder* pipelineBuilder, |
| + GrColor color, |
| + const SkMatrix& viewMatrix, |
| + bool useCoverageAA, |
| + const SkRect& circle, |
| + const SkStrokeRec& stroke) { |
| + SkRect bounds; |
| + SkAutoTUnref<GrBatch> batch(create_circle_batch(color, viewMatrix, useCoverageAA, circle, |
| + stroke, &bounds)); |
| target->drawBatch(pipelineBuilder, batch, &bounds); |
| } |
| @@ -1138,21 +1150,12 @@ private: |
| SkSTArray<1, Geometry, true> fGeoData; |
| }; |
| -bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, |
| - GrPipelineBuilder* pipelineBuilder, |
| - GrColor color, |
| - const SkMatrix& viewMatrix, |
| - bool useCoverageAA, |
| - const SkRect& ellipse, |
| - const SkStrokeRec& stroke) { |
| -#ifdef SK_DEBUG |
| - { |
| - // we should have checked for this previously |
| - bool isAxisAlignedEllipse = viewMatrix.rectStaysRect(); |
| - SkASSERT(useCoverageAA && isAxisAlignedEllipse); |
| - } |
| -#endif |
| - |
| +static GrBatch* create_ellipse_batch(GrColor color, |
| + const SkMatrix& viewMatrix, |
| + bool useCoverageAA, |
| + const SkRect& ellipse, |
| + const SkStrokeRec& stroke, |
| + SkRect* bounds) { |
| // do any matrix crunching before we reset the draw state for device coords |
| SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); |
| viewMatrix.mapPoints(¢er, 1); |
| @@ -1188,13 +1191,13 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, |
| // we only handle thick strokes for near-circular ellipses |
| if (scaledStroke.length() > SK_ScalarHalf && |
| (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)) { |
| - return false; |
| + return NULL; |
| } |
| // we don't handle it if curvature of the stroke is less than curvature of the ellipse |
| if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY)*xRadius || |
| scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX)*yRadius) { |
| - return false; |
| + return NULL; |
| } |
| // this is legit only if scale & translation (which should be the case at the moment) |
| @@ -1213,7 +1216,7 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, |
| xRadius += SK_ScalarHalf; |
| yRadius += SK_ScalarHalf; |
|
robertphillips
2015/04/30 14:07:32
same
|
| - SkRect bounds = SkRect::MakeLTRB( |
| + *bounds = SkRect::MakeLTRB( |
| center.fX - xRadius, |
| center.fY - yRadius, |
| center.fX + xRadius, |
| @@ -1228,11 +1231,34 @@ bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, |
| geometry.fInnerXRadius = innerXRadius; |
| geometry.fInnerYRadius = innerYRadius; |
| geometry.fStroke = isStrokeOnly && innerXRadius > 0 && innerYRadius > 0; |
| - geometry.fDevBounds = bounds; |
| + geometry.fDevBounds = *bounds; |
| - SkAutoTUnref<GrBatch> batch(EllipseBatch::Create(geometry)); |
| - target->drawBatch(pipelineBuilder, batch, &bounds); |
| + return EllipseBatch::Create(geometry); |
| +} |
| +bool GrOvalRenderer::drawEllipse(GrDrawTarget* target, |
| + GrPipelineBuilder* pipelineBuilder, |
| + GrColor color, |
| + const SkMatrix& viewMatrix, |
| + bool useCoverageAA, |
| + const SkRect& ellipse, |
| + const SkStrokeRec& stroke) { |
|
robertphillips
2015/04/30 14:07:32
Should this assert go in create_ellipse_batch ?
|
| +#ifdef SK_DEBUG |
| + { |
| + // we should have checked for this previously |
| + bool isAxisAlignedEllipse = viewMatrix.rectStaysRect(); |
| + SkASSERT(useCoverageAA && isAxisAlignedEllipse); |
| + } |
| +#endif |
| + |
| + SkRect bounds; |
| + SkAutoTUnref<GrBatch> batch(create_ellipse_batch(color, viewMatrix, useCoverageAA, ellipse, |
| + stroke, &bounds)); |
| + if (!batch) { |
| + return false; |
| + } |
| + |
| + target->drawBatch(pipelineBuilder, batch, &bounds); |
| return true; |
| } |
| @@ -1430,13 +1456,12 @@ private: |
| SkSTArray<1, Geometry, true> fGeoData; |
| }; |
| -bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, |
| - GrPipelineBuilder* pipelineBuilder, |
| - GrColor color, |
| - const SkMatrix& viewMatrix, |
| - bool useCoverageAA, |
| - const SkRect& ellipse, |
| - const SkStrokeRec& stroke) { |
| +static GrBatch* create_diellipse_batch(GrColor color, |
| + const SkMatrix& viewMatrix, |
| + bool useCoverageAA, |
| + const SkRect& ellipse, |
| + const SkStrokeRec& stroke, |
| + SkRect* bounds) { |
| SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY()); |
| SkScalar xRadius = SkScalarHalf(ellipse.width()); |
| SkScalar yRadius = SkScalarHalf(ellipse.height()); |
| @@ -1461,13 +1486,13 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, |
| // we only handle thick strokes for near-circular ellipses |
| if (strokeWidth > SK_ScalarHalf && |
| (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)) { |
| - return false; |
| + return NULL; |
| } |
| // we don't handle it if curvature of the stroke is less than curvature of the ellipse |
| if (strokeWidth*(yRadius*yRadius) < (strokeWidth*strokeWidth)*xRadius || |
| strokeWidth*(xRadius*xRadius) < (strokeWidth*strokeWidth)*yRadius) { |
| - return false; |
| + return NULL; |
| } |
| // set inner radius (if needed) |
| @@ -1492,7 +1517,7 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, |
| SkScalar geoDx = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(a*a + c*c)); |
| SkScalar geoDy = SkScalarDiv(SK_ScalarHalf, SkScalarSqrt(b*b + d*d)); |
|
robertphillips
2015/04/30 14:07:32
same
|
| - SkRect bounds = SkRect::MakeLTRB( |
| + *bounds = SkRect::MakeLTRB( |
| center.fX - xRadius - geoDx, |
| center.fY - yRadius - geoDy, |
| center.fX + xRadius + geoDx, |
| @@ -1509,13 +1534,26 @@ bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, |
| geometry.fGeoDx = geoDx; |
| geometry.fGeoDy = geoDy; |
| geometry.fMode = mode; |
| - geometry.fBounds = bounds; |
| + geometry.fBounds = *bounds; |
| - viewMatrix.mapRect(&bounds); |
| + viewMatrix.mapRect(bounds); |
| + return DIEllipseBatch::Create(geometry); |
| +} |
| - SkAutoTUnref<GrBatch> batch(DIEllipseBatch::Create(geometry)); |
| +bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target, |
| + GrPipelineBuilder* pipelineBuilder, |
| + GrColor color, |
| + const SkMatrix& viewMatrix, |
| + bool useCoverageAA, |
| + const SkRect& ellipse, |
| + const SkStrokeRec& stroke) { |
| + SkRect bounds; |
| + SkAutoTUnref<GrBatch> batch(create_diellipse_batch(color, viewMatrix, useCoverageAA, ellipse, |
| + stroke, &bounds)); |
| + if (!batch) { |
| + return false; |
| + } |
| target->drawBatch(pipelineBuilder, batch, &bounds); |
| - |
| return true; |
| } |
| @@ -1544,26 +1582,6 @@ static const int kIndicesPerRRect = SK_ARRAY_COUNT(gRRectIndices); |
| static const int kVertsPerRRect = 16; |
| static const int kNumRRectsInIndexBuffer = 256; |
| -GrIndexBuffer* GrOvalRenderer::rRectIndexBuffer(bool isStrokeOnly) { |
| - if (isStrokeOnly) { |
| - if (NULL == fStrokeRRectIndexBuffer) { |
| - fStrokeRRectIndexBuffer = fGpu->createInstancedIndexBuffer(gRRectIndices, |
| - kIndicesPerStrokeRRect, |
| - kNumRRectsInIndexBuffer, |
| - kVertsPerRRect); |
| - } |
| - return fStrokeRRectIndexBuffer; |
| - } else { |
| - if (NULL == fRRectIndexBuffer) { |
| - fRRectIndexBuffer = fGpu->createInstancedIndexBuffer(gRRectIndices, |
| - kIndicesPerRRect, |
| - kNumRRectsInIndexBuffer, |
| - kVertsPerRRect); |
| - } |
| - return fRRectIndexBuffer; |
| - } |
| -} |
| - |
| bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, |
| GrPipelineBuilder* pipelineBuilder, |
| GrColor color, |
| @@ -2057,34 +2075,40 @@ private: |
| const GrIndexBuffer* fIndexBuffer; |
| }; |
| -bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
| - GrPipelineBuilder* pipelineBuilder, |
| - GrColor color, |
| - const SkMatrix& viewMatrix, |
| - bool useAA, |
| - const SkRRect& rrect, |
| - const SkStrokeRec& stroke) { |
| - if (rrect.isOval()) { |
| - return this->drawOval(target, pipelineBuilder, color, viewMatrix, useAA, rrect.getBounds(), |
| - stroke); |
| - } |
| - |
| - bool useCoverageAA = useAA && |
| - !pipelineBuilder->getRenderTarget()->isMultisampled(); |
| - |
| - // only anti-aliased rrects for now |
| - if (!useCoverageAA) { |
| - return false; |
| - } |
| - |
| - if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) { |
| - return false; |
| +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, |
| + GrIndexBuffer** strokeRRectIndexBuffer, |
| + GrIndexBuffer** rrectIndexBuffer, |
| + GrGpu* gpu) { |
|
robertphillips
2015/04/30 14:07:32
SkASSERT(viewMatrix.rectStaysRect());
SkASSERT(rre
|
| // do any matrix crunching before we reset the draw state for device coords |
| const SkRect& rrectBounds = rrect.getBounds(); |
| - SkRect bounds; |
| - viewMatrix.mapRect(&bounds, rrectBounds); |
| + viewMatrix.mapRect(bounds, rrectBounds); |
| SkVector radii = rrect.getSimpleRadii(); |
| SkScalar xRadius = SkScalarAbs(viewMatrix[SkMatrix::kMScaleX]*radii.fX + |
| @@ -2114,7 +2138,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
| // if half of strokewidth is greater than radius, we don't handle that right now |
| if (SK_ScalarHalf*scaledStroke.fX > xRadius || SK_ScalarHalf*scaledStroke.fY > yRadius) { |
| - return false; |
| + return NULL; |
| } |
| } |
| @@ -2124,13 +2148,16 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
| // 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 false; |
| + return NULL; |
| } |
| - GrIndexBuffer* indexBuffer = this->rRectIndexBuffer(isStrokeOnly); |
| + GrIndexBuffer* indexBuffer = create_rrect_indexbuffer(strokeRRectIndexBuffer, |
| + rrectIndexBuffer, |
| + isStrokeOnly, |
| + gpu); |
| if (NULL == indexBuffer) { |
| SkDebugf("Failed to create index buffer!\n"); |
| - return false; |
| + return NULL; |
| } |
| // if the corners are circles, use the circle renderer |
| @@ -2149,7 +2176,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
| innerRadius = xRadius - halfWidth; |
| } |
| outerRadius += halfWidth; |
| - bounds.outset(halfWidth, halfWidth); |
| + bounds->outset(halfWidth, halfWidth); |
| } |
| isStrokeOnly = (isStrokeOnly && innerRadius >= 0); |
| @@ -2163,7 +2190,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
| innerRadius -= SK_ScalarHalf; |
| // Expand the rect so all the pixels will be captured. |
| - bounds.outset(SK_ScalarHalf, SK_ScalarHalf); |
| + bounds->outset(SK_ScalarHalf, SK_ScalarHalf); |
| RRectCircleRendererBatch::Geometry geometry; |
| geometry.fViewMatrix = viewMatrix; |
| @@ -2171,10 +2198,9 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
| geometry.fInnerRadius = innerRadius; |
| geometry.fOuterRadius = outerRadius; |
| geometry.fStroke = isStrokeOnly; |
| - geometry.fDevBounds = bounds; |
| + geometry.fDevBounds = *bounds; |
| - SkAutoTUnref<GrBatch> batch(RRectCircleRendererBatch::Create(geometry, indexBuffer)); |
| - target->drawBatch(pipelineBuilder, batch, &bounds); |
| + return RRectCircleRendererBatch::Create(geometry, indexBuffer); |
| // otherwise we use the ellipse renderer |
| } else { |
| @@ -2190,13 +2216,13 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
| // we only handle thick strokes for near-circular ellipses |
| if (scaledStroke.length() > SK_ScalarHalf && |
| (SK_ScalarHalf*xRadius > yRadius || SK_ScalarHalf*yRadius > xRadius)) { |
| - return false; |
| + return NULL; |
| } |
| // we don't handle it if curvature of the stroke is less than curvature of the ellipse |
| if (scaledStroke.fX*(yRadius*yRadius) < (scaledStroke.fY*scaledStroke.fY)*xRadius || |
| scaledStroke.fY*(xRadius*xRadius) < (scaledStroke.fX*scaledStroke.fX)*yRadius) { |
| - return false; |
| + return NULL; |
| } |
| // this is legit only if scale & translation (which should be the case at the moment) |
| @@ -2207,13 +2233,13 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
| xRadius += scaledStroke.fX; |
| yRadius += scaledStroke.fY; |
| - bounds.outset(scaledStroke.fX, scaledStroke.fY); |
| + bounds->outset(scaledStroke.fX, scaledStroke.fY); |
| } |
| isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0); |
| // Expand the rect so all the pixels will be captured. |
| - bounds.outset(SK_ScalarHalf, SK_ScalarHalf); |
| + bounds->outset(SK_ScalarHalf, SK_ScalarHalf); |
| RRectEllipseRendererBatch::Geometry geometry; |
| geometry.fViewMatrix = viewMatrix; |
| @@ -2223,10 +2249,101 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
| geometry.fInnerXRadius = innerXRadius; |
| geometry.fInnerYRadius = innerYRadius; |
| geometry.fStroke = isStrokeOnly; |
| - geometry.fDevBounds = bounds; |
| + geometry.fDevBounds = *bounds; |
| - SkAutoTUnref<GrBatch> batch(RRectEllipseRendererBatch::Create(geometry, indexBuffer)); |
| - target->drawBatch(pipelineBuilder, batch, &bounds); |
| + return RRectEllipseRendererBatch::Create(geometry, indexBuffer); |
| } |
| +} |
| + |
| +bool GrOvalRenderer::drawRRect(GrDrawTarget* target, |
| + GrPipelineBuilder* pipelineBuilder, |
| + GrColor color, |
| + const SkMatrix& viewMatrix, |
| + bool useAA, |
| + const SkRRect& rrect, |
| + const SkStrokeRec& stroke) { |
| + if (rrect.isOval()) { |
| + return this->drawOval(target, pipelineBuilder, color, viewMatrix, useAA, rrect.getBounds(), |
| + stroke); |
| + } |
| + |
| + bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isMultisampled(); |
| + |
| + // only anti-aliased rrects for now |
| + if (!useCoverageAA) { |
| + return false; |
| + } |
| + |
| + if (!viewMatrix.rectStaysRect() || !rrect.isSimple()) { |
| + return false; |
| + } |
| + |
| + SkRect bounds; |
| + SkAutoTUnref<GrBatch> batch(create_rrect_batch(color, viewMatrix, rrect, stroke, &bounds, |
| + &fStrokeRRectIndexBuffer, &fRRectIndexBuffer, |
| + fGpu)); |
| + if (!batch) { |
| + return false; |
| + } |
| + |
| + target->drawBatch(pipelineBuilder, batch, &bounds); |
| return true; |
| } |
| + |
| +/////////////////////////////////////////////////////////////////////////////////////////////////// |
| + |
| +#ifdef GR_TEST_UTILS |
| + |
| +static SkStrokeRec random_strokerec(SkRandom* random) { |
| + SkStrokeRec::InitStyle style = |
| + SkStrokeRec::InitStyle(random->nextULessThan(SkStrokeRec::kFill_InitStyle + 1)); |
| + SkStrokeRec rec(style); |
| + bool strokeAndFill = random->nextBool(); |
|
robertphillips
2015/04/30 14:07:32
Should probably also have a very wide stroke - 10.
|
| + SkScalar strokeWidth = random->nextBool() ? 0.f : 1.f; |
| + rec.setStrokeStyle(strokeWidth, strokeAndFill); |
| + return rec; |
| +} |
| + |
| +BATCH_TEST_DEFINE(CircleBatch) { |
| + SkMatrix viewMatrix = GrTest::TestMatrix(random); |
| + GrColor color = GrRandomColor(random); |
| + bool useCoverageAA = random->nextBool(); |
| + SkRect circle = GrTest::TestRect(random); |
| + SkRect bounds; // unused |
| + return create_circle_batch(color, viewMatrix, useCoverageAA, circle, random_strokerec(random), |
| + &bounds); |
| +} |
| + |
| +BATCH_TEST_DEFINE(EllipseBatch) { |
| + SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); |
| + GrColor color = GrRandomColor(random); |
| + bool useCoverageAA = random->nextBool(); |
| + SkRect ellipse = GrTest::TestRect(random); |
| + SkRect bounds; // unused |
| + return create_ellipse_batch(color, viewMatrix, useCoverageAA, ellipse, |
| + random_strokerec(random), &bounds); |
| +} |
| + |
| +BATCH_TEST_DEFINE(DIEllipseBatch) { |
| + SkMatrix viewMatrix = GrTest::TestMatrix(random); |
| + GrColor color = GrRandomColor(random); |
| + bool useCoverageAA = random->nextBool(); |
| + SkRect ellipse = GrTest::TestRect(random); |
| + SkRect bounds; // unused |
| + return create_diellipse_batch(color, viewMatrix, useCoverageAA, ellipse, |
| + random_strokerec(random), &bounds); |
| +} |
| + |
| +BATCH_TEST_DEFINE(RRectBatch) { |
| + SkMatrix viewMatrix = GrTest::TestMatrixRectStaysRect(random); |
| + 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, |
| + &gStrokeRRectIndexBuffer, &gRRectIndexBuffer, context->getGpu()); |
| +} |
| + |
| +#endif |