Revert of Move instanced index buffer creation to flush time (patchset #6 id:100001 of https://codereview.chromium.org/1116943004/)
Reason for revert:
messed up caching, recreating index buffers all the time.
Original issue's description:
> Move instanced index buffer creation to flush time
>
> Committed: https://skia.googlesource.com/skia/+/ab622c7b8cc8c39f0a594e4392b9e31b7e1ddb26
TBR=joshualitt@google.com,robertphillips@google.com
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
Review URL: https://codereview.chromium.org/1126613003
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index 6568422..182d71a 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -16,7 +16,6 @@
#include "GrBufferAllocPool.h"
#include "GrContext.h"
#include "GrPathUtils.h"
-#include "GrResourceProvider.h"
#include "GrTest.h"
#include "GrTestBatch.h"
#include "SkColorPriv.h"
@@ -67,18 +66,17 @@
}
void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
- SkAutoTUnref<const GrIndexBuffer> 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 || !indexBuffer) {
+ if (!vertices || !batchTarget->quadIndexBuffer()) {
SkDebugf("Could not allocate buffers\n");
return;
}
@@ -102,7 +100,7 @@
drawInfo.setVertexCount(kVertsPerCubic);
drawInfo.setStartIndex(0);
drawInfo.setIndexCount(kIndicesPerCubic);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(batchTarget->quadIndexBuffer());
batchTarget->draw(drawInfo);
}
@@ -475,10 +473,8 @@
}
void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
-
size_t vertexStride = this->geometryProcessor()->getVertexStride();
+
const GrVertexBuffer* vertexBuffer;
int firstVertex;
@@ -487,7 +483,7 @@
&vertexBuffer,
&firstVertex);
- if (!vertices || !indexBuffer) {
+ if (!vertices || !batchTarget->quadIndexBuffer()) {
SkDebugf("Could not allocate buffers\n");
return;
}
@@ -509,7 +505,7 @@
drawInfo.setVertexCount(kVertsPerCubic);
drawInfo.setStartIndex(0);
drawInfo.setIndexCount(kIndicesPerCubic);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(batchTarget->quadIndexBuffer());
batchTarget->draw(drawInfo);
}
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index 60b73c5..07d5fc2 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -17,7 +17,6 @@
#include "GrContext.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrPathUtils.h"
-#include "GrResourceProvider.h"
#include "GrTest.h"
#include "GrTestBatch.h"
#include "SkColorPriv.h"
@@ -53,10 +52,8 @@
}
void onGenerateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
-
size_t vertexStride = this->geometryProcessor()->getVertexStride();
+
const GrVertexBuffer* vertexBuffer;
int firstVertex;
@@ -65,7 +62,7 @@
&vertexBuffer,
&firstVertex);
- if (!vertices || !indexBuffer) {
+ if (!vertices || !batchTarget->quadIndexBuffer()) {
SkDebugf("Could not allocate buffers\n");
return;
}
@@ -85,7 +82,7 @@
drawInfo.setVertexCount(kVertsPerCubic);
drawInfo.setStartIndex(0);
drawInfo.setIndexCount(kIndicesPerCubic);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(batchTarget->quadIndexBuffer());
batchTarget->draw(drawInfo);
}
diff --git a/gyp/gpu.gypi b/gyp/gpu.gypi
index 3944a03..4d2549e 100644
--- a/gyp/gpu.gypi
+++ b/gyp/gpu.gypi
@@ -167,8 +167,6 @@
'<(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 c7a87f7..a4188d0 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 function scope or as a class member.
+// This must be used in a global scope, not in fuction 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 8bdc9f5..dc824d5 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -539,6 +539,7 @@
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 50a7145..aecdc70 100644
--- a/include/gpu/GrResourceKey.h
+++ b/include/gpu/GrResourceKey.h
@@ -10,7 +10,6 @@
#define GrResourceKey_DEFINED
#include "GrTypes.h"
-#include "SkOnce.h"
#include "SkTemplates.h"
uint32_t GrResourceKeyHash(const uint32_t* data, size_t size);
@@ -267,24 +266,6 @@
};
};
-/**
- * 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 3f8c760..3e29dab 100644
--- a/include/gpu/GrTextureProvider.h
+++ b/include/gpu/GrTextureProvider.h
@@ -154,12 +154,6 @@
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 ca8c52f..669ec09 100755
--- a/src/gpu/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp
@@ -15,7 +15,6 @@
#include "GrPipelineBuilder.h"
#include "GrSurfacePriv.h"
#include "GrSWMaskHelper.h"
-#include "GrResourceProvider.h"
#include "GrTexturePriv.h"
#include "GrVertexBuffer.h"
#include "effects/GrDistanceFieldGeoProc.h"
@@ -195,17 +194,13 @@
this->initDraw(batchTarget, dfProcessor, pipeline);
- static const int kVertsPerQuad = 4;
- static const int kIndicesPerQuad = 6;
-
- SkAutoTUnref<const GrIndexBuffer> 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,
@@ -213,23 +208,24 @@
&vertexBuffer,
&firstVertex);
- if (!vertices || !indexBuffer) {
+ if (!vertices) {
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
- int maxInstancesPerDraw = indexBuffer->maxQuads();
+ const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
+ int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
GrDrawTarget::DrawInfo drawInfo;
drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
drawInfo.setStartVertex(0);
drawInfo.setStartIndex(0);
- drawInfo.setVerticesPerInstance(kVertsPerQuad);
- drawInfo.setIndicesPerInstance(kIndicesPerQuad);
+ drawInfo.setVerticesPerInstance(GrBatchTarget::kVertsPerRect);
+ drawInfo.setIndicesPerInstance(GrBatchTarget::kIndicesPerRect);
drawInfo.adjustStartVertex(firstVertex);
drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(quadIndexBuffer);
int instancesToFlush = 0;
for (int i = 0; i < instanceCount; i++) {
@@ -284,7 +280,7 @@
// Now set vertices
intptr_t offset = reinterpret_cast<intptr_t>(vertices);
- offset += i * kVertsPerQuad * vertexStride;
+ offset += i * GrBatchTarget::kVertsPerRect * vertexStride;
SkPoint* positions = reinterpret_cast<SkPoint*>(offset);
this->drawPath(batchTarget,
atlas,
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index f046af8..ad65500 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,8 +26,6 @@
#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
@@ -63,14 +61,6 @@
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.
@@ -97,17 +87,43 @@
static const int kLineSegNumVertices = 6;
static const int kLineSegsNumInIdxBuffer = 256;
-GR_DECLARE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey);
-
-static const GrIndexBuffer* ref_lines_index_buffer(GrResourceProvider* resourceProvider) {
- GR_DEFINE_STATIC_UNIQUE_KEY(gLinesIndexBufferKey);
- return resourceProvider->refOrCreateInstancedIndexBuffer(
- kLineSegIdxBufPattern, kIdxsPerLineSeg, kLineSegsNumInIdxBuffer, kLineSegNumVertices,
- gLinesIndexBufferKey);
+GrPathRenderer* GrAAHairLinePathRenderer::Create(GrContext* context) {
+ GrGpu* gpu = context->getGpu();
+ GrIndexBuffer* qIdxBuf = gpu->createInstancedIndexBuffer(kQuadIdxBufPattern,
+ kIdxsPerQuad,
+ kQuadsNumInIdxBuffer,
+ kQuadNumVertices);
+ SkAutoTUnref<GrIndexBuffer> qIdxBuffer(qIdxBuf);
+ GrIndexBuffer* lIdxBuf = gpu->createInstancedIndexBuffer(kLineSegIdxBufPattern,
+ kIdxsPerLineSeg,
+ kLineSegsNumInIdxBuffer,
+ kLineSegNumVertices);
+ SkAutoTUnref<GrIndexBuffer> lIdxBuffer(lIdxBuf);
+ return SkNEW_ARGS(GrAAHairLinePathRenderer,
+ (context, lIdxBuf, qIdxBuf));
}
+GrAAHairLinePathRenderer::GrAAHairLinePathRenderer(
+ const GrContext* context,
+ const GrIndexBuffer* linesIndexBuffer,
+ const GrIndexBuffer* quadsIndexBuffer) {
+ fLinesIndexBuffer = linesIndexBuffer;
+ linesIndexBuffer->ref();
+ fQuadsIndexBuffer = quadsIndexBuffer;
+ quadsIndexBuffer->ref();
+}
+
+GrAAHairLinePathRenderer::~GrAAHairLinePathRenderer() {
+ fLinesIndexBuffer->unref();
+ fQuadsIndexBuffer->unref();
+}
+
+namespace {
+
+#define PREALLOC_PTARRAY(N) SkSTArray<(N),SkPoint, true>
+
// Takes 178th time of logf on Z600 / VC2010
-static int get_float_exp(float x) {
+int get_float_exp(float x) {
GR_STATIC_ASSERT(sizeof(int) == sizeof(float));
#ifdef SK_DEBUG
static bool tested;
@@ -135,7 +151,7 @@
// 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.
-static int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) {
+int split_conic(const SkPoint src[3], SkConic dst[2], const SkScalar weight) {
SkScalar t = SkFindQuadMaxCurvature(src);
if (t == 0) {
if (dst) {
@@ -155,7 +171,7 @@
// 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).
-static int chop_conic(const SkPoint src[3], SkConic dst[4], const SkScalar weight) {
+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) {
@@ -170,7 +186,7 @@
// returns 0 if quad/conic is degen or close to it
// in this case approx the path with lines
// otherwise returns 1
-static int is_degen_quad_or_conic(const SkPoint p[3], SkScalar* dsqd) {
+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);
@@ -191,14 +207,14 @@
return 0;
}
-static int is_degen_quad_or_conic(const SkPoint p[3]) {
+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
-static int num_quad_subdivs(const SkPoint p[3]) {
+int num_quad_subdivs(const SkPoint p[3]) {
SkScalar dsqd;
if (is_degen_quad_or_conic(p, &dsqd)) {
return -1;
@@ -234,14 +250,14 @@
* subdivide large quads to reduce over-fill. This subdivision has to be
* performed before applying the perspective matrix.
*/
-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) {
+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;
@@ -425,9 +441,9 @@
GR_STATIC_ASSERT(sizeof(BezierVertex) == 3 * sizeof(SkPoint));
-static void intersect_lines(const SkPoint& ptA, const SkVector& normA,
- const SkPoint& ptB, const SkVector& normB,
- SkPoint* result) {
+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);
@@ -443,14 +459,14 @@
result->fY = SkScalarMul(result->fY, wInv);
}
-static void set_uv_quad(const SkPoint qpts[3], BezierVertex verts[kQuadNumVertices]) {
+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<kQuadNumVertices, sizeof(BezierVertex), sizeof(SkPoint)>(verts);
}
-static void bloat_quad(const SkPoint qpts[3], const SkMatrix* toDevice,
- const SkMatrix* toSrc, BezierVertex verts[kQuadNumVertices]) {
+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];
@@ -528,8 +544,8 @@
// 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
-static void set_conic_coeffs(const SkPoint p[3], BezierVertex verts[kQuadNumVertices],
- const SkScalar weight) {
+void set_conic_coeffs(const SkPoint p[3], BezierVertex verts[kQuadNumVertices],
+ const SkScalar weight) {
SkScalar klm[9];
GrPathUtils::getConicKLM(p, weight, klm);
@@ -542,21 +558,21 @@
}
}
-static void add_conics(const SkPoint p[3],
- const SkScalar weight,
- const SkMatrix* toDevice,
- const SkMatrix* toSrc,
- BezierVertex** vert) {
+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;
}
-static void add_quads(const SkPoint p[3],
- int subdiv,
- const SkMatrix* toDevice,
- const SkMatrix* toSrc,
- BezierVertex** vert) {
+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];
@@ -570,10 +586,10 @@
}
}
-static void add_line(const SkPoint p[2],
- const SkMatrix* toSrc,
- uint8_t coverage,
- LineVertex** vert) {
+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];
@@ -615,6 +631,8 @@
*vert += kLineSegNumVertices;
}
+}
+
///////////////////////////////////////////////////////////////////////////////
bool GrAAHairLinePathRenderer::canDrawPath(const GrDrawTarget* target,
@@ -685,8 +703,11 @@
SkIRect fDevClipBounds;
};
- static GrBatch* Create(const Geometry& geometry) {
- return SkNEW_ARGS(AAHairlineBatch, (geometry));
+ // 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));
}
const char* name() const override { return "AAHairlineBatch"; }
@@ -724,7 +745,11 @@
typedef SkTArray<int, true> IntArray;
typedef SkTArray<float, true> FloatArray;
- AAHairlineBatch(const Geometry& geometry) {
+ AAHairlineBatch(const Geometry& geometry, const GrIndexBuffer* linesIndexBuffer,
+ const GrIndexBuffer* quadsIndexBuffer)
+ : fLinesIndexBuffer(linesIndexBuffer)
+ , fQuadsIndexBuffer(quadsIndexBuffer) {
+ SkASSERT(linesIndexBuffer && quadsIndexBuffer);
this->initClassID<AAHairlineBatch>();
fGeoData.push_back(geometry);
@@ -783,6 +808,8 @@
BatchTracker fBatch;
SkSTArray<1, Geometry, true> fGeoData;
+ const GrIndexBuffer* fLinesIndexBuffer;
+ const GrIndexBuffer* fQuadsIndexBuffer;
};
void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) {
@@ -853,8 +880,6 @@
// do lines first
if (lineCount) {
- SkAutoTUnref<const GrIndexBuffer> linesIndexBuffer(
- ref_lines_index_buffer(batchTarget->resourceProvider()));
batchTarget->initDraw(lineGP, pipeline);
// TODO remove this when batch is everywhere
@@ -875,7 +900,7 @@
&vertexBuffer,
&firstVertex);
- if (!vertices || !linesIndexBuffer) {
+ if (!vertices) {
SkDebugf("Could not allocate vertices\n");
return;
}
@@ -890,7 +915,7 @@
{
GrDrawTarget::DrawInfo info;
info.setVertexBuffer(vertexBuffer);
- info.setIndexBuffer(linesIndexBuffer);
+ info.setIndexBuffer(fLinesIndexBuffer);
info.setPrimitiveType(kTriangles_GrPrimitiveType);
info.setStartIndex(0);
@@ -912,9 +937,6 @@
const GrVertexBuffer* vertexBuffer;
int firstVertex;
- SkAutoTUnref<const GrIndexBuffer> quadsIndexBuffer(
- ref_quads_index_buffer(batchTarget->resourceProvider()));
-
size_t vertexStride = sizeof(BezierVertex);
int vertexCount = kQuadNumVertices * quadCount + kQuadNumVertices * conicCount;
void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
@@ -922,7 +944,7 @@
&vertexBuffer,
&firstVertex);
- if (!vertices || !quadsIndexBuffer) {
+ if (!vertices) {
SkDebugf("Could not allocate vertices\n");
return;
}
@@ -955,7 +977,7 @@
{
GrDrawTarget::DrawInfo info;
info.setVertexBuffer(vertexBuffer);
- info.setIndexBuffer(quadsIndexBuffer);
+ info.setIndexBuffer(fQuadsIndexBuffer);
info.setPrimitiveType(kTriangles_GrPrimitiveType);
info.setStartIndex(0);
@@ -987,7 +1009,7 @@
{
GrDrawTarget::DrawInfo info;
info.setVertexBuffer(vertexBuffer);
- info.setIndexBuffer(quadsIndexBuffer);
+ info.setIndexBuffer(fQuadsIndexBuffer);
info.setPrimitiveType(kTriangles_GrPrimitiveType);
info.setStartIndex(0);
@@ -1011,7 +1033,9 @@
const SkMatrix& viewMatrix,
const SkPath& path,
const GrStrokeInfo& stroke,
- const SkIRect& devClipBounds) {
+ const SkIRect& devClipBounds,
+ const GrIndexBuffer* linesIndexBuffer,
+ const GrIndexBuffer* quadsIndexBuffer) {
SkScalar hairlineCoverage;
uint8_t newCoverage = 0xff;
if (GrPathRenderer::IsStrokeHairlineOrEquivalent(stroke, viewMatrix, &hairlineCoverage)) {
@@ -1025,7 +1049,7 @@
geometry.fPath = path;
geometry.fDevClipBounds = devClipBounds;
- return AAHairlineBatch::Create(geometry);
+ return AAHairlineBatch::Create(geometry, linesIndexBuffer, quadsIndexBuffer);
}
bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
@@ -1035,12 +1059,18 @@
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<GrBatch> batch(create_hairline_batch(color, viewMatrix, path, stroke,
- devClipBounds));
+ devClipBounds, fLinesIndexBuffer,
+ fQuadsIndexBuffer));
target->drawBatch(pipelineBuilder, batch);
return true;
@@ -1051,13 +1081,28 @@
#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);
+ return create_hairline_batch(color, viewMatrix, path, stroke, devClipBounds, gLineIndexBuffer,
+ gQuadIndexBuffer);
}
#endif
diff --git a/src/gpu/GrAAHairLinePathRenderer.h b/src/gpu/GrAAHairLinePathRenderer.h
index b523493..9f8d8aa 100644
--- a/src/gpu/GrAAHairLinePathRenderer.h
+++ b/src/gpu/GrAAHairLinePathRenderer.h
@@ -13,30 +13,37 @@
class GrAAHairLinePathRenderer : public GrPathRenderer {
public:
- static GrPathRenderer* Create() { return SkNEW(GrAAHairLinePathRenderer); }
+ virtual ~GrAAHairLinePathRenderer();
- bool canDrawPath(const GrDrawTarget*,
- const GrPipelineBuilder*,
- const SkMatrix& viewMatrix,
- const SkPath&,
- const GrStrokeInfo&,
- bool antiAlias) const override;
+ static GrPathRenderer* Create(GrContext* context);
+
+ virtual bool canDrawPath(const GrDrawTarget*,
+ const GrPipelineBuilder*,
+ const SkMatrix& viewMatrix,
+ const SkPath&,
+ const GrStrokeInfo&,
+ bool antiAlias) const override;
typedef SkTArray<SkPoint, true> PtArray;
typedef SkTArray<int, true> IntArray;
typedef SkTArray<float, true> FloatArray;
protected:
- bool onDrawPath(GrDrawTarget*,
- GrPipelineBuilder*,
- GrColor,
- const SkMatrix& viewMatrix,
- const SkPath&,
- const GrStrokeInfo&,
- bool antiAlias) override;
+ virtual bool onDrawPath(GrDrawTarget*,
+ GrPipelineBuilder*,
+ GrColor,
+ const SkMatrix& viewMatrix,
+ const SkPath&,
+ const GrStrokeInfo&,
+ bool antiAlias) override;
private:
- GrAAHairLinePathRenderer() {}
+ GrAAHairLinePathRenderer(const GrContext* context,
+ const GrIndexBuffer* fLinesIndexBuffer,
+ const GrIndexBuffer* fQuadsIndexBuffer);
+
+ const GrIndexBuffer* fLinesIndexBuffer;
+ const GrIndexBuffer* fQuadsIndexBuffer;
typedef GrPathRenderer INHERITED;
};
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index d1c377a..778205f 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -13,11 +13,10 @@
#include "GrContext.h"
#include "GrDefaultGeoProcFactory.h"
#include "GrGeometryProcessor.h"
+#include "GrGpu.h"
#include "GrInvariantOutput.h"
-#include "GrResourceKey.h"
-#include "GrResourceProvider.h"
-#include "GrTestUtils.h"
#include "GrVertexBuffer.h"
+#include "GrTestUtils.h"
#include "SkColorPriv.h"
#include "gl/GrGLProcessor.h"
#include "gl/GrGLGeometryProcessor.h"
@@ -31,6 +30,18 @@
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;
@@ -46,8 +57,6 @@
return gp;
}
-GR_DECLARE_STATIC_UNIQUE_KEY(gAAFillRectIndexBufferKey);
-
class AAFillRectBatch : public GrBatch {
public:
struct Geometry {
@@ -57,8 +66,8 @@
SkRect fDevRect;
};
- static GrBatch* Create(const Geometry& geometry) {
- return SkNEW_ARGS(AAFillRectBatch, (geometry));
+ static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* indexBuffer) {
+ return SkNEW_ARGS(AAFillRectBatch, (geometry, indexBuffer));
}
const char* name() const override { return "AAFillRectBatch"; }
@@ -112,23 +121,24 @@
init.fUsesLocalCoords = this->usesLocalCoords();
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
- SkAutoTUnref<const GrIndexBuffer> 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 || !indexBuffer) {
+ if (!vertices) {
SkDebugf("Could not allocate vertices\n");
return;
}
@@ -153,7 +163,7 @@
drawInfo.setIndicesPerInstance(kIndicesPerAAFillRect);
drawInfo.adjustStartVertex(firstVertex);
drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(fIndexBuffer);
int maxInstancesPerDraw = kNumAAFillRectsInIndexBuffer;
@@ -172,33 +182,14 @@
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
private:
- AAFillRectBatch(const Geometry& geometry) {
+ AAFillRectBatch(const Geometry& geometry, const GrIndexBuffer* indexBuffer)
+ : fIndexBuffer(indexBuffer) {
this->initClassID<AAFillRectBatch>();
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; }
@@ -333,6 +324,7 @@
};
BatchTracker fBatch;
+ const GrIndexBuffer* fIndexBuffer;
SkSTArray<1, Geometry, true> fGeoData;
};
@@ -344,20 +336,149 @@
};
}
+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<GrBatch> batch(AAFillRectBatch::Create(geometry));
+ SkAutoTUnref<GrBatch> batch(AAFillRectBatch::Create(geometry, fAAFillRectIndexBuffer));
target->drawBatch(pipelineBuilder, batch);
}
@@ -423,9 +544,6 @@
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
@@ -437,8 +555,9 @@
bool fMiterStroke;
};
- static GrBatch* Create(const Geometry& geometry, const SkMatrix& viewMatrix) {
- return SkNEW_ARGS(AAStrokeRectBatch, (geometry, viewMatrix));
+ static GrBatch* Create(const Geometry& geometry, const SkMatrix& viewMatrix,
+ const GrIndexBuffer* indexBuffer) {
+ return SkNEW_ARGS(AAStrokeRectBatch, (geometry, viewMatrix, indexBuffer));
}
const char* name() const override { return "AAStrokeRect"; }
@@ -485,9 +604,6 @@
batchTarget->initDraw(gp, pipeline);
- const SkAutoTUnref<const GrIndexBuffer> 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
@@ -503,6 +619,7 @@
SkASSERT(canTweakAlphaForCoverage ?
vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr) :
vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorCoverageAttr));
+
int innerVertexNum = 4;
int outerVertexNum = this->miterStroke() ? 4 : 8;
int totalVertexNum = (outerVertexNum + innerVertexNum) * 2;
@@ -518,7 +635,7 @@
&vertexBuffer,
&firstVertex);
- if (!vertices || !indexBuffer) {
+ if (!vertices) {
SkDebugf("Could not allocate vertices\n");
return;
}
@@ -537,19 +654,18 @@
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(indicesPerInstance);
+ drawInfo.setIndicesPerInstance(aa_stroke_rect_index_count(this->miterStroke()));
drawInfo.adjustStartVertex(firstVertex);
drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(fIndexBuffer);
- int maxInstancesPerDraw = this->miterStroke() ? kNumMiterRectsInIndexBuffer :
- kNumBevelRectsInIndexBuffer;
+ int maxInstancesPerDraw = kNumBevelStrokeRectsInIndexBuffer;
while (instanceCount) {
drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
@@ -566,7 +682,9 @@
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
private:
- AAStrokeRectBatch(const Geometry& geometry, const SkMatrix& viewMatrix) {
+ AAStrokeRectBatch(const Geometry& geometry, const SkMatrix& viewMatrix,
+ const GrIndexBuffer* indexBuffer)
+ : fIndexBuffer(indexBuffer) {
this->initClassID<AAStrokeRectBatch>();
fBatch.fViewMatrix = viewMatrix;
fGeoData.push_back(geometry);
@@ -577,106 +695,6 @@
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; }
@@ -837,6 +855,7 @@
};
BatchTracker fBatch;
+ const GrIndexBuffer* fIndexBuffer;
SkSTArray<1, Geometry, true> fGeoData;
};
@@ -848,6 +867,15 @@
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;
@@ -855,7 +883,7 @@
geometry.fDevInside = devInside;
geometry.fMiterStroke = miterStroke;
- SkAutoTUnref<GrBatch> batch(AAStrokeRectBatch::Create(geometry, viewMatrix));
+ SkAutoTUnref<GrBatch> batch(AAStrokeRectBatch::Create(geometry, viewMatrix, indexBuffer));
target->drawBatch(pipelineBuilder, batch);
}
@@ -891,12 +919,30 @@
geo.fViewMatrix = GrTest::TestMatrix(random);
geo.fRect = GrTest::TestRect(random);
geo.fDevRect = GrTest::TestRect(random);
- return AAFillRectBatch::Create(geo);
+
+ static GrIndexBuffer* aaFillRectIndexBuffer = NULL;
+ if (!aaFillRectIndexBuffer) {
+ aaFillRectIndexBuffer =
+ context->getGpu()->createInstancedIndexBuffer(gFillAARectIdx,
+ kIndicesPerAAFillRect,
+ kNumAAFillRectsInIndexBuffer,
+ kVertsPerAAFillRect);
+ }
+
+ return AAFillRectBatch::Create(geo, aaFillRectIndexBuffer);
}
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());
@@ -913,7 +959,7 @@
geo.fDevInside = inside;
geo.fMiterStroke = miterStroke;
- return AAStrokeRectBatch::Create(geo, GrTest::TestMatrix(random));
+ return AAStrokeRectBatch::Create(geo, GrTest::TestMatrix(random), indexBuffer);
}
#endif
diff --git a/src/gpu/GrAARectRenderer.h b/src/gpu/GrAARectRenderer.h
index 023eadc..3193f4b 100644
--- a/src/gpu/GrAARectRenderer.h
+++ b/src/gpu/GrAARectRenderer.h
@@ -16,6 +16,7 @@
class GrClip;
class GrDrawTarget;
+class GrGpu;
class GrIndexBuffer;
class GrPipelineBuilder;
@@ -26,6 +27,19 @@
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).
@@ -70,6 +84,11 @@
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 0f675ac..06e98a9 100644
--- a/src/gpu/GrAddPathRenderers_default.cpp
+++ b/src/gpu/GrAddPathRenderers_default.cpp
@@ -39,7 +39,7 @@
if (GrPathRenderer* pr = GrStencilAndCoverPathRenderer::Create(ctx)) {
chain->addPathRenderer(pr)->unref();
}
- if (GrPathRenderer* pr = GrAAHairLinePathRenderer::Create()) {
+ if (GrPathRenderer* pr = GrAAHairLinePathRenderer::Create(ctx)) {
chain->addPathRenderer(pr)->unref();
}
chain->addPathRenderer(SkNEW(GrAAConvexPathRenderer))->unref();
diff --git a/src/gpu/GrAtlasTextContext.cpp b/src/gpu/GrAtlasTextContext.cpp
index 33e4f7e..14930fa 100644
--- a/src/gpu/GrAtlasTextContext.cpp
+++ b/src/gpu/GrAtlasTextContext.cpp
@@ -13,7 +13,6 @@
#include "GrDrawTarget.h"
#include "GrFontScaler.h"
#include "GrIndexBuffer.h"
-#include "GrResourceProvider.h"
#include "GrStrokeInfo.h"
#include "GrTextBlobCache.h"
#include "GrTexturePriv.h"
@@ -1515,16 +1514,14 @@
int glyphCount = this->numGlyphs();
int instanceCount = fInstanceCount;
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
-
const GrVertexBuffer* vertexBuffer;
int firstVertex;
+
void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
glyphCount * kVerticesPerGlyph,
&vertexBuffer,
&firstVertex);
- if (!vertices || !indexBuffer) {
+ if (!vertices) {
SkDebugf("Could not allocate vertices\n");
return;
}
@@ -1532,7 +1529,8 @@
unsigned char* currVertex = reinterpret_cast<unsigned char*>(vertices);
// setup drawinfo
- int maxInstancesPerDraw = indexBuffer->maxQuads();
+ const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
+ int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
GrDrawTarget::DrawInfo drawInfo;
drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
@@ -1542,7 +1540,7 @@
drawInfo.setIndicesPerInstance(kIndicesPerGlyph);
drawInfo.adjustStartVertex(firstVertex);
drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(quadIndexBuffer);
// 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 97cd2ed..9bd6b94 100644
--- a/src/gpu/GrBatchTarget.h
+++ b/src/gpu/GrBatchTarget.h
@@ -121,7 +121,9 @@
GrVertexBufferAllocPool* vertexPool() { return fVertexPool; }
GrIndexBufferAllocPool* indexPool() { return fIndexPool; }
- GrResourceProvider* resourceProvider() const { return fGpu->getContext()->resourceProvider(); }
+ const static int kVertsPerRect = 4;
+ const static int kIndicesPerRect = 6;
+ const GrIndexBuffer* quadIndexBuffer() const { return fGpu->getQuadIndexBuffer(); }
// 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 819774a..4709513 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -125,8 +125,8 @@
fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (this)));
- fAARectRenderer = SkNEW(GrAARectRenderer);
- fOvalRenderer = SkNEW(GrOvalRenderer);
+ fAARectRenderer = SkNEW_ARGS(GrAARectRenderer, (fGpu));
+ fOvalRenderer = SkNEW_ARGS(GrOvalRenderer, (fGpu));
fDidTestPMConversions = false;
@@ -186,6 +186,9 @@
delete fDrawBufferIBAllocPool;
fDrawBufferIBAllocPool = NULL;
+ fAARectRenderer->reset();
+ fOvalRenderer->reset();
+
fBatchFontCache->freeAll();
fLayerCache->freeAll();
fTextBlobCache->freeAll();
@@ -202,6 +205,9 @@
fDrawBuffer->purgeResources();
}
+ fAARectRenderer->reset();
+ fOvalRenderer->reset();
+
fBatchFontCache->freeAll();
fLayerCache->freeAll();
// a path renderer may be holding onto resources
@@ -1834,6 +1840,10 @@
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 67dc6c7..bd49a72 100644
--- a/src/gpu/GrDashLinePathRenderer.cpp
+++ b/src/gpu/GrDashLinePathRenderer.cpp
@@ -39,6 +39,6 @@
bool useAA) {
SkPoint pts[2];
SkAssertResult(path.isLine(pts));
- return GrDashingEffect::DrawDashLine(target, pipelineBuilder, color,
+ return GrDashingEffect::DrawDashLine(fGpu, target, pipelineBuilder, color,
viewMatrix, pts, useAA, stroke);
}
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index cdf5226..fdb098a 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -24,11 +24,14 @@
GrGpu::GrGpu(GrContext* context)
: fResetTimestamp(kExpiredTimestamp+1)
, fResetBits(kAll_GrBackendState)
+ , fQuadIndexBuffer(NULL)
, fGpuTraceMarkerCount(0)
, fContext(context) {
}
-GrGpu::~GrGpu() {}
+GrGpu::~GrGpu() {
+ SkSafeSetNull(fQuadIndexBuffer);
+}
void GrGpu::contextAbandoned() {}
@@ -181,6 +184,39 @@
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<GrGpu*>(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,
@@ -269,6 +305,29 @@
////////////////////////////////////////////////////////////////////////////////
+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<GrGpu*>(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 3903af6..b2dbec6 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -119,6 +119,34 @@
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.
*/
void resolveRenderTarget(GrRenderTarget* target);
@@ -492,6 +520,8 @@
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 8190ec0..e298be6 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -8,7 +8,6 @@
#include "GrInOrderDrawBuffer.h"
#include "GrDefaultGeoProcFactory.h"
-#include "GrResourceProvider.h"
#include "GrTemplates.h"
GrInOrderDrawBuffer::GrInOrderDrawBuffer(GrContext* context,
@@ -138,18 +137,17 @@
vertexStride == sizeof(GrDefaultGeoProcFactory::PositionColorAttr));
int instanceCount = fGeoData.count();
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
-
int vertexCount = kVertsPerRect * instanceCount;
+
const GrVertexBuffer* vertexBuffer;
int firstVertex;
+
void* vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
vertexCount,
&vertexBuffer,
&firstVertex);
- if (!vertices || !indexBuffer) {
+ if (!vertices || !batchTarget->quadIndexBuffer()) {
SkDebugf("Could not allocate buffers\n");
return;
}
@@ -183,6 +181,8 @@
}
}
+ const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
+
GrDrawTarget::DrawInfo drawInfo;
drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
drawInfo.setStartVertex(0);
@@ -191,9 +191,9 @@
drawInfo.setIndicesPerInstance(kIndicesPerRect);
drawInfo.adjustStartVertex(firstVertex);
drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(quadIndexBuffer);
- int maxInstancesPerDraw = indexBuffer->maxQuads();
+ int maxInstancesPerDraw = quadIndexBuffer->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 38efefa..8723d70 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -13,10 +13,10 @@
#include "GrBufferAllocPool.h"
#include "GrDrawTarget.h"
#include "GrGeometryProcessor.h"
+#include "GrGpu.h"
#include "GrInvariantOutput.h"
#include "GrPipelineBuilder.h"
#include "GrProcessor.h"
-#include "GrResourceProvider.h"
#include "GrVertexBuffer.h"
#include "SkRRect.h"
#include "SkStrokeRec.h"
@@ -646,6 +646,11 @@
///////////////////////////////////////////////////////////////////////////////
+void GrOvalRenderer::reset() {
+ SkSafeSetNull(fRRectIndexBuffer);
+ SkSafeSetNull(fStrokeRRectIndexBuffer);
+}
+
bool GrOvalRenderer::drawOval(GrDrawTarget* target,
GrPipelineBuilder* pipelineBuilder,
GrColor color,
@@ -654,7 +659,8 @@
const SkRect& oval,
const SkStrokeRec& stroke)
{
- bool useCoverageAA = useAA && !pipelineBuilder->getRenderTarget()->isMultisampled();
+ bool useCoverageAA = useAA &&
+ !pipelineBuilder->getRenderTarget()->isMultisampled();
if (!useCoverageAA) {
return false;
@@ -691,7 +697,9 @@
SkRect fDevBounds;
};
- static GrBatch* Create(const Geometry& geometry) { return SkNEW_ARGS(CircleBatch, (geometry)); }
+ static GrBatch* Create(const Geometry& geometry) {
+ return SkNEW_ARGS(CircleBatch, (geometry));
+ }
const char* name() const override { return "CircleBatch"; }
@@ -748,8 +756,6 @@
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(CircleVertex));
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
const GrVertexBuffer* vertexBuffer;
int firstVertex;
@@ -758,7 +764,7 @@
&vertexBuffer,
&firstVertex);
- if (!vertices || !indexBuffer) {
+ if (!vertices || !batchTarget->quadIndexBuffer()) {
SkDebugf("Could not allocate buffers\n");
return;
}
@@ -798,6 +804,8 @@
verts += kVertsPerCircle;
}
+ const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
+
GrDrawTarget::DrawInfo drawInfo;
drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
drawInfo.setStartVertex(0);
@@ -806,9 +814,9 @@
drawInfo.setIndicesPerInstance(kIndicesPerCircle);
drawInfo.adjustStartVertex(firstVertex);
drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(quadIndexBuffer);
- int maxInstancesPerDraw = indexBuffer->maxQuads();
+ int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
while (instanceCount) {
drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
@@ -1014,8 +1022,6 @@
SkASSERT(vertexStride == sizeof(EllipseVertex));
const GrVertexBuffer* vertexBuffer;
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
int firstVertex;
void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
@@ -1023,7 +1029,7 @@
&vertexBuffer,
&firstVertex);
- if (!vertices || !indexBuffer) {
+ if (!vertices || !batchTarget->quadIndexBuffer()) {
SkDebugf("Could not allocate buffers\n");
return;
}
@@ -1068,6 +1074,8 @@
verts += kVertsPerEllipse;
}
+ const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
+
GrDrawTarget::DrawInfo drawInfo;
drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
drawInfo.setStartVertex(0);
@@ -1076,9 +1084,9 @@
drawInfo.setIndicesPerInstance(kIndicesPerEllipse);
drawInfo.adjustStartVertex(firstVertex);
drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(quadIndexBuffer);
- int maxInstancesPerDraw = indexBuffer->maxQuads();
+ int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
while (instanceCount) {
drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
@@ -1317,21 +1325,20 @@
init.fUsesLocalCoords = this->usesLocalCoords();
gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- batchTarget->resourceProvider()->refQuadIndexBuffer());
-
int instanceCount = fGeoData.count();
int vertexCount = kVertsPerEllipse * instanceCount;
size_t vertexStride = gp->getVertexStride();
SkASSERT(vertexStride == sizeof(DIEllipseVertex));
+
const GrVertexBuffer* vertexBuffer;
int firstVertex;
+
void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
vertexCount,
&vertexBuffer,
&firstVertex);
- if (!vertices || !indexBuffer) {
+ if (!vertices || !batchTarget->quadIndexBuffer()) {
SkDebugf("Could not allocate buffers\n");
return;
}
@@ -1372,6 +1379,8 @@
verts += kVertsPerEllipse;
}
+ const GrIndexBuffer* quadIndexBuffer = batchTarget->quadIndexBuffer();
+
GrDrawTarget::DrawInfo drawInfo;
drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
drawInfo.setStartVertex(0);
@@ -1380,9 +1389,9 @@
drawInfo.setIndicesPerInstance(kIndicesPerEllipse);
drawInfo.adjustStartVertex(firstVertex);
drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(quadIndexBuffer);
- int maxInstancesPerDraw = indexBuffer->maxQuads();
+ int maxInstancesPerDraw = quadIndexBuffer->maxQuads();
while (instanceCount) {
drawInfo.setInstanceCount(SkTMin(instanceCount, maxInstancesPerDraw));
@@ -1570,24 +1579,6 @@
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,
@@ -1666,8 +1657,8 @@
SkRect fDevBounds;
};
- static GrBatch* Create(const Geometry& geometry) {
- return SkNEW_ARGS(RRectCircleRendererBatch, (geometry));
+ static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* indexBuffer) {
+ return SkNEW_ARGS(RRectCircleRendererBatch, (geometry, indexBuffer));
}
const char* name() const override { return "RRectCircleBatch"; }
@@ -1727,8 +1718,6 @@
SkASSERT(vertexStride == sizeof(CircleVertex));
const GrVertexBuffer* vertexBuffer;
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider()));
int firstVertex;
void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
@@ -1736,7 +1725,7 @@
&vertexBuffer,
&firstVertex);
- if (!vertices || !indexBuffer) {
+ if (!vertices) {
SkDebugf("Could not allocate vertices\n");
return;
}
@@ -1791,6 +1780,7 @@
int indexCnt = this->stroke() ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
SK_ARRAY_COUNT(gRRectIndices);
+
GrDrawTarget::DrawInfo drawInfo;
drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
drawInfo.setStartVertex(0);
@@ -1799,7 +1789,7 @@
drawInfo.setIndicesPerInstance(indexCnt);
drawInfo.adjustStartVertex(firstVertex);
drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(fIndexBuffer);
int maxInstancesPerDraw = kNumRRectsInIndexBuffer;
@@ -1818,7 +1808,8 @@
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
private:
- RRectCircleRendererBatch(const Geometry& geometry) {
+ RRectCircleRendererBatch(const Geometry& geometry, const GrIndexBuffer* indexBuffer)
+ : fIndexBuffer(indexBuffer) {
this->initClassID<RRectCircleRendererBatch>();
fGeoData.push_back(geometry);
@@ -1862,6 +1853,7 @@
BatchTracker fBatch;
SkSTArray<1, Geometry, true> fGeoData;
+ const GrIndexBuffer* fIndexBuffer;
};
class RRectEllipseRendererBatch : public GrBatch {
@@ -1877,8 +1869,8 @@
SkRect fDevBounds;
};
- static GrBatch* Create(const Geometry& geometry) {
- return SkNEW_ARGS(RRectEllipseRendererBatch, (geometry));
+ static GrBatch* Create(const Geometry& geometry, const GrIndexBuffer* indexBuffer) {
+ return SkNEW_ARGS(RRectEllipseRendererBatch, (geometry, indexBuffer));
}
const char* name() const override { return "RRectEllipseRendererBatch"; }
@@ -1938,8 +1930,6 @@
SkASSERT(vertexStride == sizeof(EllipseVertex));
const GrVertexBuffer* vertexBuffer;
- SkAutoTUnref<const GrIndexBuffer> indexBuffer(
- ref_rrect_index_buffer(this->stroke(), batchTarget->resourceProvider()));
int firstVertex;
void *vertices = batchTarget->vertexPool()->makeSpace(vertexStride,
@@ -1947,7 +1937,7 @@
&vertexBuffer,
&firstVertex);
- if (!vertices || !indexBuffer) {
+ if (!vertices) {
SkDebugf("Could not allocate vertices\n");
return;
}
@@ -2021,7 +2011,7 @@
drawInfo.setIndicesPerInstance(indexCnt);
drawInfo.adjustStartVertex(firstVertex);
drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(fIndexBuffer);
int maxInstancesPerDraw = kNumRRectsInIndexBuffer;
@@ -2040,7 +2030,8 @@
SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
private:
- RRectEllipseRendererBatch(const Geometry& geometry) {
+ RRectEllipseRendererBatch(const Geometry& geometry, const GrIndexBuffer* indexBuffer)
+ : fIndexBuffer(indexBuffer) {
this->initClassID<RRectEllipseRendererBatch>();
fGeoData.push_back(geometry);
@@ -2084,13 +2075,40 @@
BatchTracker fBatch;
SkSTArray<1, Geometry, true> fGeoData;
+ const GrIndexBuffer* fIndexBuffer;
};
+static GrIndexBuffer* create_rrect_indexbuffer(GrIndexBuffer** strokeRRectIndexBuffer,
+ GrIndexBuffer** rrectIndexBuffer,
+ bool isStrokeOnly,
+ GrGpu* gpu) {
+ if (isStrokeOnly) {
+ if (NULL == *strokeRRectIndexBuffer) {
+ *strokeRRectIndexBuffer = gpu->createInstancedIndexBuffer(gRRectIndices,
+ kIndicesPerStrokeRRect,
+ kNumRRectsInIndexBuffer,
+ kVertsPerRRect);
+ }
+ return *strokeRRectIndexBuffer;
+ } else {
+ if (NULL == *rrectIndexBuffer) {
+ *rrectIndexBuffer = gpu->createInstancedIndexBuffer(gRRectIndices,
+ kIndicesPerRRect,
+ kNumRRectsInIndexBuffer,
+ kVertsPerRRect);
+ }
+ return *rrectIndexBuffer;
+ }
+}
+
static GrBatch* create_rrect_batch(GrColor color,
const SkMatrix& viewMatrix,
const SkRRect& rrect,
const SkStrokeRec& stroke,
- SkRect* bounds) {
+ SkRect* bounds,
+ GrIndexBuffer** strokeRRectIndexBuffer,
+ GrIndexBuffer** rrectIndexBuffer,
+ GrGpu* gpu) {
SkASSERT(viewMatrix.rectStaysRect());
SkASSERT(rrect.isSimple());
SkASSERT(!rrect.isOval());
@@ -2141,6 +2159,15 @@
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;
@@ -2181,7 +2208,8 @@
geometry.fStroke = isStrokeOnly;
geometry.fDevBounds = *bounds;
- return RRectCircleRendererBatch::Create(geometry);
+ return RRectCircleRendererBatch::Create(geometry, indexBuffer);
+
// otherwise we use the ellipse renderer
} else {
SkScalar innerXRadius = 0.0f;
@@ -2231,7 +2259,7 @@
geometry.fStroke = isStrokeOnly;
geometry.fDevBounds = *bounds;
- return RRectEllipseRendererBatch::Create(geometry);
+ return RRectEllipseRendererBatch::Create(geometry, indexBuffer);
}
}
@@ -2259,7 +2287,9 @@
}
SkRect bounds;
- SkAutoTUnref<GrBatch> batch(create_rrect_batch(color, viewMatrix, rrect, stroke, &bounds));
+ SkAutoTUnref<GrBatch> batch(create_rrect_batch(color, viewMatrix, rrect, stroke, &bounds,
+ &fStrokeRRectIndexBuffer, &fRRectIndexBuffer,
+ fGpu));
if (!batch) {
return false;
}
@@ -2317,8 +2347,11 @@
GrColor color = GrRandomColor(random);
const SkRRect& rrect = GrTest::TestRRectSimple(random);
+ static GrIndexBuffer* gStrokeRRectIndexBuffer;
+ static GrIndexBuffer* gRRectIndexBuffer;
SkRect bounds;
- return create_rrect_batch(color, viewMatrix, rrect, random_strokerec(random), &bounds);
+ return create_rrect_batch(color, viewMatrix, rrect, random_strokerec(random), &bounds,
+ &gStrokeRRectIndexBuffer, &gRRectIndexBuffer, context->getGpu());
}
#endif
diff --git a/src/gpu/GrOvalRenderer.h b/src/gpu/GrOvalRenderer.h
index 57ce2a5..f31aa69 100644
--- a/src/gpu/GrOvalRenderer.h
+++ b/src/gpu/GrOvalRenderer.h
@@ -24,6 +24,16 @@
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,
@@ -69,6 +79,10 @@
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
deleted file mode 100644
index 1342ccc..0000000
--- a/src/gpu/GrResourceProvider.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * 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();
- }
- 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 0d80cdd..f560afa 100644
--- a/src/gpu/GrResourceProvider.h
+++ b/src/gpu/GrResourceProvider.h
@@ -10,9 +10,6 @@
#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
@@ -21,67 +18,12 @@
class GrResourceProvider : public GrTextureProvider {
public:
- GrResourceProvider(GrGpu* gpu, GrResourceCache* cache);
-
- template <typename T> T* findAndRefTByUniqueKey(const GrUniqueKey& key) {
- return static_cast<T*>(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<GrIndexBuffer>(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<GrIndexBuffer>(fQuadIndexBufferKey)) {
- return buffer;
- }
- return this->createQuadIndexBuffer();
- }
-
+ GrResourceProvider(GrGpu* gpu, GrResourceCache* cache) : INHERITED(gpu, cache) {}
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 fa8b3a2..3f0df67 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -19,7 +19,6 @@
#include "GrDrawTargetCaps.h"
#include "GrInvariantOutput.h"
#include "GrProcessor.h"
-#include "GrResourceProvider.h"
#include "GrStrokeInfo.h"
#include "GrVertexBuffer.h"
#include "SkGr.h"
@@ -536,17 +535,16 @@
draw.fHasEndRect = hasEndRect;
}
- SkAutoTUnref<const GrIndexBuffer> 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 || !indexBuffer) {
+
+ if (!vertices || !batchTarget->quadIndexBuffer()) {
SkDebugf("Could not allocate buffers\n");
return;
}
@@ -609,6 +607,8 @@
rectIndex++;
}
+ const GrIndexBuffer* dashIndexBuffer = batchTarget->quadIndexBuffer();
+
GrDrawTarget::DrawInfo drawInfo;
drawInfo.setPrimitiveType(kTriangles_GrPrimitiveType);
drawInfo.setStartVertex(0);
@@ -617,9 +617,9 @@
drawInfo.setIndicesPerInstance(kIndicesPerDash);
drawInfo.adjustStartVertex(firstVertex);
drawInfo.setVertexBuffer(vertexBuffer);
- drawInfo.setIndexBuffer(indexBuffer);
+ drawInfo.setIndexBuffer(dashIndexBuffer);
- int maxInstancesPerDraw = indexBuffer->maxQuads();
+ int maxInstancesPerDraw = dashIndexBuffer->maxQuads();
while (totalRectCount) {
drawInfo.setInstanceCount(SkTMin(totalRectCount, maxInstancesPerDraw));
drawInfo.setVertexCount(drawInfo.instanceCount() * drawInfo.verticesPerInstance());
@@ -761,7 +761,7 @@
return DashBatch::Create(geometry, cap, aaMode, fullDash);
}
-bool GrDashingEffect::DrawDashLine(GrDrawTarget* target,
+bool GrDashingEffect::DrawDashLine(GrGpu* gpu, 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 05b1c90..999abb2 100644
--- a/src/gpu/effects/GrDashingEffect.h
+++ b/src/gpu/effects/GrDashingEffect.h
@@ -15,12 +15,13 @@
class GrClip;
class GrDrawTarget;
+class GrGpu;
class GrPaint;
class GrPipelineBuilder;
class GrStrokeInfo;
namespace GrDashingEffect {
- bool DrawDashLine(GrDrawTarget*, GrPipelineBuilder*, GrColor,
+ bool DrawDashLine(GrGpu*, GrDrawTarget*, GrPipelineBuilder*, GrColor,
const SkMatrix& viewMatrix, const SkPoint pts[2], bool useAA,
const GrStrokeInfo& strokeInfo);
bool CanDrawDashLine(const SkPoint pts[2], const GrStrokeInfo& strokeInfo,