Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(225)

Unified Diff: src/gpu/GrAAHairLinePathRenderer.cpp

Issue 1116943004: Move instanced index buffer creation to flush time (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: static inline instead of inline static, because consistency Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/gpu/GrAAHairLinePathRenderer.cpp
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index 96e0677eceb691d8a457b44510d6627398f63423..e9de91b4af066ed6da73ca655eed2b597c0ded97 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -13,11 +13,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"
@@ -25,6 +25,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
@@ -60,6 +62,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.
@@ -86,43 +96,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<GrIndexBuffer> qIdxBuffer(qIdxBuf);
- GrIndexBuffer* lIdxBuf = gpu->createInstancedIndexBuffer(kLineSegIdxBufPattern,
- kIdxsPerLineSeg,
- kLineSegsNumInIdxBuffer,
- kLineSegNumVertices);
- SkAutoTUnref<GrIndexBuffer> 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;
@@ -150,7 +134,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) {
@@ -170,7 +154,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) {
@@ -185,7 +169,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);
@@ -206,14 +190,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;
@@ -249,14 +233,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;
@@ -440,9 +424,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);
@@ -458,14 +442,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<kQuadNumVertices, sizeof(BezierVertex), sizeof(SkPoint)>(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];
@@ -543,8 +527,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);
@@ -557,21 +541,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];
@@ -585,10 +569,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];
@@ -630,8 +614,6 @@ void add_line(const SkPoint p[2],
*vert += kLineSegNumVertices;
}
-}
-
///////////////////////////////////////////////////////////////////////////////
bool GrAAHairLinePathRenderer::canDrawPath(const GrDrawTarget* target,
@@ -702,11 +684,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"; }
@@ -744,11 +723,7 @@ private:
typedef SkTArray<int, true> IntArray;
typedef SkTArray<float, true> FloatArray;
- AAHairlineBatch(const Geometry& geometry, const GrIndexBuffer* linesIndexBuffer,
- const GrIndexBuffer* quadsIndexBuffer)
- : fLinesIndexBuffer(linesIndexBuffer)
- , fQuadsIndexBuffer(quadsIndexBuffer) {
- SkASSERT(linesIndexBuffer && quadsIndexBuffer);
+ AAHairlineBatch(const Geometry& geometry) {
this->initClassID<AAHairlineBatch>();
fGeoData.push_back(geometry);
@@ -807,8 +782,6 @@ private:
BatchTracker fBatch;
SkSTArray<1, Geometry, true> fGeoData;
- const GrIndexBuffer* fLinesIndexBuffer;
- const GrIndexBuffer* fQuadsIndexBuffer;
};
void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) {
@@ -879,6 +852,8 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
// do lines first
if (lineCount) {
+ SkAutoTUnref<const GrIndexBuffer> linesIndexBuffer(
+ ref_lines_index_buffer(batchTarget->resourceProvider()));
robertphillips 2015/05/04 13:16:00 Check if this fails ? We seem to do it every where
bsalomon 2015/05/04 15:01:09 Done.
batchTarget->initDraw(lineGP, pipeline);
// TODO remove this when batch is everywhere
@@ -914,7 +889,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);
@@ -936,6 +911,9 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
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,
@@ -943,7 +921,7 @@ void AAHairlineBatch::generateGeometry(GrBatchTarget* batchTarget, const GrPipel
&vertexBuffer,
&firstVertex);
- if (!vertices) {
+ if (!vertices || !quadsIndexBuffer) {
SkDebugf("Could not allocate vertices\n");
return;
}
@@ -976,7 +954,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);
@@ -1008,7 +986,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);
@@ -1035,11 +1013,6 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
const SkPath& path,
const GrStrokeInfo& stroke,
bool) {
- if (!fLinesIndexBuffer || !fQuadsIndexBuffer) {
- SkDebugf("unable to allocate indices\n");
- return false;
- }
-
SkScalar hairlineCoverage;
uint8_t newCoverage = 0xff;
if (IsStrokeHairlineOrEquivalent(stroke, viewMatrix, &hairlineCoverage)) {
@@ -1057,8 +1030,7 @@ bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
geometry.fPath = path;
geometry.fDevClipBounds = devClipBounds;
- SkAutoTUnref<GrBatch> batch(AAHairlineBatch::Create(geometry, fLinesIndexBuffer,
- fQuadsIndexBuffer));
+ SkAutoTUnref<GrBatch> batch(AAHairlineBatch::Create(geometry));
target->drawBatch(pipelineBuilder, batch);
return true;

Powered by Google App Engine
This is Rietveld 408576698