Drawstate on stack
BUG=skia:
Review URL: https://codereview.chromium.org/732693002
diff --git a/src/gpu/GrAAConvexPathRenderer.cpp b/src/gpu/GrAAConvexPathRenderer.cpp
index c3275c8..934eb04 100644
--- a/src/gpu/GrAAConvexPathRenderer.cpp
+++ b/src/gpu/GrAAConvexPathRenderer.cpp
@@ -610,9 +610,10 @@
///////////////////////////////////////////////////////////////////////////////
-bool GrAAConvexPathRenderer::canDrawPath(const SkPath& path,
+bool GrAAConvexPathRenderer::canDrawPath(const GrDrawTarget* target,
+ const GrDrawState*,
+ const SkPath& path,
const SkStrokeRec& stroke,
- const GrDrawTarget* target,
bool antiAlias) const {
return (target->caps()->shaderDerivativeSupport() && antiAlias &&
stroke.isFillStyle() && !path.isInverseFillType() && path.isConvex());
@@ -628,9 +629,10 @@
};
-bool GrAAConvexPathRenderer::onDrawPath(const SkPath& origPath,
+bool GrAAConvexPathRenderer::onDrawPath(GrDrawTarget* target,
+ GrDrawState* drawState,
+ const SkPath& origPath,
const SkStrokeRec&,
- GrDrawTarget* target,
bool antiAlias) {
const SkPath* path = &origPath;
@@ -638,12 +640,11 @@
return true;
}
- SkMatrix viewMatrix = target->getDrawState().getViewMatrix();
- GrDrawTarget::AutoStateRestore asr;
- if (!asr.setIdentity(target, GrDrawTarget::kPreserve_ASRInit)) {
+ SkMatrix viewMatrix = drawState->getViewMatrix();
+ GrDrawState::AutoViewMatrixRestore avmr;
+ if (!avmr.setIdentity(drawState)) {
return false;
}
- GrDrawState* drawState = target->drawState();
// We use the fact that SkPath::transform path does subdivision based on
// perspective. Otherwise, we apply the view matrix when copying to the
@@ -682,7 +683,7 @@
GrGeometryProcessor* quadProcessor = QuadEdgeEffect::Create();
drawState->setGeometryProcessor(quadProcessor)->unref();
- GrDrawTarget::AutoReleaseGeometry arg(target, vCount, iCount);
+ GrDrawTarget::AutoReleaseGeometry arg(target, vCount, drawState->getVertexStride(), iCount);
if (!arg.succeeded()) {
return false;
}
@@ -707,7 +708,8 @@
int vOffset = 0;
for (int i = 0; i < draws.count(); ++i) {
const Draw& draw = draws[i];
- target->drawIndexed(kTriangles_GrPrimitiveType,
+ target->drawIndexed(drawState,
+ kTriangles_GrPrimitiveType,
vOffset, // start vertex
0, // start index
draw.fVertexCnt,
diff --git a/src/gpu/GrAAConvexPathRenderer.h b/src/gpu/GrAAConvexPathRenderer.h
index 4dd8585..bb40e19 100644
--- a/src/gpu/GrAAConvexPathRenderer.h
+++ b/src/gpu/GrAAConvexPathRenderer.h
@@ -15,15 +15,17 @@
public:
GrAAConvexPathRenderer();
- virtual bool canDrawPath(const SkPath& path,
- const SkStrokeRec& stroke,
- const GrDrawTarget* target,
+ virtual bool canDrawPath(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&,
bool antiAlias) const SK_OVERRIDE;
protected:
- virtual bool onDrawPath(const SkPath& path,
- const SkStrokeRec& stroke,
- GrDrawTarget* target,
+ virtual bool onDrawPath(GrDrawTarget*,
+ GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&,
bool antiAlias) SK_OVERRIDE;
};
diff --git a/src/gpu/GrAADistanceFieldPathRenderer.cpp b/src/gpu/GrAADistanceFieldPathRenderer.cpp
index cb0c892..5e0410f 100755
--- a/src/gpu/GrAADistanceFieldPathRenderer.cpp
+++ b/src/gpu/GrAADistanceFieldPathRenderer.cpp
@@ -65,9 +65,10 @@
}
////////////////////////////////////////////////////////////////////////////////
-bool GrAADistanceFieldPathRenderer::canDrawPath(const SkPath& path,
+bool GrAADistanceFieldPathRenderer::canDrawPath(const GrDrawTarget* target,
+ const GrDrawState* drawState,
+ const SkPath& path,
const SkStrokeRec& stroke,
- const GrDrawTarget* target,
bool antiAlias) const {
// TODO: Support inverse fill
@@ -78,8 +79,7 @@
}
// currently don't support perspective
- const GrDrawState& drawState = target->getDrawState();
- const SkMatrix& vm = drawState.getViewMatrix();
+ const SkMatrix& vm = drawState->getViewMatrix();
if (vm.hasPerspective()) {
return false;
}
@@ -93,10 +93,11 @@
}
-GrPathRenderer::StencilSupport GrAADistanceFieldPathRenderer::onGetStencilSupport(
- const SkPath&,
- const SkStrokeRec&,
- const GrDrawTarget*) const {
+GrPathRenderer::StencilSupport
+GrAADistanceFieldPathRenderer::onGetStencilSupport(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&) const {
return GrPathRenderer::kNoSupport_StencilSupport;
}
@@ -109,9 +110,10 @@
};
static const size_t kSDFPathVASize = 2 * sizeof(SkPoint);
-bool GrAADistanceFieldPathRenderer::onDrawPath(const SkPath& path,
+bool GrAADistanceFieldPathRenderer::onDrawPath(GrDrawTarget* target,
+ GrDrawState* drawState,
+ const SkPath& path,
const SkStrokeRec& stroke,
- GrDrawTarget* target,
bool antiAlias) {
// we've already bailed on inverse filled paths, so this is safe
if (path.isEmpty()) {
@@ -121,8 +123,7 @@
SkASSERT(fContext);
// get mip level
- const GrDrawState& drawState = target->getDrawState();
- const SkMatrix& vm = drawState.getViewMatrix();
+ const SkMatrix& vm = drawState->getViewMatrix();
SkScalar maxScale = vm.getMaxScale();
const SkRect& bounds = path.getBounds();
SkScalar maxDim = SkMaxScalar(bounds.width(), bounds.height());
@@ -149,7 +150,7 @@
}
// use signed distance field to render
- return this->internalDrawPath(path, pathData, target);
+ return this->internalDrawPath(target, drawState, path, pathData);
}
// padding around path bounds to allow for antialiased pixels
@@ -310,11 +311,11 @@
return true;
}
-bool GrAADistanceFieldPathRenderer::internalDrawPath(const SkPath& path,
- const PathData* pathData,
- GrDrawTarget* target) {
+bool GrAADistanceFieldPathRenderer::internalDrawPath(GrDrawTarget* target,
+ GrDrawState* drawState,
+ const SkPath& path,
+ const PathData* pathData) {
GrTexture* texture = fAtlas->getTexture();
- GrDrawState* drawState = target->drawState();
GrDrawState::AutoRestoreEffects are(drawState);
SkASSERT(pathData->fPlot);
@@ -325,7 +326,8 @@
drawState->setVertexAttribs<gSDFPathVertexAttribs>(SK_ARRAY_COUNT(gSDFPathVertexAttribs),
kSDFPathVASize);
void* vertices = NULL;
- bool success = target->reserveVertexAndIndexSpace(4, 0, &vertices, NULL);
+ bool success = target->reserveVertexAndIndexSpace(4, drawState->getVertexStride(), 0, &vertices,
+ NULL);
GrAlwaysAssert(success);
SkScalar dx = pathData->fBounds.fLeft;
@@ -375,7 +377,7 @@
vm.mapRect(&r);
target->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
- target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &r);
+ target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &r);
target->resetVertexSource();
return true;
diff --git a/src/gpu/GrAADistanceFieldPathRenderer.h b/src/gpu/GrAADistanceFieldPathRenderer.h
index c337016..e9a32dc 100755
--- a/src/gpu/GrAADistanceFieldPathRenderer.h
+++ b/src/gpu/GrAADistanceFieldPathRenderer.h
@@ -25,19 +25,22 @@
GrAADistanceFieldPathRenderer(GrContext* context);
virtual ~GrAADistanceFieldPathRenderer();
- virtual bool canDrawPath(const SkPath& path,
- const SkStrokeRec& stroke,
- const GrDrawTarget* target,
+ virtual bool canDrawPath(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&,
bool antiAlias) const SK_OVERRIDE;
protected:
- virtual StencilSupport onGetStencilSupport(const SkPath&,
- const SkStrokeRec&,
- const GrDrawTarget*) const SK_OVERRIDE;
+ virtual StencilSupport onGetStencilSupport(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&) const SK_OVERRIDE;
- virtual bool onDrawPath(const SkPath& path,
- const SkStrokeRec& stroke,
- GrDrawTarget* target,
+ virtual bool onDrawPath(GrDrawTarget*,
+ GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&,
bool antiAlias) SK_OVERRIDE;
private:
@@ -76,7 +79,8 @@
SkTDynamicHash<PathData, PathData::Key> fPathCache;
PathDataList fPathList;
- bool internalDrawPath(const SkPath& path, const PathData* pathData, GrDrawTarget* target);
+ bool internalDrawPath(GrDrawTarget*, GrDrawState*, const SkPath& path,
+ const PathData* pathData);
PathData* addPathToAtlas(const SkPath& path, const SkStrokeRec& stroke, bool antiAlias,
uint32_t dimension, SkScalar scale);
bool freeUnusedPlot();
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index 74d19bd..0d16cf8 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -650,14 +650,13 @@
};
};
-bool GrAAHairLinePathRenderer::createLineGeom(const SkPath& path,
- GrDrawTarget* target,
- const PtArray& lines,
- int lineCnt,
+bool GrAAHairLinePathRenderer::createLineGeom(GrDrawTarget* target,
+ GrDrawState* drawState,
GrDrawTarget::AutoReleaseGeometry* arg,
- SkRect* devBounds) {
- GrDrawState* drawState = target->drawState();
-
+ SkRect* devBounds,
+ const SkPath& path,
+ const PtArray& lines,
+ int lineCnt) {
const SkMatrix& viewM = drawState->getViewMatrix();
int vertCnt = kLineSegNumVertices * lineCnt;
@@ -665,7 +664,7 @@
GrDefaultGeoProcFactory::SetAttribs(drawState, GrDefaultGeoProcFactory::kPosition_GPType |
GrDefaultGeoProcFactory::kCoverage_GPType);
- if (!arg->set(target, vertCnt, 0)) {
+ if (!arg->set(target, vertCnt, drawState->getVertexStride(), 0)) {
return false;
}
@@ -692,27 +691,25 @@
return true;
}
-bool GrAAHairLinePathRenderer::createBezierGeom(
- const SkPath& path,
- GrDrawTarget* target,
- const PtArray& quads,
- int quadCnt,
- const PtArray& conics,
- int conicCnt,
- const IntArray& qSubdivs,
- const FloatArray& cWeights,
- GrDrawTarget::AutoReleaseGeometry* arg,
- SkRect* devBounds) {
- GrDrawState* drawState = target->drawState();
-
+bool GrAAHairLinePathRenderer::createBezierGeom(GrDrawTarget* target,
+ GrDrawState* drawState,
+ GrDrawTarget::AutoReleaseGeometry* arg,
+ SkRect* devBounds,
+ const SkPath& path,
+ const PtArray& quads,
+ int quadCnt,
+ const PtArray& conics,
+ int conicCnt,
+ const IntArray& qSubdivs,
+ const FloatArray& cWeights) {
const SkMatrix& viewM = drawState->getViewMatrix();
int vertCnt = kQuadNumVertices * quadCnt + kQuadNumVertices * conicCnt;
int vAttribCnt = SK_ARRAY_COUNT(gHairlineBezierAttribs);
- target->drawState()->setVertexAttribs<gHairlineBezierAttribs>(vAttribCnt, sizeof(BezierVertex));
+ drawState->setVertexAttribs<gHairlineBezierAttribs>(vAttribCnt, sizeof(BezierVertex));
- if (!arg->set(target, vertCnt, 0)) {
+ if (!arg->set(target, vertCnt, drawState->getVertexStride(), 0)) {
return false;
}
@@ -757,16 +754,17 @@
return true;
}
-bool GrAAHairLinePathRenderer::canDrawPath(const SkPath& path,
+bool GrAAHairLinePathRenderer::canDrawPath(const GrDrawTarget* target,
+ const GrDrawState* drawState,
+ const SkPath& path,
const SkStrokeRec& stroke,
- const GrDrawTarget* target,
bool antiAlias) const {
if (!antiAlias) {
return false;
}
if (!IsStrokeHairlineOrEquivalent(stroke,
- target->getDrawState().getViewMatrix(),
+ drawState->getViewMatrix(),
NULL)) {
return false;
}
@@ -815,19 +813,16 @@
return true;
}
-bool GrAAHairLinePathRenderer::onDrawPath(const SkPath& path,
+bool GrAAHairLinePathRenderer::onDrawPath(GrDrawTarget* target,
+ GrDrawState* drawState,
+ const SkPath& path,
const SkStrokeRec& stroke,
- GrDrawTarget* target,
bool antiAlias) {
- GrDrawState* drawState = target->drawState();
-
SkScalar hairlineCoverage;
- if (IsStrokeHairlineOrEquivalent(stroke,
- target->getDrawState().getViewMatrix(),
+ if (IsStrokeHairlineOrEquivalent(stroke, drawState->getViewMatrix(),
&hairlineCoverage)) {
- uint8_t newCoverage = SkScalarRoundToInt(hairlineCoverage *
- target->getDrawState().getCoverage());
- target->drawState()->setCoverage(newCoverage);
+ uint8_t newCoverage = SkScalarRoundToInt(hairlineCoverage * drawState->getCoverage());
+ drawState->setCoverage(newCoverage);
}
SkIRect devClipBounds;
@@ -851,25 +846,22 @@
GrDrawTarget::AutoReleaseGeometry arg;
SkRect devBounds;
- if (!this->createLineGeom(path,
- target,
- lines,
- lineCnt,
+ if (!this->createLineGeom(target,
+ drawState,
&arg,
- &devBounds)) {
+ &devBounds,
+ path,
+ lines,
+ lineCnt)) {
return false;
}
- GrDrawTarget::AutoStateRestore asr;
-
// createLineGeom transforms the geometry to device space when the matrix does not have
// perspective.
- if (target->getDrawState().getViewMatrix().hasPerspective()) {
- asr.set(target, GrDrawTarget::kPreserve_ASRInit);
- } else if (!asr.setIdentity(target, GrDrawTarget::kPreserve_ASRInit)) {
+ GrDrawState::AutoViewMatrixRestore avmr;
+ if (!drawState->getViewMatrix().hasPerspective() && !avmr.setIdentity(drawState)) {
return false;
}
- GrDrawState* drawState = target->drawState();
// Check devBounds
SkASSERT(check_bounds<LineVertex>(drawState, devBounds, arg.vertices(),
@@ -882,7 +874,8 @@
int lines = 0;
while (lines < lineCnt) {
int n = SkTMin(lineCnt - lines, kLineSegsNumInIdxBuffer);
- target->drawIndexed(kTriangles_GrPrimitiveType,
+ target->drawIndexed(drawState,
+ kTriangles_GrPrimitiveType,
kLineSegNumVertices*lines, // startV
0, // startI
kLineSegNumVertices*n, // vCount
@@ -898,29 +891,27 @@
GrDrawTarget::AutoReleaseGeometry arg;
SkRect devBounds;
- if (!this->createBezierGeom(path,
- target,
+ if (!this->createBezierGeom(target,
+ drawState,
+ &arg,
+ &devBounds,
+ path,
quads,
quadCnt,
conics,
conicCnt,
qSubdivs,
- cWeights,
- &arg,
- &devBounds)) {
+ cWeights)) {
return false;
}
- GrDrawTarget::AutoStateRestore asr;
-
// createGeom transforms the geometry to device space when the matrix does not have
// perspective.
- if (target->getDrawState().getViewMatrix().hasPerspective()) {
- asr.set(target, GrDrawTarget::kPreserve_ASRInit);
- } else if (!asr.setIdentity(target, GrDrawTarget::kPreserve_ASRInit)) {
+ GrDrawState::AutoViewMatrixRestore avmr;
+ if (!drawState->getViewMatrix().hasPerspective() && !avmr.setIdentity(drawState)) {
return false;
}
- GrDrawState* drawState = target->drawState();
+
// Check devBounds
SkASSERT(check_bounds<BezierVertex>(drawState, devBounds, arg.vertices(),
@@ -936,7 +927,8 @@
int quads = 0;
while (quads < quadCnt) {
int n = SkTMin(quadCnt - quads, kQuadsNumInIdxBuffer);
- target->drawIndexed(kTriangles_GrPrimitiveType,
+ target->drawIndexed(drawState,
+ kTriangles_GrPrimitiveType,
kQuadNumVertices*quads, // startV
0, // startI
kQuadNumVertices*n, // vCount
@@ -955,7 +947,8 @@
int conics = 0;
while (conics < conicCnt) {
int n = SkTMin(conicCnt - conics, kQuadsNumInIdxBuffer);
- target->drawIndexed(kTriangles_GrPrimitiveType,
+ target->drawIndexed(drawState,
+ kTriangles_GrPrimitiveType,
kQuadNumVertices*(quadCnt + conics), // startV
0, // startI
kQuadNumVertices*n, // vCount
diff --git a/src/gpu/GrAAHairLinePathRenderer.h b/src/gpu/GrAAHairLinePathRenderer.h
index 22cc876e..c5f64f5 100644
--- a/src/gpu/GrAAHairLinePathRenderer.h
+++ b/src/gpu/GrAAHairLinePathRenderer.h
@@ -17,9 +17,10 @@
static GrPathRenderer* Create(GrContext* context);
- virtual bool canDrawPath(const SkPath& path,
- const SkStrokeRec& stroke,
- const GrDrawTarget* target,
+ virtual bool canDrawPath(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&,
bool antiAlias) const SK_OVERRIDE;
typedef SkTArray<SkPoint, true> PtArray;
@@ -27,9 +28,10 @@
typedef SkTArray<float, true> FloatArray;
protected:
- virtual bool onDrawPath(const SkPath& path,
- const SkStrokeRec& stroke,
- GrDrawTarget* target,
+ virtual bool onDrawPath(GrDrawTarget*,
+ GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&,
bool antiAlias) SK_OVERRIDE;
private:
@@ -37,23 +39,25 @@
const GrIndexBuffer* fLinesIndexBuffer,
const GrIndexBuffer* fQuadsIndexBuffer);
- bool createLineGeom(const SkPath& path,
- GrDrawTarget* target,
- const PtArray& lines,
- int lineCnt,
+ bool createLineGeom(GrDrawTarget* target,
+ GrDrawState*,
GrDrawTarget::AutoReleaseGeometry* arg,
- SkRect* devBounds);
+ SkRect* devBounds,
+ const SkPath& path,
+ const PtArray& lines,
+ int lineCnt);
- bool createBezierGeom(const SkPath& path,
- GrDrawTarget* target,
+ bool createBezierGeom(GrDrawTarget* target,
+ GrDrawState*,
+ GrDrawTarget::AutoReleaseGeometry* arg,
+ SkRect* devBounds,
+ const SkPath& path,
const PtArray& quads,
int quadCnt,
const PtArray& conics,
int conicCnt,
const IntArray& qSubdivs,
- const FloatArray& cWeights,
- GrDrawTarget::AutoReleaseGeometry* arg,
- SkRect* devBounds);
+ const FloatArray& cWeights);
const GrIndexBuffer* fLinesIndexBuffer;
const GrIndexBuffer* fQuadsIndexBuffer;
diff --git a/src/gpu/GrAARectRenderer.cpp b/src/gpu/GrAARectRenderer.cpp
index f748895..edb59d0 100644
--- a/src/gpu/GrAARectRenderer.cpp
+++ b/src/gpu/GrAARectRenderer.cpp
@@ -177,10 +177,10 @@
}
void GrAARectRenderer::geometryFillAARect(GrDrawTarget* target,
+ GrDrawState* drawState,
const SkRect& rect,
const SkMatrix& combinedMatrix,
const SkRect& devRect) {
- GrDrawState* drawState = target->drawState();
GrDrawState::AutoRestoreEffects are(drawState);
GrColor color = drawState->getColor();
@@ -190,7 +190,7 @@
drawState->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
}
- GrDrawTarget::AutoReleaseGeometry geo(target, 8, 0);
+ GrDrawTarget::AutoReleaseGeometry geo(target, 8, drawState->getVertexStride(), 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return;
@@ -300,13 +300,16 @@
}
target->setIndexSourceToBuffer(indexBuffer);
- target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1,
+ target->drawIndexedInstances(drawState,
+ kTriangles_GrPrimitiveType,
+ 1,
kVertsPerAAFillRect,
kIndicesPerAAFillRect);
target->resetIndexSource();
}
void GrAARectRenderer::strokeAARect(GrDrawTarget* target,
+ GrDrawState* drawState,
const SkRect& rect,
const SkMatrix& combinedMatrix,
const SkRect& devRect,
@@ -353,7 +356,7 @@
}
if (spare <= 0 && miterStroke) {
- this->fillAARect(target, devOutside, SkMatrix::I(), devOutside);
+ this->fillAARect(target, drawState, devOutside, SkMatrix::I(), devOutside);
return;
}
@@ -370,17 +373,17 @@
devOutsideAssist.outset(0, ry);
}
- this->geometryStrokeAARect(target, devOutside, devOutsideAssist, devInside, miterStroke);
+ this->geometryStrokeAARect(target, drawState, devOutside, devOutsideAssist, devInside,
+ miterStroke);
}
void GrAARectRenderer::geometryStrokeAARect(GrDrawTarget* target,
+ GrDrawState* drawState,
const SkRect& devOutside,
const SkRect& devOutsideAssist,
const SkRect& devInside,
bool miterStroke) {
- GrDrawState* drawState = target->drawState();
GrDrawState::AutoRestoreEffects are(drawState);
-
CoverageAttribType covAttribType = set_rect_attribs(drawState);
GrColor color = drawState->getColor();
@@ -392,7 +395,7 @@
int outerVertexNum = miterStroke ? 4 : 8;
int totalVertexNum = (outerVertexNum + innerVertexNum) * 2;
- GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, 0);
+ GrDrawTarget::AutoReleaseGeometry geo(target, totalVertexNum, drawState->getVertexStride(), 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return;
@@ -499,12 +502,16 @@
}
target->setIndexSourceToBuffer(indexBuffer);
- target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1,
- totalVertexNum, aa_stroke_rect_index_count(miterStroke));
+ target->drawIndexedInstances(drawState,
+ kTriangles_GrPrimitiveType,
+ 1,
+ totalVertexNum,
+ aa_stroke_rect_index_count(miterStroke));
target->resetIndexSource();
}
void GrAARectRenderer::fillAANestedRects(GrDrawTarget* target,
+ GrDrawState* drawState,
const SkRect rects[2],
const SkMatrix& combinedMatrix) {
SkASSERT(combinedMatrix.rectStaysRect());
@@ -516,9 +523,9 @@
combinedMatrix.mapPoints((SkPoint*)&devInside, (const SkPoint*)&rects[1], 2);
if (devInside.isEmpty()) {
- this->fillAARect(target, devOutside, SkMatrix::I(), devOutside);
+ this->fillAARect(target, drawState, devOutside, SkMatrix::I(), devOutside);
return;
}
- this->geometryStrokeAARect(target, devOutside, devOutsideAssist, devInside, true);
+ this->geometryStrokeAARect(target, drawState, devOutside, devOutsideAssist, devInside, true);
}
diff --git a/src/gpu/GrAARectRenderer.h b/src/gpu/GrAARectRenderer.h
index e39b87a..a8ba085 100644
--- a/src/gpu/GrAARectRenderer.h
+++ b/src/gpu/GrAARectRenderer.h
@@ -14,6 +14,7 @@
#include "SkStrokeRec.h"
class GrGpu;
+class GrDrawState;
class GrDrawTarget;
class GrIndexBuffer;
@@ -41,32 +42,37 @@
// between them by passing in stroke (==NULL means fill).
void fillAARect(GrDrawTarget* target,
+ GrDrawState* ds,
const SkRect& rect,
const SkMatrix& combinedMatrix,
const SkRect& devRect) {
- this->geometryFillAARect(target, rect, combinedMatrix, devRect);
+ this->geometryFillAARect(target, ds, rect, combinedMatrix, devRect);
}
- void strokeAARect(GrDrawTarget* target,
+ void strokeAARect(GrDrawTarget*,
+ GrDrawState*,
const SkRect& rect,
const SkMatrix& combinedMatrix,
const SkRect& devRect,
const SkStrokeRec& stroke);
// First rect is outer; second rect is inner
- void fillAANestedRects(GrDrawTarget* target,
+ void fillAANestedRects(GrDrawTarget*,
+ GrDrawState*,
const SkRect rects[2],
const SkMatrix& combinedMatrix);
private:
GrIndexBuffer* aaStrokeRectIndexBuffer(bool miterStroke);
- void geometryFillAARect(GrDrawTarget* target,
+ void geometryFillAARect(GrDrawTarget*,
+ GrDrawState*,
const SkRect& rect,
const SkMatrix& combinedMatrix,
const SkRect& devRect);
- void geometryStrokeAARect(GrDrawTarget* target,
+ void geometryStrokeAARect(GrDrawTarget*,
+ GrDrawState*,
const SkRect& devOutside,
const SkRect& devOutsideAssist,
const SkRect& devInside,
diff --git a/src/gpu/GrBitmapTextContext.cpp b/src/gpu/GrBitmapTextContext.cpp
index 50fe9ca..f22b760 100755
--- a/src/gpu/GrBitmapTextContext.cpp
+++ b/src/gpu/GrBitmapTextContext.cpp
@@ -80,10 +80,6 @@
return SkNEW_ARGS(GrBitmapTextContext, (context, props));
}
-GrBitmapTextContext::~GrBitmapTextContext() {
- this->finish();
-}
-
bool GrBitmapTextContext::canDraw(const SkPaint& paint) {
return !SkDraw::ShouldDrawTextAsPaths(paint, fContext->getMatrix());
}
@@ -102,8 +98,8 @@
}
void GrBitmapTextContext::onDrawText(const GrPaint& paint, const SkPaint& skPaint,
- const char text[], size_t byteLength,
- SkScalar x, SkScalar y) {
+ const char text[], size_t byteLength,
+ SkScalar x, SkScalar y) {
SkASSERT(byteLength == 0 || text != NULL);
// nothing to draw
@@ -196,9 +192,9 @@
}
void GrBitmapTextContext::onDrawPosText(const GrPaint& paint, const SkPaint& skPaint,
- const char text[], size_t byteLength,
- const SkScalar pos[], int scalarsPerPosition,
- const SkPoint& offset) {
+ const char text[], size_t byteLength,
+ const SkScalar pos[], int scalarsPerPosition,
+ const SkPoint& offset) {
SkASSERT(byteLength == 0 || text != NULL);
SkASSERT(1 == scalarsPerPosition || 2 == scalarsPerPosition);
@@ -347,24 +343,41 @@
this->finish();
}
-static void* alloc_vertices(GrDrawTarget* drawTarget, int numVertices, GrMaskFormat maskFormat) {
+static size_t get_vertex_stride(GrMaskFormat maskFormat) {
+ switch (maskFormat) {
+ case kA8_GrMaskFormat:
+ return kGrayTextVASize;
+ case kARGB_GrMaskFormat:
+ return kColorTextVASize;
+ default:
+ return kLCDTextVASize;
+ }
+}
+
+static void set_vertex_attributes(GrDrawState* drawState, GrMaskFormat maskFormat) {
+ if (kA8_GrMaskFormat == maskFormat) {
+ drawState->setVertexAttribs<gGrayVertexAttribs>(
+ SK_ARRAY_COUNT(gGrayVertexAttribs), kGrayTextVASize);
+ } else if (kARGB_GrMaskFormat == maskFormat) {
+ GrDefaultGeoProcFactory::SetAttribs(drawState,
+ GrDefaultGeoProcFactory::kLocalCoord_GPType);
+ } else {
+ drawState->setVertexAttribs<gLCDVertexAttribs>(
+ SK_ARRAY_COUNT(gLCDVertexAttribs), kLCDTextVASize);
+ }
+}
+
+static void* alloc_vertices(GrDrawTarget* drawTarget,
+ int numVertices,
+ GrMaskFormat maskFormat) {
if (numVertices <= 0) {
return NULL;
}
// set up attributes
- if (kA8_GrMaskFormat == maskFormat) {
- drawTarget->drawState()->setVertexAttribs<gGrayVertexAttribs>(
- SK_ARRAY_COUNT(gGrayVertexAttribs), kGrayTextVASize);
- } else if (kARGB_GrMaskFormat == maskFormat) {
- GrDefaultGeoProcFactory::SetAttribs(drawTarget->drawState(),
- GrDefaultGeoProcFactory::kLocalCoord_GPType);
- } else {
- drawTarget->drawState()->setVertexAttribs<gLCDVertexAttribs>(
- SK_ARRAY_COUNT(gLCDVertexAttribs), kLCDTextVASize);
- }
void* vertices = NULL;
bool success = drawTarget->reserveVertexAndIndexSpace(numVertices,
+ get_vertex_stride(maskFormat),
0,
&vertices,
NULL);
@@ -498,18 +511,7 @@
fVertexBounds.joinNonEmptyArg(r);
- size_t vertSize;
- switch (fCurrMaskFormat) {
- case kA8_GrMaskFormat:
- vertSize = kGrayTextVASize;
- break;
- case kARGB_GrMaskFormat:
- vertSize = kColorTextVASize;
- default:
- vertSize = kLCDTextVASize;
- }
-
- SkASSERT(vertSize == fDrawTarget->getDrawState().getVertexStride());
+ size_t vertSize = get_vertex_stride(fCurrMaskFormat);
SkPoint* positions = reinterpret_cast<SkPoint*>(
reinterpret_cast<intptr_t>(fVertices) + vertSize * fCurrVertex);
@@ -524,9 +526,6 @@
SkFixedToFloat(texture->texturePriv().normalizeFixedY(ty + height)),
vertSize);
if (kA8_GrMaskFormat == fCurrMaskFormat) {
- if (0xFF == GrColorUnpackA(fPaint.getColor())) {
- fDrawTarget->drawState()->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
- }
// color comes after position.
GrColor* colors = reinterpret_cast<GrColor*>(positions + 1);
for (int i = 0; i < 4; ++i) {
@@ -549,9 +548,10 @@
return;
}
- GrDrawState* drawState = fDrawTarget->drawState();
- GrDrawState::AutoRestoreEffects are(drawState);
- drawState->setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget());
+ GrDrawState drawState;
+ drawState.setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget());
+
+ set_vertex_attributes(&drawState, fCurrMaskFormat);
if (fCurrVertex > 0) {
// setup our sampler state for our text texture/atlas
@@ -561,11 +561,11 @@
// This effect could be stored with one of the cache objects (atlas?)
if (kARGB_GrMaskFormat == fCurrMaskFormat) {
- drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(true))->unref();
+ drawState.setGeometryProcessor(GrDefaultGeoProcFactory::Create(true))->unref();
GrFragmentProcessor* fragProcessor = GrSimpleTextureEffect::Create(fCurrTexture,
SkMatrix::I(),
params);
- drawState->addColorProcessor(fragProcessor)->unref();
+ drawState.addColorProcessor(fragProcessor)->unref();
} else {
uint32_t textureUniqueID = fCurrTexture->getUniqueID();
if (textureUniqueID != fEffectTextureUniqueID) {
@@ -574,16 +574,16 @@
fEffectTextureUniqueID = textureUniqueID;
}
- drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
+ drawState.setGeometryProcessor(fCachedGeometryProcessor.get());
}
SkASSERT(fStrike);
switch (fCurrMaskFormat) {
// Color bitmap text
case kARGB_GrMaskFormat:
- SkASSERT(!drawState->hasColorVertexAttribute());
- drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
- drawState->setAlpha(fSkPaint.getAlpha());
+ SkASSERT(!drawState.hasColorVertexAttribute());
+ drawState.setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
+ drawState.setAlpha(fSkPaint.getAlpha());
break;
// LCD text
case kA565_GrMaskFormat: {
@@ -592,34 +592,39 @@
fPaint.numColorStages()) {
SkDebugf("LCD Text will not draw correctly.\n");
}
- SkASSERT(!drawState->hasColorVertexAttribute());
+ SkASSERT(!drawState.hasColorVertexAttribute());
// We don't use the GrPaint's color in this case because it's been premultiplied by
// alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by
// the mask texture color. The end result is that we get
// mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor
int a = SkColorGetA(fSkPaint.getColor());
// paintAlpha
- drawState->setColor(SkColorSetARGB(a, a, a, a));
+ drawState.setColor(SkColorSetARGB(a, a, a, a));
// paintColor
- drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor()));
- drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
+ drawState.setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor()));
+ drawState.setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
break;
}
// Grayscale/BW text
case kA8_GrMaskFormat:
+ drawState.setHint(GrDrawState::kVertexColorsAreOpaque_Hint,
+ 0xFF == GrColorUnpackA(fPaint.getColor()));
// set back to normal in case we took LCD path previously.
- drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
+ drawState.setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
// We're using per-vertex color.
- SkASSERT(drawState->hasColorVertexAttribute());
+ SkASSERT(drawState.hasColorVertexAttribute());
break;
default:
SkFAIL("Unexpected mask format.");
}
int nGlyphs = fCurrVertex / kVerticesPerGlyph;
fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
- fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
+ fDrawTarget->drawIndexedInstances(&drawState,
+ kTriangles_GrPrimitiveType,
nGlyphs,
- kVerticesPerGlyph, kIndicesPerGlyph, &fVertexBounds);
+ kVerticesPerGlyph,
+ kIndicesPerGlyph,
+ &fVertexBounds);
fDrawTarget->resetVertexSource();
fVertices = NULL;
diff --git a/src/gpu/GrBitmapTextContext.h b/src/gpu/GrBitmapTextContext.h
index d98a9f4..a3d0eb2 100644
--- a/src/gpu/GrBitmapTextContext.h
+++ b/src/gpu/GrBitmapTextContext.h
@@ -20,7 +20,7 @@
public:
static GrBitmapTextContext* Create(GrContext*, const SkDeviceProperties&);
- virtual ~GrBitmapTextContext();
+ virtual ~GrBitmapTextContext() {}
private:
GrTextStrike* fStrike;
@@ -50,7 +50,6 @@
void appendGlyph(GrGlyph::PackedID, SkFixed left, SkFixed top, GrFontScaler*);
void flush(); // automatically called by destructor
void finish();
-
};
#endif
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index e04d444..f86aa9d 100644
--- a/src/gpu/GrClipMaskManager.cpp
+++ b/src/gpu/GrClipMaskManager.cpp
@@ -1,4 +1,3 @@
-
/*
* Copyright 2012 Google Inc.
*
@@ -24,17 +23,15 @@
#include "effects/GrRRectEffect.h"
#define GR_AA_CLIP 1
-
typedef SkClipStack::Element Element;
////////////////////////////////////////////////////////////////////////////////
namespace {
// set up the draw state to enable the aa clipping mask. Besides setting up the
// stage matrix this also alters the vertex layout
-void setup_drawstate_aaclip(GrDrawTarget* gpu,
- GrTexture* result,
- const SkIRect &devBound) {
- GrDrawState* drawState = gpu->drawState();
+void setup_drawstate_aaclip(const SkIRect &devBound,
+ GrDrawState* drawState,
+ GrTexture* result) {
SkASSERT(drawState);
SkMatrix mat;
@@ -58,7 +55,8 @@
}
bool path_needs_SW_renderer(GrContext* context,
- GrDrawTarget* gpu,
+ const GrDrawTarget* gpu,
+ const GrDrawState* drawState,
const SkPath& origPath,
const SkStrokeRec& stroke,
bool doAA) {
@@ -72,9 +70,8 @@
GrPathRendererChain::kColorAntiAlias_DrawType :
GrPathRendererChain::kColor_DrawType;
- return NULL == context->getPathRenderer(*path, stroke, gpu, false, type);
+ return NULL == context->getPathRenderer(gpu, drawState, *path, stroke, false, type);
}
-
}
/*
@@ -82,8 +79,8 @@
* will be used on any element. If so, it returns true to indicate that the
* entire clip should be rendered in SW and then uploaded en masse to the gpu.
*/
-bool GrClipMaskManager::useSWOnlyPath(const GrReducedClip::ElementList& elements) {
-
+bool GrClipMaskManager::useSWOnlyPath(const GrDrawState* drawState,
+ const GrReducedClip::ElementList& elements) {
// TODO: generalize this function so that when
// a clip gets complex enough it can just be done in SW regardless
// of whether it would invoke the GrSoftwarePathRenderer.
@@ -96,7 +93,7 @@
if (Element::kRect_Type != element->getType()) {
SkPath path;
element->asPath(&path);
- if (path_needs_SW_renderer(this->getContext(), fClipTarget, path, stroke,
+ if (path_needs_SW_renderer(this->getContext(), fClipTarget, drawState, path, stroke,
element->isAA())) {
return true;
}
@@ -105,12 +102,11 @@
return false;
}
-bool GrClipMaskManager::installClipEffects(const GrReducedClip::ElementList& elements,
+bool GrClipMaskManager::installClipEffects(GrDrawState* drawState,
GrDrawState::AutoRestoreEffects* are,
+ const GrReducedClip::ElementList& elements,
const SkVector& clipToRTOffset,
const SkRect* drawBounds) {
-
- GrDrawState* drawState = fClipTarget->drawState();
SkRect boundsInClipSpace;
if (drawBounds) {
boundsInClipSpace = *drawBounds;
@@ -120,10 +116,7 @@
are->set(drawState);
GrRenderTarget* rt = drawState->getRenderTarget();
GrReducedClip::ElementList::Iter iter(elements);
-
- bool setARE = false;
bool failed = false;
-
while (iter.get()) {
SkRegion::Op op = iter.get()->getOp();
bool invert;
@@ -187,11 +180,7 @@
break;
}
if (fp) {
- if (!setARE) {
- are->set(fClipTarget->drawState());
- setARE = true;
- }
- fClipTarget->drawState()->addCoverageProcessor(fp);
+ drawState->addCoverageProcessor(fp);
} else {
failed = true;
break;
@@ -203,18 +192,18 @@
if (failed) {
are->set(NULL);
}
-
return !failed;
}
////////////////////////////////////////////////////////////////////////////////
// sort out what kind of clip mask needs to be created: alpha, stencil,
// scissor, or entirely software
-bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
- const SkRect* devBounds,
+bool GrClipMaskManager::setupClipping(GrDrawState* drawState,
GrDrawState::AutoRestoreEffects* are,
GrDrawState::AutoRestoreStencil* ars,
- ScissorState* scissorState) {
+ ScissorState* scissorState,
+ const GrClipData* clipDataIn,
+ const SkRect* devBounds) {
fCurrClipMaskType = kNone_ClipMaskType;
if (kRespectClip_StencilClipMode == fClipMode) {
fClipMode = kIgnoreClip_StencilClipMode;
@@ -225,10 +214,8 @@
GrReducedClip::InitialState initialState;
SkIRect clipSpaceIBounds;
bool requiresAA;
+ GrRenderTarget* rt = drawState->getRenderTarget();
- GrDrawState* drawState = fClipTarget->drawState();
-
- const GrRenderTarget* rt = drawState->getRenderTarget();
// GrDrawTarget should have filtered this for us
SkASSERT(rt);
@@ -253,7 +240,7 @@
}
if (ignoreClip) {
- this->setDrawStateStencil(ars);
+ this->setDrawStateStencil(drawState, ars);
return true;
}
@@ -269,14 +256,15 @@
SkVector clipToRTOffset = { SkIntToScalar(-clipDataIn->fOrigin.fX),
SkIntToScalar(-clipDataIn->fOrigin.fY) };
if (elements.isEmpty() ||
- (requiresAA && this->installClipEffects(elements, are, clipToRTOffset, devBounds))) {
+ (requiresAA && this->installClipEffects(drawState, are, elements, clipToRTOffset,
+ devBounds))) {
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(-clipDataIn->fOrigin);
if (NULL == devBounds ||
!SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
scissorState->set(scissorSpaceIBounds);
}
- this->setDrawStateStencil(ars);
+ this->setDrawStateStencil(drawState, ars);
return true;
}
}
@@ -286,7 +274,7 @@
if (0 == rt->numSamples() && requiresAA) {
GrTexture* result = NULL;
- if (this->useSWOnlyPath(elements)) {
+ if (this->useSWOnlyPath(drawState, elements)) {
// The clip geometry is complex enough that it will be more efficient to create it
// entirely in software
result = this->createSoftwareClipMask(genID,
@@ -305,9 +293,8 @@
// clipSpace bounds. We determine the mask's position WRT to the render target here.
SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
rtSpaceMaskBounds.offset(-clipDataIn->fOrigin);
- are->set(fClipTarget->drawState());
- setup_drawstate_aaclip(fClipTarget, result, rtSpaceMaskBounds);
- this->setDrawStateStencil(ars);
+ setup_drawstate_aaclip(rtSpaceMaskBounds, drawState, result);
+ this->setDrawStateStencil(drawState, ars);
return true;
}
// if alpha clip mask creation fails fall through to the non-AA code paths
@@ -323,7 +310,8 @@
// use the stencil clip if we can't represent the clip as a rectangle.
SkIPoint clipSpaceToStencilSpaceOffset = -clipDataIn->fOrigin;
- this->createStencilClipMask(genID,
+ this->createStencilClipMask(rt,
+ genID,
initialState,
elements,
clipSpaceIBounds,
@@ -335,27 +323,15 @@
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
scissorState->set(scissorSpaceIBounds);
- this->setDrawStateStencil(ars);
+ this->setDrawStateStencil(drawState, ars);
return true;
}
-#define VISUALIZE_COMPLEX_CLIP 0
-
-#if VISUALIZE_COMPLEX_CLIP
- #include "SkRandom.h"
- SkRandom gRandom;
- #define SET_RANDOM_COLOR drawState->setColor(0xff000000 | gRandom.nextU());
-#else
- #define SET_RANDOM_COLOR
-#endif
-
namespace {
-
////////////////////////////////////////////////////////////////////////////////
// set up the OpenGL blend function to perform the specified
// boolean operation for alpha clip mask creation
-void setup_boolean_blendcoeffs(GrDrawState* drawState, SkRegion::Op op) {
-
+void setup_boolean_blendcoeffs(SkRegion::Op op, GrDrawState* drawState) {
switch (op) {
case SkRegion::kReplace_Op:
drawState->setBlendFunc(kOne_GrBlendCoeff, kZero_GrBlendCoeff);
@@ -380,14 +356,14 @@
break;
}
}
-
}
////////////////////////////////////////////////////////////////////////////////
-bool GrClipMaskManager::drawElement(GrTexture* target,
+bool GrClipMaskManager::drawElement(GrDrawState* drawState,
+ GrTexture* target,
const SkClipStack::Element* element,
GrPathRenderer* pr) {
- GrDrawState* drawState = fClipTarget->drawState();
+ GrDrawTarget::AutoGeometryPush agp(fClipTarget);
drawState->setRenderTarget(target->asRenderTarget());
@@ -401,11 +377,12 @@
// the entire mask bounds and writes 0 outside the rect.
if (element->isAA()) {
this->getContext()->getAARectRenderer()->fillAARect(fClipTarget,
+ drawState,
element->getRect(),
SkMatrix::I(),
element->getRect());
} else {
- fClipTarget->drawSimpleRect(element->getRect());
+ fClipTarget->drawSimpleRect(drawState, element->getRect());
}
return true;
default: {
@@ -420,22 +397,24 @@
GrPathRendererChain::DrawType type;
type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_DrawType :
GrPathRendererChain::kColor_DrawType;
- pr = this->getContext()->getPathRenderer(path, stroke, fClipTarget, false, type);
+ pr = this->getContext()->getPathRenderer(fClipTarget, drawState, path, stroke,
+ false, type);
}
if (NULL == pr) {
return false;
}
- pr->drawPath(path, stroke, fClipTarget, element->isAA());
+
+ pr->drawPath(fClipTarget, drawState, path, stroke, element->isAA());
break;
}
}
return true;
}
-bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target,
- const SkClipStack::Element* element,
- GrPathRenderer** pr) {
- GrDrawState* drawState = fClipTarget->drawState();
+bool GrClipMaskManager::canStencilAndDrawElement(GrDrawState* drawState,
+ GrTexture* target,
+ GrPathRenderer** pr,
+ const SkClipStack::Element* element) {
drawState->setRenderTarget(target->asRenderTarget());
if (Element::kRect_Type == element->getType()) {
@@ -452,24 +431,23 @@
GrPathRendererChain::DrawType type = element->isAA() ?
GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
GrPathRendererChain::kStencilAndColor_DrawType;
- *pr = this->getContext()->getPathRenderer(path, stroke, fClipTarget, false, type);
+ *pr = this->getContext()->getPathRenderer(fClipTarget, drawState, path, stroke, false,
+ type);
return SkToBool(*pr);
}
}
-void GrClipMaskManager::mergeMask(GrTexture* dstMask,
+void GrClipMaskManager::mergeMask(GrDrawState* drawState,
+ GrTexture* dstMask,
GrTexture* srcMask,
SkRegion::Op op,
const SkIRect& dstBound,
const SkIRect& srcBound) {
- GrDrawState::AutoViewMatrixRestore avmr;
- GrDrawState* drawState = fClipTarget->drawState();
- SkAssertResult(avmr.setIdentity(drawState));
- GrDrawState::AutoRestoreEffects are(drawState);
+ SkAssertResult(drawState->setIdentityViewMatrix());
drawState->setRenderTarget(dstMask->asRenderTarget());
- setup_boolean_blendcoeffs(drawState, op);
+ setup_boolean_blendcoeffs(op, drawState);
SkMatrix sampleM;
sampleM.setIDiv(srcMask->width(), srcMask->height());
@@ -480,7 +458,7 @@
GrTextureDomain::MakeTexelDomain(srcMask, srcBound),
GrTextureDomain::kDecal_Mode,
GrTextureParams::kNone_FilterMode))->unref();
- fClipTarget->drawSimpleRect(SkRect::Make(dstBound));
+ fClipTarget->drawSimpleRect(drawState, SkRect::Make(dstBound));
}
GrTexture* GrClipMaskManager::createTempMask(int width, int height) {
@@ -563,13 +541,6 @@
// Set the matrix so that rendered clip elements are transformed to mask space from clip space.
SkMatrix translate;
translate.setTranslate(clipToMaskOffset);
- GrDrawTarget::AutoGeometryAndStatePush agasp(fClipTarget, GrDrawTarget::kReset_ASRInit,
- &translate);
-
- GrDrawState* drawState = fClipTarget->drawState();
-
- // We're drawing a coverage mask and want coverage to be run through the blend function.
- drawState->enableState(GrDrawState::kCoverageDrawing_StateBit);
// The scratch texture that we are drawing into can be substantially larger than the mask. Only
// clear the part that we care about.
@@ -583,18 +554,21 @@
// pass must not set values outside of this bounds or stencil values outside the rect won't be
// cleared.
GrDrawTarget::AutoClipRestore acr(fClipTarget, maskSpaceIBounds);
- drawState->enableState(GrDrawState::kClip_StateBit);
-
SkAutoTUnref<GrTexture> temp;
+
// walk through each clip element and perform its set op
for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get(); iter.next()) {
const Element* element = iter.get();
SkRegion::Op op = element->getOp();
bool invert = element->isInverseFilled();
-
if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) {
+ GrDrawState drawState(translate);
+ // We're drawing a coverage mask and want coverage to be run through the blend function.
+ drawState.enableState(GrDrawState::kCoverageDrawing_StateBit |
+ GrDrawState::kClip_StateBit);
+
GrPathRenderer* pr = NULL;
- bool useTemp = !this->canStencilAndDrawElement(result, element, &pr);
+ bool useTemp = !this->canStencilAndDrawElement(&drawState, result, &pr, element);
GrTexture* dst;
// This is the bounds of the clip element in the space of the alpha-mask. The temporary
// mask buffer can be substantially larger than the actually clip stack element. We
@@ -622,11 +596,10 @@
dst = temp;
// clear the temp target and set blend to replace
fClipTarget->clear(&maskSpaceElementIBounds,
- invert ? 0xffffffff : 0x00000000,
- true,
- dst->asRenderTarget());
- setup_boolean_blendcoeffs(drawState, SkRegion::kReplace_Op);
-
+ invert ? 0xffffffff : 0x00000000,
+ true,
+ dst->asRenderTarget());
+ setup_boolean_blendcoeffs(SkRegion::kReplace_Op, &drawState);
} else {
// draw directly into the result with the stencil set to make the pixels affected
// by the clip shape be non-zero.
@@ -638,13 +611,17 @@
0xffff,
0xffff,
0xffff);
- drawState->setStencil(kStencilInElement);
- setup_boolean_blendcoeffs(drawState, op);
+ drawState.setStencil(kStencilInElement);
+ setup_boolean_blendcoeffs(op, &drawState);
}
- drawState->setAlpha(invert ? 0x00 : 0xff);
+ drawState.setAlpha(invert ? 0x00 : 0xff);
- if (!this->drawElement(dst, element, pr)) {
+ // We have to backup the drawstate because the drawElement call may call into
+ // renderers which consume it.
+ GrDrawState backupDrawState(drawState);
+
+ if (!this->drawElement(&drawState, dst, element, pr)) {
fAACache.reset();
return NULL;
}
@@ -652,14 +629,15 @@
if (useTemp) {
// Now draw into the accumulator using the real operation and the temp buffer as a
// texture
- this->mergeMask(result,
+ this->mergeMask(&backupDrawState,
+ result,
temp,
op,
maskSpaceIBounds,
maskSpaceElementIBounds);
} else {
// Draw to the exterior pixels (those with a zero stencil value).
- drawState->setAlpha(invert ? 0xff : 0x00);
+ backupDrawState.setAlpha(invert ? 0xff : 0x00);
GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement,
kZero_StencilOp,
kZero_StencilOp,
@@ -667,15 +645,18 @@
0xffff,
0x0000,
0xffff);
- drawState->setStencil(kDrawOutsideElement);
- fClipTarget->drawSimpleRect(clipSpaceIBounds);
- drawState->disableStencil();
+ backupDrawState.setStencil(kDrawOutsideElement);
+ fClipTarget->drawSimpleRect(&backupDrawState, clipSpaceIBounds);
}
} else {
+ GrDrawState drawState(translate);
+ drawState.enableState(GrDrawState::kCoverageDrawing_StateBit |
+ GrDrawState::kClip_StateBit);
+
// all the remaining ops can just be directly draw into the accumulation buffer
- drawState->setAlpha(0xff);
- setup_boolean_blendcoeffs(drawState, op);
- this->drawElement(result, element);
+ drawState.setAlpha(0xff);
+ setup_boolean_blendcoeffs(op, &drawState);
+ this->drawElement(&drawState, result, element);
}
}
@@ -686,18 +667,13 @@
////////////////////////////////////////////////////////////////////////////////
// Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
// (as opposed to canvas) coordinates
-bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID,
+bool GrClipMaskManager::createStencilClipMask(GrRenderTarget* rt,
+ int32_t elementsGenID,
GrReducedClip::InitialState initialState,
const GrReducedClip::ElementList& elements,
const SkIRect& clipSpaceIBounds,
const SkIPoint& clipSpaceToStencilOffset) {
-
SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
-
- GrDrawState* drawState = fClipTarget->drawState();
- SkASSERT(drawState->isClipState());
-
- GrRenderTarget* rt = drawState->getRenderTarget();
SkASSERT(rt);
// TODO: dynamically attach a SB when needed.
@@ -708,7 +684,6 @@
if (stencilBuffer->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset)) {
stencilBuffer->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset);
-
// Set the matrix so that rendered clip elements are transformed from clip to stencil space.
SkVector translate = {
SkIntToScalar(clipSpaceToStencilOffset.fX),
@@ -716,21 +691,11 @@
};
SkMatrix matrix;
matrix.setTranslate(translate);
- GrDrawTarget::AutoGeometryAndStatePush agasp(fClipTarget, GrDrawTarget::kReset_ASRInit,
- &matrix);
- drawState = fClipTarget->drawState();
-
- drawState->setRenderTarget(rt);
// We set the current clip to the bounds so that our recursive draws are scissored to them.
SkIRect stencilSpaceIBounds(clipSpaceIBounds);
stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
GrDrawTarget::AutoClipRestore acr(fClipTarget, stencilSpaceIBounds);
- drawState->enableState(GrDrawState::kClip_StateBit);
-
-#if !VISUALIZE_COMPLEX_CLIP
- drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
-#endif
int clipBit = stencilBuffer->bits();
SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers");
@@ -744,20 +709,26 @@
// with the existing clip.
for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
const Element* element = iter.get();
+
+ GrDrawState drawState(matrix);
+ drawState.setRenderTarget(rt);
+ drawState.enableState(GrDrawState::kClip_StateBit);
+ drawState.enableState(GrDrawState::kNoColorWrites_StateBit);
+
+ // if the target is MSAA then we want MSAA enabled when the clip is soft
+ if (rt->isMultisampled()) {
+ drawState.setState(GrDrawState::kHWAntialias_StateBit, element->isAA());
+ }
+
bool fillInverted = false;
// enabled at bottom of loop
fClipMode = kIgnoreClip_StencilClipMode;
- // if the target is MSAA then we want MSAA enabled when the clip is soft
- if (rt->isMultisampled()) {
- drawState->setState(GrDrawState::kHWAntialias_StateBit, element->isAA());
- }
// This will be used to determine whether the clip shape can be rendered into the
// stencil with arbitrary stencil settings.
GrPathRenderer::StencilSupport stencilSupport;
SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
-
SkRegion::Op op = element->getOp();
GrPathRenderer* pr = NULL;
@@ -771,9 +742,10 @@
if (fillInverted) {
clipPath.toggleInverseFillType();
}
- pr = this->getContext()->getPathRenderer(clipPath,
+ pr = this->getContext()->getPathRenderer(fClipTarget,
+ &drawState,
+ clipPath,
stroke,
- fClipTarget,
false,
GrPathRendererChain::kStencilOnly_DrawType,
&stencilSupport);
@@ -807,17 +779,17 @@
0xffff,
0x0000,
0xffff);
- SET_RANDOM_COLOR
if (Element::kRect_Type == element->getType()) {
- *drawState->stencil() = gDrawToStencil;
- fClipTarget->drawSimpleRect(element->getRect());
+ *drawState.stencil() = gDrawToStencil;
+ fClipTarget->drawSimpleRect(&drawState, element->getRect());
} else {
if (!clipPath.isEmpty()) {
+ GrDrawTarget::AutoGeometryPush agp(fClipTarget);
if (canRenderDirectToStencil) {
- *drawState->stencil() = gDrawToStencil;
- pr->drawPath(clipPath, stroke, fClipTarget, false);
+ *drawState.stencil() = gDrawToStencil;
+ pr->drawPath(fClipTarget, &drawState, clipPath, stroke, false);
} else {
- pr->stencilPath(clipPath, stroke, fClipTarget);
+ pr->stencilPath(fClipTarget, &drawState, clipPath, stroke);
}
}
}
@@ -827,20 +799,20 @@
// element directly or a bounding rect of the entire clip.
fClipMode = kModifyClip_StencilClipMode;
for (int p = 0; p < passes; ++p) {
- *drawState->stencil() = stencilSettings[p];
+ GrDrawState drawStateCopy(drawState);
+ *drawStateCopy.stencil() = stencilSettings[p];
+
if (canDrawDirectToClip) {
if (Element::kRect_Type == element->getType()) {
- SET_RANDOM_COLOR
- fClipTarget->drawSimpleRect(element->getRect());
+ fClipTarget->drawSimpleRect(&drawStateCopy, element->getRect());
} else {
- SET_RANDOM_COLOR
- pr->drawPath(clipPath, stroke, fClipTarget, false);
+ GrDrawTarget::AutoGeometryPush agp(fClipTarget);
+ pr->drawPath(fClipTarget, &drawStateCopy, clipPath, stroke, false);
}
} else {
- SET_RANDOM_COLOR
// The view matrix is setup to do clip space -> stencil space translation, so
// draw rect in clip space.
- fClipTarget->drawSimpleRect(SkRect::Make(clipSpaceIBounds));
+ fClipTarget->drawSimpleRect(&drawStateCopy, SkRect::Make(clipSpaceIBounds));
}
}
}
@@ -852,7 +824,6 @@
return true;
}
-
// mapping of clip-respecting stencil funcs to normal stencil funcs
// mapping depends on whether stencil-clipping is in effect.
static const GrStencilFunc
@@ -905,33 +876,32 @@
}
}
-void GrClipMaskManager::setDrawStateStencil(GrDrawState::AutoRestoreStencil* ars) {
+void GrClipMaskManager::setDrawStateStencil(GrDrawState* drawState,
+ GrDrawState::AutoRestoreStencil* ars) {
// We make two copies of the StencilSettings here (except in the early
// exit scenario. One copy from draw state to the stack var. Then another
// from the stack var to the gpu. We could make this class hold a ptr to
// GrGpu's fStencilSettings and eliminate the stack copy here.
- const GrDrawState& drawState = fClipTarget->getDrawState();
-
// use stencil for clipping if clipping is enabled and the clip
// has been written into the stencil.
-
GrStencilSettings settings;
+
// The GrGpu client may not be using the stencil buffer but we may need to
// enable it in order to respect a stencil clip.
- if (drawState.getStencil().isDisabled()) {
+ if (drawState->getStencil().isDisabled()) {
if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) {
settings = basic_apply_stencil_clip_settings();
} else {
return;
}
} else {
- settings = drawState.getStencil();
+ settings = drawState->getStencil();
}
// TODO: dynamically attach a stencil buffer
int stencilBits = 0;
- GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuffer();
+ GrStencilBuffer* stencilBuffer = drawState->getRenderTarget()->getStencilBuffer();
if (stencilBuffer) {
stencilBits = stencilBuffer->bits();
}
@@ -939,8 +909,8 @@
SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp());
SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSided());
this->adjustStencilParams(&settings, fClipMode, stencilBits);
- ars->set(fClipTarget->drawState());
- fClipTarget->drawState()->setStencil(settings);
+ ars->set(drawState);
+ drawState->setStencil(settings);
}
void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings,
@@ -1045,14 +1015,12 @@
SkMatrix matrix;
matrix.setTranslate(SkIntToScalar(-clipSpaceIBounds.fLeft),
SkIntToScalar(-clipSpaceIBounds.fTop));
+
helper.init(maskSpaceIBounds, &matrix, false);
-
helper.clear(GrReducedClip::kAllIn_InitialState == initialState ? 0xFF : 0x00);
-
SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
for (GrReducedClip::ElementList::Iter iter(elements.headIter()) ; iter.get(); iter.next()) {
-
const Element* element = iter.get();
SkRegion::Op op = element->getOp();
@@ -1066,12 +1034,10 @@
// invert the entire scene
helper.draw(temp, SkRegion::kXOR_Op, false, 0xFF);
}
-
SkPath clipPath;
element->asPath(&clipPath);
clipPath.toggleInverseFillType();
helper.draw(clipPath, stroke, SkRegion::kReplace_Op, element->isAA(), 0x00);
-
continue;
}
@@ -1108,14 +1074,11 @@
fAACache.setContext(clipTarget->getContext());
}
-void GrClipMaskManager::adjustPathStencilParams(GrStencilSettings* settings) {
- const GrDrawState& drawState = fClipTarget->getDrawState();
-
+void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBuffer,
+ GrStencilSettings* settings) {
// TODO: dynamically attach a stencil buffer
- int stencilBits = 0;
- GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuffer();
if (stencilBuffer) {
- stencilBits = stencilBuffer->bits();
+ int stencilBits = stencilBuffer->bits();
this->adjustStencilParams(settings, fClipMode, stencilBits);
}
}
diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h
index e2824ce..3aec257 100644
--- a/src/gpu/GrClipMaskManager.h
+++ b/src/gpu/GrClipMaskManager.h
@@ -4,7 +4,6 @@
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
-
#ifndef GrClipMaskManager_DEFINED
#define GrClipMaskManager_DEFINED
@@ -14,7 +13,6 @@
#include "GrReducedClip.h"
#include "GrStencil.h"
#include "GrTexture.h"
-
#include "SkClipStack.h"
#include "SkDeque.h"
#include "SkPath.h"
@@ -27,7 +25,6 @@
class GrPathRendererChain;
class GrTexture;
class SkPath;
-
/**
* The clip mask creator handles the generation of the clip mask. If anti
* aliasing is requested it will (in the future) generate a single channel
@@ -66,11 +63,12 @@
* the manager when it must install additional effects to implement the
* clip. devBounds is optional but can help optimize clipping.
*/
- bool setupClipping(const GrClipData* clipDataIn,
- const SkRect* devBounds,
+ bool setupClipping(GrDrawState*,
GrDrawState::AutoRestoreEffects*,
GrDrawState::AutoRestoreStencil*,
- ScissorState*);
+ ScissorState*,
+ const GrClipData* clipDataIn,
+ const SkRect* devBounds);
/**
* Purge resources to free up memory. TODO: This class shouldn't hold any long lived refs
@@ -81,6 +79,7 @@
bool isClipInStencil() const {
return kStencil_ClipMaskType == fCurrClipMaskType;
}
+
bool isClipInAlpha() const {
return kAlpha_ClipMaskType == fCurrClipMaskType;
}
@@ -91,7 +90,7 @@
void setClipTarget(GrClipTarget*);
- void adjustPathStencilParams(GrStencilSettings*);
+ void adjustPathStencilParams(const GrStencilBuffer*, GrStencilSettings*);
private:
/**
@@ -110,23 +109,27 @@
// Attempts to install a series of coverage effects to implement the clip. Return indicates
// whether the element list was successfully converted to effects.
- bool installClipEffects(const GrReducedClip::ElementList&,
+ bool installClipEffects(GrDrawState*,
GrDrawState::AutoRestoreEffects*,
+ const GrReducedClip::ElementList&,
const SkVector& clipOffset,
const SkRect* devBounds);
// Draws the clip into the stencil buffer
- bool createStencilClipMask(int32_t elementsGenID,
+ bool createStencilClipMask(GrRenderTarget*,
+ int32_t elementsGenID,
GrReducedClip::InitialState initialState,
const GrReducedClip::ElementList& elements,
const SkIRect& clipSpaceIBounds,
const SkIPoint& clipSpaceToStencilOffset);
+
// Creates an alpha mask of the clip. The mask is a rasterization of elements through the
// rect specified by clipSpaceIBounds.
GrTexture* createAlphaClipMask(int32_t elementsGenID,
GrReducedClip::InitialState initialState,
const GrReducedClip::ElementList& elements,
const SkIRect& clipSpaceIBounds);
+
// Similar to createAlphaClipMask but it rasterizes in SW and uploads to the result texture.
GrTexture* createSoftwareClipMask(int32_t elementsGenID,
GrReducedClip::InitialState initialState,
@@ -137,26 +140,32 @@
// Returns NULL if not found.
GrTexture* getCachedMaskTexture(int32_t elementsGenID, const SkIRect& clipSpaceIBounds);
-
// Handles allocation (if needed) of a clip alpha-mask texture for both the sw-upload
// or gpu-rendered cases.
GrTexture* allocMaskTexture(int32_t elementsGenID,
const SkIRect& clipSpaceIBounds,
bool willUpload);
- bool useSWOnlyPath(const GrReducedClip::ElementList& elements);
+ bool useSWOnlyPath(const GrDrawState*, const GrReducedClip::ElementList& elements);
// Draws a clip element into the target alpha mask. The caller should have already setup the
// desired blend operation. Optionally if the caller already selected a path renderer it can
// be passed. Otherwise the function will select one if the element is a path.
- bool drawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer* = NULL);
+ bool drawElement(GrDrawState*,
+ GrTexture* target,
+ const SkClipStack::Element*,
+ GrPathRenderer* pr = NULL);
// Determines whether it is possible to draw the element to both the stencil buffer and the
// alpha mask simultaneously. If so and the element is a path a compatible path renderer is
// also returned.
- bool canStencilAndDrawElement(GrTexture* target, const SkClipStack::Element*, GrPathRenderer**);
+ bool canStencilAndDrawElement(GrDrawState*,
+ GrTexture* target,
+ GrPathRenderer**,
+ const SkClipStack::Element*);
- void mergeMask(GrTexture* dstMask,
+ void mergeMask(GrDrawState*,
+ GrTexture* dstMask,
GrTexture* srcMask,
SkRegion::Op op,
const SkIRect& dstBound,
@@ -166,13 +175,12 @@
void setupCache(const SkClipStack& clip,
const SkIRect& bounds);
-
/**
* Called prior to return control back the GrGpu in setupClipping. It
* updates the GrGpu with stencil settings that account stencil-based
* clipping.
*/
- void setDrawStateStencil(GrDrawState::AutoRestoreStencil* asr);
+ void setDrawStateStencil(GrDrawState*, GrDrawState::AutoRestoreStencil*);
/**
* Adjusts the stencil settings to account for interaction with stencil
@@ -199,5 +207,4 @@
typedef SkNoncopyable INHERITED;
};
-
#endif // GrClipMaskManager_DEFINED
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index e7449da..657e57d 100755
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -60,9 +60,6 @@
#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
-// Glorified typedef to avoid including GrDrawState.h in GrContext.h
-class GrContext::AutoRestoreEffects : public GrDrawState::AutoRestoreEffects {};
-
class GrContext::AutoCheckFlush {
public:
AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context); }
@@ -95,7 +92,6 @@
}
GrContext::GrContext(const Options& opts) : fOptions(opts) {
- fDrawState = NULL;
fGpu = NULL;
fClip = NULL;
fPathRendererChain = NULL;
@@ -124,8 +120,6 @@
}
void GrContext::initCommon() {
- fDrawState = SkNEW(GrDrawState);
-
fResourceCache2 = SkNEW(GrResourceCache2);
fResourceCache2->setOverBudgetCallback(OverBudgetCB, this);
@@ -164,7 +158,6 @@
fGpu->unref();
SkSafeUnref(fPathRendererChain);
SkSafeUnref(fSoftwarePathRenderer);
- fDrawState->unref();
}
void GrContext::abandonContext() {
@@ -326,9 +319,8 @@
GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0);
if (texture) {
- GrDrawTarget::AutoStateRestore asr(fDrawBuffer, GrDrawTarget::kReset_ASRInit);
- GrDrawState* drawState = fDrawBuffer->drawState();
- drawState->setRenderTarget(texture->asRenderTarget());
+ GrDrawState drawState;
+ drawState.setRenderTarget(texture->asRenderTarget());
// if filtering is not desired then we want to ensure all
// texels in the resampled image are copies of texels from
@@ -336,21 +328,21 @@
GrTextureParams params(SkShader::kClamp_TileMode,
filter ? GrTextureParams::kBilerp_FilterMode :
GrTextureParams::kNone_FilterMode);
- drawState->addColorTextureProcessor(clampedTexture, SkMatrix::I(), params);
+ drawState.addColorTextureProcessor(clampedTexture, SkMatrix::I(), params);
- drawState->setGeometryProcessor(
+ drawState.setGeometryProcessor(
GrDefaultGeoProcFactory::CreateAndSetAttribs(
- drawState,
+ &drawState,
GrDefaultGeoProcFactory::kPosition_GPType |
GrDefaultGeoProcFactory::kLocalCoord_GPType))->unref();
- GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, 0);
+ GrDrawTarget::AutoReleaseGeometry arg(fDrawBuffer, 4, drawState.getVertexStride(), 0);
if (arg.succeeded()) {
SkPoint* verts = (SkPoint*) arg.vertices();
verts[0].setIRectFan(0, 0, texture->width(), texture->height(), 2 * sizeof(SkPoint));
verts[1].setIRectFan(0, 0, 1, 1, 2 * sizeof(SkPoint));
- fDrawBuffer->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
+ fDrawBuffer->drawNonIndexed(&drawState, kTriangleFan_GrPrimitiveType, 0, 4);
}
} else {
// TODO: Our CPU stretch doesn't filter. But we create separate
@@ -564,10 +556,9 @@
ASSERT_OWNED_RESOURCE(renderTarget);
SkASSERT(renderTarget);
- AutoRestoreEffects are;
AutoCheckFlush acf(this);
GR_CREATE_TRACE_MARKER_CONTEXT("GrContext::clear", this);
- GrDrawTarget* target = this->prepareToDraw(NULL, &are, &acf);
+ GrDrawTarget* target = this->prepareToDraw(NULL, NULL, &acf);
if (NULL == target) {
return;
}
@@ -644,19 +635,19 @@
}
static bool apply_aa_to_rect(GrDrawTarget* target,
+ GrDrawState* ds,
+ SkRect* devBoundRect,
const SkRect& rect,
SkScalar strokeWidth,
- const SkMatrix& combinedMatrix,
- SkRect* devBoundRect) {
- if (!target->getDrawState().canTweakAlphaForCoverage() &&
- target->shouldDisableCoverageAAForBlend()) {
+ const SkMatrix& combinedMatrix) {
+ if (!ds->canTweakAlphaForCoverage() && !ds->couldApplyCoverage(*target->caps())) {
#ifdef SK_DEBUG
//SkDebugf("Turning off AA to correctly apply blend.\n");
#endif
return false;
}
- const GrDrawState& drawState = target->getDrawState();
- if (drawState.getRenderTarget()->isMultisampled()) {
+
+ if (ds->getRenderTarget()->isMultisampled()) {
return false;
}
@@ -698,22 +689,22 @@
return;
}
- AutoRestoreEffects are;
AutoCheckFlush acf(this);
- GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
+ GrDrawState drawState;
+ GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
if (NULL == target) {
return;
}
GR_CREATE_TRACE_MARKER("GrContext::drawRect", target);
SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getStrokeRec().getWidth();
- SkMatrix matrix = target->drawState()->getViewMatrix();
+ SkMatrix matrix = drawState.getViewMatrix();
// Check if this is a full RT draw and can be replaced with a clear. We don't bother checking
// cases where the RT is fully inside a stroke.
if (width < 0) {
SkRect rtRect;
- target->getDrawState().getRenderTarget()->getBoundsRect(&rtRect);
+ drawState.getRenderTarget()->getBoundsRect(&rtRect);
SkRect clipSpaceRTRect = rtRect;
bool checkClip = false;
if (this->getClip()) {
@@ -745,22 +736,26 @@
}
SkRect devBoundRect;
- bool needAA = paint.isAntiAlias() &&
- !target->getDrawState().getRenderTarget()->isMultisampled();
- bool doAA = needAA && apply_aa_to_rect(target, rect, width, matrix, &devBoundRect);
+ bool needAA = paint.isAntiAlias() && !drawState.getRenderTarget()->isMultisampled();
+ bool doAA = needAA && apply_aa_to_rect(target, &drawState, &devBoundRect, rect, width, matrix);
if (doAA) {
GrDrawState::AutoViewMatrixRestore avmr;
- if (!avmr.setIdentity(target->drawState())) {
+ if (!avmr.setIdentity(&drawState)) {
return;
}
+
if (width >= 0) {
const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec();
- fAARectRenderer->strokeAARect(target, rect, matrix, devBoundRect, strokeRec);
+ fAARectRenderer->strokeAARect(target,
+ &drawState,
+ rect,
+ matrix,
+ devBoundRect,
+ strokeRec);
} else {
// filled AA rect
- fAARectRenderer->fillAARect(target,
- rect, matrix, devBoundRect);
+ fAARectRenderer->fillAARect(target, &drawState, rect, matrix, devBoundRect);
}
return;
}
@@ -771,9 +766,12 @@
// unitSquareVertexBuffer()
static const int worstCaseVertCount = 10;
- target->drawState()->setDefaultVertexAttribs();
- target->drawState()->setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
- GrDrawTarget::AutoReleaseGeometry geo(target, worstCaseVertCount, 0);
+ drawState.setDefaultVertexAttribs();
+ drawState.setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
+ GrDrawTarget::AutoReleaseGeometry geo(target,
+ worstCaseVertCount,
+ drawState.getVertexStride(),
+ 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
@@ -799,10 +797,10 @@
vertex[4].set(rect.fLeft, rect.fTop);
}
- target->drawNonIndexed(primType, 0, vertCount);
+ target->drawNonIndexed(&drawState, primType, 0, vertCount);
} else {
// filled BW rect
- target->drawSimpleRect(rect);
+ target->drawSimpleRect(&drawState, rect);
}
}
@@ -810,16 +808,16 @@
const SkRect& dstRect,
const SkRect& localRect,
const SkMatrix* localMatrix) {
- AutoRestoreEffects are;
AutoCheckFlush acf(this);
- GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
+ GrDrawState drawState;
+ GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
if (NULL == target) {
return;
}
GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target);
- target->drawRect(dstRect, &localRect, localMatrix);
+ target->drawRect(&drawState, dstRect, &localRect, localMatrix);
}
static void set_vertex_attributes(GrDrawState* drawState,
@@ -855,23 +853,22 @@
const GrColor colors[],
const uint16_t indices[],
int indexCount) {
- AutoRestoreEffects are;
AutoCheckFlush acf(this);
+ GrDrawState drawState;
GrDrawTarget::AutoReleaseGeometry geo; // must be inside AutoCheckFlush scope
- GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
+ GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
if (NULL == target) {
return;
}
- GrDrawState* drawState = target->drawState();
GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target);
int colorOffset = -1, texOffset = -1;
- set_vertex_attributes(drawState, texCoords, colors, &colorOffset, &texOffset);
+ set_vertex_attributes(&drawState, texCoords, colors, &colorOffset, &texOffset);
- size_t VertexStride = drawState->getVertexStride();
- if (!geo.set(target, vertexCount, indexCount)) {
+ size_t vertexStride = drawState.getVertexStride();
+ if (!geo.set(target, vertexCount, vertexStride, indexCount)) {
SkDebugf("Failed to get space for vertices!\n");
return;
}
@@ -886,7 +883,7 @@
if (colorOffset >= 0) {
*(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i];
}
- curVertex = (void*)((intptr_t)curVertex + VertexStride);
+ curVertex = (void*)((intptr_t)curVertex + vertexStride);
}
// we don't currently apply offscreen AA to this path. Need improved
@@ -896,9 +893,9 @@
for (int i = 0; i < indexCount; ++i) {
curIndex[i] = indices[i];
}
- target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
+ target->drawIndexed(&drawState, primitiveType, 0, 0, vertexCount, indexCount);
} else {
- target->drawNonIndexed(primitiveType, 0, vertexCount);
+ target->drawNonIndexed(&drawState, primitiveType, 0, vertexCount);
}
}
@@ -918,9 +915,9 @@
return;
}
- AutoRestoreEffects are;
AutoCheckFlush acf(this);
- GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
+ GrDrawState drawState;
+ GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
if (NULL == target) {
return;
}
@@ -929,10 +926,11 @@
const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
- if (!fOvalRenderer->drawRRect(target, this, paint.isAntiAlias(), rrect, strokeRec)) {
+ if (!fOvalRenderer->drawRRect(target, &drawState, this, paint.isAntiAlias(), rrect,
+ strokeRec)) {
SkPath path;
path.addRRect(rrect);
- this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo);
+ this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, strokeInfo);
}
}
@@ -945,20 +943,20 @@
return;
}
- AutoRestoreEffects are;
AutoCheckFlush acf(this);
- GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
+ GrDrawState drawState;
+ GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target);
- if (!fOvalRenderer->drawDRRect(target, this, paint.isAntiAlias(), outer, inner)) {
+ if (!fOvalRenderer->drawDRRect(target, &drawState, this, paint.isAntiAlias(), outer, inner)) {
SkPath path;
path.addRRect(inner);
path.addRRect(outer);
path.setFillType(SkPath::kEvenOdd_FillType);
GrStrokeInfo fillRec(SkStrokeRec::kFill_InitStyle);
- this->internalDrawPath(target, paint.isAntiAlias(), path, fillRec);
+ this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, fillRec);
}
}
@@ -978,9 +976,9 @@
return;
}
- AutoRestoreEffects are;
AutoCheckFlush acf(this);
- GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
+ GrDrawState drawState;
+ GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
if (NULL == target) {
return;
}
@@ -990,15 +988,16 @@
const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
- if (!fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), oval, strokeRec)) {
+ if (!fOvalRenderer->drawOval(target, &drawState, this, paint.isAntiAlias(), oval, strokeRec)) {
SkPath path;
path.addOval(oval);
- this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo);
+ this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, strokeInfo);
}
}
// Can 'path' be drawn as a pair of filled nested rectangles?
static bool is_nested_rects(GrDrawTarget* target,
+ GrDrawState* drawState,
const SkPath& path,
const SkStrokeRec& stroke,
SkRect rects[2]) {
@@ -1008,16 +1007,13 @@
return false;
}
- const GrDrawState& drawState = target->getDrawState();
-
// TODO: this restriction could be lifted if we were willing to apply
// the matrix to all the points individually rather than just to the rect
- if (!drawState.getViewMatrix().preservesAxisAlignment()) {
+ if (!drawState->getViewMatrix().preservesAxisAlignment()) {
return false;
}
- if (!target->getDrawState().canTweakAlphaForCoverage() &&
- target->shouldDisableCoverageAAForBlend()) {
+ if (!drawState->canTweakAlphaForCoverage() && !drawState->couldApplyCoverage(*target->caps())) {
return false;
}
@@ -1066,19 +1062,18 @@
if (strokeInfo.isDashed()) {
SkPoint pts[2];
if (path.isLine(pts)) {
- AutoRestoreEffects are;
AutoCheckFlush acf(this);
- GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
+ GrDrawState drawState;
+ GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
if (NULL == target) {
return;
- }
- GrDrawState* drawState = target->drawState();
+ };
- SkMatrix origViewMatrix = drawState->getViewMatrix();
+ SkMatrix origViewMatrix = drawState.getViewMatrix();
GrDrawState::AutoViewMatrixRestore avmr;
- if (avmr.setIdentity(target->drawState())) {
- if (GrDashingEffect::DrawDashLine(pts, paint, strokeInfo, fGpu, target,
- origViewMatrix)) {
+ if (avmr.setIdentity(&drawState)) {
+ if (GrDashingEffect::DrawDashLine(fGpu, target, &drawState, pts, paint,
+ strokeInfo, origViewMatrix)) {
return;
}
}
@@ -1103,32 +1098,31 @@
// cache. This presents a potential hazard for buffered drawing. However,
// the writePixels that uploads to the scratch will perform a flush so we're
// OK.
- AutoRestoreEffects are;
AutoCheckFlush acf(this);
- GrDrawTarget* target = this->prepareToDraw(&paint, &are, &acf);
+ GrDrawState drawState;
+ GrDrawTarget* target = this->prepareToDraw(&drawState, &paint, &acf);
if (NULL == target) {
return;
}
- GrDrawState* drawState = target->drawState();
GR_CREATE_TRACE_MARKER1("GrContext::drawPath", target, "Is Convex", path.isConvex());
const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
- bool useCoverageAA = paint.isAntiAlias() && !drawState->getRenderTarget()->isMultisampled();
+ bool useCoverageAA = paint.isAntiAlias() && !drawState.getRenderTarget()->isMultisampled();
if (useCoverageAA && strokeRec.getWidth() < 0 && !path.isConvex()) {
// Concave AA paths are expensive - try to avoid them for special cases
SkRect rects[2];
- if (is_nested_rects(target, path, strokeRec, rects)) {
- SkMatrix origViewMatrix = drawState->getViewMatrix();
+ if (is_nested_rects(target, &drawState, path, strokeRec, rects)) {
+ SkMatrix origViewMatrix = drawState.getViewMatrix();
GrDrawState::AutoViewMatrixRestore avmr;
- if (!avmr.setIdentity(target->drawState())) {
+ if (!avmr.setIdentity(&drawState)) {
return;
}
- fAARectRenderer->fillAANestedRects(target, rects, origViewMatrix);
+ fAARectRenderer->fillAANestedRects(target, &drawState, rects, origViewMatrix);
return;
}
}
@@ -1137,12 +1131,16 @@
bool isOval = path.isOval(&ovalRect);
if (!isOval || path.isInverseFillType()
- || !fOvalRenderer->drawOval(target, this, paint.isAntiAlias(), ovalRect, strokeRec)) {
- this->internalDrawPath(target, paint.isAntiAlias(), path, strokeInfo);
+ || !fOvalRenderer->drawOval(target, &drawState, this, paint.isAntiAlias(), ovalRect,
+ strokeRec)) {
+ this->internalDrawPath(target, &drawState, paint.isAntiAlias(), path, strokeInfo);
}
}
-void GrContext::internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path,
+void GrContext::internalDrawPath(GrDrawTarget* target,
+ GrDrawState* drawState,
+ bool useAA,
+ const SkPath& path,
const GrStrokeInfo& strokeInfo) {
SkASSERT(!path.isEmpty());
@@ -1154,20 +1152,20 @@
// aa. If we have some future driver-mojo path AA that can do the right
// thing WRT to the blend then we'll need some query on the PR.
bool useCoverageAA = useAA &&
- !target->getDrawState().getRenderTarget()->isMultisampled() &&
- !target->shouldDisableCoverageAAForBlend();
+ !drawState->getRenderTarget()->isMultisampled() &&
+ drawState->couldApplyCoverage(*target->caps());
GrPathRendererChain::DrawType type =
useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType :
- GrPathRendererChain::kColor_DrawType;
+ GrPathRendererChain::kColor_DrawType;
const SkPath* pathPtr = &path;
SkTLazy<SkPath> tmpPath;
SkTCopyOnFirstWrite<SkStrokeRec> stroke(strokeInfo.getStrokeRec());
// Try a 1st time without stroking the path and without allowing the SW renderer
- GrPathRenderer* pr = this->getPathRenderer(*pathPtr, *stroke, target, false, type);
+ GrPathRenderer* pr = this->getPathRenderer(target, drawState, *pathPtr, *stroke, false, type);
if (NULL == pr) {
if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*stroke, this->getMatrix(), NULL)) {
@@ -1182,7 +1180,7 @@
}
// This time, allow SW renderer
- pr = this->getPathRenderer(*pathPtr, *stroke, target, true, type);
+ pr = this->getPathRenderer(target, drawState, *pathPtr, *stroke, true, type);
}
if (NULL == pr) {
@@ -1192,7 +1190,7 @@
return;
}
- pr->drawPath(*pathPtr, *stroke, target, useCoverageAA);
+ pr->drawPath(target, drawState, *pathPtr, *stroke, useCoverageAA);
}
////////////////////////////////////////////////////////////////////////////////
@@ -1328,13 +1326,13 @@
// The bracket ensures we pop the stack if we wind up flushing below.
{
GrDrawTarget* drawTarget = this->prepareToDraw(NULL, NULL, NULL);
- GrDrawTarget::AutoGeometryAndStatePush agasp(drawTarget, GrDrawTarget::kReset_ASRInit,
- &matrix);
- GrDrawState* drawState = drawTarget->drawState();
- drawState->addColorProcessor(fp);
- drawState->setRenderTarget(renderTarget);
- drawState->disableState(GrDrawState::kClip_StateBit);
- drawTarget->drawSimpleRect(SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)));
+ GrDrawTarget::AutoGeometryPush agp(drawTarget);
+
+ GrDrawState drawState(matrix);
+ drawState.addColorProcessor(fp);
+ drawState.setRenderTarget(renderTarget);
+ drawTarget->drawSimpleRect(&drawState, SkRect::MakeWH(SkIntToScalar(width),
+ SkIntToScalar(height)));
}
if (kFlushWrites_PixelOp & pixelOpsFlags) {
@@ -1448,15 +1446,14 @@
// clear to the caller that a draw operation (i.e., drawSimpleRect)
// can be invoked in this method
{
- GrDrawTarget::AutoGeometryAndStatePush agasp(fDrawBuffer,
- GrDrawTarget::kReset_ASRInit);
- GrDrawState* drawState = fDrawBuffer->drawState();
+ GrDrawTarget::AutoGeometryPush agp(fDrawBuffer);
+ GrDrawState drawState;
SkASSERT(fp);
- drawState->addColorProcessor(fp);
+ drawState.addColorProcessor(fp);
- drawState->setRenderTarget(tempTexture->asRenderTarget());
+ drawState.setRenderTarget(tempTexture->asRenderTarget());
SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
- fDrawBuffer->drawSimpleRect(rect);
+ fDrawBuffer->drawSimpleRect(&drawState, rect);
// we want to read back from the scratch's origin
left = 0;
top = 0;
@@ -1508,9 +1505,8 @@
void GrContext::discardRenderTarget(GrRenderTarget* renderTarget) {
SkASSERT(renderTarget);
ASSERT_OWNED_RESOURCE(renderTarget);
- AutoRestoreEffects are;
AutoCheckFlush acf(this);
- GrDrawTarget* target = this->prepareToDraw(NULL, &are, &acf);
+ GrDrawTarget* target = this->prepareToDraw(NULL, NULL, &acf);
if (NULL == target) {
return;
}
@@ -1545,43 +1541,34 @@
}
}
-////////////////////////////////////////////////////////////////////////////////
-
-GrDrawTarget* GrContext::prepareToDraw(const GrPaint* paint,
- AutoRestoreEffects* are,
- AutoCheckFlush* acf) {
- // All users of this draw state should be freeing up all effects when they're done.
- // Otherwise effects that own resources may keep those resources alive indefinitely.
- SkASSERT(0 == fDrawState->numColorStages() && 0 == fDrawState->numCoverageStages() &&
- !fDrawState->hasGeometryProcessor());
-
+GrDrawTarget* GrContext::prepareToDraw(GrDrawState* ds,
+ const GrPaint* paint,
+ const AutoCheckFlush* acf) {
if (NULL == fGpu) {
return NULL;
}
ASSERT_OWNED_RESOURCE(fRenderTarget.get());
- if (paint) {
- SkASSERT(are);
- SkASSERT(acf);
- are->set(fDrawState);
- fDrawState->setFromPaint(*paint, fViewMatrix, fRenderTarget.get());
+ if (ds) {
+ if (paint) {
+ SkASSERT(acf);
+ ds->setFromPaint(*paint, fViewMatrix, fRenderTarget.get());
#if GR_DEBUG_PARTIAL_COVERAGE_CHECK
- if ((paint->hasMask() || 0xff != paint->fCoverage) &&
- !fDrawState->couldApplyCoverage(fGpu->caps())) {
- SkDebugf("Partial pixel coverage will be incorrectly blended.\n");
- }
+ if ((paint->hasMask() || 0xff != paint->fCoverage) &&
+ !fDrawState->couldApplyCoverage(fGpu->caps())) {
+ SkDebugf("Partial pixel coverage will be incorrectly blended.\n");
+ }
#endif
- // Clear any vertex attributes configured for the previous use of the
- // GrDrawState which can effect which blend optimizations are in effect.
- fDrawState->setDefaultVertexAttribs();
- } else {
- fDrawState->reset(fViewMatrix);
- fDrawState->setRenderTarget(fRenderTarget.get());
+ // Clear any vertex attributes configured for the previous use of the
+ // GrDrawState which can effect which blend optimizations are in effect.
+ ds->setDefaultVertexAttribs();
+ } else {
+ ds->reset(fViewMatrix);
+ ds->setRenderTarget(fRenderTarget.get());
+ }
+ ds->setState(GrDrawState::kClip_StateBit, fClip && !fClip->fClipStack->isWideOpen());
}
- fDrawState->setState(GrDrawState::kClip_StateBit, fClip &&
- !fClip->fClipStack->isWideOpen());
fDrawBuffer->setClip(fClip);
- SkASSERT(fDrawState == fDrawBuffer->drawState());
return fDrawBuffer;
}
@@ -1591,9 +1578,10 @@
* Due to its expense, the software path renderer has split out so it can
* can be individually allowed/disallowed via the "allowSW" boolean.
*/
-GrPathRenderer* GrContext::getPathRenderer(const SkPath& path,
+GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target,
+ const GrDrawState* drawState,
+ const SkPath& path,
const SkStrokeRec& stroke,
- const GrDrawTarget* target,
bool allowSW,
GrPathRendererChain::DrawType drawType,
GrPathRendererChain::StencilSupport* stencilSupport) {
@@ -1602,9 +1590,10 @@
fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this));
}
- GrPathRenderer* pr = fPathRendererChain->getPathRenderer(path,
+ GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target,
+ drawState,
+ path,
stroke,
- target,
drawType,
stencilSupport);
@@ -1657,8 +1646,6 @@
fDrawBuffer = SkNEW_ARGS(GrInOrderDrawBuffer, (fGpu,
fDrawBufferVBAllocPool,
fDrawBufferIBAllocPool));
-
- fDrawBuffer->setDrawState(fDrawState);
}
GrDrawTarget* GrContext::getTextTarget() {
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index e4ac225..3b31e87 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -163,10 +163,11 @@
#endif
}
-GrPathRenderer::StencilSupport GrDefaultPathRenderer::onGetStencilSupport(
- const SkPath& path,
- const SkStrokeRec& stroke,
- const GrDrawTarget*) const {
+GrPathRenderer::StencilSupport
+GrDefaultPathRenderer::onGetStencilSupport(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath& path,
+ const SkStrokeRec& stroke) const {
if (single_pass_path(path, stroke)) {
return GrPathRenderer::kNoRestriction_StencilSupport;
} else {
@@ -188,14 +189,15 @@
*((*indices)++) = edgeV0Idx + 1;
}
-bool GrDefaultPathRenderer::createGeom(const SkPath& path,
- const SkStrokeRec& stroke,
- SkScalar srcSpaceTol,
- GrDrawTarget* target,
+bool GrDefaultPathRenderer::createGeom(GrDrawTarget* target,
+ GrDrawState* drawState,
GrPrimitiveType* primType,
int* vertexCnt,
int* indexCnt,
- GrDrawTarget::AutoReleaseGeometry* arg) {
+ GrDrawTarget::AutoReleaseGeometry* arg,
+ const SkPath& path,
+ const SkStrokeRec& stroke,
+ SkScalar srcSpaceTol) {
{
SkScalar srcSpaceTolSqd = SkScalarMul(srcSpaceTol, srcSpaceTol);
int contourCnt;
@@ -231,8 +233,8 @@
}
}
- target->drawState()->setDefaultVertexAttribs();
- if (!arg->set(target, maxPts, maxIdxs)) {
+ drawState->setDefaultVertexAttribs();
+ if (!arg->set(target, maxPts, drawState->getVertexStride(), maxIdxs)) {
return false;
}
@@ -324,20 +326,19 @@
return true;
}
-bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path,
+bool GrDefaultPathRenderer::internalDrawPath(GrDrawTarget* target,
+ GrDrawState* drawState,
+ const SkPath& path,
const SkStrokeRec& origStroke,
- GrDrawTarget* target,
bool stencilOnly) {
-
- SkMatrix viewM = target->getDrawState().getViewMatrix();
+ SkMatrix viewM = drawState->getViewMatrix();
SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke);
SkScalar hairlineCoverage;
- if (IsStrokeHairlineOrEquivalent(*stroke, target->getDrawState().getViewMatrix(),
+ if (IsStrokeHairlineOrEquivalent(*stroke, drawState->getViewMatrix(),
&hairlineCoverage)) {
- uint8_t newCoverage = SkScalarRoundToInt(hairlineCoverage *
- target->getDrawState().getCoverage());
- target->drawState()->setCoverage(newCoverage);
+ uint8_t newCoverage = SkScalarRoundToInt(hairlineCoverage * drawState->getCoverage());
+ drawState->setCoverage(newCoverage);
if (!stroke->isHairlineStyle()) {
stroke.writable()->setHairlineStyle();
@@ -351,20 +352,18 @@
int indexCnt;
GrPrimitiveType primType;
GrDrawTarget::AutoReleaseGeometry arg;
- if (!this->createGeom(path,
- *stroke,
- tol,
- target,
+ if (!this->createGeom(target,
+ drawState,
&primType,
&vertexCnt,
&indexCnt,
- &arg)) {
+ &arg,
+ path,
+ *stroke,
+ tol)) {
return false;
}
- SkASSERT(target);
- GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit);
- GrDrawState* drawState = target->drawState();
bool colorWritesWereDisabled = drawState->isColorWriteDisabled();
// face culling doesn't make sense here
SkASSERT(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());
@@ -491,8 +490,8 @@
} else {
bounds = path.getBounds();
}
- GrDrawTarget::AutoGeometryAndStatePush agasp(target, GrDrawTarget::kPreserve_ASRInit);
- target->drawSimpleRect(bounds);
+ GrDrawTarget::AutoGeometryPush agp(target);
+ target->drawSimpleRect(drawState, bounds);
} else {
if (passCount > 1) {
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
@@ -500,41 +499,50 @@
GrDrawState::AutoRestoreEffects are(drawState);
drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
if (indexCnt) {
- target->drawIndexed(primType, 0, 0,
- vertexCnt, indexCnt, &devBounds);
+ target->drawIndexed(drawState,
+ primType,
+ 0,
+ 0,
+ vertexCnt,
+ indexCnt,
+ &devBounds);
} else {
- target->drawNonIndexed(primType, 0, vertexCnt, &devBounds);
+ target->drawNonIndexed(drawState, primType, 0, vertexCnt, &devBounds);
}
}
}
return true;
}
-bool GrDefaultPathRenderer::canDrawPath(const SkPath& path,
+bool GrDefaultPathRenderer::canDrawPath(const GrDrawTarget* target,
+ const GrDrawState* drawState,
+ const SkPath& path,
const SkStrokeRec& stroke,
- const GrDrawTarget* target,
bool antiAlias) const {
// this class can draw any path with any fill but doesn't do any anti-aliasing.
return !antiAlias && !(SkPath::kConic_SegmentMask & path.getSegmentMasks()) &&
(stroke.isFillStyle() ||
- IsStrokeHairlineOrEquivalent(stroke, target->getDrawState().getViewMatrix(), NULL));
+ IsStrokeHairlineOrEquivalent(stroke, drawState->getViewMatrix(), NULL));
}
-bool GrDefaultPathRenderer::onDrawPath(const SkPath& path,
+bool GrDefaultPathRenderer::onDrawPath(GrDrawTarget* target,
+ GrDrawState* drawState,
+ const SkPath& path,
const SkStrokeRec& stroke,
- GrDrawTarget* target,
bool antiAlias) {
- return this->internalDrawPath(path,
+ return this->internalDrawPath(target,
+ drawState,
+ path,
stroke,
- target,
false);
}
-void GrDefaultPathRenderer::onStencilPath(const SkPath& path,
- const SkStrokeRec& stroke,
- GrDrawTarget* target) {
+void GrDefaultPathRenderer::onStencilPath(GrDrawTarget* target,
+ GrDrawState* drawState,
+ const SkPath& path,
+ const SkStrokeRec& stroke) {
SkASSERT(SkPath::kInverseEvenOdd_FillType != path.getFillType());
SkASSERT(SkPath::kInverseWinding_FillType != path.getFillType());
- this->internalDrawPath(path, stroke, target, true);
+ this->internalDrawPath(target, drawState, path, stroke, true);
}
diff --git a/src/gpu/GrDefaultPathRenderer.h b/src/gpu/GrDefaultPathRenderer.h
index c60afcc..0f90daa 100644
--- a/src/gpu/GrDefaultPathRenderer.h
+++ b/src/gpu/GrDefaultPathRenderer.h
@@ -19,39 +19,45 @@
public:
GrDefaultPathRenderer(bool separateStencilSupport, bool stencilWrapOpsSupport);
- virtual bool canDrawPath(const SkPath&,
+ virtual bool canDrawPath(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
const SkStrokeRec&,
- const GrDrawTarget*,
bool antiAlias) const SK_OVERRIDE;
private:
- virtual StencilSupport onGetStencilSupport(const SkPath&,
- const SkStrokeRec&,
- const GrDrawTarget*) const SK_OVERRIDE;
+ virtual StencilSupport onGetStencilSupport(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&) const SK_OVERRIDE;
- virtual bool onDrawPath(const SkPath&,
+ virtual bool onDrawPath(GrDrawTarget*,
+ GrDrawState*,
+ const SkPath&,
const SkStrokeRec&,
- GrDrawTarget*,
bool antiAlias) SK_OVERRIDE;
- virtual void onStencilPath(const SkPath&,
- const SkStrokeRec&,
- GrDrawTarget*) SK_OVERRIDE;
+ virtual void onStencilPath(GrDrawTarget*,
+ GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&) SK_OVERRIDE;
- bool internalDrawPath(const SkPath&,
+ bool internalDrawPath(GrDrawTarget*,
+ GrDrawState*,
+ const SkPath&,
const SkStrokeRec&,
- GrDrawTarget*,
bool stencilOnly);
- bool createGeom(const SkPath&,
- const SkStrokeRec&,
- SkScalar srcSpaceTol,
- GrDrawTarget*,
+ bool createGeom(GrDrawTarget*,
+ GrDrawState*,
GrPrimitiveType*,
int* vertexCnt,
int* indexCnt,
- GrDrawTarget::AutoReleaseGeometry*);
+ GrDrawTarget::AutoReleaseGeometry*,
+ const SkPath&,
+ const SkStrokeRec&,
+ SkScalar srcSpaceTol);
bool fSeparateStencil;
bool fStencilWrapOps;
diff --git a/src/gpu/GrDistanceFieldTextContext.cpp b/src/gpu/GrDistanceFieldTextContext.cpp
index 58c8121..db98238 100755
--- a/src/gpu/GrDistanceFieldTextContext.cpp
+++ b/src/gpu/GrDistanceFieldTextContext.cpp
@@ -96,7 +96,6 @@
}
GrDistanceFieldTextContext::~GrDistanceFieldTextContext() {
- this->finish();
SkSafeSetNull(fGammaTexture);
}
@@ -382,21 +381,21 @@
return GrColorPackRGBA(r, g, b, 0xff);
}
-static void* alloc_vertices(GrDrawTarget* drawTarget, int numVertices, bool useColorVerts) {
+static size_t get_vertex_stride(bool useColorVerts) {
+ return useColorVerts ? (2 * sizeof(SkPoint) + sizeof(GrColor)) :
+ (2 * sizeof(SkPoint));
+}
+
+static void* alloc_vertices(GrDrawTarget* drawTarget,
+ int numVertices,
+ bool useColorVerts) {
if (numVertices <= 0) {
return NULL;
}
- // set up attributes
- if (useColorVerts) {
- drawTarget->drawState()->setVertexAttribs<gTextVertexWithColorAttribs>(
- SK_ARRAY_COUNT(gTextVertexWithColorAttribs), kTextVAColorSize);
- } else {
- drawTarget->drawState()->setVertexAttribs<gTextVertexAttribs>(
- SK_ARRAY_COUNT(gTextVertexAttribs), kTextVASize);
- }
void* vertices = NULL;
bool success = drawTarget->reserveVertexAndIndexSpace(numVertices,
+ get_vertex_stride(useColorVerts),
0,
&vertices,
NULL);
@@ -578,7 +577,9 @@
if (NULL == fVertices) {
int maxQuadVertices = kVerticesPerGlyph * fContext->getQuadIndexBuffer()->maxQuads();
fAllocVertexCount = SkMin32(fTotalVertexCount, maxQuadVertices);
- fVertices = alloc_vertices(fDrawTarget, fAllocVertexCount, useColorVerts);
+ fVertices = alloc_vertices(fDrawTarget,
+ fAllocVertexCount,
+ useColorVerts);
}
SkFixed tx = SkIntToFixed(glyph->fAtlasLocation.fX + SK_DistanceFieldInset);
@@ -588,10 +589,7 @@
fVertexBounds.joinNonEmptyArg(glyphRect);
- size_t vertSize = fUseLCDText ? (2 * sizeof(SkPoint))
- : (2 * sizeof(SkPoint) + sizeof(GrColor));
-
- SkASSERT(vertSize == fDrawTarget->getDrawState().getVertexStride());
+ size_t vertSize = get_vertex_stride(useColorVerts);
SkPoint* positions = reinterpret_cast<SkPoint*>(
reinterpret_cast<intptr_t>(fVertices) + vertSize * fCurrVertex);
@@ -607,9 +605,6 @@
SkFixedToFloat(texture->texturePriv().normalizeFixedY(ty + th)),
vertSize);
if (useColorVerts) {
- if (0xFF == GrColorUnpackA(fPaint.getColor())) {
- fDrawTarget->drawState()->setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
- }
// color comes after position.
GrColor* colors = reinterpret_cast<GrColor*>(positions + 1);
for (int i = 0; i < 4; ++i) {
@@ -623,15 +618,27 @@
return true;
}
+// We use color vertices if we aren't drawing LCD text
+static void set_vertex_attributes(GrDrawState* drawState, bool useColorVerts) {
+ // set up attributes
+ if (useColorVerts) {
+ drawState->setVertexAttribs<gTextVertexWithColorAttribs>(
+ SK_ARRAY_COUNT(gTextVertexWithColorAttribs), kTextVAColorSize);
+ } else {
+ drawState->setVertexAttribs<gTextVertexAttribs>(
+ SK_ARRAY_COUNT(gTextVertexAttribs), kTextVASize);
+ }
+}
+
void GrDistanceFieldTextContext::flush() {
if (NULL == fDrawTarget) {
return;
}
- GrDrawState* drawState = fDrawTarget->drawState();
- GrDrawState::AutoRestoreEffects are(drawState);
-
- drawState->setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTarget());
+ GrDrawState drawState;
+ drawState.setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTarget());
+ bool useColorVerts = !fUseLCDText;
+ set_vertex_attributes(&drawState, useColorVerts);
if (fCurrVertex > 0) {
// setup our sampler state for our text texture/atlas
@@ -648,7 +655,7 @@
this->setupCoverageEffect(filteredColor);
// Effects could be stored with one of the cache objects (atlas?)
- drawState->setGeometryProcessor(fCachedGeometryProcessor.get());
+ drawState.setGeometryProcessor(fCachedGeometryProcessor.get());
// Set draw state
if (fUseLCDText) {
@@ -658,28 +665,34 @@
fPaint.numColorStages()) {
SkDebugf("LCD Text will not draw correctly.\n");
}
- SkASSERT(!drawState->hasColorVertexAttribute());
+ SkASSERT(!drawState.hasColorVertexAttribute());
// We don't use the GrPaint's color in this case because it's been premultiplied by
// alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by
// the mask texture color. The end result is that we get
// mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor
int a = SkColorGetA(fSkPaint.getColor());
// paintAlpha
- drawState->setColor(SkColorSetARGB(a, a, a, a));
+ drawState.setColor(SkColorSetARGB(a, a, a, a));
// paintColor
- drawState->setBlendConstant(colorNoPreMul);
- drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
+ drawState.setBlendConstant(colorNoPreMul);
+ drawState.setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
} else {
+ if (0xFF == GrColorUnpackA(fPaint.getColor())) {
+ drawState.setHint(GrDrawState::kVertexColorsAreOpaque_Hint, true);
+ }
// set back to normal in case we took LCD path previously.
- drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
+ drawState.setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
// We're using per-vertex color.
- SkASSERT(drawState->hasColorVertexAttribute());
+ SkASSERT(drawState.hasColorVertexAttribute());
}
int nGlyphs = fCurrVertex / kVerticesPerGlyph;
fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
- fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
+ fDrawTarget->drawIndexedInstances(&drawState,
+ kTriangles_GrPrimitiveType,
nGlyphs,
- kVerticesPerGlyph, kIndicesPerGlyph, &fVertexBounds);
+ kVerticesPerGlyph,
+ kIndicesPerGlyph,
+ &fVertexBounds);
fDrawTarget->resetVertexSource();
fVertices = NULL;
fTotalVertexCount -= fCurrVertex;
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 974aff4..baa7564 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -25,10 +25,8 @@
class GrPaint;
class GrTexture;
-class GrDrawState : public SkRefCnt {
+class GrDrawState {
public:
- SK_DECLARE_INST_COUNT(GrDrawState)
-
GrDrawState() {
SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
this->reset();
@@ -42,7 +40,7 @@
/**
* Copies another draw state.
**/
- GrDrawState(const GrDrawState& state) : INHERITED() {
+ GrDrawState(const GrDrawState& state) {
SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
*this = state;
}
@@ -872,8 +870,6 @@
mutable bool fCoverageProcInfoValid;
friend class GrOptDrawState;
-
- typedef SkRefCnt INHERITED;
};
GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 3d858c3..cd1e0b5 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -93,9 +93,6 @@
, fContext(context)
, fGpuTraceMarkerCount(0) {
SkASSERT(context);
- fDrawState = &fDefaultDrawState;
- // We assume that fDrawState always owns a ref to the object it points at.
- fDefaultDrawState.ref();
GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
#ifdef SK_DEBUG
geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
@@ -112,7 +109,6 @@
SkDEBUGCODE(GeometrySrcState& geoSrc = fGeoSrcStateStack.back());
SkASSERT(kNone_GeometrySrcType == geoSrc.fIndexSrc);
SkASSERT(kNone_GeometrySrcType == geoSrc.fVertexSrc);
- fDrawState->unref();
}
void GrDrawTarget::releaseGeometry() {
@@ -133,18 +129,6 @@
return fClip;
}
-void GrDrawTarget::setDrawState(GrDrawState* drawState) {
- SkASSERT(fDrawState);
- if (NULL == drawState) {
- drawState = &fDefaultDrawState;
- }
- if (fDrawState != drawState) {
- fDrawState->unref();
- drawState->ref();
- fDrawState = drawState;
- }
-}
-
bool GrDrawTarget::reserveVertexSpace(size_t vertexSize,
int vertexCount,
void** vertices) {
@@ -191,11 +175,11 @@
}
bool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount,
+ size_t vertexStride,
int indexCount,
void** vertices,
void** indices) {
- size_t vertexStride = this->drawState()->getVertexStride();
- this->willReserveVertexAndIndexSpace(vertexCount, indexCount);
+ this->willReserveVertexAndIndexSpace(vertexCount, vertexStride, indexCount);
if (vertexCount) {
if (!this->reserveVertexSpace(vertexStride, vertexCount, vertices)) {
if (indexCount) {
@@ -215,7 +199,8 @@
return true;
}
-bool GrDrawTarget::geometryHints(int32_t* vertexCount,
+bool GrDrawTarget::geometryHints(size_t vertexStride,
+ int32_t* vertexCount,
int32_t* indexCount) const {
if (vertexCount) {
*vertexCount = -1;
@@ -266,13 +251,13 @@
}
}
-void GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer) {
+void GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer, size_t vertexStride) {
this->releasePreviousVertexSource();
GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
geoSrc.fVertexSrc = kBuffer_GeometrySrcType;
geoSrc.fVertexBuffer = buffer;
buffer->ref();
- geoSrc.fVertexSize = this->drawState()->getVertexStride();
+ geoSrc.fVertexSize = vertexStride;
}
void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
@@ -320,10 +305,12 @@
////////////////////////////////////////////////////////////////////////////////
-bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
- int startIndex, int vertexCount,
+bool GrDrawTarget::checkDraw(const GrDrawState& drawState,
+ GrPrimitiveType type,
+ int startVertex,
+ int startIndex,
+ int vertexCount,
int indexCount) const {
- const GrDrawState& drawState = this->getDrawState();
#ifdef SK_DEBUG
const GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
int maxVertex = startVertex + vertexCount;
@@ -395,13 +382,15 @@
return true;
}
-bool GrDrawTarget::setupDstReadIfNecessary(GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds) {
- if (this->caps()->dstReadInShaderSupport() || !this->getDrawState().willEffectReadDstColor()) {
+bool GrDrawTarget::setupDstReadIfNecessary(GrDrawState* ds,
+ GrDeviceCoordTexture* dstCopy,
+ const SkRect* drawBounds) {
+ if (this->caps()->dstReadInShaderSupport() || !ds->willEffectReadDstColor()) {
return true;
}
- GrRenderTarget* rt = this->drawState()->getRenderTarget();
SkIRect copyRect;
const GrClipData* clip = this->getClip();
+ GrRenderTarget* rt = ds->getRenderTarget();
clip->getConservativeBounds(rt, ©Rect);
if (drawBounds) {
@@ -443,18 +432,22 @@
}
}
-void GrDrawTarget::drawIndexed(GrPrimitiveType type,
+void GrDrawTarget::drawIndexed(GrDrawState* ds,
+ GrPrimitiveType type,
int startVertex,
int startIndex,
int vertexCount,
int indexCount,
const SkRect* devBounds) {
- if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexCount, indexCount)) {
+ SkASSERT(ds);
+ if (indexCount > 0 &&
+ this->checkDraw(*ds, type, startVertex, startIndex, vertexCount, indexCount)) {
+
// Setup clip
GrClipMaskManager::ScissorState scissorState;
GrDrawState::AutoRestoreEffects are;
GrDrawState::AutoRestoreStencil ars;
- if (!this->setupClip(devBounds, &are, &ars, &scissorState)) {
+ if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) {
return;
}
@@ -473,23 +466,26 @@
info.setDevBounds(*devBounds);
}
// TODO: We should continue with incorrect blending.
- if (!this->setupDstReadIfNecessary(&info)) {
+ if (!this->setupDstReadIfNecessary(ds, &info)) {
return;
}
- this->onDraw(info, scissorState);
+ this->onDraw(*ds, info, scissorState);
}
}
-void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
+void GrDrawTarget::drawNonIndexed(GrDrawState* ds,
+ GrPrimitiveType type,
int startVertex,
int vertexCount,
const SkRect* devBounds) {
- if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, -1)) {
+ SkASSERT(ds);
+ if (vertexCount > 0 && this->checkDraw(*ds, type, startVertex, -1, vertexCount, -1)) {
+
// Setup clip
GrClipMaskManager::ScissorState scissorState;
GrDrawState::AutoRestoreEffects are;
GrDrawState::AutoRestoreStencil ars;
- if (!this->setupClip(devBounds, &are, &ars, &scissorState)) {
+ if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) {
return;
}
@@ -509,10 +505,10 @@
}
// TODO: We should continue with incorrect blending.
- if (!this->setupDstReadIfNecessary(&info)) {
+ if (!this->setupDstReadIfNecessary(ds, &info)) {
return;
}
- this->onDraw(info, scissorState);
+ this->onDraw(*ds, info, scissorState);
}
}
@@ -535,6 +531,7 @@
}
void GrDrawTarget::getPathStencilSettingsForFilltype(GrPathRendering::FillType fill,
+ const GrStencilBuffer* sb,
GrStencilSettings* outStencilSettings) {
switch (fill) {
@@ -547,94 +544,112 @@
*outStencilSettings = even_odd_path_stencil_settings();
break;
}
- this->clipMaskManager()->adjustPathStencilParams(outStencilSettings);
+ this->clipMaskManager()->adjustPathStencilParams(sb, outStencilSettings);
}
-void GrDrawTarget::stencilPath(const GrPath* path, GrPathRendering::FillType fill) {
+void GrDrawTarget::stencilPath(GrDrawState* ds,
+ const GrPath* path,
+ GrPathRendering::FillType fill) {
// TODO: extract portions of checkDraw that are relevant to path stenciling.
SkASSERT(path);
SkASSERT(this->caps()->pathRenderingSupport());
+ SkASSERT(ds);
// Setup clip
GrClipMaskManager::ScissorState scissorState;
GrDrawState::AutoRestoreEffects are;
GrDrawState::AutoRestoreStencil ars;
- if (!this->setupClip(NULL, &are, &ars, &scissorState)) {
+ if (!this->setupClip(NULL, &are, &ars, ds, &scissorState)) {
return;
}
// set stencil settings for path
GrStencilSettings stencilSettings;
- this->getPathStencilSettingsForFilltype(fill, &stencilSettings);
+ this->getPathStencilSettingsForFilltype(fill,
+ ds->getRenderTarget()->getStencilBuffer(),
+ &stencilSettings);
- this->onStencilPath(path, scissorState, stencilSettings);
+ this->onStencilPath(*ds, path, scissorState, stencilSettings);
}
-void GrDrawTarget::drawPath(const GrPath* path, GrPathRendering::FillType fill) {
+void GrDrawTarget::drawPath(GrDrawState* ds,
+ const GrPath* path,
+ GrPathRendering::FillType fill) {
// TODO: extract portions of checkDraw that are relevant to path rendering.
SkASSERT(path);
SkASSERT(this->caps()->pathRenderingSupport());
+ SkASSERT(ds);
SkRect devBounds = path->getBounds();
- SkMatrix viewM = this->drawState()->getViewMatrix();
+ SkMatrix viewM = ds->getViewMatrix();
viewM.mapRect(&devBounds);
// Setup clip
GrClipMaskManager::ScissorState scissorState;
GrDrawState::AutoRestoreEffects are;
GrDrawState::AutoRestoreStencil ars;
- if (!this->setupClip(&devBounds, &are, &ars, &scissorState)) {
+ if (!this->setupClip(&devBounds, &are, &ars, ds, &scissorState)) {
return;
}
// set stencil settings for path
GrStencilSettings stencilSettings;
- this->getPathStencilSettingsForFilltype(fill, &stencilSettings);
+ this->getPathStencilSettingsForFilltype(fill,
+ ds->getRenderTarget()->getStencilBuffer(),
+ &stencilSettings);
GrDeviceCoordTexture dstCopy;
- if (!this->setupDstReadIfNecessary(&dstCopy, &devBounds)) {
+ if (!this->setupDstReadIfNecessary(ds, &dstCopy, &devBounds)) {
return;
}
- this->onDrawPath(path, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
+ this->onDrawPath(*ds, path, scissorState, stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
}
-void GrDrawTarget::drawPaths(const GrPathRange* pathRange,
- const uint32_t indices[], int count,
- const float transforms[], PathTransformType transformsType,
+void GrDrawTarget::drawPaths(GrDrawState* ds,
+ const GrPathRange* pathRange,
+ const uint32_t indices[],
+ int count,
+ const float transforms[],
+ PathTransformType transformsType,
GrPathRendering::FillType fill) {
SkASSERT(this->caps()->pathRenderingSupport());
SkASSERT(pathRange);
SkASSERT(indices);
SkASSERT(transforms);
+ SkASSERT(ds);
// Setup clip
GrClipMaskManager::ScissorState scissorState;
GrDrawState::AutoRestoreEffects are;
GrDrawState::AutoRestoreStencil ars;
- if (!this->setupClip(NULL, &are, &ars, &scissorState)) {
+ if (!this->setupClip(NULL, &are, &ars, ds, &scissorState)) {
return;
}
// set stencil settings for path
GrStencilSettings stencilSettings;
- this->getPathStencilSettingsForFilltype(fill, &stencilSettings);
+ this->getPathStencilSettingsForFilltype(fill,
+ ds->getRenderTarget()->getStencilBuffer(),
+ &stencilSettings);
// Don't compute a bounding box for setupDstReadIfNecessary(), we'll opt
// instead for it to just copy the entire dst. Realistically this is a moot
// point, because any context that supports NV_path_rendering will also
// support NV_blend_equation_advanced.
GrDeviceCoordTexture dstCopy;
- if (!this->setupDstReadIfNecessary(&dstCopy, NULL)) {
+ if (!this->setupDstReadIfNecessary(ds, &dstCopy, NULL)) {
return;
}
- this->onDrawPaths(pathRange, indices, count, transforms, transformsType, scissorState,
+ this->onDrawPaths(*ds, pathRange, indices, count, transforms, transformsType, scissorState,
stencilSettings, dstCopy.texture() ? &dstCopy : NULL);
}
-void GrDrawTarget::clear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
+void GrDrawTarget::clear(const SkIRect* rect,
+ GrColor color,
+ bool canIgnoreRect,
GrRenderTarget* renderTarget) {
if (fCaps->useDrawInsteadOfClear()) {
// This works around a driver bug with clear by drawing a rect instead.
@@ -646,14 +661,13 @@
// We first issue a discard() since that may help tilers.
this->discard(renderTarget);
}
- AutoStateRestore asr(this, kReset_ASRInit, &SkMatrix::I());
- this->drawState()->setColor(color);
- this->drawState()->disableState(GrDrawState::kClip_StateBit);
- this->drawState()->disableState(GrDrawState::kHWAntialias_StateBit);
- this->drawState()->setRenderTarget(renderTarget);
+ GrDrawState drawState;
- this->drawSimpleRect(*rect);
+ drawState.setColor(color);
+ drawState.setRenderTarget(renderTarget);
+
+ this->drawSimpleRect(&drawState, *rect);
} else {
this->onClear(rect, color, canIgnoreRect, renderTarget);
}
@@ -700,11 +714,14 @@
////////////////////////////////////////////////////////////////////////////////
-void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
+void GrDrawTarget::drawIndexedInstances(GrDrawState* ds,
+ GrPrimitiveType type,
int instanceCount,
int verticesPerInstance,
int indicesPerInstance,
const SkRect* devBounds) {
+ SkASSERT(ds);
+
if (!verticesPerInstance || !indicesPerInstance) {
return;
}
@@ -718,7 +735,7 @@
GrClipMaskManager::ScissorState scissorState;
GrDrawState::AutoRestoreEffects are;
GrDrawState::AutoRestoreStencil ars;
- if (!this->setupClip(devBounds, &are, &ars, &scissorState)) {
+ if (!this->setupClip(devBounds, &are, &ars, ds, &scissorState)) {
return;
}
@@ -734,21 +751,21 @@
info.setDevBounds(*devBounds);
}
// TODO: We should continue with incorrect blending.
- if (!this->setupDstReadIfNecessary(&info)) {
+ if (!this->setupDstReadIfNecessary(ds, &info)) {
return;
}
-
while (instanceCount) {
info.fInstanceCount = SkTMin(instanceCount, maxInstancesPerDraw);
info.fVertexCount = info.fInstanceCount * verticesPerInstance;
info.fIndexCount = info.fInstanceCount * indicesPerInstance;
- if (this->checkDraw(type,
+ if (this->checkDraw(*ds,
+ type,
info.fStartVertex,
info.fStartIndex,
info.fVertexCount,
info.fIndexCount)) {
- this->onDraw(info, scissorState);
+ this->onDraw(*ds, info, scissorState);
}
info.fStartVertex += info.fVertexCount;
instanceCount -= info.fInstanceCount;
@@ -757,82 +774,13 @@
////////////////////////////////////////////////////////////////////////////////
-GrDrawTarget::AutoStateRestore::AutoStateRestore() {
- fDrawTarget = NULL;
-}
-
-GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target,
- ASRInit init,
- const SkMatrix* vm) {
- fDrawTarget = NULL;
- this->set(target, init, vm);
-}
-
-GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
- if (fDrawTarget) {
- fDrawTarget->setDrawState(fSavedState);
- fSavedState->unref();
- }
-}
-
-void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init, const SkMatrix* vm) {
- SkASSERT(NULL == fDrawTarget);
- fDrawTarget = target;
- fSavedState = target->drawState();
- SkASSERT(fSavedState);
- fSavedState->ref();
- if (kReset_ASRInit == init) {
- if (NULL == vm) {
- // calls the default cons
- fTempState.init();
- } else {
- SkNEW_IN_TLAZY(&fTempState, GrDrawState, (*vm));
- }
- } else {
- SkASSERT(kPreserve_ASRInit == init);
- if (NULL == vm) {
- fTempState.set(*fSavedState);
- } else {
- SkNEW_IN_TLAZY(&fTempState, GrDrawState, (*fSavedState, *vm));
- }
- }
- target->setDrawState(fTempState.get());
-}
-
-bool GrDrawTarget::AutoStateRestore::setIdentity(GrDrawTarget* target, ASRInit init) {
- SkASSERT(NULL == fDrawTarget);
- fDrawTarget = target;
- fSavedState = target->drawState();
- SkASSERT(fSavedState);
- fSavedState->ref();
- if (kReset_ASRInit == init) {
- // calls the default cons
- fTempState.init();
- } else {
- SkASSERT(kPreserve_ASRInit == init);
- // calls the copy cons
- fTempState.set(*fSavedState);
- if (!fTempState.get()->setIdentityViewMatrix()) {
- // let go of any resources held by the temp
- fTempState.get()->reset();
- fDrawTarget = NULL;
- fSavedState->unref();
- fSavedState = NULL;
- return false;
- }
- }
- target->setDrawState(fTempState.get());
- return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-
GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
GrDrawTarget* target,
int vertexCount,
+ size_t vertexStride,
int indexCount) {
fTarget = NULL;
- this->set(target, vertexCount, indexCount);
+ this->set(target, vertexCount, vertexStride, indexCount);
}
GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
@@ -845,12 +793,14 @@
bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget* target,
int vertexCount,
+ size_t vertexStride,
int indexCount) {
this->reset();
fTarget = target;
bool success = true;
if (fTarget) {
success = target->reserveVertexAndIndexSpace(vertexCount,
+ vertexStride,
indexCount,
&fVertices,
&fIndices);
@@ -966,23 +916,23 @@
GrRenderTarget* rt = dst->asRenderTarget();
GrTexture* tex = src->asTexture();
- GrDrawTarget::AutoStateRestore asr(this, kReset_ASRInit);
- this->drawState()->setRenderTarget(rt);
+ GrDrawState drawState;
+ drawState.setRenderTarget(rt);
SkMatrix matrix;
matrix.setTranslate(SkIntToScalar(clippedSrcRect.fLeft - clippedDstPoint.fX),
SkIntToScalar(clippedSrcRect.fTop - clippedDstPoint.fY));
matrix.postIDiv(tex->width(), tex->height());
- this->drawState()->addColorTextureProcessor(tex, matrix);
+ drawState.addColorTextureProcessor(tex, matrix);
SkIRect dstRect = SkIRect::MakeXYWH(clippedDstPoint.fX,
clippedDstPoint.fY,
clippedSrcRect.width(),
clippedSrcRect.height());
- this->drawSimpleRect(dstRect);
+ this->drawSimpleRect(&drawState, dstRect);
return true;
}
-bool GrDrawTarget::canCopySurface(GrSurface* dst,
- GrSurface* src,
+bool GrDrawTarget::canCopySurface(const GrSurface* dst,
+ const GrSurface* src,
const SkIRect& srcRect,
const SkIPoint& dstPoint) {
SkASSERT(dst);
@@ -1187,10 +1137,12 @@
bool GrClipTarget::setupClip(const SkRect* devBounds,
GrDrawState::AutoRestoreEffects* are,
GrDrawState::AutoRestoreStencil* ars,
+ GrDrawState* ds,
GrClipMaskManager::ScissorState* scissorState) {
- return fClipMaskManager.setupClipping(this->getClip(),
- devBounds,
+ return fClipMaskManager.setupClipping(ds,
are,
ars,
- scissorState);
+ scissorState,
+ this->getClip(),
+ devBounds);
}
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 75a2f25..a41fc43 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -67,34 +67,6 @@
const GrClipData* getClip() const;
/**
- * Sets the draw state object for the draw target. Note that this does not
- * make a copy. The GrDrawTarget will take a reference to passed object.
- * Passing NULL will cause the GrDrawTarget to use its own internal draw
- * state object rather than an externally provided one.
- */
- void setDrawState(GrDrawState* drawState);
-
- /**
- * Read-only access to the GrDrawTarget's current draw state.
- */
- const GrDrawState& getDrawState() const { return *fDrawState; }
-
- /**
- * Read-write access to the GrDrawTarget's current draw state. Note that
- * this doesn't ref.
- */
- GrDrawState* drawState() { return fDrawState; }
-
- /** When we're using coverage AA but the blend is incompatible (given gpu
- * limitations) we should disable AA. */
- bool shouldDisableCoverageAAForBlend() const {
- // Enable below if we should draw with AA even when it produces
- // incorrect blending.
- // return false;
- return !this->getDrawState().couldApplyCoverage(*this->caps());
- }
-
- /**
* There are three types of "sources" of geometry (vertices and indices) for
* draw calls made on the target. When performing an indexed draw, the
* indices and vertices can use different source types. Once a source is
@@ -168,6 +140,7 @@
* non-zero. Illegal to pass NULL if indexCount > 0.
*/
bool reserveVertexAndIndexSpace(int vertexCount,
+ size_t vertexStride,
int indexCount,
void** vertices,
void** indices);
@@ -194,8 +167,7 @@
*
* @return true if target should be flushed based on the input values.
*/
- virtual bool geometryHints(int* vertexCount,
- int* indexCount) const;
+ virtual bool geometryHints(size_t vertexStride, int* vertexCount, int* indexCount) const;
/**
* Sets source of vertex data for the next draw. Data does not have to be
@@ -205,7 +177,7 @@
* unlocked before draw call. Vertex size is queried
* from current GrDrawState.
*/
- void setVertexSourceToBuffer(const GrVertexBuffer* buffer);
+ void setVertexSourceToBuffer(const GrVertexBuffer* buffer, size_t vertexStride);
/**
* Sets source of index data for the next indexed draw. Data does not have
@@ -267,7 +239,8 @@
* @param devBounds optional bounds hint. This is a promise from the caller,
* not a request for clipping.
*/
- void drawIndexed(GrPrimitiveType type,
+ void drawIndexed(GrDrawState*,
+ GrPrimitiveType type,
int startVertex,
int startIndex,
int vertexCount,
@@ -285,7 +258,8 @@
* @param devBounds optional bounds hint. This is a promise from the caller,
* not a request for clipping.
*/
- void drawNonIndexed(GrPrimitiveType type,
+ void drawNonIndexed(GrDrawState*,
+ GrPrimitiveType type,
int startVertex,
int vertexCount,
const SkRect* devBounds = NULL);
@@ -296,13 +270,13 @@
* on the draw state (if possible in the 3D API). Note, we will never have an inverse fill
* with stencil path
*/
- void stencilPath(const GrPath*, GrPathRendering::FillType fill);
+ void stencilPath(GrDrawState*, const GrPath*, GrPathRendering::FillType fill);
/**
* Draws a path. Fill must not be a hairline. It will respect the HW
* antialias flag on the draw state (if possible in the 3D API).
*/
- void drawPath(const GrPath*, GrPathRendering::FillType fill);
+ void drawPath(GrDrawState*, const GrPath*, GrPathRendering::FillType fill);
/**
* Draws many paths. It will respect the HW
@@ -316,9 +290,11 @@
PathTransformSize(transformsType) * count elements
* @param fill Fill type for drawing all the paths
*/
- void drawPaths(const GrPathRange* pathRange,
- const uint32_t indices[], int count,
- const float transforms[], PathTransformType transformsType,
+ void drawPaths(GrDrawState*, const GrPathRange* pathRange,
+ const uint32_t indices[],
+ int count,
+ const float transforms[],
+ PathTransformType transformsType,
GrPathRendering::FillType fill);
/**
@@ -333,22 +309,23 @@
* then srcRect will be transformed by srcMatrix.
* srcMatrix can be NULL when no srcMatrix is desired.
*/
- void drawRect(const SkRect& rect,
+ void drawRect(GrDrawState* ds,
+ const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix) {
AutoGeometryPush agp(this);
- this->onDrawRect(rect, localRect, localMatrix);
+ this->onDrawRect(ds, rect, localRect, localMatrix);
}
/**
* Helper for drawRect when the caller doesn't need separate local rects or matrices.
*/
- void drawSimpleRect(const SkRect& rect) {
- this->drawRect(rect, NULL, NULL);
+ void drawSimpleRect(GrDrawState* ds, const SkRect& rect) {
+ this->drawRect(ds, rect, NULL, NULL);
}
- void drawSimpleRect(const SkIRect& irect) {
+ void drawSimpleRect(GrDrawState* ds, const SkIRect& irect) {
SkRect rect = SkRect::Make(irect);
- this->drawRect(rect, NULL, NULL);
+ this->drawRect(ds, rect, NULL, NULL);
}
/**
@@ -381,7 +358,8 @@
* @param devBounds optional bounds hint. This is a promise from the caller,
* not a request for clipping.
*/
- void drawIndexedInstances(GrPrimitiveType type,
+ void drawIndexedInstances(GrDrawState*,
+ GrPrimitiveType type,
int instanceCount,
int verticesPerInstance,
int indicesPerInstance,
@@ -392,7 +370,9 @@
* rect is NULL, otherwise just the rect. If canIgnoreRect is set then the entire render target
* can be optionally cleared.
*/
- void clear(const SkIRect* rect, GrColor color, bool canIgnoreRect,
+ void clear(const SkIRect* rect,
+ GrColor color,
+ bool canIgnoreRect,
GrRenderTarget* renderTarget);
/**
@@ -438,8 +418,8 @@
* Function that determines whether a copySurface call would succeed without
* performing the copy.
*/
- virtual bool canCopySurface(GrSurface* dst,
- GrSurface* src,
+ virtual bool canCopySurface(const GrSurface* dst,
+ const GrSurface* src,
const SkIRect& srcRect,
const SkIPoint& dstPoint);
@@ -457,136 +437,19 @@
*/
virtual void purgeResources() {};
- class DrawInfo;
- /**
- * For subclass internal use to invoke a call to onDraw(). See DrawInfo below.
- */
- void executeDraw(const DrawInfo& info,
- const GrClipMaskManager::ScissorState& scissorState) {
- this->onDraw(info, scissorState);
- }
-
- /**
- * For subclass internal use to invoke a call to onStencilPath().
- */
- void executeStencilPath(const GrPath* path,
- const GrClipMaskManager::ScissorState& scissorState,
- const GrStencilSettings& stencilSettings) {
- this->onStencilPath(path, scissorState, stencilSettings);
- }
-
- /**
- * For subclass internal use to invoke a call to onDrawPath().
- */
- void executeDrawPath(const GrPath* path,
- const GrClipMaskManager::ScissorState& scissorState,
- const GrStencilSettings& stencilSettings,
- const GrDeviceCoordTexture* dstCopy) {
- this->onDrawPath(path, scissorState, stencilSettings, dstCopy);
- }
-
- /**
- * For subclass internal use to invoke a call to onDrawPaths().
- */
- void executeDrawPaths(const GrPathRange* pathRange,
- const uint32_t indices[],
- int count,
- const float transforms[],
- PathTransformType transformsType,
- const GrClipMaskManager::ScissorState& scissorState,
- const GrStencilSettings& stencilSettings,
- const GrDeviceCoordTexture* dstCopy) {
- this->onDrawPaths(pathRange, indices, count, transforms, transformsType,
- scissorState, stencilSettings, dstCopy);
- }
-
- ////////////////////////////////////////////////////////////////////////////
-
- /**
- * See AutoStateRestore below.
- */
- enum ASRInit {
- kPreserve_ASRInit,
- kReset_ASRInit
- };
-
- /**
- * Saves off the current state and restores it in the destructor. It will
- * install a new GrDrawState object on the target (setDrawState) and restore
- * the previous one in the destructor. The caller should call drawState() to
- * get the new draw state after the ASR is installed.
- *
- * GrDrawState* state = target->drawState();
- * AutoStateRestore asr(target, GrDrawTarget::kReset_ASRInit).
- * state->setRenderTarget(rt); // state refers to the GrDrawState set on
- * // target before asr was initialized.
- * // Therefore, rt is set on the GrDrawState
- * // that will be restored after asr's
- * // destructor rather than target's current
- * // GrDrawState.
- */
- class AutoStateRestore : public ::SkNoncopyable {
- public:
- /**
- * Default ASR will have no effect unless set() is subsequently called.
- */
- AutoStateRestore();
-
- /**
- * Saves the state on target. The state will be restored when the ASR
- * is destroyed. If this constructor is used do not call set().
- *
- * @param init Should the newly installed GrDrawState be a copy of the
- * previous state or a default-initialized GrDrawState.
- * @param viewMatrix Optional view matrix. If init = kPreserve then the draw state's
- * matrix will be preconcat'ed with the param. All stages will be
- updated to compensate for the matrix change. If init == kReset
- then the draw state's matrix will be this matrix.
- */
- AutoStateRestore(GrDrawTarget* target, ASRInit init, const SkMatrix* viewMatrix = NULL);
-
- ~AutoStateRestore();
-
- /**
- * Saves the state on target. The state will be restored when the ASR
- * is destroyed. This should only be called once per ASR object and only
- * when the default constructor was used. For nested saves use multiple
- * ASR objects.
- *
- * @param init Should the newly installed GrDrawState be a copy of the
- * previous state or a default-initialized GrDrawState.
- * @param viewMatrix Optional view matrix. If init = kPreserve then the draw state's
- * matrix will be preconcat'ed with the param. All stages will be
- updated to compensate for the matrix change. If init == kReset
- then the draw state's matrix will be this matrix.
- */
- void set(GrDrawTarget* target, ASRInit init, const SkMatrix* viewMatrix = NULL);
-
- /**
- * Like set() but makes the view matrix identity. When init is kReset it is as though
- * NULL was passed to set's viewMatrix param. When init is kPreserve it is as though
- * the inverse view matrix was passed. If kPreserve is passed and the draw state's matrix
- * is not invertible then this may fail.
- */
- bool setIdentity(GrDrawTarget* target, ASRInit init);
-
- private:
- GrDrawTarget* fDrawTarget;
- SkTLazy<GrDrawState> fTempState;
- GrDrawState* fSavedState;
- };
-
////////////////////////////////////////////////////////////////////////////
class AutoReleaseGeometry : public ::SkNoncopyable {
public:
AutoReleaseGeometry(GrDrawTarget* target,
int vertexCount,
+ size_t vertexStride,
int indexCount);
AutoReleaseGeometry();
~AutoReleaseGeometry();
bool set(GrDrawTarget* target,
int vertexCount,
+ size_t vertexStride,
int indexCount);
bool succeeded() const { return SkToBool(fTarget); }
void* vertices() const { SkASSERT(this->succeeded()); return fVertices; }
@@ -632,8 +495,7 @@
*/
class AutoGeometryPush : public ::SkNoncopyable {
public:
- AutoGeometryPush(GrDrawTarget* target)
- : fAttribRestore(target->drawState()) {
+ AutoGeometryPush(GrDrawTarget* target) {
SkASSERT(target);
fTarget = target;
target->pushGeometrySource();
@@ -643,32 +505,6 @@
private:
GrDrawTarget* fTarget;
- GrDrawState::AutoVertexAttribRestore fAttribRestore;
- };
-
- /**
- * Combination of AutoGeometryPush and AutoStateRestore. The vertex attribs will be in default
- * state regardless of ASRInit value.
- */
- class AutoGeometryAndStatePush : public ::SkNoncopyable {
- public:
- AutoGeometryAndStatePush(GrDrawTarget* target,
- ASRInit init,
- const SkMatrix* viewMatrix = NULL)
- : fState(target, init, viewMatrix) {
- SkASSERT(target);
- fTarget = target;
- target->pushGeometrySource();
- if (kPreserve_ASRInit == init) {
- target->drawState()->setDefaultVertexAttribs();
- }
- }
-
- ~AutoGeometryAndStatePush() { fTarget->popGeometrySource(); }
-
- private:
- AutoStateRestore fState;
- GrDrawTarget* fTarget;
};
///////////////////////////////////////////////////////////////////////////
@@ -830,15 +666,19 @@
// Makes a copy of the dst if it is necessary for the draw. Returns false if a copy is required
// but couldn't be made. Otherwise, returns true. This method needs to be protected because it
// needs to be accessed by GLPrograms to setup a correct drawstate
- bool setupDstReadIfNecessary(DrawInfo* info) {
- return this->setupDstReadIfNecessary(&info->fDstCopy, info->getDevBounds());
+ bool setupDstReadIfNecessary(GrDrawState* ds, DrawInfo* info) {
+ return this->setupDstReadIfNecessary(ds, &info->fDstCopy, info->getDevBounds());
}
- bool setupDstReadIfNecessary(GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds);
+ bool setupDstReadIfNecessary(GrDrawState*,
+ GrDeviceCoordTexture* dstCopy,
+ const SkRect* drawBounds);
private:
// A subclass can optionally overload this function to be notified before
// vertex and index space is reserved.
- virtual void willReserveVertexAndIndexSpace(int vertexCount, int indexCount) {}
+ virtual void willReserveVertexAndIndexSpace(int vertexCount,
+ size_t vertexStride,
+ int indexCount) {}
// implemented by subclass to allocate space for reserved geom
virtual bool onReserveVertexSpace(size_t vertexSize, int vertexCount, void** vertices) = 0;
@@ -850,20 +690,26 @@
virtual void geometrySourceWillPush() = 0;
virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) = 0;
// subclass called to perform drawing
- virtual void onDraw(const DrawInfo&, const GrClipMaskManager::ScissorState&) = 0;
+ virtual void onDraw(const GrDrawState&,
+ const DrawInfo&,
+ const GrClipMaskManager::ScissorState&) = 0;
// TODO copy in order drawbuffer onDrawRect to here
- virtual void onDrawRect(const SkRect& rect,
+ virtual void onDrawRect(GrDrawState*,
+ const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix) = 0;
- virtual void onStencilPath(const GrPath*,
+ virtual void onStencilPath(const GrDrawState&,
+ const GrPath*,
const GrClipMaskManager::ScissorState&,
const GrStencilSettings&) = 0;
- virtual void onDrawPath(const GrPath*,
+ virtual void onDrawPath(const GrDrawState&,
+ const GrPath*,
const GrClipMaskManager::ScissorState&,
const GrStencilSettings&,
const GrDeviceCoordTexture* dstCopy) = 0;
- virtual void onDrawPaths(const GrPathRange*,
+ virtual void onDrawPaths(const GrDrawState&,
+ const GrPathRange*,
const uint32_t indices[],
int count,
const float transforms[],
@@ -884,8 +730,11 @@
// called by drawIndexed and drawNonIndexed. Use a negative indexCount to
// indicate non-indexed drawing.
- bool checkDraw(GrPrimitiveType type, int startVertex,
- int startIndex, int vertexCount,
+ bool checkDraw(const GrDrawState&,
+ GrPrimitiveType type,
+ int startVertex,
+ int startIndex,
+ int vertexCount,
int indexCount) const;
// called when setting a new vert/idx source to unref prev vb/ib
void releasePreviousVertexSource();
@@ -893,11 +742,14 @@
// Check to see if this set of draw commands has been sent out
virtual bool isIssued(uint32_t drawID) { return true; }
- void getPathStencilSettingsForFilltype(GrPathRendering::FillType, GrStencilSettings*);
+ void getPathStencilSettingsForFilltype(GrPathRendering::FillType,
+ const GrStencilBuffer*,
+ GrStencilSettings*);
virtual GrClipMaskManager* clipMaskManager() = 0;
virtual bool setupClip(const SkRect* devBounds,
GrDrawState::AutoRestoreEffects* are,
GrDrawState::AutoRestoreStencil* ars,
+ GrDrawState*,
GrClipMaskManager::ScissorState* scissorState) = 0;
enum {
@@ -905,8 +757,6 @@
};
SkSTArray<kPreallocGeoSrcStateStackCnt, GeometrySrcState, true> fGeoSrcStateStack;
const GrClipData* fClip;
- GrDrawState* fDrawState;
- GrDrawState fDefaultDrawState;
// The context owns us, not vice-versa, so this ptr is not ref'ed by DrawTarget.
GrContext* fContext;
// To keep track that we always have at least as many debug marker adds as removes
@@ -959,6 +809,7 @@
virtual bool setupClip(const SkRect* devBounds,
GrDrawState::AutoRestoreEffects* are,
GrDrawState::AutoRestoreStencil* ars,
+ GrDrawState*,
GrClipMaskManager::ScissorState* scissorState) SK_OVERRIDE;
typedef GrDrawTarget INHERITED;
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index dfc71fe..5c25927 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -360,8 +360,8 @@
// classes must keep this consistent with their implementation of onCopySurface(). The inputs
// are the same as onCopySurface(), i.e. srcRect and dstPoint are clipped to be inside the src
// and dst bounds.
- virtual bool canCopySurface(GrSurface* dst,
- GrSurface* src,
+ virtual bool canCopySurface(const GrSurface* dst,
+ const GrSurface* src,
const SkIRect& srcRect,
const SkIPoint& dstPoint) = 0;
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index c180cc6..b0504b7 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -133,34 +133,33 @@
static inline bool cmd_has_trace_marker(uint8_t cmd) { return SkToBool(cmd & kTraceCmdBit); }
-void GrInOrderDrawBuffer::onDrawRect(const SkRect& rect,
+void GrInOrderDrawBuffer::onDrawRect(GrDrawState* ds,
+ const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix) {
- GrDrawState* drawState = this->drawState();
- GrDrawState::AutoRestoreEffects are(drawState);
+ GrDrawState::AutoRestoreEffects are(ds);
- GrColor color = drawState->getColor();
+ GrColor color = ds->getColor();
+ set_vertex_attributes(ds, SkToBool(localRect), color);
- set_vertex_attributes(drawState, SkToBool(localRect), color);
-
- AutoReleaseGeometry geo(this, 4, 0);
+ AutoReleaseGeometry geo(this, 4, ds->getVertexStride(), 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return;
}
// Go to device coords to allow batching across matrix changes
- SkMatrix matrix = drawState->getViewMatrix();
+ SkMatrix matrix = ds->getViewMatrix();
// When the caller has provided an explicit source rect for a stage then we don't want to
// modify that stage's matrix. Otherwise if the effect is generating its source rect from
// the vertex positions then we have to account for the view matrix change.
GrDrawState::AutoViewMatrixRestore avmr;
- if (!avmr.setIdentity(drawState)) {
+ if (!avmr.setIdentity(ds)) {
return;
}
- size_t vstride = drawState->getVertexStride();
+ size_t vstride = ds->getVertexStride();
geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vstride);
matrix.mapPointsWithStride(geo.positions(), vstride, 4);
@@ -189,19 +188,16 @@
}
this->setIndexSourceToBuffer(this->getContext()->getQuadIndexBuffer());
- this->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds);
-
- // to ensure that stashing the drawState ptr is valid
- SkASSERT(this->drawState() == drawState);
+ this->drawIndexedInstances(ds, kTriangles_GrPrimitiveType, 1, 4, 6, &devBounds);
}
-int GrInOrderDrawBuffer::concatInstancedDraw(const DrawInfo& info,
+int GrInOrderDrawBuffer::concatInstancedDraw(const GrDrawState& ds,
+ const DrawInfo& info,
const GrClipMaskManager::ScissorState& scissorState) {
SkASSERT(!fCmdBuffer.empty());
SkASSERT(info.isInstanced());
const GeometrySrcState& geomSrc = this->getGeomSrc();
- const GrDrawState& drawState = this->getDrawState();
// we only attempt to concat the case when reserved verts are used with a client-specified index
// buffer. To make this work with client-specified VBs we'd need to know if the VB was updated
@@ -243,8 +239,7 @@
instancesToConcat = SkTMin(instancesToConcat, info.instanceCount());
// update the amount of reserved vertex data actually referenced in draws
- size_t vertexBytes = instancesToConcat * info.verticesPerInstance() *
- drawState.getVertexStride();
+ size_t vertexBytes = instancesToConcat * info.verticesPerInstance() * ds.getVertexStride();
poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, vertexBytes);
draw->fInfo.adjustInstanceCount(instancesToConcat);
@@ -262,12 +257,13 @@
return instancesToConcat;
}
-void GrInOrderDrawBuffer::onDraw(const DrawInfo& info,
+void GrInOrderDrawBuffer::onDraw(const GrDrawState& ds,
+ const DrawInfo& info,
const GrClipMaskManager::ScissorState& scissorState) {
GeometryPoolState& poolState = fGeoPoolStateStack.back();
- const GrDrawState& drawState = this->getDrawState();
- this->recordStateIfNecessary(GrGpu::PrimTypeToDrawType(info.primitiveType()),
+ this->recordStateIfNecessary(ds,
+ GrGpu::PrimTypeToDrawType(info.primitiveType()),
info.getDstCopy());
const GrVertexBuffer* vb;
@@ -288,7 +284,7 @@
Draw* draw;
if (info.isInstanced()) {
- int instancesConcated = this->concatInstancedDraw(info, scissorState);
+ int instancesConcated = this->concatInstancedDraw(ds, info, scissorState);
if (info.instanceCount() > instancesConcated) {
draw = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, Draw, (info, scissorState, vb, ib));
draw->fInfo.adjustInstanceCount(-instancesConcated);
@@ -303,7 +299,7 @@
// Adjust the starting vertex and index when we are using reserved or array sources to
// compensate for the fact that the data was inserted into a larger vb/ib owned by the pool.
if (kBuffer_GeometrySrcType != this->getGeomSrc().fVertexSrc) {
- size_t bytes = (info.vertexCount() + info.startVertex()) * drawState.getVertexStride();
+ size_t bytes = (info.vertexCount() + info.startVertex()) * ds.getVertexStride();
poolState.fUsedPoolVertexBytes = SkTMax(poolState.fUsedPoolVertexBytes, bytes);
draw->fInfo.adjustStartVertex(poolState.fPoolStartVertex);
}
@@ -315,23 +311,25 @@
}
}
-void GrInOrderDrawBuffer::onStencilPath(const GrPath* path,
+void GrInOrderDrawBuffer::onStencilPath(const GrDrawState& ds,
+ const GrPath* path,
const GrClipMaskManager::ScissorState& scissorState,
const GrStencilSettings& stencilSettings) {
// Only compare the subset of GrDrawState relevant to path stenciling?
- this->recordStateIfNecessary(GrGpu::kStencilPath_DrawType, NULL);
+ this->recordStateIfNecessary(ds, GrGpu::kStencilPath_DrawType, NULL);
StencilPath* sp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, StencilPath, (path));
sp->fScissorState = scissorState;
sp->fStencilSettings = stencilSettings;
this->recordTraceMarkersIfNecessary();
}
-void GrInOrderDrawBuffer::onDrawPath(const GrPath* path,
+void GrInOrderDrawBuffer::onDrawPath(const GrDrawState& ds,
+ const GrPath* path,
const GrClipMaskManager::ScissorState& scissorState,
const GrStencilSettings& stencilSettings,
const GrDeviceCoordTexture* dstCopy) {
// TODO: Only compare the subset of GrDrawState relevant to path covering?
- this->recordStateIfNecessary(GrGpu::kDrawPath_DrawType, dstCopy);
+ this->recordStateIfNecessary(ds, GrGpu::kDrawPath_DrawType, dstCopy);
DrawPath* dp = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, DrawPath, (path));
if (dstCopy) {
dp->fDstCopy = *dstCopy;
@@ -341,7 +339,8 @@
this->recordTraceMarkersIfNecessary();
}
-void GrInOrderDrawBuffer::onDrawPaths(const GrPathRange* pathRange,
+void GrInOrderDrawBuffer::onDrawPaths(const GrDrawState& ds,
+ const GrPathRange* pathRange,
const uint32_t indices[],
int count,
const float transforms[],
@@ -353,7 +352,7 @@
SkASSERT(indices);
SkASSERT(transforms);
- this->recordStateIfNecessary(GrGpu::kDrawPaths_DrawType, dstCopy);
+ this->recordStateIfNecessary(ds, GrGpu::kDrawPaths_DrawType, dstCopy);
uint32_t* savedIndices = fPathIndexBuffer.append(count, indices);
float* savedTransforms = fPathTransformBuffer.append(count *
@@ -373,7 +372,7 @@
scissorState == previous->fScissorState &&
stencilSettings == previous->fStencilSettings &&
path_fill_type_is_winding(stencilSettings) &&
- !this->getDrawState().willBlendWithDst()) {
+ !ds.willBlendWithDst()) {
// Fold this DrawPaths call into the one previous.
previous->fCount += count;
return;
@@ -396,11 +395,8 @@
void GrInOrderDrawBuffer::onClear(const SkIRect* rect, GrColor color,
bool canIgnoreRect, GrRenderTarget* renderTarget) {
+ SkASSERT(renderTarget);
SkIRect r;
- if (NULL == renderTarget) {
- renderTarget = this->drawState()->getRenderTarget();
- SkASSERT(renderTarget);
- }
if (NULL == rect) {
// We could do something smart and remove previous draws and clears to
// the current render target. If we get that smart we have to make sure
@@ -419,10 +415,7 @@
void GrInOrderDrawBuffer::clearStencilClip(const SkIRect& rect,
bool insideClip,
GrRenderTarget* renderTarget) {
- if (NULL == renderTarget) {
- renderTarget = this->drawState()->getRenderTarget();
- SkASSERT(renderTarget);
- }
+ SkASSERT(renderTarget);
ClearStencilClip* clr = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, ClearStencilClip, (renderTarget));
clr->fRect = rect;
clr->fInsideClip = insideClip;
@@ -493,7 +486,7 @@
}
if (kSetState_Cmd == strip_trace_bit(iter->fType)) {
- const SetState* ss = reinterpret_cast<const SetState*>(iter.get());
+ SetState* ss = reinterpret_cast<SetState*>(iter.get());
currentOptState.reset(GrOptDrawState::Create(ss->fState,
fDstGpu,
&ss->fDstCopy,
@@ -592,8 +585,8 @@
}
}
-bool GrInOrderDrawBuffer::canCopySurface(GrSurface* dst,
- GrSurface* src,
+bool GrInOrderDrawBuffer::canCopySurface(const GrSurface* dst,
+ const GrSurface* src,
const SkIRect& srcRect,
const SkIPoint& dstPoint) {
return fDstGpu->canCopySurface(dst, src, srcRect, dstPoint) ||
@@ -605,6 +598,7 @@
}
void GrInOrderDrawBuffer::willReserveVertexAndIndexSpace(int vertexCount,
+ size_t vertexStride,
int indexCount) {
// We use geometryHints() to know whether to flush the draw buffer. We
// can't flush if we are inside an unbalanced pushGeometrySource.
@@ -628,12 +622,13 @@
if (!insideGeoPush &&
!unreleasedVertexSpace &&
!unreleasedIndexSpace &&
- this->geometryHints(&vcount, &icount)) {
+ this->geometryHints(vertexStride, &vcount, &icount)) {
this->flush();
}
}
-bool GrInOrderDrawBuffer::geometryHints(int* vertexCount,
+bool GrInOrderDrawBuffer::geometryHints(size_t vertexStride,
+ int* vertexCount,
int* indexCount) const {
// we will recommend a flush if the data could fit in a single
// preallocated buffer but none are left and it can't fit
@@ -650,7 +645,6 @@
*indexCount = currIndices;
}
if (vertexCount) {
- size_t vertexStride = this->getDrawState().getVertexStride();
int32_t currVertices = fVertexPool.currentBufferVertices(vertexStride);
if (*vertexCount > currVertices &&
(!fVertexPool.preallocatedBuffersRemaining() &&
@@ -753,10 +747,11 @@
}
}
-void GrInOrderDrawBuffer::recordStateIfNecessary(GrGpu::DrawType drawType,
+void GrInOrderDrawBuffer::recordStateIfNecessary(const GrDrawState& ds,
+ GrGpu::DrawType drawType,
const GrDeviceCoordTexture* dstCopy) {
if (!fLastState) {
- SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (this->getDrawState()));
+ SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (ds));
fLastState = &ss->fState;
if (dstCopy) {
ss->fDstCopy = *dstCopy;
@@ -766,10 +761,9 @@
this->recordTraceMarkersIfNecessary();
return;
}
- const GrDrawState& curr = this->getDrawState();
- switch (GrDrawState::CombineIfPossible(*fLastState, curr, *this->caps())) {
+ switch (GrDrawState::CombineIfPossible(*fLastState, ds, *this->caps())) {
case GrDrawState::kIncompatible_CombinedState: {
- SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (curr));
+ SetState* ss = GrNEW_APPEND_TO_RECORDER(fCmdBuffer, SetState, (ds));
fLastState = &ss->fState;
if (dstCopy) {
ss->fDstCopy = *dstCopy;
@@ -788,7 +782,7 @@
// Note that this goes away when we move GrIODB over to taking optimized snapshots
// of draw states.
fLastState->~GrDrawState();
- SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (curr));
+ SkNEW_PLACEMENT_ARGS(fLastState, GrDrawState, (ds));
this->convertDrawStateToPendingExec(fLastState);
break;
}
diff --git a/src/gpu/GrInOrderDrawBuffer.h b/src/gpu/GrInOrderDrawBuffer.h
index 4129d0a..c898236 100644
--- a/src/gpu/GrInOrderDrawBuffer.h
+++ b/src/gpu/GrInOrderDrawBuffer.h
@@ -73,7 +73,8 @@
virtual DrawToken getCurrentDrawToken() { return DrawToken(this, fDrawID); }
// overrides from GrDrawTarget
- virtual bool geometryHints(int* vertexCount,
+ virtual bool geometryHints(size_t vertexStride,
+ int* vertexCount,
int* indexCount) const SK_OVERRIDE;
virtual bool copySurface(GrSurface* dst,
@@ -81,8 +82,8 @@
const SkIRect& srcRect,
const SkIPoint& dstPoint) SK_OVERRIDE;
- virtual bool canCopySurface(GrSurface* dst,
- GrSurface* src,
+ virtual bool canCopySurface(const GrSurface* dst,
+ const GrSurface* src,
const SkIRect& srcRect,
const SkIPoint& dstPoint) SK_OVERRIDE;
@@ -248,19 +249,25 @@
typedef GrTRecorder<Cmd, TCmdAlign> CmdBuffer;
// overrides from GrDrawTarget
- virtual void onDraw(const DrawInfo&, const GrClipMaskManager::ScissorState&) SK_OVERRIDE;
- virtual void onDrawRect(const SkRect& rect,
+ virtual void onDraw(const GrDrawState&,
+ const DrawInfo&,
+ const GrClipMaskManager::ScissorState&) SK_OVERRIDE;
+ virtual void onDrawRect(GrDrawState*,
+ const SkRect& rect,
const SkRect* localRect,
const SkMatrix* localMatrix) SK_OVERRIDE;
- virtual void onStencilPath(const GrPath*,
+ virtual void onStencilPath(const GrDrawState&,
+ const GrPath*,
const GrClipMaskManager::ScissorState&,
const GrStencilSettings&) SK_OVERRIDE;
- virtual void onDrawPath(const GrPath*,
+ virtual void onDrawPath(const GrDrawState&,
+ const GrPath*,
const GrClipMaskManager::ScissorState&,
const GrStencilSettings&,
const GrDeviceCoordTexture* dstCopy) SK_OVERRIDE;
- virtual void onDrawPaths(const GrPathRange*,
+ virtual void onDrawPaths(const GrDrawState&,
+ const GrPathRange*,
const uint32_t indices[],
int count,
const float transforms[],
@@ -283,14 +290,17 @@
virtual void geometrySourceWillPush() SK_OVERRIDE;
virtual void geometrySourceWillPop(const GeometrySrcState& restoredState) SK_OVERRIDE;
virtual void willReserveVertexAndIndexSpace(int vertexCount,
+ size_t vertexStride,
int indexCount) SK_OVERRIDE;
// Attempts to concat instances from info onto the previous draw. info must represent an
// instanced draw. The caller must have already recorded a new draw state and clip if necessary.
- int concatInstancedDraw(const DrawInfo& info, const GrClipMaskManager::ScissorState&);
+ int concatInstancedDraw(const GrDrawState&,
+ const DrawInfo&,
+ const GrClipMaskManager::ScissorState&);
// Determines whether the current draw operation requieres a new drawstate and if so records it.
- void recordStateIfNecessary(GrGpu::DrawType, const GrDeviceCoordTexture*);
+ void recordStateIfNecessary(const GrDrawState&, GrGpu::DrawType, const GrDeviceCoordTexture*);
// We lazily record clip changes in order to skip clips that have no effect.
void recordClipIfNecessary();
// Records any trace markers for a command after adding it to the buffer.
diff --git a/src/gpu/GrOptDrawState.h b/src/gpu/GrOptDrawState.h
index cef32b6..c44bb6f 100644
--- a/src/gpu/GrOptDrawState.h
+++ b/src/gpu/GrOptDrawState.h
@@ -30,8 +30,10 @@
* Returns a snapshot of the current optimized state. The GrOptDrawState is reffed and ownership
* is given to the caller.
*/
- static GrOptDrawState* Create(const GrDrawState& drawState, GrGpu*,
- const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType drawType);
+ static GrOptDrawState* Create(const GrDrawState& drawState,
+ GrGpu*,
+ const GrDeviceCoordTexture* dstCopy,
+ GrGpu::DrawType drawType);
bool operator== (const GrOptDrawState& that) const;
diff --git a/src/gpu/GrOvalRenderer.cpp b/src/gpu/GrOvalRenderer.cpp
index 2bb674a..42844ee 100644
--- a/src/gpu/GrOvalRenderer.cpp
+++ b/src/gpu/GrOvalRenderer.cpp
@@ -481,12 +481,16 @@
SkSafeSetNull(fStrokeRRectIndexBuffer);
}
-bool GrOvalRenderer::drawOval(GrDrawTarget* target, const GrContext* context, bool useAA,
- const SkRect& oval, const SkStrokeRec& stroke)
+bool GrOvalRenderer::drawOval(GrDrawTarget* target,
+ GrDrawState* drawState,
+ const GrContext* context,
+ bool useAA,
+ const SkRect& oval,
+ const SkStrokeRec& stroke)
{
bool useCoverageAA = useAA &&
- !target->getDrawState().getRenderTarget()->isMultisampled() &&
- !target->shouldDisableCoverageAAForBlend();
+ !drawState->getRenderTarget()->isMultisampled() &&
+ drawState->couldApplyCoverage(*target->caps());
if (!useCoverageAA) {
return false;
@@ -497,13 +501,13 @@
// we can draw circles
if (SkScalarNearlyEqual(oval.width(), oval.height())
&& circle_stays_circle(vm)) {
- this->drawCircle(target, context, useCoverageAA, oval, stroke);
+ this->drawCircle(target, drawState, context, useCoverageAA, oval, stroke);
// if we have shader derivative support, render as device-independent
} else if (target->caps()->shaderDerivativeSupport()) {
- return this->drawDIEllipse(target, context, useCoverageAA, oval, stroke);
+ return this->drawDIEllipse(target, drawState, context, useCoverageAA, oval, stroke);
// otherwise axis-aligned ellipses only
} else if (vm.rectStaysRect()) {
- return this->drawEllipse(target, context, useCoverageAA, oval, stroke);
+ return this->drawEllipse(target, drawState, context, useCoverageAA, oval, stroke);
} else {
return false;
}
@@ -520,13 +524,12 @@
};
void GrOvalRenderer::drawCircle(GrDrawTarget* target,
+ GrDrawState* drawState,
const GrContext* context,
bool useCoverageAA,
const SkRect& circle,
const SkStrokeRec& stroke)
{
- GrDrawState* drawState = target->drawState();
-
const SkMatrix& vm = drawState->getViewMatrix();
SkPoint center = SkPoint::Make(circle.centerX(), circle.centerY());
vm.mapPoints(¢er, 1);
@@ -541,7 +544,7 @@
drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVertexAttribs),
sizeof(CircleVertex));
- GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
+ GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride(), 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return;
@@ -608,7 +611,7 @@
verts[3].fInnerRadius = innerRadius;
target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
- target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
+ target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
target->resetIndexSource();
}
@@ -629,12 +632,12 @@
};
bool GrOvalRenderer::drawEllipse(GrDrawTarget* target,
+ GrDrawState* drawState,
const GrContext* context,
bool useCoverageAA,
const SkRect& ellipse,
const SkStrokeRec& stroke)
{
- GrDrawState* drawState = target->drawState();
#ifdef SK_DEBUG
{
// we should have checked for this previously
@@ -704,7 +707,7 @@
drawState->setVertexAttribs<gEllipseVertexAttribs>(SK_ARRAY_COUNT(gEllipseVertexAttribs),
sizeof(EllipseVertex));
- GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
+ GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride(), 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return false;
@@ -757,19 +760,19 @@
verts[3].fInnerRadii = SkPoint::Make(xInnerRadRecip, yInnerRadRecip);
target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
- target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
+ target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
target->resetIndexSource();
return true;
}
bool GrOvalRenderer::drawDIEllipse(GrDrawTarget* target,
+ GrDrawState* drawState,
const GrContext* context,
bool useCoverageAA,
const SkRect& ellipse,
const SkStrokeRec& stroke)
{
- GrDrawState* drawState = target->drawState();
const SkMatrix& vm = drawState->getViewMatrix();
SkPoint center = SkPoint::Make(ellipse.centerX(), ellipse.centerY());
@@ -824,7 +827,7 @@
drawState->setVertexAttribs<gDIEllipseVertexAttribs>(SK_ARRAY_COUNT(gDIEllipseVertexAttribs),
sizeof(DIEllipseVertex));
- GrDrawTarget::AutoReleaseGeometry geo(target, 4, 0);
+ GrDrawTarget::AutoReleaseGeometry geo(target, 4, drawState->getVertexStride(), 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return false;
@@ -871,7 +874,7 @@
verts[3].fInnerOffset = SkPoint::Make(innerRatioX + offsetDx, -innerRatioY - offsetDy);
target->setIndexSourceToBuffer(context->getGpu()->getQuadIndexBuffer());
- target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
+ target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 4, 6, &bounds);
target->resetIndexSource();
return true;
@@ -922,11 +925,15 @@
}
}
-bool GrOvalRenderer::drawDRRect(GrDrawTarget* target, GrContext* context, bool useAA,
- const SkRRect& origOuter, const SkRRect& origInner) {
+bool GrOvalRenderer::drawDRRect(GrDrawTarget* target,
+ GrDrawState* drawState,
+ GrContext* context,
+ bool useAA,
+ const SkRRect& origOuter,
+ const SkRRect& origInner) {
bool applyAA = useAA &&
- !target->getDrawState().getRenderTarget()->isMultisampled() &&
- !target->shouldDisableCoverageAAForBlend();
+ !drawState->getRenderTarget()->isMultisampled() &&
+ drawState->couldApplyCoverage(*target->caps());
GrDrawState::AutoRestoreEffects are;
if (!origInner.isEmpty()) {
SkTCopyOnFirstWrite<SkRRect> inner(origInner);
@@ -942,12 +949,12 @@
if (NULL == fp) {
return false;
}
- are.set(target->drawState());
- target->drawState()->addCoverageProcessor(fp)->unref();
+ are.set(drawState);
+ drawState->addCoverageProcessor(fp)->unref();
}
SkStrokeRec fillRec(SkStrokeRec::kFill_InitStyle);
- if (this->drawRRect(target, context, useAA, origOuter, fillRec)) {
+ if (this->drawRRect(target, drawState, context, useAA, origOuter, fillRec)) {
return true;
}
@@ -965,30 +972,34 @@
return false;
}
if (!are.isSet()) {
- are.set(target->drawState());
+ are.set(drawState);
}
GrDrawState::AutoViewMatrixRestore avmr;
- if (!avmr.setIdentity(target->drawState())) {
+ if (!avmr.setIdentity(drawState)) {
return false;
}
- target->drawState()->addCoverageProcessor(effect)->unref();
+ drawState->addCoverageProcessor(effect)->unref();
SkRect bounds = outer->getBounds();
if (applyAA) {
bounds.outset(SK_ScalarHalf, SK_ScalarHalf);
}
- target->drawRect(bounds, NULL, NULL);
+ target->drawRect(drawState, bounds, NULL, NULL);
return true;
}
-bool GrOvalRenderer::drawRRect(GrDrawTarget* target, GrContext* context, bool useAA,
- const SkRRect& rrect, const SkStrokeRec& stroke) {
+bool GrOvalRenderer::drawRRect(GrDrawTarget* target,
+ GrDrawState* drawState,
+ GrContext* context,
+ bool useAA,
+ const SkRRect& rrect,
+ const SkStrokeRec& stroke) {
if (rrect.isOval()) {
- return this->drawOval(target, context, useAA, rrect.getBounds(), stroke);
+ return this->drawOval(target, drawState, context, useAA, rrect.getBounds(), stroke);
}
bool useCoverageAA = useAA &&
- !target->getDrawState().getRenderTarget()->isMultisampled() &&
- !target->shouldDisableCoverageAAForBlend();
+ !drawState->getRenderTarget()->isMultisampled() &&
+ drawState->couldApplyCoverage(*target->caps());
// only anti-aliased rrects for now
if (!useCoverageAA) {
@@ -1048,7 +1059,6 @@
}
// reset to device coordinates
- GrDrawState* drawState = target->drawState();
GrDrawState::AutoViewMatrixRestore avmr;
if (!avmr.setIdentity(drawState)) {
return false;
@@ -1065,7 +1075,7 @@
drawState->setVertexAttribs<gCircleVertexAttribs>(SK_ARRAY_COUNT(gCircleVertexAttribs),
sizeof(CircleVertex));
- GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0);
+ GrDrawTarget::AutoReleaseGeometry geo(target, 16, drawState->getVertexStride(), 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return false;
@@ -1146,7 +1156,8 @@
int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
SK_ARRAY_COUNT(gRRectIndices);
target->setIndexSourceToBuffer(indexBuffer);
- target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 16, indexCnt, &bounds);
+ target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 16, indexCnt,
+ &bounds);
// otherwise we use the ellipse renderer
} else {
@@ -1187,7 +1198,7 @@
isStrokeOnly = (isStrokeOnly && innerXRadius >= 0 && innerYRadius >= 0);
- GrDrawTarget::AutoReleaseGeometry geo(target, 16, 0);
+ GrDrawTarget::AutoReleaseGeometry geo(target, 16, drawState->getVertexStride(), 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return false;
@@ -1253,7 +1264,8 @@
int indexCnt = isStrokeOnly ? SK_ARRAY_COUNT(gRRectIndices) - 6 :
SK_ARRAY_COUNT(gRRectIndices);
target->setIndexSourceToBuffer(indexBuffer);
- target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1, 16, indexCnt, &bounds);
+ target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, 1, 16, indexCnt,
+ &bounds);
}
target->resetIndexSource();
diff --git a/src/gpu/GrOvalRenderer.h b/src/gpu/GrOvalRenderer.h
index 96f9b3a..abad623 100644
--- a/src/gpu/GrOvalRenderer.h
+++ b/src/gpu/GrOvalRenderer.h
@@ -31,21 +31,42 @@
void reset();
- bool drawOval(GrDrawTarget* target, const GrContext* context, bool useAA,
- const SkRect& oval, const SkStrokeRec& stroke);
- bool drawRRect(GrDrawTarget* target, GrContext* context, bool useAA,
- const SkRRect& rrect, const SkStrokeRec& stroke);
- bool drawDRRect(GrDrawTarget* target, GrContext* context, bool useAA,
- const SkRRect& outer, const SkRRect& inner);
+ bool drawOval(GrDrawTarget*,
+ GrDrawState*,
+ const GrContext*,
+ bool useAA,
+ const SkRect& oval,
+ const SkStrokeRec& stroke);
+ bool drawRRect(GrDrawTarget*,
+ GrDrawState*,
+ GrContext*,
+ bool useAA,
+ const SkRRect& rrect,
+ const SkStrokeRec& stroke);
+ bool drawDRRect(GrDrawTarget* target,
+ GrDrawState*,
+ GrContext* context,
+ bool useAA,
+ const SkRRect& outer,
+ const SkRRect& inner);
private:
- bool drawEllipse(GrDrawTarget* target, const GrContext* context, bool useCoverageAA,
+ bool drawEllipse(GrDrawTarget* target,
+ GrDrawState*,
+ const GrContext* context,
+ bool useCoverageAA,
const SkRect& ellipse,
const SkStrokeRec& stroke);
- bool drawDIEllipse(GrDrawTarget* target, const GrContext* context, bool useCoverageAA,
+ bool drawDIEllipse(GrDrawTarget* target,
+ GrDrawState*,
+ const GrContext* context,
+ bool useCoverageAA,
const SkRect& ellipse,
const SkStrokeRec& stroke);
- void drawCircle(GrDrawTarget* target, const GrContext* context, bool useCoverageAA,
+ void drawCircle(GrDrawTarget* target,
+ GrDrawState*,
+ const GrContext* context,
+ bool useCoverageAA,
const SkRect& circle,
const SkStrokeRec& stroke);
diff --git a/src/gpu/GrPathRenderer.h b/src/gpu/GrPathRenderer.h
index 0720c3f..8f2d465 100644
--- a/src/gpu/GrPathRenderer.h
+++ b/src/gpu/GrPathRenderer.h
@@ -81,11 +81,12 @@
* @param path the path that will be drawn
* @param stroke the stroke information (width, join, cap).
*/
- StencilSupport getStencilSupport(const SkPath& path,
- const SkStrokeRec& stroke,
- const GrDrawTarget* target) const {
+ StencilSupport getStencilSupport(const GrDrawTarget* target,
+ const GrDrawState* drawState,
+ const SkPath& path,
+ const SkStrokeRec& stroke) const {
SkASSERT(!path.isInverseFillType());
- return this->onGetStencilSupport(path, stroke, target);
+ return this->onGetStencilSupport(target, drawState, path, stroke);
}
/**
@@ -100,9 +101,10 @@
*
* @return true if the path can be drawn by this object, false otherwise.
*/
- virtual bool canDrawPath(const SkPath& path,
+ virtual bool canDrawPath(const GrDrawTarget* target,
+ const GrDrawState* drawState,
+ const SkPath& path,
const SkStrokeRec& rec,
- const GrDrawTarget* target,
bool antiAlias) const = 0;
/**
* Draws the path into the draw target. If getStencilSupport() would return kNoRestriction then
@@ -113,15 +115,17 @@
* @param target target that the path will be rendered to
* @param antiAlias true if anti-aliasing is required.
*/
- bool drawPath(const SkPath& path,
+ bool drawPath(GrDrawTarget* target,
+ GrDrawState* ds,
+ const SkPath& path,
const SkStrokeRec& stroke,
- GrDrawTarget* target,
bool antiAlias) {
SkASSERT(!path.isEmpty());
- SkASSERT(this->canDrawPath(path, stroke, target, antiAlias));
- SkASSERT(target->drawState()->getStencil().isDisabled() ||
- kNoRestriction_StencilSupport == this->getStencilSupport(path, stroke, target));
- return this->onDrawPath(path, stroke, target, antiAlias);
+ SkASSERT(this->canDrawPath(target, ds, path, stroke, antiAlias));
+ SkASSERT(ds->getStencil().isDisabled() ||
+ kNoRestriction_StencilSupport == this->getStencilSupport(target, ds, path,
+ stroke));
+ return this->onDrawPath(target, ds, path, stroke, antiAlias);
}
/**
@@ -132,10 +136,13 @@
* @param stroke the stroke information (width, join, cap)
* @param target target that the path will be rendered to
*/
- void stencilPath(const SkPath& path, const SkStrokeRec& stroke, GrDrawTarget* target) {
+ void stencilPath(GrDrawTarget* target,
+ GrDrawState* ds,
+ const SkPath& path,
+ const SkStrokeRec& stroke) {
SkASSERT(!path.isEmpty());
- SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(path, stroke, target));
- this->onStencilPath(path, stroke, target);
+ SkASSERT(kNoSupport_StencilSupport != this->getStencilSupport(target, ds, path, stroke));
+ this->onStencilPath(target, ds, path, stroke);
}
// Helper for determining if we can treat a thin stroke as a hairline w/ coverage.
@@ -156,27 +163,30 @@
/**
* Subclass overrides if it has any limitations of stenciling support.
*/
- virtual StencilSupport onGetStencilSupport(const SkPath&,
- const SkStrokeRec&,
- const GrDrawTarget*) const {
+ virtual StencilSupport onGetStencilSupport(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&) const {
return kNoRestriction_StencilSupport;
}
/**
* Subclass implementation of drawPath()
*/
- virtual bool onDrawPath(const SkPath& path,
- const SkStrokeRec& stroke,
- GrDrawTarget* target,
+ virtual bool onDrawPath(GrDrawTarget*,
+ GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&,
bool antiAlias) = 0;
/**
* Subclass implementation of stencilPath(). Subclass must override iff it ever returns
* kStencilOnly in onGetStencilSupport().
*/
- virtual void onStencilPath(const SkPath& path, const SkStrokeRec& stroke, GrDrawTarget* target) {
- GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit);
- GrDrawState* drawState = target->drawState();
+ virtual void onStencilPath(GrDrawTarget* target,
+ GrDrawState* drawState,
+ const SkPath& path,
+ const SkStrokeRec& stroke) {
GR_STATIC_CONST_SAME_STENCIL(kIncrementStencil,
kReplace_StencilOp,
kReplace_StencilOp,
@@ -186,7 +196,7 @@
0xffff);
drawState->setStencil(kIncrementStencil);
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
- this->drawPath(path, stroke, target, false);
+ this->drawPath(target, drawState, path, stroke, false);
}
// Helper for getting the device bounds of a path. Inverse filled paths will have bounds set
diff --git a/src/gpu/GrPathRendererChain.cpp b/src/gpu/GrPathRendererChain.cpp
index 8108572..5c3f1c9 100644
--- a/src/gpu/GrPathRendererChain.cpp
+++ b/src/gpu/GrPathRendererChain.cpp
@@ -31,9 +31,10 @@
return pr;
}
-GrPathRenderer* GrPathRendererChain::getPathRenderer(const SkPath& path,
+GrPathRenderer* GrPathRendererChain::getPathRenderer(const GrDrawTarget* target,
+ const GrDrawState* drawState,
+ const SkPath& path,
const SkStrokeRec& stroke,
- const GrDrawTarget* target,
DrawType drawType,
StencilSupport* stencilSupport) {
if (!fInit) {
@@ -58,11 +59,12 @@
for (int i = 0; i < fChain.count(); ++i) {
- if (fChain[i]->canDrawPath(path, stroke, target, antiAlias)) {
+ if (fChain[i]->canDrawPath(target, drawState, path, stroke, antiAlias)) {
if (GrPathRenderer::kNoSupport_StencilSupport != minStencilSupport) {
- GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(path,
- stroke,
- target);
+ GrPathRenderer::StencilSupport support = fChain[i]->getStencilSupport(target,
+ drawState,
+ path,
+ stroke);
if (support < minStencilSupport) {
continue;
} else if (stencilSupport) {
diff --git a/src/gpu/GrSWMaskHelper.cpp b/src/gpu/GrSWMaskHelper.cpp
index 2a2e161..590a040 100644
--- a/src/gpu/GrSWMaskHelper.cpp
+++ b/src/gpu/GrSWMaskHelper.cpp
@@ -347,9 +347,8 @@
void GrSWMaskHelper::DrawToTargetWithPathMask(GrTexture* texture,
GrDrawTarget* target,
+ GrDrawState* drawState,
const SkIRect& rect) {
- GrDrawState* drawState = target->drawState();
-
GrDrawState::AutoViewMatrixRestore avmr;
if (!avmr.setIdentity(drawState)) {
return;
@@ -376,5 +375,5 @@
GrTextureParams::kNone_FilterMode,
kPosition_GrCoordSet))->unref();
- target->drawSimpleRect(dstRect);
+ target->drawSimpleRect(drawState, dstRect);
}
diff --git a/src/gpu/GrSWMaskHelper.h b/src/gpu/GrSWMaskHelper.h
index 22d04ef..54a3897 100644
--- a/src/gpu/GrSWMaskHelper.h
+++ b/src/gpu/GrSWMaskHelper.h
@@ -92,6 +92,7 @@
// output of DrawPathMaskToTexture.
static void DrawToTargetWithPathMask(GrTexture* texture,
GrDrawTarget* target,
+ GrDrawState* drawState,
const SkIRect& rect);
private:
diff --git a/src/gpu/GrSoftwarePathRenderer.cpp b/src/gpu/GrSoftwarePathRenderer.cpp
index 0d3ef62..9a9cf32 100644
--- a/src/gpu/GrSoftwarePathRenderer.cpp
+++ b/src/gpu/GrSoftwarePathRenderer.cpp
@@ -11,9 +11,10 @@
#include "GrSWMaskHelper.h"
////////////////////////////////////////////////////////////////////////////////
-bool GrSoftwarePathRenderer::canDrawPath(const SkPath&,
+bool GrSoftwarePathRenderer::canDrawPath(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
const SkStrokeRec&,
- const GrDrawTarget*,
bool antiAlias) const {
if (NULL == fContext) {
return false;
@@ -22,10 +23,11 @@
return true;
}
-GrPathRenderer::StencilSupport GrSoftwarePathRenderer::onGetStencilSupport(
- const SkPath&,
- const SkStrokeRec&,
- const GrDrawTarget*) const {
+GrPathRenderer::StencilSupport
+GrSoftwarePathRenderer::onGetStencilSupport(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&) const {
return GrPathRenderer::kNoSupport_StencilSupport;
}
@@ -36,12 +38,13 @@
// path bounds will be a subset of the clip bounds. returns false if
// path bounds would be empty.
bool get_path_and_clip_bounds(const GrDrawTarget* target,
+ const GrDrawState* drawState,
const SkPath& path,
const SkMatrix& matrix,
SkIRect* devPathBounds,
SkIRect* devClipBounds) {
// compute bounds as intersection of rt size, clip, and path
- const GrRenderTarget* rt = target->getDrawState().getRenderTarget();
+ const GrRenderTarget* rt = drawState->getRenderTarget();
if (NULL == rt) {
return false;
}
@@ -74,32 +77,33 @@
////////////////////////////////////////////////////////////////////////////////
void draw_around_inv_path(GrDrawTarget* target,
+ GrDrawState* drawState,
const SkIRect& devClipBounds,
const SkIRect& devPathBounds) {
GrDrawState::AutoViewMatrixRestore avmr;
- if (!avmr.setIdentity(target->drawState())) {
+ if (!avmr.setIdentity(drawState)) {
return;
}
SkRect rect;
if (devClipBounds.fTop < devPathBounds.fTop) {
rect.iset(devClipBounds.fLeft, devClipBounds.fTop,
devClipBounds.fRight, devPathBounds.fTop);
- target->drawSimpleRect(rect);
+ target->drawSimpleRect(drawState, rect);
}
if (devClipBounds.fLeft < devPathBounds.fLeft) {
rect.iset(devClipBounds.fLeft, devPathBounds.fTop,
devPathBounds.fLeft, devPathBounds.fBottom);
- target->drawSimpleRect(rect);
+ target->drawSimpleRect(drawState, rect);
}
if (devClipBounds.fRight > devPathBounds.fRight) {
rect.iset(devPathBounds.fRight, devPathBounds.fTop,
devClipBounds.fRight, devPathBounds.fBottom);
- target->drawSimpleRect(rect);
+ target->drawSimpleRect(drawState, rect);
}
if (devClipBounds.fBottom > devPathBounds.fBottom) {
rect.iset(devClipBounds.fLeft, devPathBounds.fBottom,
devClipBounds.fRight, devClipBounds.fBottom);
- target->drawSimpleRect(rect);
+ target->drawSimpleRect(drawState, rect);
}
}
@@ -107,24 +111,23 @@
////////////////////////////////////////////////////////////////////////////////
// return true on success; false on failure
-bool GrSoftwarePathRenderer::onDrawPath(const SkPath& path,
+bool GrSoftwarePathRenderer::onDrawPath(GrDrawTarget* target,
+ GrDrawState* drawState,
+ const SkPath& path,
const SkStrokeRec& stroke,
- GrDrawTarget* target,
bool antiAlias) {
if (NULL == fContext) {
return false;
}
- GrDrawState* drawState = target->drawState();
-
SkMatrix vm = drawState->getViewMatrix();
SkIRect devPathBounds, devClipBounds;
- if (!get_path_and_clip_bounds(target, path, vm,
+ if (!get_path_and_clip_bounds(target, drawState, path, vm,
&devPathBounds, &devClipBounds)) {
if (path.isInverseFillType()) {
- draw_around_inv_path(target, devClipBounds, devPathBounds);
+ draw_around_inv_path(target, drawState, devClipBounds, devPathBounds);
}
return true;
}
@@ -137,10 +140,11 @@
return false;
}
- GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, devPathBounds);
+ GrDrawState copy = *drawState;
+ GrSWMaskHelper::DrawToTargetWithPathMask(texture, target, ©, devPathBounds);
if (path.isInverseFillType()) {
- draw_around_inv_path(target, devClipBounds, devPathBounds);
+ draw_around_inv_path(target, drawState, devClipBounds, devPathBounds);
}
return true;
diff --git a/src/gpu/GrSoftwarePathRenderer.h b/src/gpu/GrSoftwarePathRenderer.h
index bc35532..620e00b 100644
--- a/src/gpu/GrSoftwarePathRenderer.h
+++ b/src/gpu/GrSoftwarePathRenderer.h
@@ -23,18 +23,21 @@
: fContext(context) {
}
- virtual bool canDrawPath(const SkPath&,
+ virtual bool canDrawPath(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
const SkStrokeRec&,
- const GrDrawTarget*,
bool antiAlias) const SK_OVERRIDE;
protected:
- virtual StencilSupport onGetStencilSupport(const SkPath&,
- const SkStrokeRec&,
- const GrDrawTarget*) const SK_OVERRIDE;
+ virtual StencilSupport onGetStencilSupport(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&) const SK_OVERRIDE;
- virtual bool onDrawPath(const SkPath&,
+ virtual bool onDrawPath(GrDrawTarget*,
+ GrDrawState*,
+ const SkPath&,
const SkStrokeRec&,
- GrDrawTarget*,
bool antiAlias) SK_OVERRIDE;
private:
diff --git a/src/gpu/GrStencilAndCoverPathRenderer.cpp b/src/gpu/GrStencilAndCoverPathRenderer.cpp
index 6ed4b9e..022ed94 100644
--- a/src/gpu/GrStencilAndCoverPathRenderer.cpp
+++ b/src/gpu/GrStencilAndCoverPathRenderer.cpp
@@ -50,20 +50,22 @@
fGpu->unref();
}
-bool GrStencilAndCoverPathRenderer::canDrawPath(const SkPath& path,
+bool GrStencilAndCoverPathRenderer::canDrawPath(const GrDrawTarget* target,
+ const GrDrawState* drawState,
+ const SkPath& path,
const SkStrokeRec& stroke,
- const GrDrawTarget* target,
bool antiAlias) const {
return !stroke.isHairlineStyle() &&
!antiAlias && // doesn't do per-path AA, relies on the target having MSAA
- target->getDrawState().getRenderTarget()->getStencilBuffer() &&
- target->getDrawState().getStencil().isDisabled();
+ drawState->getRenderTarget()->getStencilBuffer() &&
+ drawState->getStencil().isDisabled();
}
GrPathRenderer::StencilSupport
-GrStencilAndCoverPathRenderer::onGetStencilSupport(const SkPath&,
- const SkStrokeRec& ,
- const GrDrawTarget*) const {
+GrStencilAndCoverPathRenderer::onGetStencilSupport(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&) const {
return GrPathRenderer::kStencilOnly_StencilSupport;
}
@@ -78,22 +80,23 @@
return path.detach();
}
-void GrStencilAndCoverPathRenderer::onStencilPath(const SkPath& path,
- const SkStrokeRec& stroke,
- GrDrawTarget* target) {
+void GrStencilAndCoverPathRenderer::onStencilPath(GrDrawTarget* target,
+ GrDrawState* drawState,
+ const SkPath& path,
+ const SkStrokeRec& stroke) {
SkASSERT(!path.isInverseFillType());
SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke));
- target->stencilPath(p, convert_skpath_filltype(path.getFillType()));
+ target->stencilPath(drawState, p, convert_skpath_filltype(path.getFillType()));
}
-bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
+bool GrStencilAndCoverPathRenderer::onDrawPath(GrDrawTarget* target,
+ GrDrawState* drawState,
+ const SkPath& path,
const SkStrokeRec& stroke,
- GrDrawTarget* target,
bool antiAlias) {
SkASSERT(!antiAlias);
SkASSERT(!stroke.isHairlineStyle());
- GrDrawState* drawState = target->drawState();
SkASSERT(drawState->getStencil().isDisabled());
SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke));
@@ -113,7 +116,7 @@
drawState->setStencil(kInvertedStencilPass);
// fake inverse with a stencil and cover
- target->stencilPath(p, convert_skpath_filltype(path.getFillType()));
+ target->stencilPath(drawState, p, convert_skpath_filltype(path.getFillType()));
GrDrawState::AutoViewMatrixRestore avmr;
SkRect bounds = SkRect::MakeLTRB(0, 0,
@@ -130,7 +133,7 @@
} else {
avmr.setIdentity(drawState);
}
- target->drawSimpleRect(bounds);
+ target->drawSimpleRect(drawState, bounds);
} else {
GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
kZero_StencilOp,
@@ -141,9 +144,9 @@
0xffff);
drawState->setStencil(kStencilPass);
- target->drawPath(p, convert_skpath_filltype(path.getFillType()));
+ target->drawPath(drawState, p, convert_skpath_filltype(path.getFillType()));
}
- target->drawState()->stencil()->setDisabled();
+ drawState->stencil()->setDisabled();
return true;
}
diff --git a/src/gpu/GrStencilAndCoverPathRenderer.h b/src/gpu/GrStencilAndCoverPathRenderer.h
index 9ebcec9..dacdcd0 100644
--- a/src/gpu/GrStencilAndCoverPathRenderer.h
+++ b/src/gpu/GrStencilAndCoverPathRenderer.h
@@ -25,24 +25,28 @@
virtual ~GrStencilAndCoverPathRenderer();
- virtual bool canDrawPath(const SkPath&,
+ virtual bool canDrawPath(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
const SkStrokeRec&,
- const GrDrawTarget*,
bool antiAlias) const SK_OVERRIDE;
protected:
- virtual StencilSupport onGetStencilSupport(const SkPath&,
- const SkStrokeRec&,
- const GrDrawTarget*) const SK_OVERRIDE;
+ virtual StencilSupport onGetStencilSupport(const GrDrawTarget*,
+ const GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&) const SK_OVERRIDE;
- virtual bool onDrawPath(const SkPath&,
+ virtual bool onDrawPath(GrDrawTarget*,
+ GrDrawState*,
+ const SkPath&,
const SkStrokeRec&,
- GrDrawTarget*,
bool antiAlias) SK_OVERRIDE;
- virtual void onStencilPath(const SkPath&,
- const SkStrokeRec&,
- GrDrawTarget*) SK_OVERRIDE;
+ virtual void onStencilPath(GrDrawTarget*,
+ GrDrawState*,
+ const SkPath&,
+ const SkStrokeRec&) SK_OVERRIDE;
private:
GrStencilAndCoverPathRenderer(GrGpu*);
diff --git a/src/gpu/GrStencilAndCoverTextContext.cpp b/src/gpu/GrStencilAndCoverTextContext.cpp
index 14a14a0..d70593e 100644
--- a/src/gpu/GrStencilAndCoverTextContext.cpp
+++ b/src/gpu/GrStencilAndCoverTextContext.cpp
@@ -333,10 +333,9 @@
&fGlyphCache->getDescriptor(), gpuStroke);
}
- fStateRestore.set(fDrawTarget->drawState());
+ fStateRestore.set(&fDrawState);
- fDrawTarget->drawState()->setFromPaint(fPaint, fContext->getMatrix(),
- fContext->getRenderTarget());
+ fDrawState.setFromPaint(fPaint, fContext->getMatrix(), fContext->getRenderTarget());
GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
kZero_StencilOp,
@@ -346,7 +345,7 @@
0x0000,
0xffff);
- *fDrawTarget->drawState()->stencil() = kStencilPass;
+ *fDrawState.stencil() = kStencilPass;
SkASSERT(0 == fPendingGlyphCount);
}
@@ -368,7 +367,7 @@
return;
}
- fDrawTarget->drawPaths(fGlyphs, fIndexBuffer, fPendingGlyphCount, fTransformBuffer,
+ fDrawTarget->drawPaths(&fDrawState, fGlyphs, fIndexBuffer, fPendingGlyphCount, fTransformBuffer,
GrPathRendering::kTranslate_PathTransformType,
GrPathRendering::kWinding_FillType);
@@ -384,7 +383,7 @@
SkGlyphCache::AttachCache(fGlyphCache);
fGlyphCache = NULL;
- fDrawTarget->drawState()->stencil()->setDisabled();
+ fDrawState.stencil()->setDisabled();
fStateRestore.set(NULL);
fContext->setMatrix(fContextInitialMatrix);
GrTextContext::finish();
diff --git a/src/gpu/GrStencilAndCoverTextContext.h b/src/gpu/GrStencilAndCoverTextContext.h
index 535ebdb..dabd3b3 100644
--- a/src/gpu/GrStencilAndCoverTextContext.h
+++ b/src/gpu/GrStencilAndCoverTextContext.h
@@ -9,7 +9,6 @@
#define GrStencilAndCoverTextContext_DEFINED
#include "GrTextContext.h"
-#include "GrDrawState.h"
#include "GrDrawTarget.h"
#include "SkStrokeRec.h"
@@ -52,6 +51,7 @@
kMaxPerformance_RenderMode,
};
+ GrDrawState fDrawState;
GrDrawState::AutoRestoreEffects fStateRestore;
SkScalar fTextRatio;
float fTextInverseRatio;
diff --git a/src/gpu/GrTest.cpp b/src/gpu/GrTest.cpp
index 5286984..5c03189 100644
--- a/src/gpu/GrTest.cpp
+++ b/src/gpu/GrTest.cpp
@@ -17,7 +17,6 @@
fContext.reset(SkRef(ctx));
fDrawTarget.reset(SkRef(target));
- SkNEW_IN_TLAZY(&fASR, GrDrawTarget::AutoStateRestore, (target, GrDrawTarget::kReset_ASRInit));
SkNEW_IN_TLAZY(&fACR, GrDrawTarget::AutoClipRestore, (target));
SkNEW_IN_TLAZY(&fAGP, GrDrawTarget::AutoGeometryPush, (target));
}
@@ -73,8 +72,8 @@
virtual void discard(GrRenderTarget*) SK_OVERRIDE { }
- virtual bool canCopySurface(GrSurface* dst,
- GrSurface* src,
+ virtual bool canCopySurface(const GrSurface* dst,
+ const GrSurface* src,
const SkIRect& srcRect,
const SkIPoint& dstPoint) SK_OVERRIDE { return false; };
diff --git a/src/gpu/GrTest.h b/src/gpu/GrTest.h
index 5e61c29..e63d11e 100644
--- a/src/gpu/GrTest.h
+++ b/src/gpu/GrTest.h
@@ -24,7 +24,6 @@
GrDrawTarget* target() { return fDrawTarget.get(); }
private:
- SkTLazy<GrDrawTarget::AutoStateRestore> fASR;
SkTLazy<GrDrawTarget::AutoClipRestore> fACR;
SkTLazy<GrDrawTarget::AutoGeometryPush> fAGP;
diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp
index af96ef6..71d92cb 100644
--- a/src/gpu/effects/GrDashingEffect.cpp
+++ b/src/gpu/effects/GrDashingEffect.cpp
@@ -29,8 +29,9 @@
// Returns whether or not the gpu can fast path the dash line effect.
static bool can_fast_path_dash(const SkPoint pts[2], const GrStrokeInfo& strokeInfo,
- const GrDrawTarget& target, const SkMatrix& viewMatrix) {
- if (target.getDrawState().getRenderTarget()->isMultisampled()) {
+ const GrDrawTarget& target, const GrDrawState& ds,
+ const SkMatrix& viewMatrix) {
+ if (ds.getRenderTarget()->isMultisampled()) {
return false;
}
@@ -170,11 +171,11 @@
matrix.mapPoints(&verts[idx], 4);
}
-bool GrDashingEffect::DrawDashLine(const SkPoint pts[2], const GrPaint& paint,
- const GrStrokeInfo& strokeInfo, GrGpu* gpu,
- GrDrawTarget* target, const SkMatrix& vm) {
+bool GrDashingEffect::DrawDashLine(GrGpu* gpu, GrDrawTarget* target, GrDrawState* drawState,
+ const SkPoint pts[2], const GrPaint& paint,
+ const GrStrokeInfo& strokeInfo, const SkMatrix& vm) {
- if (!can_fast_path_dash(pts, strokeInfo, *target, vm)) {
+ if (!can_fast_path_dash(pts, strokeInfo, *target, *drawState, vm)) {
return false;
}
@@ -319,7 +320,6 @@
SkScalar devBloat = useAA ? 0.5f : 0.f;
- GrDrawState* drawState = target->drawState();
if (devIntervals[1] <= 0.f && useAA) {
// Case when we end up drawing a solid AA rect
// Reset the start rect to draw this single solid rect
@@ -372,7 +372,9 @@
totalRectCnt += hasStartRect ? 1 : 0;
totalRectCnt += hasEndRect ? 1 : 0;
- GrDrawTarget::AutoReleaseGeometry geo(target, totalRectCnt * 4, 0);
+ GrDrawTarget::AutoReleaseGeometry geo(target,
+ totalRectCnt * 4,
+ drawState->getVertexStride(), 0);
if (!geo.succeeded()) {
SkDebugf("Failed to get space for vertices!\n");
return false;
@@ -438,7 +440,7 @@
}
target->setIndexSourceToBuffer(gpu->getContext()->getQuadIndexBuffer());
- target->drawIndexedInstances(kTriangles_GrPrimitiveType, totalRectCnt, 4, 6);
+ target->drawIndexedInstances(drawState, kTriangles_GrPrimitiveType, totalRectCnt, 4, 6);
target->resetIndexSource();
return true;
}
diff --git a/src/gpu/effects/GrDashingEffect.h b/src/gpu/effects/GrDashingEffect.h
index 331b6c8..14df1ae 100644
--- a/src/gpu/effects/GrDashingEffect.h
+++ b/src/gpu/effects/GrDashingEffect.h
@@ -13,6 +13,7 @@
#include "SkPathEffect.h"
class GrGpu;
+class GrDrawState;
class GrDrawTarget;
class GrGeometryProcessor;
class GrPaint;
@@ -22,8 +23,9 @@
class SkPath;
namespace GrDashingEffect {
- bool DrawDashLine(const SkPoint pts[2], const GrPaint& paint, const GrStrokeInfo& strokeInfo,
- GrGpu* gpu, GrDrawTarget* target, const SkMatrix& vm);
+ bool DrawDashLine(GrGpu*, GrDrawTarget*, GrDrawState*, const SkPoint pts[2],
+ const GrPaint& paint, const GrStrokeInfo& strokeInfo,
+ const SkMatrix& vm);
enum DashCap {
kRound_DashCap,
diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp
index 89f26ef..a17329f 100644
--- a/src/gpu/gl/GrGpuGL.cpp
+++ b/src/gpu/gl/GrGpuGL.cpp
@@ -2490,8 +2490,8 @@
return copied;
}
-bool GrGpuGL::canCopySurface(GrSurface* dst,
- GrSurface* src,
+bool GrGpuGL::canCopySurface(const GrSurface* dst,
+ const GrSurface* src,
const SkIRect& srcRect,
const SkIPoint& dstPoint) {
// This mirrors the logic in onCopySurface. We prefer our base makes the copy if we need to
diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h
index 3757d76..778ee16 100644
--- a/src/gpu/gl/GrGpuGL.h
+++ b/src/gpu/gl/GrGpuGL.h
@@ -100,8 +100,8 @@
const SkIRect& srcRect,
const SkIPoint& dstPoint) SK_OVERRIDE;
- virtual bool canCopySurface(GrSurface* dst,
- GrSurface* src,
+ virtual bool canCopySurface(const GrSurface* dst,
+ const GrSurface* src,
const SkIRect& srcRect,
const SkIPoint& dstPoint) SK_OVERRIDE;