aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/gpu/GrConfig.h9
-rw-r--r--include/gpu/GrUserConfig.h11
-rw-r--r--src/gpu/GrContext.cpp65
-rw-r--r--src/gpu/GrGpu.cpp38
-rw-r--r--src/gpu/GrGpu.h10
5 files changed, 130 insertions, 3 deletions
diff --git a/include/gpu/GrConfig.h b/include/gpu/GrConfig.h
index d929d580ac..00e77eadb3 100644
--- a/include/gpu/GrConfig.h
+++ b/include/gpu/GrConfig.h
@@ -316,6 +316,15 @@ inline void GrCrash(const char* msg) { GrPrintf(msg); GrAlwaysAssert(false); }
#endif
/**
+ * GR_STATIC_RECT_VB controls whether rects are drawn by issuing a vertex
+ * for each corner or using a static vb that is positioned by modifying the
+ * view / texture matrix.
+ */
+#if !defined(GR_STATIC_RECT_VB)
+ #define GR_STATIC_RECT_VB 1
+#endif
+
+/**
* GR_GEOM_BUFFER_LOCK_THRESHOLD gives a threshold (in bytes) for when Gr should
* lock a GrGeometryBuffer to update its contents. It will use lock() if the
* size of the updated region is greater than the threshold. Otherwise it will
diff --git a/include/gpu/GrUserConfig.h b/include/gpu/GrUserConfig.h
index b9df083c48..594889b1a7 100644
--- a/include/gpu/GrUserConfig.h
+++ b/include/gpu/GrUserConfig.h
@@ -21,7 +21,16 @@
#define GR_DEBUG 1
#endif
-/*
+/**
+ * When drawing rects this causes Ganesh to use a vertex buffer containing
+ * a unit square that is positioned by a matrix. Enable on systems where
+ * emitting per-rect-draw verts is more expensive than constant/matrix
+ * updates. Defaults to 0.
+ */
+//#define GR_STATIC_RECT_VB 1
+
+
+/**
* This gives a threshold in bytes of when to lock a GrGeometryBuffer vs using
* updateData. (Note the depending on the underlying 3D API the update functions
* may always be implemented using a lock)
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index a73a5b5278..ef3fd6d2f3 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -734,6 +734,8 @@ void GrContext::drawRect(const GrPaint& paint,
if (width >= 0) {
// TODO: consider making static vertex buffers for these cases.
+ // Hairline could be done by just adding closing vertex to
+ // unitSquareVertexBuffer()
static const int worstCaseVertCount = 10;
target->drawState()->setVertexLayout(GrDrawState::kDefault_VertexLayout);
@@ -771,7 +773,30 @@ void GrContext::drawRect(const GrPaint& paint,
target->drawNonIndexed(primType, 0, vertCount);
} else {
- target->drawSimpleRect(rect, matrix);
+#if GR_STATIC_RECT_VB
+ const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer();
+ if (NULL == sqVB) {
+ GrPrintf("Failed to create static rect vb.\n");
+ return;
+ }
+
+ GrDrawState* drawState = target->drawState();
+ drawState->setVertexLayout(GrDrawState::kDefault_VertexLayout);
+ target->setVertexSourceToBuffer(sqVB);
+ SkMatrix m;
+ m.setAll(rect.width(), 0, rect.fLeft,
+ 0, rect.height(), rect.fTop,
+ 0, 0, SkMatrix::I()[8]);
+
+ if (NULL != matrix) {
+ m.postConcat(*matrix);
+ }
+ GrDrawState::AutoViewMatrixRestore avmr(drawState, m);
+
+ target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
+#else
+ target->drawSimpleRect(rect, matrix);
+#endif
}
}
@@ -789,6 +814,43 @@ void GrContext::drawRectToRect(const GrPaint& paint,
}
GrDrawTarget* target = this->prepareToDraw(&paint, BUFFERED_DRAW);
+
+#if GR_STATIC_RECT_VB
+ GrDrawState::AutoStageDisable atr(fDrawState);
+ GrDrawState* drawState = target->drawState();
+
+ SkMatrix m;
+
+ m.setAll(dstRect.width(), 0, dstRect.fLeft,
+ 0, dstRect.height(), dstRect.fTop,
+ 0, 0, SkMatrix::I()[8]);
+ if (NULL != dstMatrix) {
+ m.postConcat(*dstMatrix);
+ }
+
+ // The first color stage's coords come from srcRect rather than applying a matrix to dstRect.
+ // We explicitly compute a matrix for that stage below, no need to adjust here.
+ static const uint32_t kExplicitCoordMask = 1 << GrPaint::kFirstColorStage;
+ GrDrawState::AutoViewMatrixRestore avmr(drawState, m, kExplicitCoordMask);
+
+ m.setAll(srcRect.width(), 0, srcRect.fLeft,
+ 0, srcRect.height(), srcRect.fTop,
+ 0, 0, SkMatrix::I()[8]);
+ if (NULL != srcMatrix) {
+ m.postConcat(*srcMatrix);
+ }
+
+ drawState->preConcatStageMatrices(kExplicitCoordMask, m);
+
+ const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer();
+ if (NULL == sqVB) {
+ GrPrintf("Failed to create static rect vb.\n");
+ return;
+ }
+ drawState->setVertexLayout(GrDrawState::kDefault_VertexLayout);
+ target->setVertexSourceToBuffer(sqVB);
+ target->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
+#else
GrDrawState::AutoStageDisable atr(fDrawState);
const GrRect* srcRects[GrDrawState::kNumStages] = {NULL};
@@ -797,6 +859,7 @@ void GrContext::drawRectToRect(const GrPaint& paint,
srcMatrices[0] = srcMatrix;
target->drawRect(dstRect, dstMatrix, srcRects, srcMatrices);
+#endif
}
void GrContext::drawVertices(const GrPaint& paint,
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 3f33a2abeb..c9aa046fa2 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -33,6 +33,7 @@ GrGpu::GrGpu()
, fIndexPool(NULL)
, fVertexPoolUseCnt(0)
, fIndexPoolUseCnt(0)
+ , fUnitSquareVertexBuffer(NULL)
, fQuadIndexBuffer(NULL)
, fContextIsDirty(true) {
@@ -65,7 +66,10 @@ void GrGpu::abandonResources() {
}
GrAssert(NULL == fQuadIndexBuffer || !fQuadIndexBuffer->isValid());
+ GrAssert(NULL == fUnitSquareVertexBuffer ||
+ !fUnitSquareVertexBuffer->isValid());
GrSafeSetNull(fQuadIndexBuffer);
+ GrSafeSetNull(fUnitSquareVertexBuffer);
delete fVertexPool;
fVertexPool = NULL;
delete fIndexPool;
@@ -81,7 +85,10 @@ void GrGpu::releaseResources() {
}
GrAssert(NULL == fQuadIndexBuffer || !fQuadIndexBuffer->isValid());
+ GrAssert(NULL == fUnitSquareVertexBuffer ||
+ !fUnitSquareVertexBuffer->isValid());
GrSafeSetNull(fQuadIndexBuffer);
+ GrSafeSetNull(fUnitSquareVertexBuffer);
delete fVertexPool;
fVertexPool = NULL;
delete fIndexPool;
@@ -289,6 +296,37 @@ const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const {
return fQuadIndexBuffer;
}
+const GrVertexBuffer* GrGpu::getUnitSquareVertexBuffer() const {
+ if (NULL == fUnitSquareVertexBuffer) {
+
+ static const GrPoint DATA[] = {
+ { 0, 0 },
+ { SK_Scalar1, 0 },
+ { SK_Scalar1, SK_Scalar1 },
+ { 0, SK_Scalar1 }
+#if 0
+ GrPoint(0, 0),
+ GrPoint(SK_Scalar1,0),
+ GrPoint(SK_Scalar1,SK_Scalar1),
+ GrPoint(0, SK_Scalar1)
+#endif
+ };
+ static const size_t SIZE = sizeof(DATA);
+
+ GrGpu* me = const_cast<GrGpu*>(this);
+ fUnitSquareVertexBuffer = me->createVertexBuffer(SIZE, false);
+ if (NULL != fUnitSquareVertexBuffer) {
+ if (!fUnitSquareVertexBuffer->updateData(DATA, SIZE)) {
+ fUnitSquareVertexBuffer->unref();
+ fUnitSquareVertexBuffer = NULL;
+ GrCrash("Can't get vertices into buffer!");
+ }
+ }
+ }
+
+ return fUnitSquareVertexBuffer;
+}
+
////////////////////////////////////////////////////////////////////////////////
bool GrGpu::setupClipAndFlushState(DrawType type) {
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 93427e01ac..d0ca377093 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -146,6 +146,13 @@ public:
const GrIndexBuffer* getQuadIndexBuffer() const;
/**
+ * Returns a vertex buffer with four position-only vertices [(0,0), (1,0),
+ * (1,1), (0,1)].
+ * @ return unit square vertex buffer
+ */
+ const GrVertexBuffer* getUnitSquareVertexBuffer() const;
+
+ /**
* Resolves MSAA.
*/
void resolveRenderTarget(GrRenderTarget* target);
@@ -527,7 +534,8 @@ private:
// counts number of uses of vertex/index pool in the geometry stack
int fVertexPoolUseCnt;
int fIndexPoolUseCnt;
- // this is mutable so it can be created on-demand
+ // these are mutable so they can be created on-demand
+ mutable GrVertexBuffer* fUnitSquareVertexBuffer;
mutable GrIndexBuffer* fQuadIndexBuffer;
bool fContextIsDirty;
ResourceList fResourceList;