Drawstate on stack
BUG=skia:
Review URL: https://codereview.chromium.org/732693002
diff --git a/expectations/gm/ignored-tests.txt b/expectations/gm/ignored-tests.txt
index 00b1ac3..fbd6da5 100644
--- a/expectations/gm/ignored-tests.txt
+++ b/expectations/gm/ignored-tests.txt
@@ -54,3 +54,12 @@
# cdalton https://codereview.chromium.org/712223002
# Pixels off by one from covering gradient fills with different bounding boxes
textblobshader
+
+# joshualitt nvprmsaa4
+simpleaaclip_path
+complexclip2_rrect_bw
+complexclip2_path_aa
+pathopsskpclip
+complexclip2_rrect_aa
+circular-clips
+complexclip2_path_bw
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index 0e811d9..3de47d3 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -158,10 +158,10 @@
context->getTestTarget(&tt);
SkASSERT(tt.target());
- GrDrawState* drawState = tt.target()->drawState();
- drawState->setVertexAttribs<kAttribs>(2, sizeof(Vertex));
+ GrDrawState ds;
+ ds.setVertexAttribs<kAttribs>(2, sizeof(Vertex));
- GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, 0);
+ GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, ds.getVertexStride(), 0);
Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
@@ -173,12 +173,12 @@
verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
}
- drawState->setGeometryProcessor(gp);
- drawState->setRenderTarget(rt);
- drawState->setColor(0xff000000);
+ ds.setGeometryProcessor(gp);
+ ds.setRenderTarget(rt);
+ ds.setColor(0xff000000);
tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
- tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
+ tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
}
++col;
if (numCols == col) {
@@ -315,10 +315,10 @@
context->getTestTarget(&tt);
SkASSERT(tt.target());
- GrDrawState* drawState = tt.target()->drawState();
- drawState->setVertexAttribs<kAttribs>(2, sizeof(Vertex));
+ GrDrawState ds;
+ ds.setVertexAttribs<kAttribs>(2, sizeof(Vertex));
- GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, 0);
+ GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, ds.getVertexStride(), 0);
Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
@@ -330,12 +330,12 @@
verts[v].fKLM[2] = eval_line(verts[v].fPosition, klmEqs + 6, 1.f);
}
- drawState->setGeometryProcessor(gp);
- drawState->setRenderTarget(rt);
- drawState->setColor(0xff000000);
+ ds.setGeometryProcessor(gp);
+ ds.setRenderTarget(rt);
+ ds.setColor(0xff000000);
tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
- tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
+ tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
}
++col;
if (numCols == col) {
@@ -503,10 +503,10 @@
context->getTestTarget(&tt);
SkASSERT(tt.target());
- GrDrawState* drawState = tt.target()->drawState();
- drawState->setVertexAttribs<kAttribs>(2, sizeof(Vertex));
+ GrDrawState ds;
+ ds.setVertexAttribs<kAttribs>(2, sizeof(Vertex));
- GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, 0);
+ GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, ds.getVertexStride(), 0);
Vertex* verts = reinterpret_cast<Vertex*>(geo.vertices());
verts[0].fPosition.setRectFan(bounds.fLeft, bounds.fTop,
@@ -516,12 +516,12 @@
GrPathUtils::QuadUVMatrix DevToUV(pts);
DevToUV.apply<4, sizeof(Vertex), sizeof(SkPoint)>(verts);
- drawState->setGeometryProcessor(gp);
- drawState->setRenderTarget(rt);
- drawState->setColor(0xff000000);
+ ds.setGeometryProcessor(gp);
+ ds.setRenderTarget(rt);
+ ds.setColor(0xff000000);
tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
- tt.target()->drawIndexed(kTriangles_GrPrimitiveType, 0, 0, 4, 6);
+ tt.target()->drawIndexed(&ds, kTriangles_GrPrimitiveType, 0, 0, 4, 6);
}
++col;
if (numCols == col) {
diff --git a/gm/convexpolyeffect.cpp b/gm/convexpolyeffect.cpp
index 9f4c48b..8ee4a5d 100644
--- a/gm/convexpolyeffect.cpp
+++ b/gm/convexpolyeffect.cpp
@@ -121,8 +121,6 @@
SkDEBUGFAIL("Couldn't get Gr test target.");
return;
}
- GrDrawState* drawState = tt.target()->drawState();
-
SkMatrix m;
SkPath p;
m.setTranslate(x, y);
@@ -133,13 +131,15 @@
if (!fp) {
continue;
}
- drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
- drawState->addCoverageProcessor(fp);
- drawState->setIdentityViewMatrix();
- drawState->setRenderTarget(rt);
- drawState->setColor(0xff000000);
- GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, 0);
+ GrDrawState ds;
+ ds.setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
+ ds.addCoverageProcessor(fp);
+ ds.setIdentityViewMatrix();
+ ds.setRenderTarget(rt);
+ ds.setColor(0xff000000);
+
+ GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, ds.getVertexStride(), 0);
SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
SkRect bounds = p.getBounds();
@@ -149,7 +149,7 @@
bounds.toQuad(verts);
tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
- tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
+ tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
x += SkScalarCeilToScalar(path->getBounds().width() + 10.f);
}
@@ -188,14 +188,14 @@
continue;
}
- GrDrawState* drawState = tt.target()->drawState();
- drawState->setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
- drawState->addCoverageProcessor(fp);
- drawState->setIdentityViewMatrix();
- drawState->setRenderTarget(rt);
- drawState->setColor(0xff000000);
+ GrDrawState ds;
+ ds.setGeometryProcessor(GrDefaultGeoProcFactory::Create(false))->unref();
+ ds.addCoverageProcessor(fp);
+ ds.setIdentityViewMatrix();
+ ds.setRenderTarget(rt);
+ ds.setColor(0xff000000);
- GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, 0);
+ GrDrawTarget::AutoReleaseGeometry geo(tt.target(), 4, ds.getVertexStride(), 0);
SkPoint* verts = reinterpret_cast<SkPoint*>(geo.vertices());
SkRect bounds = rect;
@@ -203,7 +203,7 @@
bounds.toQuad(verts);
tt.target()->setIndexSourceToBuffer(context->getQuadIndexBuffer());
- tt.target()->drawIndexed(kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
+ tt.target()->drawIndexed(&ds, kTriangleFan_GrPrimitiveType, 0, 0, 4, 6);
x += SkScalarCeilToScalar(rect.width() + 10.f);
}
diff --git a/gm/rrects.cpp b/gm/rrects.cpp
index b0496e3..34e6bdb 100644
--- a/gm/rrects.cpp
+++ b/gm/rrects.cpp
@@ -112,7 +112,7 @@
SkDEBUGFAIL("Couldn't get Gr test target.");
return;
}
- GrDrawState* drawState = tt.target()->drawState();
+ GrDrawState drawState;
SkRRect rrect = fRRects[curRRect];
rrect.offset(SkIntToScalar(x), SkIntToScalar(y));
@@ -120,15 +120,15 @@
SkAutoTUnref<GrFragmentProcessor> fp(GrRRectEffect::Create(edgeType,
rrect));
if (fp) {
- drawState->addCoverageProcessor(fp);
- drawState->setIdentityViewMatrix();
- drawState->setRenderTarget(rt);
- drawState->setColor(0xff000000);
+ drawState.addCoverageProcessor(fp);
+ drawState.setIdentityViewMatrix();
+ drawState.setRenderTarget(rt);
+ drawState.setColor(0xff000000);
SkRect bounds = rrect.getBounds();
bounds.outset(2.f, 2.f);
- tt.target()->drawSimpleRect(bounds);
+ tt.target()->drawSimpleRect(&drawState, bounds);
} else {
drew = false;
}
diff --git a/gm/texturedomaineffect.cpp b/gm/texturedomaineffect.cpp
index d235f7f..efa7531 100644
--- a/gm/texturedomaineffect.cpp
+++ b/gm/texturedomaineffect.cpp
@@ -90,8 +90,6 @@
return;
}
- GrDrawState* drawState = tt.target()->drawState();
-
SkAutoTUnref<GrTexture> texture(GrRefCachedBitmapTexture(context, fBmp, NULL));
if (!texture) {
return;
@@ -132,12 +130,12 @@
}
SkMatrix viewMatrix;
viewMatrix.setTranslate(x, y);
- drawState->reset(viewMatrix);
- drawState->setRenderTarget(rt);
- drawState->setColor(0xffffffff);
- drawState->addColorProcessor(fp);
+ GrDrawState drawState(viewMatrix);
+ drawState.setRenderTarget(rt);
+ drawState.setColor(0xffffffff);
+ drawState.addColorProcessor(fp);
- tt.target()->drawSimpleRect(renderRect);
+ tt.target()->drawSimpleRect(&drawState, renderRect);
x += renderRect.width() + kTestPad;
}
y += renderRect.height() + kTestPad;
diff --git a/gm/yuvtorgbeffect.cpp b/gm/yuvtorgbeffect.cpp
index b5c6b95..5e7a940 100644
--- a/gm/yuvtorgbeffect.cpp
+++ b/gm/yuvtorgbeffect.cpp
@@ -81,8 +81,6 @@
return;
}
- GrDrawState* drawState = tt.target()->drawState();
-
SkAutoTUnref<GrTexture> texture[3];
texture[0].reset(GrRefCachedBitmapTexture(context, fBmp[0], NULL));
texture[1].reset(GrRefCachedBitmapTexture(context, fBmp[1], NULL));
@@ -117,11 +115,11 @@
if (fp) {
SkMatrix viewMatrix;
viewMatrix.setTranslate(x, y);
- drawState->reset(viewMatrix);
- drawState->setRenderTarget(rt);
- drawState->setColor(0xffffffff);
- drawState->addColorProcessor(fp);
- tt.target()->drawSimpleRect(renderRect);
+ GrDrawState drawState(viewMatrix);
+ drawState.setRenderTarget(rt);
+ drawState.setColor(0xffffffff);
+ drawState.addColorProcessor(fp);
+ tt.target()->drawSimpleRect(&drawState, renderRect);
}
x += renderRect.width() + kTestPad;
}
diff --git a/include/gpu/GrContext.h b/include/gpu/GrContext.h
index b48ac40..b83df45 100644
--- a/include/gpu/GrContext.h
+++ b/include/gpu/GrContext.h
@@ -898,9 +898,10 @@
GrStencilBuffer* findAndRefStencilBuffer(int width, int height, int sampleCnt);
GrPathRenderer* getPathRenderer(
+ const GrDrawTarget* target,
+ const GrDrawState*,
const SkPath& path,
const SkStrokeRec& stroke,
- const GrDrawTarget* target,
bool allowSW,
GrPathRendererChain::DrawType drawType = GrPathRendererChain::kColor_DrawType,
GrPathRendererChain::StencilSupport* stencilSupport = NULL);
@@ -944,7 +945,6 @@
SkMatrix fViewMatrix;
SkAutoTUnref<GrRenderTarget> fRenderTarget;
const GrClipData* fClip; // TODO: make this ref counted
- GrDrawState* fDrawState;
GrResourceCache2* fResourceCache2;
GrFontCache* fFontCache;
@@ -984,14 +984,16 @@
void setupDrawBuffer();
- class AutoRestoreEffects;
class AutoCheckFlush;
/// Sets the paint and returns the target to draw into. The paint can be NULL in which case the
/// draw state is left unmodified.
- GrDrawTarget* prepareToDraw(const GrPaint*, AutoRestoreEffects*, AutoCheckFlush*);
+ GrDrawTarget* prepareToDraw(GrDrawState* ds, const GrPaint* paint, const AutoCheckFlush*);
- void internalDrawPath(GrDrawTarget* target, bool useAA, const SkPath& path,
- const GrStrokeInfo& stroke);
+ void internalDrawPath(GrDrawTarget*,
+ GrDrawState*,
+ bool useAA,
+ const SkPath&,
+ const GrStrokeInfo&);
GrTexture* createResizedTexture(const GrSurfaceDesc& desc,
const GrCacheID& cacheID,
diff --git a/include/gpu/GrPathRendererChain.h b/include/gpu/GrPathRendererChain.h
index ca8c35b..8e1f49b 100644
--- a/include/gpu/GrPathRendererChain.h
+++ b/include/gpu/GrPathRendererChain.h
@@ -12,6 +12,7 @@
#include "SkTArray.h"
class GrContext;
+class GrDrawState;
class GrDrawTarget;
class GrPathRenderer;
class SkPath;
@@ -55,9 +56,10 @@
is drawing the path to the stencil buffer then stencilSupport can be used to determine
whether the path can be rendered with arbitrary stencil rules or not. See comments on
StencilSupport in GrPathRenderer.h. */
- GrPathRenderer* getPathRenderer(const SkPath& path,
+ GrPathRenderer* getPathRenderer(const GrDrawTarget* target,
+ const GrDrawState*,
+ const SkPath& path,
const SkStrokeRec& rec,
- const GrDrawTarget* target,
DrawType drawType,
StencilSupport* stencilSupport);
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;
diff --git a/tests/GLProgramsTest.cpp b/tests/GLProgramsTest.cpp
index a3ef323..7c3ba0f 100644
--- a/tests/GLProgramsTest.cpp
+++ b/tests/GLProgramsTest.cpp
@@ -429,8 +429,8 @@
return false;
}
- GrDrawState* ds = this->drawState();
- ds->setRenderTarget(rt.get());
+ GrDrawState ds;
+ ds.setRenderTarget(rt.get());
// if path rendering we have to setup a couple of things like the draw type
bool usePathRendering = gpu->glCaps().pathRenderingSupport() && random.nextBool();
@@ -441,36 +441,35 @@
// twiddle drawstate knobs randomly
bool hasGeometryProcessor = !usePathRendering;
if (hasGeometryProcessor) {
- set_random_gp(fContext, gpu->glCaps(), ds, &random, dummyTextures);
+ set_random_gp(fContext, gpu->glCaps(), &ds, &random, dummyTextures);
}
set_random_color_coverage_stages(gpu,
- ds,
+ &ds,
maxStages - hasGeometryProcessor,
usePathRendering,
&random,
dummyTextures);
- set_random_color(ds, &random);
- set_random_coverage(ds, &random);
- set_random_hints(ds, &random);
- set_random_state(ds, &random);
- set_random_blend_func(ds, &random);
- set_random_stencil(ds, &random);
+ set_random_color(&ds, &random);
+ set_random_coverage(&ds, &random);
+ set_random_hints(&ds, &random);
+ set_random_state(&ds, &random);
+ set_random_blend_func(&ds, &random);
+ set_random_stencil(&ds, &random);
GrDeviceCoordTexture dstCopy;
- if (!this->setupDstReadIfNecessary(&dstCopy, NULL)) {
+ if (!this->setupDstReadIfNecessary(&ds, &dstCopy, NULL)) {
SkDebugf("Couldn't setup dst read texture");
return false;
}
// create optimized draw state, setup readDst texture if required, and build a descriptor
// and program. ODS creation can fail, so we have to check
- SkAutoTUnref<GrOptDrawState> ods(GrOptDrawState::Create(this->getDrawState(),
+ SkAutoTUnref<GrOptDrawState> ods(GrOptDrawState::Create(ds,
gpu,
&dstCopy,
drawType));
if (!ods.get()) {
- ds->reset();
continue;
}
SkAutoTUnref<GrGLProgram> program(GrGLProgramBuilder::CreateProgram(*ods, drawType, gpu));
@@ -479,9 +478,6 @@
return false;
}
- // We have to reset the drawstate because we might have added a gp
- ds->reset();
-
// because occasionally optimized drawstate creation will fail for valid reasons, we only
// want to increment on success
++t;