From: bsalomon Date: Mon, 4 May 2015 17:36:42 +0000 (-0700) Subject: Move instanced index buffer creation to flush time X-Git-Tag: submit/tizen/20180928.044319~2544 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66b;p=platform%2Fupstream%2FlibSkiaSharp.git Move instanced index buffer creation to flush time Committed: https://skia.googlesource.com/skia/+/ab622c7b8cc8c39f0a594e4392b9e31b7e1ddb26 Review URL: https://codereview.chromium.org/1116943004 --- diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp index 182d71aaf6..6568422898 100644 --- a/gm/beziereffects.cpp +++ b/gm/beziereffects.cpp @@ -16,6 +16,7 @@ #include "GrBufferAllocPool.h" #include "GrContext.h" #include "GrPathUtils.h" +#include "GrResourceProvider.h" #include "GrTest.h" #include "GrTestBatch.h" #include "SkColorPriv.h" @@ -66,17 +67,18 @@ private: } void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { - size_t vertexStride = this->geometryProcessor()->getVertexStride(); + SkAutoTUnref indexBuffer( + batchTarget->resourceProvider()->refQuadIndexBuffer()); + size_t vertexStride = this->geometryProcessor()->getVertexStride(); const GrVertexBuffer* vertexBuffer; int firstVertex; - void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, kVertsPerCubic, &vertexBuffer, &firstVertex); - if (!vertices || !batchTarget->quadIndexBuffer()) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate buffers\n"); return; } @@ -100,7 +102,7 @@ private: drawInfo.setVertexCount(kVertsPerCubic); drawInfo.setStartIndex(0); drawInfo.setIndexCount(kIndicesPerCubic); - drawInfo.setIndexBuffer(batchTarget->quadIndexBuffer()); + drawInfo.setIndexBuffer(indexBuffer); batchTarget->draw(drawInfo); } @@ -473,8 +475,10 @@ private: } void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { - size_t vertexStride = this->geometryProcessor()->getVertexStride(); + SkAutoTUnref indexBuffer( + batchTarget->resourceProvider()->refQuadIndexBuffer()); + size_t vertexStride = this->geometryProcessor()->getVertexStride(); const GrVertexBuffer* vertexBuffer; int firstVertex; @@ -483,7 +487,7 @@ private: &vertexBuffer, &firstVertex); - if (!vertices || !batchTarget->quadIndexBuffer()) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate buffers\n"); return; } @@ -505,7 +509,7 @@ private: drawInfo.setVertexCount(kVertsPerCubic); drawInfo.setStartIndex(0); drawInfo.setIndexCount(kIndicesPerCubic); - drawInfo.setIndexBuffer(batchTarget->quadIndexBuffer()); + drawInfo.setIndexBuffer(indexBuffer); batchTarget->draw(drawInfo); } diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp index 07d5fc2112..60b73c571d 100644 --- a/gm/convexpolyeffect.cpp +++ b/gm/convexpolyeffect.cpp @@ -17,6 +17,7 @@ #include "GrContext.h" #include "GrDefaultGeoProcFactory.h" #include "GrPathUtils.h" +#include "GrResourceProvider.h" #include "GrTest.h" #include "GrTestBatch.h" #include "SkColorPriv.h" @@ -52,8 +53,10 @@ private: } void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override { - size_t vertexStride = this->geometryProcessor()->getVertexStride(); + SkAutoTUnref indexBuffer( + batchTarget->resourceProvider()->refQuadIndexBuffer()); + size_t vertexStride = this->geometryProcessor()->getVertexStride(); const GrVertexBuffer* vertexBuffer; int firstVertex; @@ -62,7 +65,7 @@ private: &vertexBuffer, &firstVertex); - if (!vertices || !batchTarget->quadIndexBuffer()) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate buffers\n"); return; } @@ -82,7 +85,7 @@ private: drawInfo.setVertexCount(kVertsPerCubic); drawInfo.setStartIndex(0); drawInfo.setIndexCount(kIndicesPerCubic); - drawInfo.setIndexBuffer(batchTarget->quadIndexBuffer()); + drawInfo.setIndexBuffer(indexBuffer); batchTarget->draw(drawInfo); } diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi index 4d2549e2fd..3944a0355e 100644 --- a/gyp/gpu.gypi +++ b/gyp/gpu.gypi @@ -167,6 +167,8 @@ '<(skia_src_path)/gpu/GrReducedClip.h', '<(skia_src_path)/gpu/GrResourceCache.cpp', '<(skia_src_path)/gpu/GrResourceCache.h', + '<(skia_src_path)/gpu/GrResourceProvider.cpp', + '<(skia_src_path)/gpu/GrResourceProvider.h', '<(skia_src_path)/gpu/GrStencil.cpp', '<(skia_src_path)/gpu/GrStencil.h', '<(skia_src_path)/gpu/GrStencilAndCoverPathRenderer.cpp', diff --git a/include/core/SkOnce.h b/include/core/SkOnce.h index a4188d08f0..c7a87f77a0 100644 --- a/include/core/SkOnce.h +++ b/include/core/SkOnce.h @@ -30,7 +30,7 @@ #include "SkAtomics.h" #include "SkSpinlock.h" -// This must be used in a global scope, not in fuction scope or as a class member. +// This must be used in a global scope, not in function scope or as a class member. #define SK_DECLARE_STATIC_ONCE(name) namespace {} static SkOnceFlag name class SkOnceFlag; diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h index dc824d51d5..8bdc9f5b2d 100644 --- a/include/gpu/GrContext.h +++ b/include/gpu/GrContext.h @@ -539,7 +539,6 @@ public: GrLayerCache* getLayerCache() { return fLayerCache.get(); } GrTextBlobCache* getTextBlobCache() { return fTextBlobCache; } GrDrawTarget* getTextTarget(); - const GrIndexBuffer* getQuadIndexBuffer() const; GrAARectRenderer* getAARectRenderer() { return fAARectRenderer; } GrResourceProvider* resourceProvider() { return fResourceProvider; } const GrResourceProvider* resourceProvider() const { return fResourceProvider; } diff --git a/include/gpu/GrResourceKey.h b/include/gpu/GrResourceKey.h index aecdc70c0b..50a7145929 100644 --- a/include/gpu/GrResourceKey.h +++ b/include/gpu/GrResourceKey.h @@ -10,6 +10,7 @@ #define GrResourceKey_DEFINED #include "GrTypes.h" +#include "SkOnce.h" #include "SkTemplates.h" uint32_t GrResourceKeyHash(const uint32_t* data, size_t size); @@ -266,6 +267,24 @@ public: }; }; +/** + * It is common to need a frequently reused GrUniqueKey where the only requirement is that the key + * is unique. These macros create such a key in a thread safe manner so the key can be truly global + * and only constructed once. + */ + +/** Place outside of function/class definitions. */ +#define GR_DECLARE_STATIC_UNIQUE_KEY(name) SK_DECLARE_STATIC_ONCE(name##_once) + +/** Place inside function where the key is used. */ +#define GR_DEFINE_STATIC_UNIQUE_KEY(name) \ + static GrUniqueKey name; \ + SkOnce(&name##_once, gr_init_static_unique_key_once, &name) + +static inline void gr_init_static_unique_key_once(GrUniqueKey* key) { + GrUniqueKey::Builder builder(key, GrUniqueKey::GenerateDomain(), 0); +} + // The cache listens for these messages to purge junk resources proactively. class GrUniqueKeyInvalidatedMessage { public: diff --git a/include/gpu/GrTextureProvider.h b/include/gpu/GrTextureProvider.h index 3e29dabd47..3f8c760f9b 100644 --- a/include/gpu/GrTextureProvider.h +++ b/include/gpu/GrTextureProvider.h @@ -154,6 +154,12 @@ protected: fGpu = NULL; } + GrResourceCache* cache() { return fCache; } + const GrResourceCache* cache() const { return fCache; } + + GrGpu* gpu() { return fGpu; } + const GrGpu* gpu() const { return fGpu; } + private: bool isAbandoned() const { SkASSERT(SkToBool(fGpu) == SkToBool(fCache)); diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp index 669ec09d97..ca8c52fa34 100755 --- a/src/gpu/GrAADistanceFieldPathRenderer.cpp +++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp @@ -15,6 +15,7 @@ #include "GrPipelineBuilder.h" #include "GrSurfacePriv.h" #include "GrSWMaskHelper.h" +#include "GrResourceProvider.h" #include "GrTexturePriv.h" #include "GrVertexBuffer.h" #include "effects/GrDistanceFieldGeoProc.h" @@ -194,13 +195,17 @@ public: this->initDraw(batchTarget, dfProcessor, pipeline); + static const int kVertsPerQuad = 4; + static const int kIndicesPerQuad = 6; + + SkAutoTUnref indexBuffer( + batchTarget->resourceProvider()->refQuadIndexBuffer()); + // allocate vertices size_t vertexStride = dfProcessor->getVertexStride(); SkASSERT(vertexStride == 2 * sizeof(SkPoint)); - - int vertexCount = GrBatchTarget::kVertsPerRect * instanceCount; - const GrVertexBuffer* vertexBuffer; + int vertexCount = kVertsPerQuad * instanceCount; int firstVertex; void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, @@ -208,24 +213,23 @@ public: &vertexBuffer, &firstVertex); - if (!vertices) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate vertices\n"); return; } // We may have to flush while uploading path data to the atlas, so we set up the draw here - const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer(); - int maxInstancesPerDraw = quadIndexBuffer->maxQuads(); + int maxInstancesPerDraw = indexBuffer->maxQuads(); GrDrawTarget::DrawInfo drawInfo; drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); drawInfo.setStartVertex(0); drawInfo.setStartIndex(0); - drawInfo.setVerticesPerInstance(GrBatchTarget::kVertsPerRect); - drawInfo.setIndicesPerInstance(GrBatchTarget::kIndicesPerRect); + drawInfo.setVerticesPerInstance(kVertsPerQuad); + drawInfo.setIndicesPerInstance(kIndicesPerQuad); drawInfo.adjustStartVertex(firstVertex); drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setIndexBuffer(quadIndexBuffer); + drawInfo.setIndexBuffer(indexBuffer); int instancesToFlush = 0; for (int i = 0; i < instanceCount; i++) { @@ -280,7 +284,7 @@ public: // Now set vertices intptr_t offset = reinterpret_cast(vertices); - offset += i * GrBatchTarget::kVertsPerRect * vertexStride; + offset += i * kVertsPerQuad * vertexStride; SkPoint* positions = reinterpret_cast(offset); this->drawPath(batchTarget, atlas, diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp index ad6550072d..f046af871f 100644 --- a/src/gpu/GrAAHairLinePathRenderer.cpp +++ b/src/gpu/GrAAHairLinePathRenderer.cpp @@ -14,11 +14,11 @@ #include "GrContext.h" #include "GrDefaultGeoProcFactory.h" #include "GrDrawTargetCaps.h" -#include "GrGpu.h" #include "GrIndexBuffer.h" #include "GrPathUtils.h" #include "GrPipelineBuilder.h" #include "GrProcessor.h" +#include "GrResourceProvider.h" #include "GrVertexBuffer.h" #include "SkGeometry.h" #include "SkStroke.h" @@ -26,6 +26,8 @@ #include "effects/GrBezierEffect.h" +#define PREALLOC_PTARRAY(N) SkSTArray<(N),SkPoint, true> + // quadratics are rendered as 5-sided polys in order to bound the // AA stroke around the center-curve. See comments in push_quad_index_buffer and // bloat_quad. Quadratics and conics share an index buffer @@ -61,6 +63,14 @@ static const uint16_t kQuadIdxBufPattern[] = { static const int kIdxsPerQuad = SK_ARRAY_COUNT(kQuadIdxBufPattern); static const int kQuadNumVertices = 5; static const int kQuadsNumInIdxBuffer = 256; +GR_DECLARE_STATIC_UNIQUE_KEY(gQuadsIndexBufferKey); + +static const GrIndexBuffer* ref_quads_index_buffer(GrResourceProvider* resourceProvider) { + GR_DEFINE_STATIC_UNIQUE_KEY(gQuadsIndexBufferKey); + return resourceProvider->refOrCreateInstancedIndexBuffer( + kQuadIdxBufPattern, kIdxsPerQuad, kQuadsNumInIdxBuffer, kQuadNumVertices, + gQuadsIndexBufferKey); +} // Each line segment is rendered as two quads and two triangles. @@ -87,43 +97,17 @@ static const int kIdxsPerLineSeg = SK_ARRAY_COUNT(kLineSegIdxBufPattern); static const int kLineSegNumVertices = 6; static const int kLineSegsNumInIdxBuffer = 256; -GrPathRenderer* GrAAHairLinePathRenderer::Create(GrContext* context) { - GrGpu* gpu = context->getGpu(); - GrIndexBuffer* qIdxBuf = gpu->createInstancedIndexBuffer(kQuadIdxBufPattern, - kIdxsPerQuad, - kQuadsNumInIdxBuffer, - kQuadNumVertices); - SkAutoTUnref qIdxBuffer(qIdxBuf); - GrIndexBuffer* lIdxBuf = gpu->createInstancedIndexBuffer(kLineSegIdxBufPattern, - kIdxsPerLineSeg, - kLineSegsNumInIdxBuffer, - kLineSegNumVertices); - SkAutoTUnref lIdxBuffer(lIdxBuf); - return SkNEW_ARGS(GrAAHairLinePathRenderer, - (context, lIdxBuf, qIdxBuf)); -} +GR_DECLARE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey); -GrAAHairLinePathRenderer::GrAAHairLinePathRenderer( - const GrContext* context, - const GrIndexBuffer* linesIndexBuffer, - const GrIndexBuffer* quadsIndexBuffer) { - fLinesIndexBuffer = linesIndexBuffer; - linesIndexBuffer->ref(); - fQuadsIndexBuffer = quadsIndexBuffer; - quadsIndexBuffer->ref(); +static const GrIndexBuffer* ref_lines_index_buffer(GrResourceProvider* resourceProvider) { + GR_DEFINE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey); + return resourceProvider->refOrCreateInstancedIndexBuffer( + kLineSegIdxBufPattern, kIdxsPerLineSeg, kLineSegsNumInIdxBuffer, kLineSegNumVertices, + gLinesIndexBufferKey); } -GrAAHairLinePathRenderer::~GrAAHairLinePathRenderer() { - fLinesIndexBuffer->unref(); - fQuadsIndexBuffer->unref(); -} - -namespace { - -#define PREALLOC_PTARRAY(N) SkSTArray<(N),SkPoint, true> - // Takes 178th time of logf on Z600 / VC2010 -int get_float_exp(float x) { +static int get_float_exp(float x) { GR_STATIC_ASSERT(sizeof(int) == sizeof(float)); #ifdef SK_DEBUG static bool tested; @@ -151,7 +135,7 @@ int get_float_exp(float x) { // found along the curve segment it will return 1 and // dst[0] is the original conic. If it returns 2 the dst[0] // and dst[1] are the two new conics. -int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) { +static int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) { SkScalar t = SkFindQuadMaxCurvature(src); if (t == 0) { if (dst) { @@ -171,7 +155,7 @@ int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) { // Calls split_conic on the entire conic and then once more on each subsection. // Most cases will result in either 1 conic (chop point is not within t range) // or 3 points (split once and then one subsection is split again). -int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) { +static int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) { SkConic dstTemp[2]; int conicCnt = split_conic(src, dstTemp, weight); if (2 == conicCnt) { @@ -186,7 +170,7 @@ int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) { // returns 0 if quad/conic is degen or close to it // in this case approx the path with lines // otherwise returns 1 -int is_degen_quad_or_conic(const SkPoint p[3], SkScalar* dsqd) { +static int is_degen_quad_or_conic(const SkPoint p[3], SkScalar* dsqd) { static const SkScalar gDegenerateToLineTol = SK_Scalar1; static const SkScalar gDegenerateToLineTolSqd = SkScalarMul(gDegenerateToLineTol, gDegenerateToLineTol); @@ -207,14 +191,14 @@ int is_degen_quad_or_conic(const SkPoint p[3], SkScalar* dsqd) { return 0; } -int is_degen_quad_or_conic(const SkPoint p[3]) { +static int is_degen_quad_or_conic(const SkPoint p[3]) { SkScalar dsqd; return is_degen_quad_or_conic(p, &dsqd); } // we subdivide the quads to avoid huge overfill // if it returns -1 then should be drawn as lines -int num_quad_subdivs(const SkPoint p[3]) { +static int num_quad_subdivs(const SkPoint p[3]) { SkScalar dsqd; if (is_degen_quad_or_conic(p, &dsqd)) { return -1; @@ -250,14 +234,14 @@ int num_quad_subdivs(const SkPoint p[3]) { * subdivide large quads to reduce over-fill. This subdivision has to be * performed before applying the perspective matrix. */ -int gather_lines_and_quads(const SkPath& path, - const SkMatrix& m, - const SkIRect& devClipBounds, - GrAAHairLinePathRenderer::PtArray* lines, - GrAAHairLinePathRenderer::PtArray* quads, - GrAAHairLinePathRenderer::PtArray* conics, - GrAAHairLinePathRenderer::IntArray* quadSubdivCnts, - GrAAHairLinePathRenderer::FloatArray* conicWeights) { +static int gather_lines_and_quads(const SkPath& path, + const SkMatrix& m, + const SkIRect& devClipBounds, + GrAAHairLinePathRenderer::PtArray* lines, + GrAAHairLinePathRenderer::PtArray* quads, + GrAAHairLinePathRenderer::PtArray* conics, + GrAAHairLinePathRenderer::IntArray* quadSubdivCnts, + GrAAHairLinePathRenderer::FloatArray* conicWeights) { SkPath::Iter iter(path, false); int totalQuadCount = 0; @@ -441,9 +425,9 @@ struct BezierVertex { GR_STATIC_ASSERT(sizeof(BezierVertex) == 3 * sizeof(SkPoint)); -void intersect_lines(const SkPoint& ptA, const SkVector& normA, - const SkPoint& ptB, const SkVector& normB, - SkPoint* result) { +static void intersect_lines(const SkPoint& ptA, const SkVector& normA, + const SkPoint& ptB, const SkVector& normB, + SkPoint* result) { SkScalar lineAW = -normA.dot(ptA); SkScalar lineBW = -normB.dot(ptB); @@ -459,14 +443,14 @@ void intersect_lines(const SkPoint& ptA, const SkVector& normA, result->fY = SkScalarMul(result->fY, wInv); } -void set_uv_quad(const SkPoint qpts[3], BezierVertex verts[kQuadNumVertices]) { +static void set_uv_quad(const SkPoint qpts[3], BezierVertex verts[kQuadNumVertices]) { // this should be in the src space, not dev coords, when we have perspective GrPathUtils::QuadUVMatrix DevToUV(qpts); DevToUV.apply(verts); } -void bloat_quad(const SkPoint qpts[3], const SkMatrix* toDevice, - const SkMatrix* toSrc, BezierVertex verts[kQuadNumVertices]) { +static void bloat_quad(const SkPoint qpts[3], const SkMatrix* toDevice, + const SkMatrix* toSrc, BezierVertex verts[kQuadNumVertices]) { SkASSERT(!toDevice == !toSrc); // original quad is specified by tri a,b,c SkPoint a = qpts[0]; @@ -544,8 +528,8 @@ void bloat_quad(const SkPoint qpts[3], const SkMatrix* toDevice, // f(x, y, w) = f(P) = K^2 - LM // K = dot(k, P), L = dot(l, P), M = dot(m, P) // k, l, m are calculated in function GrPathUtils::getConicKLM -void set_conic_coeffs(const SkPoint p[3], BezierVertex verts[kQuadNumVertices], - const SkScalar weight) { +static void set_conic_coeffs(const SkPoint p[3], BezierVertex verts[kQuadNumVertices], + const SkScalar weight) { SkScalar klm[9]; GrPathUtils::getConicKLM(p, weight, klm); @@ -558,21 +542,21 @@ void set_conic_coeffs(const SkPoint p[3], BezierVertex verts[kQuadNumVertices], } } -void add_conics(const SkPoint p[3], - const SkScalar weight, - const SkMatrix* toDevice, - const SkMatrix* toSrc, - BezierVertex** vert) { +static void add_conics(const SkPoint p[3], + const SkScalar weight, + const SkMatrix* toDevice, + const SkMatrix* toSrc, + BezierVertex** vert) { bloat_quad(p, toDevice, toSrc, *vert); set_conic_coeffs(p, *vert, weight); *vert += kQuadNumVertices; } -void add_quads(const SkPoint p[3], - int subdiv, - const SkMatrix* toDevice, - const SkMatrix* toSrc, - BezierVertex** vert) { +static void add_quads(const SkPoint p[3], + int subdiv, + const SkMatrix* toDevice, + const SkMatrix* toSrc, + BezierVertex** vert) { SkASSERT(subdiv >= 0); if (subdiv) { SkPoint newP[5]; @@ -586,10 +570,10 @@ void add_quads(const SkPoint p[3], } } -void add_line(const SkPoint p[2], - const SkMatrix* toSrc, - uint8_t coverage, - LineVertex** vert) { +static void add_line(const SkPoint p[2], + const SkMatrix* toSrc, + uint8_t coverage, + LineVertex** vert) { const SkPoint& a = p[0]; const SkPoint& b = p[1]; @@ -631,8 +615,6 @@ void add_line(const SkPoint p[2], *vert += kLineSegNumVertices; } -} - /////////////////////////////////////////////////////////////////////////////// bool GrAAHairLinePathRenderer::canDrawPath(const GrDrawTarget* target, @@ -703,11 +685,8 @@ public: SkIRect fDevClipBounds; }; - // TODO Batch itself should not hold on to index buffers. Instead, these should live in the - // cache. - static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* linesIndexBuffer, - const GrIndexBuffer* quadsIndexBuffer) { - return SkNEW_ARGS(AAHairlineBatch, (geometry, linesIndexBuffer, quadsIndexBuffer)); + static GrBatch* Create(const Geometry& geometry) { + return SkNEW_ARGS(AAHairlineBatch, (geometry)); } const char* name() const override { return "AAHairlineBatch"; } @@ -745,11 +724,7 @@ private: typedef SkTArray IntArray; typedef SkTArray FloatArray; - AAHairlineBatch(const Geometry& geometry, const GrIndexBuffer* linesIndexBuffer, - const GrIndexBuffer* quadsIndexBuffer) - : fLinesIndexBuffer(linesIndexBuffer) - , fQuadsIndexBuffer(quadsIndexBuffer) { - SkASSERT(linesIndexBuffer && quadsIndexBuffer); + AAHairlineBatch(const Geometry& geometry) { this->initClassID(); fGeoData.push_back(geometry); @@ -808,8 +783,6 @@ private: BatchTracker fBatch; SkSTArray<1, Geometry, true> fGeoData; - const GrIndexBuffer* fLinesIndexBuffer; - const GrIndexBuffer* fQuadsIndexBuffer; }; void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) { @@ -880,6 +853,8 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel // do lines first if (lineCount) { + SkAutoTUnref linesIndexBuffer( + ref_lines_index_buffer(batchTarget->resourceProvider())); batchTarget->initDraw(lineGP, pipeline); // TODO remove this when batch is everywhere @@ -900,7 +875,7 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel &vertexBuffer, &firstVertex); - if (!vertices) { + if (!vertices || !linesIndexBuffer) { SkDebugf("Could not allocate vertices\n"); return; } @@ -915,7 +890,7 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel { GrDrawTarget::DrawInfo info; info.setVertexBuffer(vertexBuffer); - info.setIndexBuffer(fLinesIndexBuffer); + info.setIndexBuffer(linesIndexBuffer); info.setPrimitiveType(kTriangles_GrPrimitiveType); info.setStartIndex(0); @@ -937,6 +912,9 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel const GrVertexBuffer* vertexBuffer; int firstVertex; + SkAutoTUnref quadsIndexBuffer( + ref_quads_index_buffer(batchTarget->resourceProvider())); + size_t vertexStride = sizeof(BezierVertex); int vertexCount = kQuadNumVertices * quadCount + kQuadNumVertices * conicCount; void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, @@ -944,7 +922,7 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel &vertexBuffer, &firstVertex); - if (!vertices) { + if (!vertices || !quadsIndexBuffer) { SkDebugf("Could not allocate vertices\n"); return; } @@ -977,7 +955,7 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel { GrDrawTarget::DrawInfo info; info.setVertexBuffer(vertexBuffer); - info.setIndexBuffer(fQuadsIndexBuffer); + info.setIndexBuffer(quadsIndexBuffer); info.setPrimitiveType(kTriangles_GrPrimitiveType); info.setStartIndex(0); @@ -1009,7 +987,7 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel { GrDrawTarget::DrawInfo info; info.setVertexBuffer(vertexBuffer); - info.setIndexBuffer(fQuadsIndexBuffer); + info.setIndexBuffer(quadsIndexBuffer); info.setPrimitiveType(kTriangles_GrPrimitiveType); info.setStartIndex(0); @@ -1033,9 +1011,7 @@ static GrBatch* create_hairline_batch(GrColor color, const SkMatrix& viewMatrix, const SkPath& path, const GrStrokeInfo& stroke, - const SkIRect& devClipBounds, - const GrIndexBuffer* linesIndexBuffer, - const GrIndexBuffer* quadsIndexBuffer) { + const SkIRect& devClipBounds) { SkScalar hairlineCoverage; uint8_t newCoverage = 0xff; if (GrPathRenderer::IsStrokeHairlineOrEquivalent(stroke, viewMatrix, &hairlineCoverage)) { @@ -1049,7 +1025,7 @@ static GrBatch* create_hairline_batch(GrColor color, geometry.fPath = path; geometry.fDevClipBounds = devClipBounds; - return AAHairlineBatch::Create(geometry, linesIndexBuffer, quadsIndexBuffer); + return AAHairlineBatch::Create(geometry); } bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target, @@ -1059,18 +1035,12 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target, const SkPath& path, const GrStrokeInfo& stroke, bool) { - if (!fLinesIndexBuffer || !fQuadsIndexBuffer) { - SkDebugf("unable to allocate indices\n"); - return false; - } - SkIRect devClipBounds; pipelineBuilder->clip().getConservativeBounds(pipelineBuilder->getRenderTarget(), &devClipBounds); SkAutoTUnref batch(create_hairline_batch(color, viewMatrix, path, stroke, - devClipBounds, fLinesIndexBuffer, - fQuadsIndexBuffer)); + devClipBounds)); target->drawBatch(pipelineBuilder, batch); return true; @@ -1081,28 +1051,13 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target, #ifdef GR_TEST_UTILS BATCH_TEST_DEFINE(AAHairlineBatch) { - // TODO put these in the cache - static GrIndexBuffer* gQuadIndexBuffer; - static GrIndexBuffer* gLineIndexBuffer; - if (!gQuadIndexBuffer) { - gQuadIndexBuffer = context->getGpu()->createInstancedIndexBuffer(kQuadIdxBufPattern, - kIdxsPerQuad, - kQuadsNumInIdxBuffer, - kQuadNumVertices); - gLineIndexBuffer = context->getGpu()->createInstancedIndexBuffer(kLineSegIdxBufPattern, - kIdxsPerLineSeg, - kLineSegsNumInIdxBuffer, - kLineSegNumVertices); - } - GrColor color = GrRandomColor(random); SkMatrix viewMatrix = GrTest::TestMatrix(random); GrStrokeInfo stroke(SkStrokeRec::kHairline_InitStyle); SkPath path = GrTest::TestPath(random); SkIRect devClipBounds; devClipBounds.setEmpty(); - return create_hairline_batch(color, viewMatrix, path, stroke, devClipBounds, gLineIndexBuffer, - gQuadIndexBuffer); + return create_hairline_batch(color, viewMatrix, path, stroke, devClipBounds); } #endif diff --git a/src/gpu/GrAAHairLinePathRenderer.h b/src/gpu/GrAAHairLinePathRenderer.h index 9f8d8aae9e..b523493bad 100644 --- a/src/gpu/GrAAHairLinePathRenderer.h +++ b/src/gpu/GrAAHairLinePathRenderer.h @@ -13,37 +13,30 @@ class GrAAHairLinePathRenderer : public GrPathRenderer { public: - virtual ~GrAAHairLinePathRenderer(); + static GrPathRenderer* Create() { return SkNEW(GrAAHairLinePathRenderer); } - static GrPathRenderer* Create(GrContext* context); - - virtual bool canDrawPath(const GrDrawTarget*, - const GrPipelineBuilder*, - const SkMatrix& viewMatrix, - const SkPath&, - const GrStrokeInfo&, - bool antiAlias) const override; + bool canDrawPath(const GrDrawTarget*, + const GrPipelineBuilder*, + const SkMatrix& viewMatrix, + const SkPath&, + const GrStrokeInfo&, + bool antiAlias) const override; typedef SkTArray PtArray; typedef SkTArray IntArray; typedef SkTArray FloatArray; protected: - virtual bool onDrawPath(GrDrawTarget*, - GrPipelineBuilder*, - GrColor, - const SkMatrix& viewMatrix, - const SkPath&, - const GrStrokeInfo&, - bool antiAlias) override; + bool onDrawPath(GrDrawTarget*, + GrPipelineBuilder*, + GrColor, + const SkMatrix& viewMatrix, + const SkPath&, + const GrStrokeInfo&, + bool antiAlias) override; private: - GrAAHairLinePathRenderer(const GrContext* context, - const GrIndexBuffer* fLinesIndexBuffer, - const GrIndexBuffer* fQuadsIndexBuffer); - - const GrIndexBuffer* fLinesIndexBuffer; - const GrIndexBuffer* fQuadsIndexBuffer; + GrAAHairLinePathRenderer() {} typedef GrPathRenderer INHERITED; }; diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp index 778205f3bb..d1c377aa53 100644 --- a/src/gpu/GrAARectRenderer.cpp +++ b/src/gpu/GrAARectRenderer.cpp @@ -13,10 +13,11 @@ #include "GrContext.h" #include "GrDefaultGeoProcFactory.h" #include "GrGeometryProcessor.h" -#include "GrGpu.h" #include "GrInvariantOutput.h" -#include "GrVertexBuffer.h" +#include "GrResourceKey.h" +#include "GrResourceProvider.h" #include "GrTestUtils.h" +#include "GrVertexBuffer.h" #include "SkColorPriv.h" #include "gl/GrGLProcessor.h" #include "gl/GrGLGeometryProcessor.h" @@ -30,18 +31,6 @@ static void set_inset_fan(SkPoint* pts, size_t stride, r.fRight - dx, r.fBottom - dy, stride); } -static const uint16_t gFillAARectIdx[] = { - 0, 1, 5, 5, 4, 0, - 1, 2, 6, 6, 5, 1, - 2, 3, 7, 7, 6, 2, - 3, 0, 4, 4, 7, 3, - 4, 5, 6, 6, 7, 4, -}; - -static const int kIndicesPerAAFillRect = SK_ARRAY_COUNT(gFillAARectIdx); -static const int kVertsPerAAFillRect = 8; -static const int kNumAAFillRectsInIndexBuffer = 256; - static const GrGeometryProcessor* create_fill_rect_gp(bool tweakAlphaForCoverage, const SkMatrix& localMatrix) { uint32_t flags = GrDefaultGeoProcFactory::kColor_GPType; @@ -57,6 +46,8 @@ static const GrGeometryProcessor* create_fill_rect_gp(bool tweakAlphaForCoverage return gp; } +GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); + class AAFillRectBatch : public GrBatch { public: struct Geometry { @@ -66,8 +57,8 @@ public: SkRect fDevRect; }; - static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* indexBuffer) { - return SkNEW_ARGS(AAFillRectBatch, (geometry, indexBuffer)); + static GrBatch* Create(const Geometry& geometry) { + return SkNEW_ARGS(AAFillRectBatch, (geometry)); } const char* name() const override { return "AAFillRectBatch"; } @@ -121,24 +112,23 @@ public: init.fUsesLocalCoords = this->usesLocalCoords(); gp->initBatchTracker(batchTarget->currentBatchTracker(), init); - size_t vertexStride = gp->getVertexStride(); + SkAutoTUnref indexBuffer(this->getIndexBuffer( + batchTarget->resourceProvider())); + size_t vertexStride = gp->getVertexStride(); SkASSERT(canTweakAlphaForCoverage ? vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) : vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); - int instanceCount = fGeoData.count(); int vertexCount = kVertsPerAAFillRect * instanceCount; - const GrVertexBuffer* vertexBuffer; int firstVertex; - void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex); - if (!vertices) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate vertices\n"); return; } @@ -163,7 +153,7 @@ public: drawInfo.setIndicesPerInstance(kIndicesPerAAFillRect); drawInfo.adjustStartVertex(firstVertex); drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setIndexBuffer(fIndexBuffer); + drawInfo.setIndexBuffer(indexBuffer); int maxInstancesPerDraw = kNumAAFillRectsInIndexBuffer; @@ -182,14 +172,33 @@ public: SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } private: - AAFillRectBatch(const Geometry& geometry, const GrIndexBuffer* indexBuffer) - : fIndexBuffer(indexBuffer) { + AAFillRectBatch(const Geometry& geometry) { this->initClassID(); fGeoData.push_back(geometry); this->setBounds(geometry.fDevRect); } + static const int kNumAAFillRectsInIndexBuffer = 256; + static const int kVertsPerAAFillRect = 8; + static const int kIndicesPerAAFillRect = 30; + + const GrIndexBuffer* getIndexBuffer(GrResourceProvider* resourceProvider) { + GR_DEFINE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey); + + static const uint16_t gFillAARectIdx[] = { + 0, 1, 5, 5, 4, 0, + 1, 2, 6, 6, 5, 1, + 2, 3, 7, 7, 6, 2, + 3, 0, 4, 4, 7, 3, + 4, 5, 6, 6, 7, 4, + }; + GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFillAARectIdx) == kIndicesPerAAFillRect); + return resourceProvider->refOrCreateInstancedIndexBuffer(gFillAARectIdx, + kIndicesPerAAFillRect, kNumAAFillRectsInIndexBuffer, kVertsPerAAFillRect, + gAAFillRectIndexBufferKey); + } + GrColor color() const { return fBatch.fColor; } bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; } @@ -324,7 +333,6 @@ private: }; BatchTracker fBatch; - const GrIndexBuffer* fIndexBuffer; SkSTArray<1, Geometry, true> fGeoData; }; @@ -336,149 +344,20 @@ enum CoverageAttribType { }; } -void GrAARectRenderer::reset() { - SkSafeSetNull(fAAFillRectIndexBuffer); - SkSafeSetNull(fAAMiterStrokeRectIndexBuffer); - SkSafeSetNull(fAABevelStrokeRectIndexBuffer); -} - -static const uint16_t gMiterStrokeAARectIdx[] = { - 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, - 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, - 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, - 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, - - 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, - 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, - 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4, - 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4, - - 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8, - 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8, - 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8, - 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, -}; - -static const int kIndicesPerMiterStrokeRect = SK_ARRAY_COUNT(gMiterStrokeAARectIdx); -static const int kVertsPerMiterStrokeRect = 16; -static const int kNumMiterStrokeRectsInIndexBuffer = 256; - -/** - * As in miter-stroke, index = a + b, and a is the current index, b is the shift - * from the first index. The index layout: - * outer AA line: 0~3, 4~7 - * outer edge: 8~11, 12~15 - * inner edge: 16~19 - * inner AA line: 20~23 - * Following comes a bevel-stroke rect and its indices: - * - * 4 7 - * ********************************* - * * ______________________________ * - * * / 12 15 \ * - * * / \ * - * 0 * |8 16_____________________19 11 | * 3 - * * | | | | * - * * | | **************** | | * - * * | | * 20 23 * | | * - * * | | * * | | * - * * | | * 21 22 * | | * - * * | | **************** | | * - * * | |____________________| | * - * 1 * |9 17 18 10| * 2 - * * \ / * - * * \13 __________________________14/ * - * * * - * ********************************** - * 5 6 - */ -static const uint16_t gBevelStrokeAARectIdx[] = { - // Draw outer AA, from outer AA line to outer edge, shift is 0. - 0 + 0, 1 + 0, 9 + 0, 9 + 0, 8 + 0, 0 + 0, - 1 + 0, 5 + 0, 13 + 0, 13 + 0, 9 + 0, 1 + 0, - 5 + 0, 6 + 0, 14 + 0, 14 + 0, 13 + 0, 5 + 0, - 6 + 0, 2 + 0, 10 + 0, 10 + 0, 14 + 0, 6 + 0, - 2 + 0, 3 + 0, 11 + 0, 11 + 0, 10 + 0, 2 + 0, - 3 + 0, 7 + 0, 15 + 0, 15 + 0, 11 + 0, 3 + 0, - 7 + 0, 4 + 0, 12 + 0, 12 + 0, 15 + 0, 7 + 0, - 4 + 0, 0 + 0, 8 + 0, 8 + 0, 12 + 0, 4 + 0, - - // Draw the stroke, from outer edge to inner edge, shift is 8. - 0 + 8, 1 + 8, 9 + 8, 9 + 8, 8 + 8, 0 + 8, - 1 + 8, 5 + 8, 9 + 8, - 5 + 8, 6 + 8, 10 + 8, 10 + 8, 9 + 8, 5 + 8, - 6 + 8, 2 + 8, 10 + 8, - 2 + 8, 3 + 8, 11 + 8, 11 + 8, 10 + 8, 2 + 8, - 3 + 8, 7 + 8, 11 + 8, - 7 + 8, 4 + 8, 8 + 8, 8 + 8, 11 + 8, 7 + 8, - 4 + 8, 0 + 8, 8 + 8, - - // Draw the inner AA, from inner edge to inner AA line, shift is 16. - 0 + 16, 1 + 16, 5 + 16, 5 + 16, 4 + 16, 0 + 16, - 1 + 16, 2 + 16, 6 + 16, 6 + 16, 5 + 16, 1 + 16, - 2 + 16, 3 + 16, 7 + 16, 7 + 16, 6 + 16, 2 + 16, - 3 + 16, 0 + 16, 4 + 16, 4 + 16, 7 + 16, 3 + 16, -}; - -static const int kIndicesPerBevelStrokeRect = SK_ARRAY_COUNT(gBevelStrokeAARectIdx); -static const int kVertsPerBevelStrokeRect = 24; -static const int kNumBevelStrokeRectsInIndexBuffer = 256; - -static int aa_stroke_rect_index_count(bool miterStroke) { - return miterStroke ? SK_ARRAY_COUNT(gMiterStrokeAARectIdx) : - SK_ARRAY_COUNT(gBevelStrokeAARectIdx); -} - -static GrIndexBuffer* setup_aa_stroke_rect_indexbuffer(GrIndexBuffer** aaMiterStrokeRectIndexBuffer, - GrIndexBuffer** aaBevelStrokeRectIndexBuffer, - GrGpu* gpu, - bool miterStroke) { - if (miterStroke) { - if (!*aaMiterStrokeRectIndexBuffer) { - *aaMiterStrokeRectIndexBuffer = - gpu->createInstancedIndexBuffer(gMiterStrokeAARectIdx, - kIndicesPerMiterStrokeRect, - kNumMiterStrokeRectsInIndexBuffer, - kVertsPerMiterStrokeRect); - } - return *aaMiterStrokeRectIndexBuffer; - } else { - if (!*aaBevelStrokeRectIndexBuffer) { - *aaBevelStrokeRectIndexBuffer = - gpu->createInstancedIndexBuffer(gBevelStrokeAARectIdx, - kIndicesPerBevelStrokeRect, - kNumBevelStrokeRectsInIndexBuffer, - kVertsPerBevelStrokeRect); - } - return *aaBevelStrokeRectIndexBuffer; - } -} - void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target, GrPipelineBuilder* pipelineBuilder, GrColor color, const SkMatrix& viewMatrix, const SkRect& rect, const SkRect& devRect) { - if (!fAAFillRectIndexBuffer) { - fAAFillRectIndexBuffer = fGpu->createInstancedIndexBuffer(gFillAARectIdx, - kIndicesPerAAFillRect, - kNumAAFillRectsInIndexBuffer, - kVertsPerAAFillRect); - } - - if (!fAAFillRectIndexBuffer) { - SkDebugf("Unable to create index buffer\n"); - return; - } - AAFillRectBatch::Geometry geometry; geometry.fRect = rect; geometry.fViewMatrix = viewMatrix; geometry.fDevRect = devRect; geometry.fColor = color; - SkAutoTUnref batch(AAFillRectBatch::Create(geometry, fAAFillRectIndexBuffer)); + + SkAutoTUnref batch(AAFillRectBatch::Create(geometry)); target->drawBatch(pipelineBuilder, batch); } @@ -544,6 +423,9 @@ void GrAARectRenderer::strokeAARect(GrDrawTarget* target, devOutsideAssist, devInside, miterStroke); } +GR_DECLARE_STATIC_UNIQUE_KEY(gMiterIndexBufferKey); +GR_DECLARE_STATIC_UNIQUE_KEY(gBevelIndexBufferKey); + class AAStrokeRectBatch : public GrBatch { public: // TODO support AA rotated stroke rects by copying around view matrices @@ -555,9 +437,8 @@ public: bool fMiterStroke; }; - static GrBatch* Create(const Geometry& geometry, const SkMatrix& viewMatrix, - const GrIndexBuffer* indexBuffer) { - return SkNEW_ARGS(AAStrokeRectBatch, (geometry, viewMatrix, indexBuffer)); + static GrBatch* Create(const Geometry& geometry, const SkMatrix& viewMatrix) { + return SkNEW_ARGS(AAStrokeRectBatch, (geometry, viewMatrix)); } const char* name() const override { return "AAStrokeRect"; } @@ -604,6 +485,9 @@ public: batchTarget->initDraw(gp, pipeline); + const SkAutoTUnref indexBuffer( + GetIndexBuffer(batchTarget->resourceProvider(), this->miterStroke())); + // TODO this is hacky, but the only way we have to initialize the GP is to use the // GrPipelineInfo struct so we can generate the correct shader. Once we have GrBatch // everywhere we can remove this nastiness @@ -619,7 +503,6 @@ public: SkASSERT(canTweakAlphaForCoverage ? vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) : vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr)); - int innerVertexNum = 4; int outerVertexNum = this->miterStroke() ? 4 : 8; int totalVertexNum = (outerVertexNum + innerVertexNum) * 2; @@ -635,7 +518,7 @@ public: &vertexBuffer, &firstVertex); - if (!vertices) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate vertices\n"); return; } @@ -654,18 +537,19 @@ public: args.fMiterStroke, canTweakAlphaForCoverage); } - + int indicesPerInstance = this->miterStroke() ? kMiterIndexCnt : kBevelIndexCnt; GrDrawTarget::DrawInfo drawInfo; drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); drawInfo.setStartVertex(0); drawInfo.setStartIndex(0); drawInfo.setVerticesPerInstance(totalVertexNum); - drawInfo.setIndicesPerInstance(aa_stroke_rect_index_count(this->miterStroke())); + drawInfo.setIndicesPerInstance(indicesPerInstance); drawInfo.adjustStartVertex(firstVertex); drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setIndexBuffer(fIndexBuffer); + drawInfo.setIndexBuffer(indexBuffer); - int maxInstancesPerDraw = kNumBevelStrokeRectsInIndexBuffer; + int maxInstancesPerDraw = this->miterStroke() ? kNumMiterRectsInIndexBuffer : + kNumBevelRectsInIndexBuffer; while (instanceCount) { drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)); @@ -682,9 +566,7 @@ public: SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } private: - AAStrokeRectBatch(const Geometry& geometry, const SkMatrix& viewMatrix, - const GrIndexBuffer* indexBuffer) - : fIndexBuffer(indexBuffer) { + AAStrokeRectBatch(const Geometry& geometry, const SkMatrix& viewMatrix) { this->initClassID(); fBatch.fViewMatrix = viewMatrix; fGeoData.push_back(geometry); @@ -695,6 +577,106 @@ private: fBounds.join(geometry.fDevOutsideAssist); } + + static const int kMiterIndexCnt = 3 * 24; + static const int kMiterVertexCnt = 16; + static const int kNumMiterRectsInIndexBuffer = 256; + + static const int kBevelIndexCnt = 48 + 36 + 24; + static const int kBevelVertexCnt = 24; + static const int kNumBevelRectsInIndexBuffer = 256; + + static const GrIndexBuffer* GetIndexBuffer(GrResourceProvider* resourceProvider, + bool miterStroke) { + + if (miterStroke) { + static const uint16_t gMiterIndices[] = { + 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, + 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, + 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, + 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, + + 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, + 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, + 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4, + 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4, + + 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8, + 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8, + 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8, + 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, + }; + GR_STATIC_ASSERT(SK_ARRAY_COUNT(gMiterIndices) == kMiterIndexCnt); + GR_DEFINE_STATIC_UNIQUE_KEY(gMiterIndexBufferKey); + return resourceProvider->refOrCreateInstancedIndexBuffer(gMiterIndices, + kMiterIndexCnt, kNumMiterRectsInIndexBuffer, kMiterVertexCnt, + gMiterIndexBufferKey); + } else { + /** + * As in miter-stroke, index = a + b, and a is the current index, b is the shift + * from the first index. The index layout: + * outer AA line: 0~3, 4~7 + * outer edge: 8~11, 12~15 + * inner edge: 16~19 + * inner AA line: 20~23 + * Following comes a bevel-stroke rect and its indices: + * + * 4 7 + * ********************************* + * * ______________________________ * + * * / 12 15 \ * + * * / \ * + * 0 * |8 16_____________________19 11 | * 3 + * * | | | | * + * * | | **************** | | * + * * | | * 20 23 * | | * + * * | | * * | | * + * * | | * 21 22 * | | * + * * | | **************** | | * + * * | |____________________| | * + * 1 * |9 17 18 10| * 2 + * * \ / * + * * \13 __________________________14/ * + * * * + * ********************************** + * 5 6 + */ + static const uint16_t gBevelIndices[] = { + // Draw outer AA, from outer AA line to outer edge, shift is 0. + 0 + 0, 1 + 0, 9 + 0, 9 + 0, 8 + 0, 0 + 0, + 1 + 0, 5 + 0, 13 + 0, 13 + 0, 9 + 0, 1 + 0, + 5 + 0, 6 + 0, 14 + 0, 14 + 0, 13 + 0, 5 + 0, + 6 + 0, 2 + 0, 10 + 0, 10 + 0, 14 + 0, 6 + 0, + 2 + 0, 3 + 0, 11 + 0, 11 + 0, 10 + 0, 2 + 0, + 3 + 0, 7 + 0, 15 + 0, 15 + 0, 11 + 0, 3 + 0, + 7 + 0, 4 + 0, 12 + 0, 12 + 0, 15 + 0, 7 + 0, + 4 + 0, 0 + 0, 8 + 0, 8 + 0, 12 + 0, 4 + 0, + + // Draw the stroke, from outer edge to inner edge, shift is 8. + 0 + 8, 1 + 8, 9 + 8, 9 + 8, 8 + 8, 0 + 8, + 1 + 8, 5 + 8, 9 + 8, + 5 + 8, 6 + 8, 10 + 8, 10 + 8, 9 + 8, 5 + 8, + 6 + 8, 2 + 8, 10 + 8, + 2 + 8, 3 + 8, 11 + 8, 11 + 8, 10 + 8, 2 + 8, + 3 + 8, 7 + 8, 11 + 8, + 7 + 8, 4 + 8, 8 + 8, 8 + 8, 11 + 8, 7 + 8, + 4 + 8, 0 + 8, 8 + 8, + + // Draw the inner AA, from inner edge to inner AA line, shift is 16. + 0 + 16, 1 + 16, 5 + 16, 5 + 16, 4 + 16, 0 + 16, + 1 + 16, 2 + 16, 6 + 16, 6 + 16, 5 + 16, 1 + 16, + 2 + 16, 3 + 16, 7 + 16, 7 + 16, 6 + 16, 2 + 16, + 3 + 16, 0 + 16, 4 + 16, 4 + 16, 7 + 16, 3 + 16, + }; + GR_STATIC_ASSERT(SK_ARRAY_COUNT(gBevelIndices) == kBevelIndexCnt); + + GR_DEFINE_STATIC_UNIQUE_KEY(gBevelIndexBufferKey); + return resourceProvider->refOrCreateInstancedIndexBuffer(gBevelIndices, + kBevelIndexCnt, kNumBevelRectsInIndexBuffer, kBevelVertexCnt, + gBevelIndexBufferKey); + } + } + GrColor color() const { return fBatch.fColor; } bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; } bool canTweakAlphaForCoverage() const { return fBatch.fCanTweakAlphaForCoverage; } @@ -855,7 +837,6 @@ private: }; BatchTracker fBatch; - const GrIndexBuffer* fIndexBuffer; SkSTArray<1, Geometry, true> fGeoData; }; @@ -867,15 +848,6 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target, const SkRect& devOutsideAssist, const SkRect& devInside, bool miterStroke) { - GrIndexBuffer* indexBuffer = setup_aa_stroke_rect_indexbuffer(&fAAMiterStrokeRectIndexBuffer, - &fAABevelStrokeRectIndexBuffer, - fGpu, - miterStroke); - if (!indexBuffer) { - SkDebugf("Failed to create index buffer!\n"); - return; - } - AAStrokeRectBatch::Geometry geometry; geometry.fColor = color; geometry.fDevOutside = devOutside; @@ -883,7 +855,7 @@ void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target, geometry.fDevInside = devInside; geometry.fMiterStroke = miterStroke; - SkAutoTUnref batch(AAStrokeRectBatch::Create(geometry, viewMatrix, indexBuffer)); + SkAutoTUnref batch(AAStrokeRectBatch::Create(geometry, viewMatrix)); target->drawBatch(pipelineBuilder, batch); } @@ -919,30 +891,12 @@ BATCH_TEST_DEFINE(AAFillRectBatch) { geo.fViewMatrix = GrTest::TestMatrix(random); geo.fRect = GrTest::TestRect(random); geo.fDevRect = GrTest::TestRect(random); - - static GrIndexBuffer* aaFillRectIndexBuffer = NULL; - if (!aaFillRectIndexBuffer) { - aaFillRectIndexBuffer = - context->getGpu()->createInstancedIndexBuffer(gFillAARectIdx, - kIndicesPerAAFillRect, - kNumAAFillRectsInIndexBuffer, - kVertsPerAAFillRect); - } - - return AAFillRectBatch::Create(geo, aaFillRectIndexBuffer); + return AAFillRectBatch::Create(geo); } BATCH_TEST_DEFINE(AAStrokeRectBatch) { - static GrIndexBuffer* aaMiterStrokeRectIndexBuffer = NULL; - static GrIndexBuffer* aaBevelStrokeRectIndexBuffer = NULL; - bool miterStroke = random->nextBool(); - GrIndexBuffer* indexBuffer = setup_aa_stroke_rect_indexbuffer(&aaMiterStrokeRectIndexBuffer, - &aaBevelStrokeRectIndexBuffer, - context->getGpu(), - miterStroke); - // Create mock stroke rect SkRect outside = GrTest::TestRect(random); SkScalar minDim = SkMinScalar(outside.width(), outside.height()); @@ -959,7 +913,7 @@ BATCH_TEST_DEFINE(AAStrokeRectBatch) { geo.fDevInside = inside; geo.fMiterStroke = miterStroke; - return AAStrokeRectBatch::Create(geo, GrTest::TestMatrix(random), indexBuffer); + return AAStrokeRectBatch::Create(geo, GrTest::TestMatrix(random)); } #endif diff --git a/src/gpu/GrAARectRenderer.h b/src/gpu/GrAARectRenderer.h index 3193f4bc3a..023eadc34f 100644 --- a/src/gpu/GrAARectRenderer.h +++ b/src/gpu/GrAARectRenderer.h @@ -16,7 +16,6 @@ class GrClip; class GrDrawTarget; -class GrGpu; class GrIndexBuffer; class GrPipelineBuilder; @@ -27,19 +26,6 @@ class GrAARectRenderer : public SkRefCnt { public: SK_DECLARE_INST_COUNT(GrAARectRenderer) - GrAARectRenderer(GrGpu* gpu) - : fGpu(gpu) - , fAAFillRectIndexBuffer(NULL) - , fAAMiterStrokeRectIndexBuffer(NULL) - , fAABevelStrokeRectIndexBuffer(NULL) { - } - - void reset(); - - ~GrAARectRenderer() { - this->reset(); - } - // TODO: potentialy fuse the fill & stroke methods and differentiate // between them by passing in stroke (==NULL means fill). @@ -84,11 +70,6 @@ private: const SkRect& devInside, bool miterStroke); - GrGpu* fGpu; - GrIndexBuffer* fAAFillRectIndexBuffer; - GrIndexBuffer* fAAMiterStrokeRectIndexBuffer; - GrIndexBuffer* fAABevelStrokeRectIndexBuffer; - typedef SkRefCnt INHERITED; }; diff --git a/src/gpu/GrAddPathRenderers_default.cpp b/src/gpu/GrAddPathRenderers_default.cpp index 06e98a98cf..0f675acb4c 100644 --- a/src/gpu/GrAddPathRenderers_default.cpp +++ b/src/gpu/GrAddPathRenderers_default.cpp @@ -39,7 +39,7 @@ void GrPathRenderer::AddPathRenderers(GrContext* ctx, GrPathRendererChain* chain if (GrPathRenderer* pr = GrStencilAndCoverPathRenderer::Create(ctx)) { chain->addPathRenderer(pr)->unref(); } - if (GrPathRenderer* pr = GrAAHairLinePathRenderer::Create(ctx)) { + if (GrPathRenderer* pr = GrAAHairLinePathRenderer::Create()) { chain->addPathRenderer(pr)->unref(); } chain->addPathRenderer(SkNEW(GrAAConvexPathRenderer))->unref(); diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp index 14930fa4a3..33e4f7ed86 100644 --- a/src/gpu/GrAtlasTextContext.cpp +++ b/src/gpu/GrAtlasTextContext.cpp @@ -13,6 +13,7 @@ #include "GrDrawTarget.h" #include "GrFontScaler.h" #include "GrIndexBuffer.h" +#include "GrResourceProvider.h" #include "GrStrokeInfo.h" #include "GrTextBlobCache.h" #include "GrTexturePriv.h" @@ -1514,14 +1515,16 @@ public: int glyphCount = this->numGlyphs(); int instanceCount = fInstanceCount; + SkAutoTUnref indexBuffer( + batchTarget->resourceProvider()->refQuadIndexBuffer()); + const GrVertexBuffer* vertexBuffer; int firstVertex; - void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, glyphCount * kVerticesPerGlyph, &vertexBuffer, &firstVertex); - if (!vertices) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate vertices\n"); return; } @@ -1529,8 +1532,7 @@ public: unsigned char* currVertex = reinterpret_cast(vertices); // setup drawinfo - const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer(); - int maxInstancesPerDraw = quadIndexBuffer->maxQuads(); + int maxInstancesPerDraw = indexBuffer->maxQuads(); GrDrawTarget::DrawInfo drawInfo; drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); @@ -1540,7 +1542,7 @@ public: drawInfo.setIndicesPerInstance(kIndicesPerGlyph); drawInfo.adjustStartVertex(firstVertex); drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setIndexBuffer(quadIndexBuffer); + drawInfo.setIndexBuffer(indexBuffer); // We cache some values to avoid going to the glyphcache for the same fontScaler twice // in a row diff --git a/src/gpu/GrBatchTarget.h b/src/gpu/GrBatchTarget.h index 9bd6b9409c..97cd2ed727 100644 --- a/src/gpu/GrBatchTarget.h +++ b/src/gpu/GrBatchTarget.h @@ -121,9 +121,7 @@ public: GrVertexBufferAllocPool* vertexPool() { return fVertexPool; } GrIndexBufferAllocPool* indexPool() { return fIndexPool; } - const static int kVertsPerRect = 4; - const static int kIndicesPerRect = 6; - const GrIndexBuffer* quadIndexBuffer() const { return fGpu->getQuadIndexBuffer(); } + GrResourceProvider* resourceProvider() const { return fGpu->getContext()->resourceProvider(); } // A helper for draws which overallocate and then return data to the pool void putBackIndices(size_t indices) { fIndexPool->putBack(indices * sizeof(uint16_t)); } diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp index 4709513525..819774a076 100755 --- a/src/gpu/GrContext.cpp +++ b/src/gpu/GrContext.cpp @@ -125,8 +125,8 @@ void GrContext::initCommon() { fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (this))); - fAARectRenderer = SkNEW_ARGS(GrAARectRenderer, (fGpu)); - fOvalRenderer = SkNEW_ARGS(GrOvalRenderer, (fGpu)); + fAARectRenderer = SkNEW(GrAARectRenderer); + fOvalRenderer = SkNEW(GrOvalRenderer); fDidTestPMConversions = false; @@ -186,9 +186,6 @@ void GrContext::abandonContext() { delete fDrawBufferIBAllocPool; fDrawBufferIBAllocPool = NULL; - fAARectRenderer->reset(); - fOvalRenderer->reset(); - fBatchFontCache->freeAll(); fLayerCache->freeAll(); fTextBlobCache->freeAll(); @@ -205,9 +202,6 @@ void GrContext::freeGpuResources() { fDrawBuffer->purgeResources(); } - fAARectRenderer->reset(); - fOvalRenderer->reset(); - fBatchFontCache->freeAll(); fLayerCache->freeAll(); // a path renderer may be holding onto resources @@ -1840,10 +1834,6 @@ GrDrawTarget* GrContext::getTextTarget() { return this->prepareToDraw(); } -const GrIndexBuffer* GrContext::getQuadIndexBuffer() const { - return fGpu->getQuadIndexBuffer(); -} - namespace { void test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) { GrConfigConversionEffect::PMConversion pmToUPM; diff --git a/src/gpu/GrDashLinePathRenderer.cpp b/src/gpu/GrDashLinePathRenderer.cpp index bd49a72156..67dc6c7703 100644 --- a/src/gpu/GrDashLinePathRenderer.cpp +++ b/src/gpu/GrDashLinePathRenderer.cpp @@ -39,6 +39,6 @@ bool GrDashLinePathRenderer::onDrawPath(GrDrawTarget* target, bool useAA) { SkPoint pts[2]; SkAssertResult(path.isLine(pts)); - return GrDashingEffect::DrawDashLine(fGpu, target, pipelineBuilder, color, + return GrDashingEffect::DrawDashLine(target, pipelineBuilder, color, viewMatrix, pts, useAA, stroke); } diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index fdb098a637..cdf5226ed1 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -24,14 +24,11 @@ GrGpu::GrGpu(GrContext* context) : fResetTimestamp(kExpiredTimestamp+1) , fResetBits(kAll_GrBackendState) - , fQuadIndexBuffer(NULL) , fGpuTraceMarkerCount(0) , fContext(context) { } -GrGpu::~GrGpu() { - SkSafeSetNull(fQuadIndexBuffer); -} +GrGpu::~GrGpu() {} void GrGpu::contextAbandoned() {} @@ -184,39 +181,6 @@ GrIndexBuffer* GrGpu::createIndexBuffer(size_t size, bool dynamic) { return this->onCreateIndexBuffer(size, dynamic); } -GrIndexBuffer* GrGpu::createInstancedIndexBuffer(const uint16_t* pattern, - int patternSize, - int reps, - int vertCount, - bool isDynamic) { - size_t bufferSize = patternSize * reps * sizeof(uint16_t); - GrGpu* me = const_cast(this); - GrIndexBuffer* buffer = me->createIndexBuffer(bufferSize, isDynamic); - if (buffer) { - uint16_t* data = (uint16_t*) buffer->map(); - bool useTempData = (NULL == data); - if (useTempData) { - data = SkNEW_ARRAY(uint16_t, reps * patternSize); - } - for (int i = 0; i < reps; ++i) { - int baseIdx = i * patternSize; - uint16_t baseVert = (uint16_t)(i * vertCount); - for (int j = 0; j < patternSize; ++j) { - data[baseIdx+j] = baseVert + pattern[j]; - } - } - if (useTempData) { - if (!buffer->updateData(data, bufferSize)) { - SkFAIL("Can't get indices into buffer!"); - } - SkDELETE_ARRAY(data); - } else { - buffer->unmap(); - } - } - return buffer; -} - void GrGpu::clear(const SkIRect* rect, GrColor color, bool canIgnoreRect, @@ -305,29 +269,6 @@ void GrGpu::removeGpuTraceMarker(const GrGpuTraceMarker* marker) { //////////////////////////////////////////////////////////////////////////////// -static const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1; - -GR_STATIC_ASSERT(4 * MAX_QUADS <= 65535); - -static const uint16_t gQuadIndexPattern[] = { - 0, 1, 2, 0, 2, 3 -}; - -const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const { - if (NULL == fQuadIndexBuffer || fQuadIndexBuffer->wasDestroyed()) { - SkSafeUnref(fQuadIndexBuffer); - GrGpu* me = const_cast(this); - fQuadIndexBuffer = me->createInstancedIndexBuffer(gQuadIndexPattern, - 6, - MAX_QUADS, - 4); - } - - return fQuadIndexBuffer; -} - -//////////////////////////////////////////////////////////////////////////////// - void GrGpu::draw(const DrawArgs& args, const GrDrawTarget::DrawInfo& info) { this->handleDirtyContext(); this->onDraw(args, info); diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index b2dbec65fb..3903af6344 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -118,34 +118,6 @@ public: */ GrIndexBuffer* createIndexBuffer(size_t size, bool dynamic); - /** - * Creates an index buffer for instance drawing with a specific pattern. - * - * @param pattern the pattern to repeat - * @param patternSize size in bytes of the pattern - * @param reps number of times to repeat the pattern - * @param vertCount number of vertices the pattern references - * @param dynamic hints whether the data will be frequently changed - * by either GrIndexBuffer::map() or - * GrIndexBuffer::updateData(). - * - * @return The index buffer if successful, otherwise NULL. - */ - GrIndexBuffer* createInstancedIndexBuffer(const uint16_t* pattern, - int patternSize, - int reps, - int vertCount, - bool isDynamic = false); - - /** - * Returns an index buffer that can be used to render quads. - * Six indices per quad: 0, 1, 2, 0, 2, 3, etc. - * The max number of quads can be queried using GrIndexBuffer::maxQuads(). - * Draw with kTriangles_GrPrimitiveType - * @ return the quad index buffer - */ - const GrIndexBuffer* getQuadIndexBuffer() const; - /** * Resolves MSAA. */ @@ -520,8 +492,6 @@ private: ResetTimestamp fResetTimestamp; uint32_t fResetBits; - // these are mutable so they can be created on-demand - mutable GrIndexBuffer* fQuadIndexBuffer; // To keep track that we always have at least as many debug marker adds as removes int fGpuTraceMarkerCount; GrTraceMarkerSet fActiveTraceMarkers; diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp index e298be6c8b..8190ec0e8a 100644 --- a/src/gpu/GrInOrderDrawBuffer.cpp +++ b/src/gpu/GrInOrderDrawBuffer.cpp @@ -8,6 +8,7 @@ #include "GrInOrderDrawBuffer.h" #include "GrDefaultGeoProcFactory.h" +#include "GrResourceProvider.h" #include "GrTemplates.h" GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context, @@ -137,17 +138,18 @@ public: vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr)); int instanceCount = fGeoData.count(); - int vertexCount = kVertsPerRect * instanceCount; + SkAutoTUnref indexBuffer( + batchTarget->resourceProvider()->refQuadIndexBuffer()); + int vertexCount = kVertsPerRect * instanceCount; const GrVertexBuffer* vertexBuffer; int firstVertex; - void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, vertexCount, &vertexBuffer, &firstVertex); - if (!vertices || !batchTarget->quadIndexBuffer()) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate buffers\n"); return; } @@ -181,8 +183,6 @@ public: } } - const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer(); - GrDrawTarget::DrawInfo drawInfo; drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); drawInfo.setStartVertex(0); @@ -191,9 +191,9 @@ public: drawInfo.setIndicesPerInstance(kIndicesPerRect); drawInfo.adjustStartVertex(firstVertex); drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setIndexBuffer(quadIndexBuffer); + drawInfo.setIndexBuffer(indexBuffer); - int maxInstancesPerDraw = quadIndexBuffer->maxQuads(); + int maxInstancesPerDraw = indexBuffer->maxQuads(); while (instanceCount) { drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)); drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance()); diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp index 8723d70a58..38efefa857 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,11 +646,6 @@ GrGeometryProcessor* DIEllipseEdgeEffect::TestCreate(SkRandom* random, /////////////////////////////////////////////////////////////////////////////// -void GrOvalRenderer::reset() { - SkSafeSetNull(fRRectIndexBuffer); - SkSafeSetNull(fStrokeRRectIndexBuffer); -} - bool GrOvalRenderer::drawOval(GrDrawTarget* target, GrPipelineBuilder* pipelineBuilder, GrColor color, @@ -659,8 +654,7 @@ bool GrOvalRenderer::drawOval(GrDrawTarget* target, const SkRect& oval, const SkStrokeRec& stroke) { - bool useCoverageAA = useAA && - !pipelineBuilder->getRenderTarget()->isMultisampled(); + bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isMultisampled(); if (!useCoverageAA) { return false; @@ -697,9 +691,7 @@ public: 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"; } @@ -756,6 +748,8 @@ public: size_t vertexStride = gp->getVertexStride(); SkASSERT(vertexStride == sizeof(CircleVertex)); + SkAutoTUnref indexBuffer( + batchTarget->resourceProvider()->refQuadIndexBuffer()); const GrVertexBuffer* vertexBuffer; int firstVertex; @@ -764,7 +758,7 @@ public: &vertexBuffer, &firstVertex); - if (!vertices || !batchTarget->quadIndexBuffer()) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate buffers\n"); return; } @@ -804,8 +798,6 @@ public: verts += kVertsPerCircle; } - const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer(); - GrDrawTarget::DrawInfo drawInfo; drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); drawInfo.setStartVertex(0); @@ -814,9 +806,9 @@ public: drawInfo.setIndicesPerInstance(kIndicesPerCircle); drawInfo.adjustStartVertex(firstVertex); drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setIndexBuffer(quadIndexBuffer); + drawInfo.setIndexBuffer(indexBuffer); - int maxInstancesPerDraw = quadIndexBuffer->maxQuads(); + int maxInstancesPerDraw = indexBuffer->maxQuads(); while (instanceCount) { drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)); @@ -1022,6 +1014,8 @@ public: SkASSERT(vertexStride == sizeof(EllipseVertex)); const GrVertexBuffer* vertexBuffer; + SkAutoTUnref indexBuffer( + batchTarget->resourceProvider()->refQuadIndexBuffer()); int firstVertex; void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, @@ -1029,7 +1023,7 @@ public: &vertexBuffer, &firstVertex); - if (!vertices || !batchTarget->quadIndexBuffer()) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate buffers\n"); return; } @@ -1074,8 +1068,6 @@ public: verts += kVertsPerEllipse; } - const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer(); - GrDrawTarget::DrawInfo drawInfo; drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); drawInfo.setStartVertex(0); @@ -1084,9 +1076,9 @@ public: drawInfo.setIndicesPerInstance(kIndicesPerEllipse); drawInfo.adjustStartVertex(firstVertex); drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setIndexBuffer(quadIndexBuffer); + drawInfo.setIndexBuffer(indexBuffer); - int maxInstancesPerDraw = quadIndexBuffer->maxQuads(); + int maxInstancesPerDraw = indexBuffer->maxQuads(); while (instanceCount) { drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)); @@ -1325,20 +1317,21 @@ public: init.fUsesLocalCoords = this->usesLocalCoords(); gp->initBatchTracker(batchTarget->currentBatchTracker(), init); + SkAutoTUnref 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 || !batchTarget->quadIndexBuffer()) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate buffers\n"); return; } @@ -1379,8 +1372,6 @@ public: verts += kVertsPerEllipse; } - const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer(); - GrDrawTarget::DrawInfo drawInfo; drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); drawInfo.setStartVertex(0); @@ -1389,9 +1380,9 @@ public: drawInfo.setIndicesPerInstance(kIndicesPerEllipse); drawInfo.adjustStartVertex(firstVertex); drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setIndexBuffer(quadIndexBuffer); + drawInfo.setIndexBuffer(indexBuffer); - int maxInstancesPerDraw = quadIndexBuffer->maxQuads(); + int maxInstancesPerDraw = indexBuffer->maxQuads(); while (instanceCount) { drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw)); @@ -1579,6 +1570,24 @@ 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, GrColor color, @@ -1657,8 +1666,8 @@ public: SkRect fDevBounds; }; - static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* indexBuffer) { - return SkNEW_ARGS(RRectCircleRendererBatch, (geometry, indexBuffer)); + static GrBatch* Create(const Geometry& geometry) { + return SkNEW_ARGS(RRectCircleRendererBatch, (geometry)); } const char* name() const override { return "RRectCircleBatch"; } @@ -1718,6 +1727,8 @@ public: SkASSERT(vertexStride == sizeof(CircleVertex)); const GrVertexBuffer* vertexBuffer; + SkAutoTUnref indexBuffer( + ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider())); int firstVertex; void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, @@ -1725,7 +1736,7 @@ public: &vertexBuffer, &firstVertex); - if (!vertices) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate vertices\n"); return; } @@ -1780,7 +1791,6 @@ public: int indexCnt = this->stroke() ? SK_ARRAY_COUNT(gRRectIndices) - 6 : SK_ARRAY_COUNT(gRRectIndices); - GrDrawTarget::DrawInfo drawInfo; drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); drawInfo.setStartVertex(0); @@ -1789,7 +1799,7 @@ public: drawInfo.setIndicesPerInstance(indexCnt); drawInfo.adjustStartVertex(firstVertex); drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setIndexBuffer(fIndexBuffer); + drawInfo.setIndexBuffer(indexBuffer); int maxInstancesPerDraw = kNumRRectsInIndexBuffer; @@ -1808,8 +1818,7 @@ public: SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } private: - RRectCircleRendererBatch(const Geometry& geometry, const GrIndexBuffer* indexBuffer) - : fIndexBuffer(indexBuffer) { + RRectCircleRendererBatch(const Geometry& geometry) { this->initClassID(); fGeoData.push_back(geometry); @@ -1853,7 +1862,6 @@ private: BatchTracker fBatch; SkSTArray<1, Geometry, true> fGeoData; - const GrIndexBuffer* fIndexBuffer; }; class RRectEllipseRendererBatch : public GrBatch { @@ -1869,8 +1877,8 @@ public: SkRect fDevBounds; }; - static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* indexBuffer) { - return SkNEW_ARGS(RRectEllipseRendererBatch, (geometry, indexBuffer)); + static GrBatch* Create(const Geometry& geometry) { + return SkNEW_ARGS(RRectEllipseRendererBatch, (geometry)); } const char* name() const override { return "RRectEllipseRendererBatch"; } @@ -1930,6 +1938,8 @@ public: SkASSERT(vertexStride == sizeof(EllipseVertex)); const GrVertexBuffer* vertexBuffer; + SkAutoTUnref indexBuffer( + ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider())); int firstVertex; void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride, @@ -1937,7 +1947,7 @@ public: &vertexBuffer, &firstVertex); - if (!vertices) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate vertices\n"); return; } @@ -2011,7 +2021,7 @@ public: drawInfo.setIndicesPerInstance(indexCnt); drawInfo.adjustStartVertex(firstVertex); drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setIndexBuffer(fIndexBuffer); + drawInfo.setIndexBuffer(indexBuffer); int maxInstancesPerDraw = kNumRRectsInIndexBuffer; @@ -2030,8 +2040,7 @@ public: SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; } private: - RRectEllipseRendererBatch(const Geometry& geometry, const GrIndexBuffer* indexBuffer) - : fIndexBuffer(indexBuffer) { + RRectEllipseRendererBatch(const Geometry& geometry) { this->initClassID(); fGeoData.push_back(geometry); @@ -2075,40 +2084,13 @@ private: 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, - GrIndexBuffer** strokeRRectIndexBuffer, - GrIndexBuffer** rrectIndexBuffer, - GrGpu* gpu) { + SkRect* bounds) { SkASSERT(viewMatrix.rectStaysRect()); SkASSERT(rrect.isSimple()); SkASSERT(!rrect.isOval()); @@ -2159,15 +2141,6 @@ static GrBatch* create_rrect_batch(GrColor color, return NULL; } - GrIndexBuffer* indexBuffer = create_rrect_indexbuffer(strokeRRectIndexBuffer, - rrectIndexBuffer, - isStrokeOnly, - gpu); - if (NULL == indexBuffer) { - SkDebugf("Failed to create index buffer!\n"); - return NULL; - } - // if the corners are circles, use the circle renderer if ((!hasStroke || scaledStroke.fX == scaledStroke.fY) && xRadius == yRadius) { SkScalar innerRadius = 0.0f; @@ -2208,8 +2181,7 @@ static GrBatch* create_rrect_batch(GrColor color, geometry.fStroke = isStrokeOnly; geometry.fDevBounds = *bounds; - return RRectCircleRendererBatch::Create(geometry, indexBuffer); - + return RRectCircleRendererBatch::Create(geometry); // otherwise we use the ellipse renderer } else { SkScalar innerXRadius = 0.0f; @@ -2259,7 +2231,7 @@ static GrBatch* create_rrect_batch(GrColor color, geometry.fStroke = isStrokeOnly; geometry.fDevBounds = *bounds; - return RRectEllipseRendererBatch::Create(geometry, indexBuffer); + return RRectEllipseRendererBatch::Create(geometry); } } @@ -2287,9 +2259,7 @@ bool GrOvalRenderer::drawRRect(GrDrawTarget* target, } SkRect bounds; - SkAutoTUnref batch(create_rrect_batch(color, viewMatrix, rrect, stroke, &bounds, - &fStrokeRRectIndexBuffer, &fRRectIndexBuffer, - fGpu)); + SkAutoTUnref batch(create_rrect_batch(color, viewMatrix, rrect, stroke, &bounds)); if (!batch) { return false; } @@ -2347,11 +2317,8 @@ BATCH_TEST_DEFINE(RRectBatch) { 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()); + return create_rrect_batch(color, viewMatrix, rrect, random_strokerec(random), &bounds); } #endif diff --git a/src/gpu/GrOvalRenderer.h b/src/gpu/GrOvalRenderer.h index f31aa69bb2..57ce2a5dfe 100644 --- a/src/gpu/GrOvalRenderer.h +++ b/src/gpu/GrOvalRenderer.h @@ -24,16 +24,6 @@ class GrOvalRenderer : public SkRefCnt { public: SK_DECLARE_INST_COUNT(GrOvalRenderer) - GrOvalRenderer(GrGpu* gpu) - : fGpu(gpu) - , fRRectIndexBuffer(NULL) - , fStrokeRRectIndexBuffer(NULL) {} - ~GrOvalRenderer() { - this->reset(); - } - - void reset(); - bool drawOval(GrDrawTarget*, GrPipelineBuilder*, GrColor, @@ -79,10 +69,6 @@ private: const SkRect& circle, const SkStrokeRec& stroke); - GrGpu* fGpu; - GrIndexBuffer* fRRectIndexBuffer; - GrIndexBuffer* fStrokeRRectIndexBuffer; - typedef SkRefCnt INHERITED; }; diff --git a/src/gpu/GrResourceProvider.cpp b/src/gpu/GrResourceProvider.cpp new file mode 100644 index 0000000000..8fc3272ae2 --- /dev/null +++ b/src/gpu/GrResourceProvider.cpp @@ -0,0 +1,65 @@ +/* + * Copyright 2015 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "GrResourceProvider.h" + +#include "GrGpu.h" +#include "GrResourceCache.h" +#include "GrResourceKey.h" +#include "GrVertexBuffer.h" + +GR_DECLARE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey); + +GrResourceProvider::GrResourceProvider(GrGpu* gpu, GrResourceCache* cache) : INHERITED(gpu, cache) { + GR_DEFINE_STATIC_UNIQUE_KEY(gQuadIndexBufferKey); + fQuadIndexBufferKey = gQuadIndexBufferKey; +} + +const GrIndexBuffer* GrResourceProvider::createInstancedIndexBuffer(const uint16_t* pattern, + int patternSize, + int reps, + int vertCount, + const GrUniqueKey& key) { + size_t bufferSize = patternSize * reps * sizeof(uint16_t); + + GrIndexBuffer* buffer = this->gpu()->createIndexBuffer(bufferSize, /* dynamic = */ false); + if (!buffer) { + return NULL; + } + uint16_t* data = (uint16_t*) buffer->map(); + bool useTempData = (NULL == data); + if (useTempData) { + data = SkNEW_ARRAY(uint16_t, reps * patternSize); + } + for (int i = 0; i < reps; ++i) { + int baseIdx = i * patternSize; + uint16_t baseVert = (uint16_t)(i * vertCount); + for (int j = 0; j < patternSize; ++j) { + data[baseIdx+j] = baseVert + pattern[j]; + } + } + if (useTempData) { + if (!buffer->updateData(data, bufferSize)) { + buffer->unref(); + return NULL; + } + SkDELETE_ARRAY(data); + } else { + buffer->unmap(); + } + this->assignUniqueKeyToResource(key, buffer); + return buffer; +} + +const GrIndexBuffer* GrResourceProvider::createQuadIndexBuffer() { + static const int kMaxQuads = 1 << 12; // max possible: (1 << 14) - 1; + GR_STATIC_ASSERT(4 * kMaxQuads <= 65535); + static const uint16_t kPattern[] = { 0, 1, 2, 0, 2, 3 }; + + return this->createInstancedIndexBuffer(kPattern, 6, kMaxQuads, 4, fQuadIndexBufferKey); +} + diff --git a/src/gpu/GrResourceProvider.h b/src/gpu/GrResourceProvider.h index f560afa0fd..0d80cdd2a0 100644 --- a/src/gpu/GrResourceProvider.h +++ b/src/gpu/GrResourceProvider.h @@ -10,6 +10,9 @@ #include "GrTextureProvider.h" +class GrIndexBuffer; +class GrVertexBuffer; + /** * An extension of the texture provider for arbitrary resource types. This class is intended for * use within the Gr code base, not by clients or extensions (e.g. third party GrProcessor @@ -18,12 +21,67 @@ class GrResourceProvider : public GrTextureProvider { public: - GrResourceProvider(GrGpu* gpu, GrResourceCache* cache) : INHERITED(gpu, cache) {} + GrResourceProvider(GrGpu* gpu, GrResourceCache* cache); + + template T* findAndRefTByUniqueKey(const GrUniqueKey& key) { + return static_cast(this->findAndRefResourceByUniqueKey(key)); + } + + /** + * Either finds and refs, or creates an index buffer for instanced drawing with a specific + * pattern if the index buffer is not found. If the return is non-null, the caller owns + * a ref on the returned GrIndexBuffer. + * + * @param pattern the pattern of indices to repeat + * @param patternSize size in bytes of the pattern + * @param reps number of times to repeat the pattern + * @param vertCount number of vertices the pattern references + * @param key Key to be assigned to the index buffer. + * + * @return The index buffer if successful, otherwise NULL. + */ + const GrIndexBuffer* refOrCreateInstancedIndexBuffer(const uint16_t* pattern, + int patternSize, + int reps, + int vertCount, + const GrUniqueKey& key) { + if (GrIndexBuffer* buffer = this->findAndRefTByUniqueKey(key)) { + return buffer; + } + return this->createInstancedIndexBuffer(pattern, patternSize, reps, vertCount, key); + } + + /** + * Returns an index buffer that can be used to render quads. + * Six indices per quad: 0, 1, 2, 0, 2, 3, etc. + * The max number of quads can be queried using GrIndexBuffer::maxQuads(). + * Draw with kTriangles_GrPrimitiveType + * @ return the quad index buffer + */ + const GrIndexBuffer* refQuadIndexBuffer() { + if (GrIndexBuffer* buffer = + this->findAndRefTByUniqueKey(fQuadIndexBufferKey)) { + return buffer; + } + return this->createQuadIndexBuffer(); + } + using GrTextureProvider::assignUniqueKeyToResource; using GrTextureProvider::findAndRefResourceByUniqueKey; using GrTextureProvider::abandon; +private: + const GrIndexBuffer* createInstancedIndexBuffer(const uint16_t* pattern, + int patternSize, + int reps, + int vertCount, + const GrUniqueKey& key); + + const GrIndexBuffer* createQuadIndexBuffer(); + + GrUniqueKey fQuadIndexBufferKey; + typedef GrTextureProvider INHERITED; }; diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp index 3f0df67377..fa8b3a2dcf 100644 --- a/src/gpu/effects/GrDashingEffect.cpp +++ b/src/gpu/effects/GrDashingEffect.cpp @@ -19,6 +19,7 @@ #include "GrDrawTargetCaps.h" #include "GrInvariantOutput.h" #include "GrProcessor.h" +#include "GrResourceProvider.h" #include "GrStrokeInfo.h" #include "GrVertexBuffer.h" #include "SkGr.h" @@ -535,16 +536,17 @@ public: draw.fHasEndRect = hasEndRect; } + SkAutoTUnref indexBuffer( + batchTarget->resourceProvider()->refQuadIndexBuffer()); + const GrVertexBuffer* vertexBuffer; int firstVertex; - size_t vertexStride = gp->getVertexStride(); void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride, totalRectCount * kVertsPerDash, &vertexBuffer, &firstVertex); - - if (!vertices || !batchTarget->quadIndexBuffer()) { + if (!vertices || !indexBuffer) { SkDebugf("Could not allocate buffers\n"); return; } @@ -607,8 +609,6 @@ public: rectIndex++; } - const GrIndexBuffer* dashIndexBuffer = batchTarget->quadIndexBuffer(); - GrDrawTarget::DrawInfo drawInfo; drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType); drawInfo.setStartVertex(0); @@ -617,9 +617,9 @@ public: drawInfo.setIndicesPerInstance(kIndicesPerDash); drawInfo.adjustStartVertex(firstVertex); drawInfo.setVertexBuffer(vertexBuffer); - drawInfo.setIndexBuffer(dashIndexBuffer); + drawInfo.setIndexBuffer(indexBuffer); - int maxInstancesPerDraw = dashIndexBuffer->maxQuads(); + int maxInstancesPerDraw = indexBuffer->maxQuads(); while (totalRectCount) { drawInfo.setInstanceCount(SkTMin(totalRectCount, maxInstancesPerDraw)); drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance()); @@ -761,7 +761,7 @@ static GrBatch* create_batch(GrColor color, const SkMatrix& viewMatrix, const Sk return DashBatch::Create(geometry, cap, aaMode, fullDash); } -bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, +bool GrDashingEffect::DrawDashLine(GrDrawTarget* target, GrPipelineBuilder* pipelineBuilder, GrColor color, const SkMatrix& viewMatrix, const SkPoint pts[2], bool useAA, const GrStrokeInfo& strokeInfo) { diff --git a/src/gpu/effects/GrDashingEffect.h b/src/gpu/effects/GrDashingEffect.h index 999abb23d8..05b1c90205 100644 --- a/src/gpu/effects/GrDashingEffect.h +++ b/src/gpu/effects/GrDashingEffect.h @@ -15,13 +15,12 @@ class GrClip; class GrDrawTarget; -class GrGpu; class GrPaint; class GrPipelineBuilder; class GrStrokeInfo; namespace GrDashingEffect { - bool DrawDashLine(GrGpu*, GrDrawTarget*, GrPipelineBuilder*, GrColor, + bool DrawDashLine(GrDrawTarget*, GrPipelineBuilder*, GrColor, const SkMatrix& viewMatrix, const SkPoint pts[2], bool useAA, const GrStrokeInfo& strokeInfo); bool CanDrawDashLine(const SkPoint pts[2], const GrStrokeInfo& strokeInfo,