Cleanup of r2830.
git-svn-id: http://skia.googlecode.com/svn/trunk@2841 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/gpu/GrAAHairLinePathRenderer.cpp b/src/gpu/GrAAHairLinePathRenderer.cpp
index e306b67..29db9aa 100644
--- a/src/gpu/GrAAHairLinePathRenderer.cpp
+++ b/src/gpu/GrAAHairLinePathRenderer.cpp
@@ -602,8 +602,8 @@
}
bool GrAAHairLinePathRenderer::createGeom(GrDrawState::StageMask stageMask) {
-
- int rtHeight = fTarget->getRenderTarget()->height();
+ const GrDrawState& drawState = fTarget->getDrawState();
+ int rtHeight = drawState.getRenderTarget()->height();
GrIRect clip;
if (fTarget->getClip().hasConservativeBounds()) {
@@ -617,7 +617,7 @@
// have changed since last previous path draw then we can reuse the
// previous geoemtry.
if (stageMask == fPreviousStages &&
- fPreviousViewMatrix == fTarget->getViewMatrix() &&
+ fPreviousViewMatrix == drawState.getViewMatrix() &&
fPreviousTranslate == fTranslate &&
rtHeight == fPreviousRTHeight &&
fClipRect == clip) {
@@ -631,7 +631,7 @@
}
}
- GrMatrix viewM = fTarget->getViewMatrix();
+ GrMatrix viewM = drawState.getViewMatrix();
PREALLOC_PTARRAY(128) lines;
PREALLOC_PTARRAY(128) quads;
@@ -672,7 +672,7 @@
}
fPreviousStages = stageMask;
- fPreviousViewMatrix = fTarget->getViewMatrix();
+ fPreviousViewMatrix = drawState.getViewMatrix();
fPreviousRTHeight = rtHeight;
fClipRect = clip;
fPreviousTranslate = fTranslate;
@@ -685,14 +685,16 @@
return;
}
+ GrDrawState* drawState = fTarget->drawState();
+
GrDrawTarget::AutoStateRestore asr;
- if (!fTarget->getViewMatrix().hasPerspective()) {
+ if (!drawState->getViewMatrix().hasPerspective()) {
asr.set(fTarget);
GrMatrix ivm;
- if (fTarget->getViewInverse(&ivm)) {
- fTarget->preConcatSamplerMatrices(stageMask, ivm);
+ if (drawState->getViewInverse(&ivm)) {
+ drawState->preConcatSamplerMatrices(stageMask, ivm);
}
- fTarget->setViewMatrix(GrMatrix::I());
+ drawState->setViewMatrix(GrMatrix::I());
}
// TODO: See whether rendering lines as degenerate quads improves perf
@@ -702,7 +704,7 @@
int nBufLines = fLinesIndexBuffer->maxQuads();
while (lines < fLineSegmentCnt) {
int n = GrMin(fLineSegmentCnt-lines, nBufLines);
- fTarget->setVertexEdgeType(GrDrawState::kHairLine_EdgeType);
+ drawState->setVertexEdgeType(GrDrawState::kHairLine_EdgeType);
fTarget->drawIndexed(kTriangles_PrimitiveType,
kVertsPerLineSeg*lines, // startV
0, // startI
@@ -715,7 +717,7 @@
int quads = 0;
while (quads < fQuadCnt) {
int n = GrMin(fQuadCnt-quads, kNumQuadsInIdxBuffer);
- fTarget->setVertexEdgeType(GrDrawState::kHairQuad_EdgeType);
+ drawState->setVertexEdgeType(GrDrawState::kHairQuad_EdgeType);
fTarget->drawIndexed(kTriangles_PrimitiveType,
4*fLineSegmentCnt + kVertsPerQuad*quads, // startV
0, // startI
diff --git a/src/gpu/GrContext.cpp b/src/gpu/GrContext.cpp
index de80f65..f455984 100644
--- a/src/gpu/GrContext.cpp
+++ b/src/gpu/GrContext.cpp
@@ -218,20 +218,22 @@
// they aren't used unless the vertex layout references them.
// It also doesn't set the render target.
void reset_target_state(GrDrawTarget* target){
- target->setViewMatrix(GrMatrix::I());
- target->setColorFilter(0, SkXfermode::kDst_Mode);
- target->disableState(GrDrawTarget::kDither_StateBit |
- GrDrawTarget::kHWAntialias_StateBit |
- GrDrawTarget::kClip_StateBit |
- GrDrawTarget::kNoColorWrites_StateBit |
- GrDrawTarget::kEdgeAAConcave_StateBit);
- target->setEdgeAAData(NULL, 0);
- target->disableStencil();
- target->setAlpha(0xFF);
+ GrDrawState* drawState = target->drawState();
+
+ drawState->setViewMatrix(GrMatrix::I());
+ drawState->setColorFilter(0, SkXfermode::kDst_Mode);
+ drawState->disableState(GrDrawState::kDither_StateBit |
+ GrDrawState::kHWAntialias_StateBit |
+ GrDrawState::kClip_StateBit |
+ GrDrawState::kNoColorWrites_StateBit |
+ GrDrawState::kEdgeAAConcave_StateBit);
+ drawState->setEdgeAAData(NULL, 0);
+ drawState->disableStencil();
+ drawState->setAlpha(0xFF);
target->setBlendFunc(kOne_BlendCoeff,
kZero_BlendCoeff);
- target->setFirstCoverageStage(GrDrawState::kNumStages);
- target->setDrawFace(GrDrawState::kBoth_DrawFace);
+ drawState->setFirstCoverageStage(GrDrawState::kNumStages);
+ drawState->setDrawFace(GrDrawState::kBoth_DrawFace);
}
}
@@ -353,9 +355,9 @@
if (NULL != texture) {
GrDrawTarget::AutoStateRestore asr(fGpu);
reset_target_state(fGpu);
-
- fGpu->setRenderTarget(texture->asRenderTarget());
- fGpu->setTexture(0, clampEntry.texture());
+ GrDrawState* drawState = fGpu->drawState();
+ drawState->setRenderTarget(texture->asRenderTarget());
+ drawState->setTexture(0, clampEntry.texture());
GrSamplerState::Filter filter;
// if filtering is not desired then we want to ensure all
@@ -368,7 +370,7 @@
}
GrSamplerState stretchSampler(GrSamplerState::kClamp_WrapMode,
filter);
- fGpu->setSamplerState(0, stretchSampler);
+ drawState->setSampler(0, stretchSampler);
static const GrVertexLayout layout =
GrDrawTarget::StageTexCoordVertexLayoutBit(0,0);
@@ -601,7 +603,7 @@
void GrContext::setClip(const GrClip& clip) {
fGpu->setClip(clip);
- fGpu->enableState(GrDrawTarget::kClip_StateBit);
+ fGpu->drawState()->enableState(GrDrawState::kClip_StateBit);
}
void GrContext::setClip(const GrIRect& rect) {
@@ -624,22 +626,24 @@
r.setLTRB(0, 0,
GrIntToScalar(getRenderTarget()->width()),
GrIntToScalar(getRenderTarget()->height()));
- GrAutoMatrix am;
GrMatrix inverse;
SkTLazy<GrPaint> tmpPaint;
const GrPaint* p = &paint;
+ GrDrawState* drawState = fGpu->drawState();
+ GrAutoMatrix am;
+
// We attempt to map r by the inverse matrix and draw that. mapRect will
// map the four corners and bound them with a new rect. This will not
// produce a correct result for some perspective matrices.
if (!this->getMatrix().hasPerspective()) {
- if (!fGpu->getViewInverse(&inverse)) {
+ if (!drawState->getViewInverse(&inverse)) {
GrPrintf("Could not invert matrix");
return;
}
inverse.mapRect(&r);
} else {
if (paint.getActiveMaskStageMask() || paint.getActiveStageMask()) {
- if (!fGpu->getViewInverse(&inverse)) {
+ if (!drawState->getViewInverse(&inverse)) {
GrPrintf("Could not invert matrix");
return;
}
@@ -697,7 +701,7 @@
(!PREFER_MSAA_OFFSCREEN_AA || !fGpu->getCaps().fFSAASupport)) {
return false;
}
- if (target->getRenderTarget()->isMultisampled()) {
+ if (target->getDrawState().getRenderTarget()->isMultisampled()) {
return false;
}
if (disable_coverage_aa_for_blend(target)) {
@@ -801,19 +805,20 @@
GrPaint tempPaint;
tempPaint.reset();
this->setPaint(tempPaint, target);
- target->setRenderTarget(offRT0);
+ GrDrawState* drawState = target->drawState();
+ drawState->setRenderTarget(offRT0);
#if PREFER_MSAA_OFFSCREEN_AA
- target->enableState(GrDrawTarget::kHWAntialias_StateBit);
+ target->enableState(GrDrawState::kHWAntialias_StateBit);
#endif
GrMatrix transM;
int left = boundRect.fLeft + tileX * record->fTileSizeX;
int top = boundRect.fTop + tileY * record->fTileSizeY;
transM.setTranslate(-left * GR_Scalar1, -top * GR_Scalar1);
- target->postConcatViewMatrix(transM);
+ drawState->viewMatrix()->postConcat(transM);
GrMatrix scaleM;
scaleM.setScale(record->fScale * GR_Scalar1, record->fScale * GR_Scalar1);
- target->postConcatViewMatrix(scaleM);
+ drawState->viewMatrix()->postConcat(scaleM);
int w = (tileX == record->fTileCountX-1) ? boundRect.fRight - left :
record->fTileSizeX;
@@ -872,19 +877,21 @@
kOffscreenStage = GrPaint::kTotalStages,
};
+ GrDrawState* drawState = target->drawState();
+
if (OffscreenRecord::k4x4TwoPass_Downsample == record->fDownsample) {
GrAssert(NULL != record->fOffscreen1.texture());
scale = 2;
GrRenderTarget* dst = record->fOffscreen1.texture()->asRenderTarget();
-
+
// Do 2x2 downsample from first to second
- target->setTexture(kOffscreenStage, src);
- target->setRenderTarget(dst);
- target->setViewMatrix(GrMatrix::I());
+ drawState->setTexture(kOffscreenStage, src);
+ drawState->setRenderTarget(dst);
+ drawState->setViewMatrix(GrMatrix::I());
sampleM.setScale(scale * GR_Scalar1 / src->width(),
scale * GR_Scalar1 / src->height());
sampler.setMatrix(sampleM);
- target->setSamplerState(kOffscreenStage, sampler);
+ drawState->setSampler(kOffscreenStage, sampler);
GrRect rect = SkRect::MakeWH(SkIntToScalar(scale * tileRect.width()),
SkIntToScalar(scale * tileRect.height()));
target->drawSimpleRect(rect, NULL, 1 << kOffscreenStage);
@@ -911,24 +918,22 @@
if (stageMask) {
GrMatrix invVM;
- if (target->getViewInverse(&invVM)) {
- target->preConcatSamplerMatrices(stageMask, invVM);
+ if (drawState->getViewInverse(&invVM)) {
+ drawState->preConcatSamplerMatrices(stageMask, invVM);
}
}
// This is important when tiling, otherwise second tile's
// pass 1 view matrix will be incorrect.
- GrDrawTarget::AutoViewMatrixRestore avmr(target);
+ GrDrawState::AutoViewMatrixRestore avmr(drawState, GrMatrix::I());
- target->setViewMatrix(GrMatrix::I());
-
- target->setTexture(kOffscreenStage, src);
+ drawState->setTexture(kOffscreenStage, src);
sampleM.setScale(scale * GR_Scalar1 / src->width(),
scale * GR_Scalar1 / src->height());
sampler.setMatrix(sampleM);
sampleM.setTranslate(SkIntToScalar(-tileRect.fLeft),
SkIntToScalar(-tileRect.fTop));
sampler.preConcatMatrix(sampleM);
- target->setSamplerState(kOffscreenStage, sampler);
+ drawState->setSampler(kOffscreenStage, sampler);
GrRect dstRect;
int stages = (1 << kOffscreenStage) | stageMask;
@@ -1040,7 +1045,7 @@
bool useCoverage) {
GrVertexLayout layout = 0;
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- if (NULL != target->getTexture(s)) {
+ if (NULL != target->getDrawState().getTexture(s)) {
layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s);
}
}
@@ -1087,7 +1092,7 @@
if (useVertexCoverage) {
innerColor = 0xffffffff;
} else {
- innerColor = target->getColor();
+ innerColor = target->getDrawState().getColor();
}
verts += 4 * vsize;
@@ -1158,7 +1163,7 @@
if (useVertexCoverage) {
innerColor = 0xffffffff;
} else {
- innerColor = target->getColor();
+ innerColor = target->getDrawState().getColor();
}
verts += 4 * vsize;
for (int i = 0; i < 8; ++i) {
@@ -1214,8 +1219,8 @@
return false;
}
}
-
- if (target->getRenderTarget()->isMultisampled()) {
+ const GrDrawState& drawState = target->getDrawState();
+ if (drawState.getRenderTarget()->isMultisampled()) {
return false;
}
@@ -1223,7 +1228,7 @@
return false;
}
- if (!target->getViewMatrix().preservesAxisAlignment()) {
+ if (!drawState.getViewMatrix().preservesAxisAlignment()) {
return false;
}
@@ -1232,7 +1237,7 @@
return false;
}
- *combinedMatrix = target->getViewMatrix();
+ *combinedMatrix = drawState.getViewMatrix();
if (NULL != matrix) {
combinedMatrix->preConcat(*matrix);
GrAssert(combinedMatrix->preservesAxisAlignment());
@@ -1267,14 +1272,7 @@
&useVertexCoverage);
if (doAA) {
- GrDrawTarget::AutoViewMatrixRestore avm(target);
- if (stageMask) {
- GrMatrix inv;
- if (combinedMatrix.invert(&inv)) {
- target->preConcatSamplerMatrices(stageMask, inv);
- }
- }
- target->setViewMatrix(GrMatrix::I());
+ GrDrawTarget::AutoDeviceCoordDraw adcd(target, stageMask);
if (width >= 0) {
GrVec strokeSize;;
if (width > 0) {
@@ -1324,16 +1322,17 @@
vertex[4].set(rect.fLeft, rect.fTop);
}
- GrDrawTarget::AutoViewMatrixRestore avmr;
+ GrDrawState::AutoViewMatrixRestore avmr;
if (NULL != matrix) {
- avmr.set(target);
- target->preConcatViewMatrix(*matrix);
- target->preConcatSamplerMatrices(stageMask, *matrix);
+ GrDrawState* drawState = target->drawState();
+ avmr.set(drawState);
+ drawState->preConcatViewMatrix(*matrix);
+ drawState->preConcatSamplerMatrices(stageMask, *matrix);
}
target->drawNonIndexed(primType, 0, vertCount);
} else {
- #if GR_STATIC_RECT_VB
+#if GR_STATIC_RECT_VB
GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer();
if (NULL == sqVB) {
@@ -1341,7 +1340,8 @@
return;
}
target->setVertexSourceToBuffer(layout, sqVB);
- GrDrawTarget::AutoViewMatrixRestore avmr(target);
+ GrDrawState* drawState = target->drawState();
+ GrDrawState::AutoViewMatrixRestore avmr(drawState);
GrMatrix m;
m.setAll(rect.width(), 0, rect.fLeft,
0, rect.height(), rect.fTop,
@@ -1350,14 +1350,13 @@
if (NULL != matrix) {
m.postConcat(*matrix);
}
-
- target->preConcatViewMatrix(m);
- target->preConcatSamplerMatrices(stageMask, m);
+ drawState->preConcatViewMatrix(m);
+ drawState->preConcatSamplerMatrices(stageMask, m);
target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4);
- #else
+#else
target->drawSimpleRect(rect, matrix, stageMask);
- #endif
+#endif
}
}
@@ -1378,9 +1377,9 @@
#if GR_STATIC_RECT_VB
GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory);
-
+ GrDrawState* drawState = target->drawState();
GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL);
- GrDrawTarget::AutoViewMatrixRestore avmr(target);
+ GrDrawState::AutoViewMatrixRestore avmr(drawState);
GrMatrix m;
@@ -1390,13 +1389,13 @@
if (NULL != dstMatrix) {
m.postConcat(*dstMatrix);
}
- target->preConcatViewMatrix(m);
+ drawState->preConcatViewMatrix(m);
// srcRect refers to first stage
int otherStageMask = paint.getActiveStageMask() &
(~(1 << GrPaint::kFirstTextureStage));
if (otherStageMask) {
- target->preConcatSamplerMatrices(otherStageMask, m);
+ drawState->preConcatSamplerMatrices(otherStageMask, m);
}
m.setAll(srcRect.width(), 0, srcRect.fLeft,
@@ -1405,7 +1404,7 @@
if (NULL != srcMatrix) {
m.postConcat(*srcMatrix);
}
- target->preConcatSamplerMatrix(GrPaint::kFirstTextureStage, m);
+ drawState->sampler(GrPaint::kFirstTextureStage)->preConcatMatrix(m);
const GrVertexBuffer* sqVB = fGpu->getUnitSquareVertexBuffer();
if (NULL == sqVB) {
@@ -1553,10 +1552,9 @@
if (doOSAA) {
bool needsStencil = pr->requiresStencilPass(target, path, fill);
-
+ const GrRenderTarget* rt = target->getDrawState().getRenderTarget();
// compute bounds as intersection of rt size, clip, and path
- GrIRect bound = SkIRect::MakeWH(target->getRenderTarget()->width(),
- target->getRenderTarget()->height());
+ GrIRect bound = SkIRect::MakeWH(rt->width(), rt->height());
GrIRect clipIBounds;
if (target->getClip().hasConservativeBounds()) {
target->getClip().getConservativeBounds().roundOut(&clipIBounds);
@@ -1564,13 +1562,13 @@
return;
}
}
-
GrRect pathBounds = path.getBounds();
if (!pathBounds.isEmpty()) {
if (NULL != translate) {
pathBounds.offset(*translate);
}
- target->getViewMatrix().mapRect(&pathBounds, pathBounds);
+ target->getDrawState().getViewMatrix().mapRect(&pathBounds,
+ pathBounds);
GrIRect pathIBounds;
pathBounds.roundOut(&pathIBounds);
if (!bound.intersect(pathIBounds)) {
@@ -1706,7 +1704,7 @@
ASSERT_OWNED_RESOURCE(target);
if (NULL == target) {
- target = fGpu->getRenderTarget();
+ target = fGpu->drawState()->getRenderTarget();
if (NULL == target) {
return false;
}
@@ -1782,8 +1780,8 @@
GrDrawTarget::AutoStateRestore asr(fGpu);
reset_target_state(fGpu);
-
- fGpu->setRenderTarget(target);
+ GrDrawState* drawState = fGpu->drawState();
+ drawState->setRenderTarget(target);
GrMatrix matrix;
if (flipY) {
@@ -1799,8 +1797,8 @@
GrSamplerState::kNearest_Filter,
matrix);
sampler.setRAndBSwap(swapRAndB);
- fGpu->setSamplerState(0, sampler);
- fGpu->setTexture(0, src);
+ drawState->setSampler(0, sampler);
+ drawState->setTexture(0, src);
GrRect rect;
rect.setXYWH(0, 0, SK_Scalar1 * width, SK_Scalar1 * height);
fGpu->drawSimpleRect(rect, NULL, 0x1);
@@ -1820,14 +1818,15 @@
GrDrawTarget::AutoStateRestore asr(fGpu);
reset_target_state(fGpu);
- fGpu->setRenderTarget(dst);
+ GrDrawState* drawState = fGpu->drawState();
+ drawState->setRenderTarget(dst);
GrSamplerState sampler(GrSamplerState::kClamp_WrapMode,
GrSamplerState::kNearest_Filter);
GrMatrix sampleM;
sampleM.setIDiv(src->width(), src->height());
sampler.setMatrix(sampleM);
- fGpu->setTexture(0, src);
- fGpu->setSamplerState(0, sampler);
+ drawState->setTexture(0, src);
+ drawState->setSampler(0, sampler);
SkRect rect = SkRect::MakeXYWH(0, 0, src->width(), src->height());
fGpu->drawSimpleRect(rect, NULL, 1 << 0);
}
@@ -1843,7 +1842,7 @@
ASSERT_OWNED_RESOURCE(target);
if (NULL == target) {
- target = fGpu->getRenderTarget();
+ target = fGpu->drawState()->getRenderTarget();
if (NULL == target) {
return;
}
@@ -1890,12 +1889,13 @@
GrDrawTarget::AutoStateRestore asr(fGpu);
reset_target_state(fGpu);
+ GrDrawState* drawState = fGpu->drawState();
GrMatrix matrix;
matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top));
- fGpu->setViewMatrix(matrix);
- fGpu->setRenderTarget(target);
- fGpu->setTexture(0, texture);
+ drawState->setViewMatrix(matrix);
+ drawState->setRenderTarget(target);
+ drawState->setTexture(0, texture);
matrix.setIDiv(texture->width(), texture->height());
GrSamplerState sampler;
@@ -1903,7 +1903,7 @@
GrSamplerState::kNearest_Filter,
matrix);
sampler.setRAndBSwap(swapRAndB);
- fGpu->setSamplerState(0, sampler);
+ drawState->setSampler(0, sampler);
GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0);
static const int VCOUNT = 4;
@@ -1919,37 +1919,38 @@
////////////////////////////////////////////////////////////////////////////////
void GrContext::setPaint(const GrPaint& paint, GrDrawTarget* target) {
+ GrDrawState* drawState = target->drawState();
for (int i = 0; i < GrPaint::kMaxTextures; ++i) {
int s = i + GrPaint::kFirstTextureStage;
- target->setTexture(s, paint.getTexture(i));
+ drawState->setTexture(s, paint.getTexture(i));
ASSERT_OWNED_RESOURCE(paint.getTexture(i));
- target->setSamplerState(s, paint.getTextureSampler(i));
+ drawState->setSampler(s, paint.getTextureSampler(i));
}
- target->setFirstCoverageStage(GrPaint::kFirstMaskStage);
+ drawState->setFirstCoverageStage(GrPaint::kFirstMaskStage);
for (int i = 0; i < GrPaint::kMaxMasks; ++i) {
int s = i + GrPaint::kFirstMaskStage;
- target->setTexture(s, paint.getMask(i));
+ drawState->setTexture(s, paint.getMask(i));
ASSERT_OWNED_RESOURCE(paint.getMask(i));
- target->setSamplerState(s, paint.getMaskSampler(i));
+ drawState->setSampler(s, paint.getMaskSampler(i));
}
- target->setColor(paint.fColor);
+ drawState->setColor(paint.fColor);
if (paint.fDither) {
- target->enableState(GrDrawTarget::kDither_StateBit);
+ drawState->enableState(GrDrawState::kDither_StateBit);
} else {
- target->disableState(GrDrawTarget::kDither_StateBit);
+ drawState->disableState(GrDrawState::kDither_StateBit);
}
if (paint.fAntiAlias) {
- target->enableState(GrDrawTarget::kHWAntialias_StateBit);
+ drawState->enableState(GrDrawState::kHWAntialias_StateBit);
} else {
- target->disableState(GrDrawTarget::kHWAntialias_StateBit);
+ drawState->disableState(GrDrawState::kHWAntialias_StateBit);
}
target->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff);
- target->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode);
+ drawState->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode);
if (paint.getActiveMaskStageMask() && !target->canApplyCoverage()) {
GrPrintf("Partial pixel coverage will be incorrectly blended.\n");
@@ -2000,27 +2001,27 @@
void GrContext::setRenderTarget(GrRenderTarget* target) {
ASSERT_OWNED_RESOURCE(target);
this->flush(false);
- fGpu->setRenderTarget(target);
+ fGpu->drawState()->setRenderTarget(target);
}
GrRenderTarget* GrContext::getRenderTarget() {
- return fGpu->getRenderTarget();
+ return fGpu->drawState()->getRenderTarget();
}
const GrRenderTarget* GrContext::getRenderTarget() const {
- return fGpu->getRenderTarget();
+ return fGpu->getDrawState().getRenderTarget();
}
const GrMatrix& GrContext::getMatrix() const {
- return fGpu->getViewMatrix();
+ return fGpu->getDrawState().getViewMatrix();
}
void GrContext::setMatrix(const GrMatrix& m) {
- fGpu->setViewMatrix(m);
+ fGpu->drawState()->setViewMatrix(m);
}
void GrContext::concatMatrix(const GrMatrix& m) const {
- fGpu->preConcatViewMatrix(m);
+ fGpu->drawState()->preConcatViewMatrix(m);
}
static inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) {
@@ -2149,10 +2150,11 @@
sampler.setConvolutionParams(kernelWidth, kernel, imageIncrement);
sampleM.setIDiv(texture->width(), texture->height());
sampler.setMatrix(sampleM);
- fGpu->setSamplerState(0, sampler);
- fGpu->setViewMatrix(GrMatrix::I());
- fGpu->setTexture(0, texture);
- fGpu->setColor(0xFFFFFFFF);
+ GrDrawState* drawState = fGpu->drawState();
+ drawState->setSampler(0, sampler);
+ drawState->setViewMatrix(GrMatrix::I());
+ drawState->setTexture(0, texture);
+ drawState->setAlpha(0xFF);
fGpu->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff);
fGpu->drawSimpleRect(rect, NULL, 1 << 0);
}
diff --git a/src/gpu/GrDefaultPathRenderer.cpp b/src/gpu/GrDefaultPathRenderer.cpp
index 197ee06..ebd0cc1 100644
--- a/src/gpu/GrDefaultPathRenderer.cpp
+++ b/src/gpu/GrDefaultPathRenderer.cpp
@@ -190,7 +190,8 @@
return hint == kConvex_ConvexHint ||
hint == kNonOverlappingConvexPieces_ConvexHint ||
(hint == kSameWindingConvexPieces_ConvexHint &&
- !target.drawWillReadDst() && !target.isDitherState());
+ !target.drawWillReadDst() &&
+ !target.getDrawState().isDitherState());
}
return false;
@@ -384,9 +385,10 @@
void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
bool stencilOnly) {
- GrMatrix viewM = fTarget->getViewMatrix();
+ GrMatrix viewM = fTarget->getDrawState().getViewMatrix();
GrScalar tol = GR_Scalar1;
tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, fPath->getBounds());
+ GrDrawState* drawState = fTarget->drawState();
// FIXME: It's really dumb that we recreate the verts for a new vertex
// layout. We only do that because the GrDrawTarget API doesn't allow
@@ -405,9 +407,9 @@
GrAssert(NULL != fTarget);
GrDrawTarget::AutoStateRestore asr(fTarget);
- bool colorWritesWereDisabled = fTarget->isColorWriteDisabled();
+ bool colorWritesWereDisabled = drawState->isColorWriteDisabled();
// face culling doesn't make sense here
- GrAssert(GrDrawState::kBoth_DrawFace == fTarget->getDrawFace());
+ GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());
int passCount = 0;
const GrStencilSettings* passes[3];
@@ -503,36 +505,36 @@
{
for (int p = 0; p < passCount; ++p) {
- fTarget->setDrawFace(drawFace[p]);
+ drawState->setDrawFace(drawFace[p]);
if (NULL != passes[p]) {
- fTarget->setStencil(*passes[p]);
+ *drawState->stencil() = *passes[p];
}
if (lastPassIsBounds && (p == passCount-1)) {
if (!colorWritesWereDisabled) {
- fTarget->disableState(GrDrawTarget::kNoColorWrites_StateBit);
+ drawState->disableState(GrDrawState::kNoColorWrites_StateBit);
}
GrRect bounds;
if (reverse) {
- GrAssert(NULL != fTarget->getRenderTarget());
+ GrAssert(NULL != drawState->getRenderTarget());
// draw over the whole world.
bounds.setLTRB(0, 0,
- GrIntToScalar(fTarget->getRenderTarget()->width()),
- GrIntToScalar(fTarget->getRenderTarget()->height()));
+ GrIntToScalar(drawState->getRenderTarget()->width()),
+ GrIntToScalar(drawState->getRenderTarget()->height()));
GrMatrix vmi;
// mapRect through persp matrix may not be correct
- if (!fTarget->getViewMatrix().hasPerspective() &&
- fTarget->getViewInverse(&vmi)) {
+ if (!drawState->getViewMatrix().hasPerspective() &&
+ drawState->getViewInverse(&vmi)) {
vmi.mapRect(&bounds);
} else {
if (stageMask) {
- if (!fTarget->getViewInverse(&vmi)) {
+ if (!drawState->getViewInverse(&vmi)) {
GrPrintf("Could not invert matrix.");
return;
}
- fTarget->preConcatSamplerMatrices(stageMask, vmi);
+ drawState->preConcatSamplerMatrices(stageMask, vmi);
}
- fTarget->setViewMatrix(GrMatrix::I());
+ drawState->setViewMatrix(GrMatrix::I());
}
} else {
bounds = fPath->getBounds();
@@ -542,7 +544,7 @@
fTarget->drawSimpleRect(bounds, NULL, stageMask);
} else {
if (passCount > 1) {
- fTarget->enableState(GrDrawTarget::kNoColorWrites_StateBit);
+ drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
}
if (fUseIndexedDraw) {
fTarget->drawIndexed(fPrimitiveType, 0, 0,
diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h
index 90de1a3..7526b9f 100644
--- a/src/gpu/GrDrawState.h
+++ b/src/gpu/GrDrawState.h
@@ -10,6 +10,7 @@
#include "GrColor.h"
#include "GrMatrix.h"
+#include "GrNoncopyable.h"
#include "GrSamplerState.h"
#include "GrStencil.h"
@@ -45,13 +46,433 @@
typedef uint32_t StageMask;
GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages);
- enum DrawFace {
- kBoth_DrawFace,
- kCCW_DrawFace,
- kCW_DrawFace,
+ GrDrawState() {
+ // make sure any pad is zero for memcmp
+ // all GrDrawState members should default to something
+ // valid by the memset
+ memset(this, 0, sizeof(GrDrawState));
+
+ // memset exceptions
+ fColorFilterMode = SkXfermode::kDstIn_Mode;
+ fFirstCoverageStage = kNumStages;
+
+ // pedantic assertion that our ptrs will
+ // be NULL (0 ptr is mem addr 0)
+ GrAssert((intptr_t)(void*)NULL == 0LL);
+
+ GrAssert(fStencilSettings.isDisabled());
+ fFirstCoverageStage = kNumStages;
+ }
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name Color
+ ////
+
+ /**
+ * Sets color for next draw to a premultiplied-alpha color.
+ *
+ * @param color the color to set.
+ */
+ void setColor(GrColor color) { fColor = color; }
+
+ GrColor getColor() const { return fColor; }
+
+ /**
+ * Sets the color to be used for the next draw to be
+ * (r,g,b,a) = (alpha, alpha, alpha, alpha).
+ *
+ * @param alpha The alpha value to set as the color.
+ */
+ void setAlpha(uint8_t a) {
+ this->setColor((a << 24) | (a << 16) | (a << 8) | a);
+ }
+
+ /**
+ * Add a color filter that can be represented by a color and a mode. Applied
+ * after color-computing texture stages.
+ */
+ void setColorFilter(GrColor c, SkXfermode::Mode mode) {
+ fColorFilterColor = c;
+ fColorFilterMode = mode;
+ }
+
+ GrColor getColorFilterColor() const { return fColorFilterColor; }
+ SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
+
+ /// @}
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name Textures
+ ////
+
+ /**
+ * Sets the texture used at the next drawing call
+ *
+ * @param stage The texture stage for which the texture will be set
+ *
+ * @param texture The texture to set. Can be NULL though there is no
+ * advantage to settings a NULL texture if doing non-textured drawing
+ */
+ void setTexture(int stage, GrTexture* texture) {
+ GrAssert((unsigned)stage < kNumStages);
+ fTextures[stage] = texture;
+ }
+
+ /**
+ * Retrieves the currently set texture.
+ *
+ * @return The currently set texture. The return value will be NULL if no
+ * texture has been set, NULL was most recently passed to
+ * setTexture, or the last setTexture was destroyed.
+ */
+ const GrTexture* getTexture(int stage) const {
+ GrAssert((unsigned)stage < kNumStages);
+ return fTextures[stage];
+ }
+ GrTexture* getTexture(int stage) {
+ GrAssert((unsigned)stage < kNumStages);
+ return fTextures[stage];
+ }
+
+ /// @}
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name Samplers
+ ////
+
+ /**
+ * Returns the current sampler for a stage.
+ */
+ const GrSamplerState& getSampler(int stage) const {
+ GrAssert((unsigned)stage < kNumStages);
+ return fSamplerStates[stage];
+ }
+
+ /**
+ * Sets the sampler. This will be removed soon in favor of direct access.
+ */
+ void setSampler(int stage, const GrSamplerState& sampler) {
+ GrAssert((unsigned)stage < kNumStages);
+ fSamplerStates[stage] = sampler;
+ }
+
+ /**
+ * Writable pointer to a stage's sampler.
+ */
+ GrSamplerState* sampler(int stage) {
+ GrAssert((unsigned)stage < kNumStages);
+ return fSamplerStates + stage;
+ }
+
+ /**
+ * Preconcats the matrix of all samplers in the mask with the same matrix.
+ */
+ void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) {
+ GrAssert(!(stageMask & kIllegalStageMaskBits));
+ for (int i = 0; i < kNumStages; ++i) {
+ if ((1 << i) & stageMask) {
+ fSamplerStates[i].preConcatMatrix(matrix);
+ }
+ }
+ }
+
+ /// @}
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name Coverage / Color Stages
+ ////
+
+ /**
+ * A common pattern is to compute a color with the initial stages and then
+ * modulate that color by a coverage value in later stage(s) (AA, mask-
+ * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
+ * computed based on the pre-coverage-modulated color. The division of
+ * stages between color-computing and coverage-computing is specified by
+ * this method. Initially this is kNumStages (all stages
+ * are color-computing).
+ */
+ void setFirstCoverageStage(int firstCoverageStage) {
+ GrAssert((unsigned)firstCoverageStage <= kNumStages);
+ fFirstCoverageStage = firstCoverageStage;
+ }
+
+ /**
+ * Gets the index of the first coverage-computing stage.
+ */
+ int getFirstCoverageStage() const {
+ return fFirstCoverageStage;
+ }
+
+ ///@}
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name Blending
+ ////
+
+ /**
+ * Sets the blending function coeffecients.
+ *
+ * The blend function will be:
+ * D' = sat(S*srcCoef + D*dstCoef)
+ *
+ * where D is the existing destination color, S is the incoming source
+ * color, and D' is the new destination color that will be written. sat()
+ * is the saturation function.
+ *
+ * @param srcCoef coeffecient applied to the src color.
+ * @param dstCoef coeffecient applied to the dst color.
+ */
+ void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+ fSrcBlend = srcCoeff;
+ fDstBlend = dstCoeff;
+ #if GR_DEBUG
+ switch (dstCoeff) {
+ case kDC_BlendCoeff:
+ case kIDC_BlendCoeff:
+ case kDA_BlendCoeff:
+ case kIDA_BlendCoeff:
+ GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
+ "coverage stages.\n");
+ break;
+ default:
+ break;
+ }
+ switch (srcCoeff) {
+ case kSC_BlendCoeff:
+ case kISC_BlendCoeff:
+ case kSA_BlendCoeff:
+ case kISA_BlendCoeff:
+ GrPrintf("Unexpected src blend coeff. Won't work correctly with"
+ "coverage stages.\n");
+ break;
+ default:
+ break;
+ }
+ #endif
+ }
+
+ GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
+ GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
+
+ void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
+ GrBlendCoeff* dstBlendCoeff) const {
+ *srcBlendCoeff = fSrcBlend;
+ *dstBlendCoeff = fDstBlend;
+ }
+
+ /**
+ * Sets the blending function constant referenced by the following blending
+ * coeffecients:
+ * kConstC_BlendCoeff
+ * kIConstC_BlendCoeff
+ * kConstA_BlendCoeff
+ * kIConstA_BlendCoeff
+ *
+ * @param constant the constant to set
+ */
+ void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
+
+ /**
+ * Retrieves the last value set by setBlendConstant()
+ * @return the blending constant value
+ */
+ GrColor getBlendConstant() const { return fBlendConstant; }
+
+ /// @}
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name View Matrix
+ ////
+
+ /**
+ * Sets the matrix applied to veretx positions.
+ *
+ * In the post-view-matrix space the rectangle [0,w]x[0,h]
+ * fully covers the render target. (w and h are the width and height of the
+ * the rendertarget.)
+ */
+ void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; }
+
+ /**
+ * Gets a writable pointer to the view matrix.
+ */
+ GrMatrix* viewMatrix() { return &fViewMatrix; }
+
+ /**
+ * Multiplies the current view matrix by a matrix
+ *
+ * After this call V' = V*m where V is the old view matrix,
+ * m is the parameter to this function, and V' is the new view matrix.
+ * (We consider positions to be column vectors so position vector p is
+ * transformed by matrix X as p' = X*p.)
+ *
+ * @param m the matrix used to modify the view matrix.
+ */
+ void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); }
+
+ /**
+ * Multiplies the current view matrix by a matrix
+ *
+ * After this call V' = m*V where V is the old view matrix,
+ * m is the parameter to this function, and V' is the new view matrix.
+ * (We consider positions to be column vectors so position vector p is
+ * transformed by matrix X as p' = X*p.)
+ *
+ * @param m the matrix used to modify the view matrix.
+ */
+ void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); }
+
+ /**
+ * Retrieves the current view matrix
+ * @return the current view matrix.
+ */
+ const GrMatrix& getViewMatrix() const { return fViewMatrix; }
+
+ /**
+ * Retrieves the inverse of the current view matrix.
+ *
+ * If the current view matrix is invertible, return true, and if matrix
+ * is non-null, copy the inverse into it. If the current view matrix is
+ * non-invertible, return false and ignore the matrix parameter.
+ *
+ * @param matrix if not null, will receive a copy of the current inverse.
+ */
+ bool getViewInverse(GrMatrix* matrix) const {
+ // TODO: determine whether we really need to leave matrix unmodified
+ // at call sites when inversion fails.
+ GrMatrix inverse;
+ if (fViewMatrix.invert(&inverse)) {
+ if (matrix) {
+ *matrix = inverse;
+ }
+ return true;
+ }
+ return false;
+ }
+
+ class AutoViewMatrixRestore : public ::GrNoncopyable {
+ public:
+ AutoViewMatrixRestore() : fDrawState(NULL) {}
+ AutoViewMatrixRestore(GrDrawState* ds, const GrMatrix& newMatrix) {
+ fDrawState = NULL;
+ this->set(ds, newMatrix);
+ }
+ AutoViewMatrixRestore(GrDrawState* ds) {
+ fDrawState = NULL;
+ this->set(ds);
+ }
+ ~AutoViewMatrixRestore() {
+ this->set(NULL, GrMatrix::I());
+ }
+ void set(GrDrawState* ds, const GrMatrix& newMatrix) {
+ if (NULL != fDrawState) {
+ fDrawState->setViewMatrix(fSavedMatrix);
+ }
+ if (NULL != ds) {
+ fSavedMatrix = ds->getViewMatrix();
+ ds->setViewMatrix(newMatrix);
+ }
+ fDrawState = ds;
+ }
+ void set(GrDrawState* ds) {
+ if (NULL != fDrawState) {
+ fDrawState->setViewMatrix(fSavedMatrix);
+ }
+ if (NULL != ds) {
+ fSavedMatrix = ds->getViewMatrix();
+ }
+ fDrawState = ds;
+ }
+ private:
+ GrDrawState* fDrawState;
+ GrMatrix fSavedMatrix;
};
- /**
+ /// @}
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name Render Target
+ ////
+
+ /**
+ * Sets the rendertarget used at the next drawing call
+ *
+ * @param target The render target to set.
+ */
+ void setRenderTarget(GrRenderTarget* target) { fRenderTarget = target; }
+
+ /**
+ * Retrieves the currently set rendertarget.
+ *
+ * @return The currently set render target.
+ */
+ const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
+ GrRenderTarget* getRenderTarget() { return fRenderTarget; }
+
+ class AutoRenderTargetRestore : public ::GrNoncopyable {
+ public:
+ AutoRenderTargetRestore() : fDrawState(NULL) {}
+ AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
+ fDrawState = NULL;
+ this->set(ds, newTarget);
+ }
+ ~AutoRenderTargetRestore() { this->set(NULL, NULL); }
+ void set(GrDrawState* ds, GrRenderTarget* newTarget) {
+ if (NULL != fDrawState) {
+ fDrawState->setRenderTarget(fSavedTarget);
+ }
+ if (NULL != ds) {
+ fSavedTarget = ds->getRenderTarget();
+ ds->setRenderTarget(newTarget);
+ }
+ fDrawState = ds;
+ }
+ private:
+ GrDrawState* fDrawState;
+ GrRenderTarget* fSavedTarget;
+ };
+
+ /// @}
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name Stencil
+ ////
+
+ /**
+ * Sets the stencil settings to use for the next draw.
+ * Changing the clip has the side-effect of possibly zeroing
+ * out the client settable stencil bits. So multipass algorithms
+ * using stencil should not change the clip between passes.
+ * @param settings the stencil settings to use.
+ */
+ void setStencil(const GrStencilSettings& settings) {
+ fStencilSettings = settings;
+ }
+
+ /**
+ * Shortcut to disable stencil testing and ops.
+ */
+ void disableStencil() {
+ fStencilSettings.setDisabled();
+ }
+
+ const GrStencilSettings& getStencil() const { return fStencilSettings; }
+
+ GrStencilSettings* stencil() { return &fStencilSettings; }
+
+ /// @}
+
+ ///////////////////////////////////////////////////////////////////////////
+ // @name Edge AA
+ // There are two ways to perform antialiasing using edge equations. One
+ // is to specify an (linear or quadratic) edge eq per-vertex. This requires
+ // splitting vertices shared by primitives.
+ //
+ // The other is via setEdgeAAData which sets a set of edges and each
+ // is tested against all the edges.
+ ////
+
+ /**
* When specifying edges as vertex data this enum specifies what type of
* edges are in use. The edges are always 4 GrScalars in memory, even when
* the edge type requires fewer than 4.
@@ -66,6 +487,19 @@
};
/**
+ * Determines the interpretation per-vertex edge data when the
+ * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
+ * are not specified the value of this setting has no effect.
+ */
+ void setVertexEdgeType(VertexEdgeType type) {
+ fVertexEdgeType = type;
+ }
+
+ VertexEdgeType getVertexEdgeType() const {
+ return fVertexEdgeType;
+ }
+
+ /**
* The absolute maximum number of edges that may be specified for
* a single draw call when performing edge antialiasing. This is used for
* the size of several static buffers, so implementations of getMaxEdges()
@@ -91,53 +525,146 @@
float fX, fY, fZ;
};
- GrDrawState() {
- // make sure any pad is zero for memcmp
- // all GrDrawState members should default to something
- // valid by the memset
- memset(this, 0, sizeof(GrDrawState));
-
- // memset exceptions
- fColorFilterXfermode = SkXfermode::kDstIn_Mode;
- fFirstCoverageStage = kNumStages;
-
- // pedantic assertion that our ptrs will
- // be NULL (0 ptr is mem addr 0)
- GrAssert((intptr_t)(void*)NULL == 0LL);
-
- // default stencil setting should be disabled
- GrAssert(fStencilSettings.isDisabled());
- fFirstCoverageStage = kNumStages;
+ /**
+ * Sets the edge data required for edge antialiasing.
+ *
+ * @param edges 3 * numEdges float values, representing the edge
+ * equations in Ax + By + C form
+ */
+ void setEdgeAAData(const Edge* edges, int numEdges) {
+ GrAssert(numEdges <= GrDrawState::kMaxEdges);
+ memcpy(fEdgeAAEdges, edges, numEdges * sizeof(GrDrawState::Edge));
+ fEdgeAANumEdges = numEdges;
}
- uint8_t fFlagBits;
- GrBlendCoeff fSrcBlend : 8;
- GrBlendCoeff fDstBlend : 8;
- DrawFace fDrawFace : 8;
- uint8_t fFirstCoverageStage;
- SkXfermode::Mode fColorFilterXfermode : 8;
- GrColor fBlendConstant;
- GrTexture* fTextures[kNumStages];
- GrRenderTarget* fRenderTarget;
- GrColor fColor;
- GrColor fColorFilterColor;
+ int getNumAAEdges() const { return fEdgeAANumEdges; }
- GrStencilSettings fStencilSettings;
- GrMatrix fViewMatrix;
+ const Edge* getAAEdges() const { return fEdgeAAEdges; }
- // @{ Data for GrTesselatedPathRenderer
- // TODO: currently ignored in copying & comparison for performance.
- // Must be considered if GrTesselatedPathRenderer is being used.
+ /// @}
- int fEdgeAANumEdges;
- VertexEdgeType fVertexEdgeType;
- Edge fEdgeAAEdges[kMaxEdges];
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name State Flags
+ ////
- // @}
+ /**
+ * Flags that affect rendering. Controlled using enable/disableState(). All
+ * default to disabled.
+ */
+ enum StateBits {
+ /**
+ * Perform dithering. TODO: Re-evaluate whether we need this bit
+ */
+ kDither_StateBit = 0x01,
+ /**
+ * Perform HW anti-aliasing. This means either HW FSAA, if supported
+ * by the render target, or smooth-line rendering if a line primitive
+ * is drawn and line smoothing is supported by the 3D API.
+ */
+ kHWAntialias_StateBit = 0x02,
+ /**
+ * Draws will respect the clip, otherwise the clip is ignored.
+ */
+ kClip_StateBit = 0x04,
+ /**
+ * Disables writing to the color buffer. Useful when performing stencil
+ * operations.
+ */
+ kNoColorWrites_StateBit = 0x08,
+ /**
+ * Modifies the behavior of edge AA specified by setEdgeAA. If set,
+ * will test edge pairs for convexity when rasterizing. Set this if the
+ * source polygon is non-convex.
+ */
+ kEdgeAAConcave_StateBit = 0x10,
- // This field must be last; it will not be copied or compared
- // if the corresponding fTexture[] is NULL.
- GrSamplerState fSamplerStates[kNumStages];
+ // Users of the class may add additional bits to the vector
+ kDummyStateBit,
+ kLastPublicStateBit = kDummyStateBit-1,
+ };
+
+ void resetStateFlags() {
+ fFlagBits = 0;
+ }
+
+ /**
+ * Enable render state settings.
+ *
+ * @param flags bitfield of StateBits specifing the states to enable
+ */
+ void enableState(uint32_t stateBits) {
+ fFlagBits |= stateBits;
+ }
+
+ /**
+ * Disable render state settings.
+ *
+ * @param flags bitfield of StateBits specifing the states to disable
+ */
+ void disableState(uint32_t stateBits) {
+ fFlagBits &= ~(stateBits);
+ }
+
+ bool isDitherState() const {
+ return 0 != (fFlagBits & kDither_StateBit);
+ }
+
+ bool isHWAntialiasState() const {
+ return 0 != (fFlagBits & kHWAntialias_StateBit);
+ }
+
+ bool isClipState() const {
+ return 0 != (fFlagBits & kClip_StateBit);
+ }
+
+ bool isColorWriteDisabled() const {
+ return 0 != (fFlagBits & kNoColorWrites_StateBit);
+ }
+
+ bool isConcaveEdgeAAState() const {
+ return 0 != (fFlagBits & kEdgeAAConcave_StateBit);
+ }
+
+ bool isStateFlagEnabled(uint32_t stateBit) const {
+ return 0 != (stateBit & fFlagBits);
+ }
+
+ void copyStateFlags(const GrDrawState& ds) {
+ fFlagBits = ds.fFlagBits;
+ }
+
+ /// @}
+
+ ///////////////////////////////////////////////////////////////////////////
+ /// @name Face Culling
+ ////
+
+ enum DrawFace {
+ kBoth_DrawFace,
+ kCCW_DrawFace,
+ kCW_DrawFace,
+ };
+
+ /**
+ * Controls whether clockwise, counterclockwise, or both faces are drawn.
+ * @param face the face(s) to draw.
+ */
+ void setDrawFace(DrawFace face) {
+ fDrawFace = face;
+ }
+
+ /**
+ * Gets whether the target is drawing clockwise, counterclockwise,
+ * or both faces.
+ * @return the current draw face(s).
+ */
+ DrawFace getDrawFace() const {
+ return fDrawFace;
+ }
+
+ /// @}
+
+ ///////////////////////////////////////////////////////////////////////////
// Most stages are usually not used, so conditionals here
// reduce the expected number of bytes touched by 50%.
@@ -172,6 +699,33 @@
}
private:
+ static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1);
+ uint8_t fFlagBits;
+ GrBlendCoeff fSrcBlend : 8;
+ GrBlendCoeff fDstBlend : 8;
+ DrawFace fDrawFace : 8;
+ uint8_t fFirstCoverageStage;
+ SkXfermode::Mode fColorFilterMode : 8;
+ GrColor fBlendConstant;
+ GrTexture* fTextures[kNumStages];
+ GrRenderTarget* fRenderTarget;
+ GrColor fColor;
+ GrColor fColorFilterColor;
+ GrStencilSettings fStencilSettings;
+ GrMatrix fViewMatrix;
+ // @{ Data for GrTesselatedPathRenderer
+ // TODO: currently ignored in copying & comparison for performance.
+ // Must be considered if GrTesselatedPathRenderer is being used.
+
+ VertexEdgeType fVertexEdgeType;
+ int fEdgeAANumEdges;
+ Edge fEdgeAAEdges[kMaxEdges];
+
+ // @}
+ // This field must be last; it will not be copied or compared
+ // if the corresponding fTexture[] is NULL.
+ GrSamplerState fSamplerStates[kNumStages];
+
size_t leadingBytes() const {
// Can't use offsetof() with non-POD types, so stuck with pointer math.
// TODO: ignores GrTesselatedPathRenderer data structures. We don't
@@ -184,4 +738,3 @@
};
#endif
-
diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp
index 7a84262..aa5cf20 100644
--- a/src/gpu/GrDrawTarget.cpp
+++ b/src/gpu/GrDrawTarget.cpp
@@ -10,9 +10,10 @@
#include "GrDrawTarget.h"
#include "GrGpuVertex.h"
+#include "GrIndexBuffer.h"
+#include "GrRenderTarget.h"
#include "GrTexture.h"
#include "GrVertexBuffer.h"
-#include "GrIndexBuffer.h"
namespace {
@@ -455,119 +456,6 @@
return fClip;
}
-void GrDrawTarget::setTexture(int stage, GrTexture* tex) {
- GrAssert(stage >= 0 && stage < GrDrawState::kNumStages);
- fCurrDrawState.fTextures[stage] = tex;
-}
-
-const GrTexture* GrDrawTarget::getTexture(int stage) const {
- GrAssert(stage >= 0 && stage < GrDrawState::kNumStages);
- return fCurrDrawState.fTextures[stage];
-}
-
-GrTexture* GrDrawTarget::getTexture(int stage) {
- GrAssert(stage >= 0 && stage < GrDrawState::kNumStages);
- return fCurrDrawState.fTextures[stage];
-}
-
-void GrDrawTarget::setRenderTarget(GrRenderTarget* target) {
- fCurrDrawState.fRenderTarget = target;
-}
-
-const GrRenderTarget* GrDrawTarget::getRenderTarget() const {
- return fCurrDrawState.fRenderTarget;
-}
-
-GrRenderTarget* GrDrawTarget::getRenderTarget() {
- return fCurrDrawState.fRenderTarget;
-}
-
-void GrDrawTarget::setViewMatrix(const GrMatrix& m) {
- fCurrDrawState.fViewMatrix = m;
-}
-
-void GrDrawTarget::preConcatViewMatrix(const GrMatrix& matrix) {
- fCurrDrawState.fViewMatrix.preConcat(matrix);
-}
-
-void GrDrawTarget::postConcatViewMatrix(const GrMatrix& matrix) {
- fCurrDrawState.fViewMatrix.postConcat(matrix);
-}
-
-const GrMatrix& GrDrawTarget::getViewMatrix() const {
- return fCurrDrawState.fViewMatrix;
-}
-
-bool GrDrawTarget::getViewInverse(GrMatrix* matrix) const {
- // Mike: Can we cache this somewhere?
- // Brian: Sure, do we use it often?
-
- GrMatrix inverse;
- if (fCurrDrawState.fViewMatrix.invert(&inverse)) {
- if (matrix) {
- *matrix = inverse;
- }
- return true;
- }
- return false;
-}
-
-void GrDrawTarget::setSamplerState(int stage, const GrSamplerState& state) {
- GrAssert(stage >= 0 && stage < GrDrawState::kNumStages);
- fCurrDrawState.fSamplerStates[stage] = state;
-}
-
-void GrDrawTarget::enableState(uint32_t bits) {
- fCurrDrawState.fFlagBits |= bits;
-}
-
-void GrDrawTarget::disableState(uint32_t bits) {
- fCurrDrawState.fFlagBits &= ~(bits);
-}
-
-void GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoeff,
- GrBlendCoeff dstCoeff) {
- fCurrDrawState.fSrcBlend = srcCoeff;
- fCurrDrawState.fDstBlend = dstCoeff;
-#if GR_DEBUG
- switch (dstCoeff) {
- case kDC_BlendCoeff:
- case kIDC_BlendCoeff:
- case kDA_BlendCoeff:
- case kIDA_BlendCoeff:
- GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
- "coverage stages.\n");
- break;
- default:
- break;
- }
- switch (srcCoeff) {
- case kSC_BlendCoeff:
- case kISC_BlendCoeff:
- case kSA_BlendCoeff:
- case kISA_BlendCoeff:
- GrPrintf("Unexpected src blend coeff. Won't work correctly with"
- "coverage stages.\n");
- break;
- default:
- break;
- }
-#endif
-}
-
-void GrDrawTarget::setColor(GrColor c) {
- fCurrDrawState.fColor = c;
-}
-
-void GrDrawTarget::setColorFilter(GrColor c, SkXfermode::Mode mode) {
- fCurrDrawState.fColorFilterColor = c;
- fCurrDrawState.fColorFilterXfermode = mode;
-}
-
-void GrDrawTarget::setAlpha(uint8_t a) {
- this->setColor((a << 24) | (a << 16) | (a << 8) | a);
-}
-
void GrDrawTarget::saveCurrentDrawState(SavedDrawState* state) const {
state->fState = fCurrDrawState;
}
@@ -800,12 +688,13 @@
}
}
#endif
- if (NULL == this->getRenderTarget()) {
+ const GrDrawState& drawState = this->getDrawState();
+ if (NULL == drawState.getRenderTarget()) {
return false;
}
- if (GrPixelConfigIsUnpremultiplied(this->getRenderTarget()->config())) {
- if (kOne_BlendCoeff != fCurrDrawState.fSrcBlend ||
- kZero_BlendCoeff != fCurrDrawState.fDstBlend) {
+ if (GrPixelConfigIsUnpremultiplied(drawState.getRenderTarget()->config())) {
+ if (kOne_BlendCoeff != drawState.getSrcBlendCoeff() ||
+ kZero_BlendCoeff != drawState.getDstBlendCoeff()) {
return false;
}
}
@@ -817,8 +706,9 @@
// a custom bilerp in the shader. Until Skia itself supports unpremul
// configs there is no pressure to implement this.
if (this->isStageEnabled(s) &&
- GrPixelConfigIsUnpremultiplied(fCurrDrawState.fTextures[s]->config()) &&
- GrSamplerState::kNearest_Filter != fCurrDrawState.fSamplerStates[s].getFilter()) {
+ GrPixelConfigIsUnpremultiplied(drawState.getTexture(s)->config()) &&
+ GrSamplerState::kNearest_Filter !=
+ drawState.getSampler(s).getFilter()) {
return false;
}
}
@@ -861,31 +751,33 @@
* for Cd we find that only 1, ISA, and ISC produce the correct depth
* coeffecient in terms of S' and D.
*/
- return kOne_BlendCoeff == fCurrDrawState.fDstBlend||
- kISA_BlendCoeff == fCurrDrawState.fDstBlend ||
- kISC_BlendCoeff == fCurrDrawState.fDstBlend;
+ GrBlendCoeff dstCoeff = this->getDrawState().getDstBlendCoeff();
+ return kOne_BlendCoeff == dstCoeff ||
+ kISA_BlendCoeff == dstCoeff ||
+ kISC_BlendCoeff == dstCoeff;
}
bool GrDrawTarget::srcAlphaWillBeOne() const {
const GrVertexLayout& layout = this->getGeomSrc().fVertexLayout;
+ const GrDrawState& drawState = this->getDrawState();
// Check if per-vertex or constant color may have partial alpha
if ((layout & kColor_VertexLayoutBit) ||
- 0xff != GrColorUnpackA(fCurrDrawState.fColor)) {
+ 0xff != GrColorUnpackA(drawState.getColor())) {
return false;
}
// Check if color filter could introduce an alpha
// (TODO: Consider being more aggressive with regards to detecting 0xff
// final alpha from color filter).
- if (SkXfermode::kDst_Mode != fCurrDrawState.fColorFilterXfermode) {
+ if (SkXfermode::kDst_Mode != drawState.getColorFilterMode()) {
return false;
}
// Check if a color stage could create a partial alpha
- for (int s = 0; s < fCurrDrawState.fFirstCoverageStage; ++s) {
+ for (int s = 0; s < drawState.getFirstCoverageStage(); ++s) {
if (StageWillBeUsed(s, layout, fCurrDrawState)) {
- GrAssert(NULL != fCurrDrawState.fTextures[s]);
- GrPixelConfig config = fCurrDrawState.fTextures[s]->config();
+ GrAssert(NULL != drawState.getTexture(s));
+ GrPixelConfig config = drawState.getTexture(s)->config();
if (!GrPixelConfigIsOpaque(config)) {
return false;
}
@@ -900,17 +792,18 @@
GrBlendCoeff* dstCoeff) const {
const GrVertexLayout& layout = this->getGeomSrc().fVertexLayout;
+ const GrDrawState& drawState = this->getDrawState();
GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
if (NULL == srcCoeff) {
srcCoeff = &bogusSrcCoeff;
}
- *srcCoeff = fCurrDrawState.fSrcBlend;
+ *srcCoeff = drawState.getSrcBlendCoeff();
if (NULL == dstCoeff) {
dstCoeff = &bogusDstCoeff;
}
- *dstCoeff = fCurrDrawState.fDstBlend;
+ *dstCoeff = drawState.getDstBlendCoeff();
// We don't ever expect source coeffecients to reference the source
GrAssert(kSA_BlendCoeff != *srcCoeff &&
@@ -923,7 +816,7 @@
kDC_BlendCoeff != *dstCoeff &&
kIDC_BlendCoeff != *dstCoeff);
- if (SkToBool(kNoColorWrites_StateBit & fCurrDrawState.fFlagBits)) {
+ if (drawState.isColorWriteDisabled()) {
*srcCoeff = kZero_BlendCoeff;
*dstCoeff = kOne_BlendCoeff;
}
@@ -939,7 +832,7 @@
// stenciling is enabled. Having color writes disabled is effectively
// (0,1).
if ((kZero_BlendCoeff == *srcCoeff && dstCoeffIsOne)) {
- if (fCurrDrawState.fStencilSettings.doesWrite()) {
+ if (drawState.getStencil().doesWrite()) {
if (fCaps.fShaderSupport) {
return kDisableBlend_BlendOptFlag |
kEmitTransBlack_BlendOptFlag;
@@ -953,10 +846,10 @@
// check for coverage due to edge aa or coverage texture stage
bool hasCoverage = forceCoverage ||
- fCurrDrawState.fEdgeAANumEdges > 0 ||
+ drawState.getNumAAEdges() > 0 ||
(layout & kCoverage_VertexLayoutBit) ||
(layout & kEdge_VertexLayoutBit);
- for (int s = fCurrDrawState.fFirstCoverageStage;
+ for (int s = drawState.getFirstCoverageStage();
!hasCoverage && s < GrDrawState::kNumStages;
++s) {
if (StageWillBeUsed(s, layout, fCurrDrawState)) {
@@ -1023,7 +916,7 @@
// but not in a premul-alpha way. So we only use them when our alpha
// is 0xff and tweaking the color for partial coverage is OK
if (!fCaps.fHWAALineSupport ||
- !(kHWAntialias_StateBit & fCurrDrawState.fFlagBits)) {
+ !this->getDrawState().isHWAntialiasState()) {
return false;
}
BlendOptFlags opts = this->getBlendOpts();
@@ -1043,15 +936,6 @@
this->getBlendOpts());
}
-///////////////////////////////////////////////////////////////////////////////
-
-void GrDrawTarget::setEdgeAAData(const GrDrawState::Edge* edges, int numEdges) {
- GrAssert(numEdges <= GrDrawState::kMaxEdges);
- memcpy(fCurrDrawState.fEdgeAAEdges, edges,
- numEdges * sizeof(GrDrawState::Edge));
- fCurrDrawState.fEdgeAANumEdges = numEdges;
-}
-
////////////////////////////////////////////////////////////////////////////////
@@ -1174,32 +1058,34 @@
GrDrawTarget* target,
GrDrawState::StageMask stageMask) {
GrAssert(NULL != target);
+ GrDrawState* drawState = target->drawState();
fDrawTarget = target;
- fViewMatrix = target->getViewMatrix();
+ fViewMatrix = drawState->getViewMatrix();
fStageMask = stageMask;
if (fStageMask) {
GrMatrix invVM;
if (fViewMatrix.invert(&invVM)) {
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
if (fStageMask & (1 << s)) {
- fSamplerMatrices[s] = target->getSamplerMatrix(s);
+ fSamplerMatrices[s] = drawState->getSampler(s).getMatrix();
}
}
- target->preConcatSamplerMatrices(fStageMask, invVM);
+ drawState->preConcatSamplerMatrices(fStageMask, invVM);
} else {
// sad trombone sound
fStageMask = 0;
}
}
- target->setViewMatrix(GrMatrix::I());
+ drawState->setViewMatrix(GrMatrix::I());
}
GrDrawTarget::AutoDeviceCoordDraw::~AutoDeviceCoordDraw() {
- fDrawTarget->setViewMatrix(fViewMatrix);
+ GrDrawState* drawState = fDrawTarget->drawState();
+ drawState->setViewMatrix(fViewMatrix);
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
if (fStageMask & (1 << s)) {
- fDrawTarget->setSamplerMatrix(s, fSamplerMatrices[s]);
+ drawState->sampler(s)->setMatrix(fSamplerMatrices[s]);
}
}
}
diff --git a/src/gpu/GrDrawTarget.h b/src/gpu/GrDrawTarget.h
index 4bd9eee..262f72c 100644
--- a/src/gpu/GrDrawTarget.h
+++ b/src/gpu/GrDrawTarget.h
@@ -16,7 +16,6 @@
#include "GrDrawState.h"
#include "GrMatrix.h"
#include "GrRefCnt.h"
-#include "GrRenderTarget.h"
#include "GrSamplerState.h"
#include "GrStencil.h"
#include "GrTexture.h"
@@ -57,62 +56,9 @@
int fMaxTextureSize;
};
+ // for convenience
typedef GrDrawState::StageMask StageMask;
- /**
- * Flags that affect rendering. Controlled using enable/disableState(). All
- * default to disabled.
- */
- enum StateBits {
- /**
- * Perform dithering. TODO: Re-evaluate whether we need this bit
- */
- kDither_StateBit = 0x01,
- /**
- * Perform HW anti-aliasing. This means either HW FSAA, if supported
- * by the render target, or smooth-line rendering if a line primitive
- * is drawn and line smoothing is supported by the 3D API.
- */
- kHWAntialias_StateBit = 0x02,
- /**
- * Draws will respect the clip, otherwise the clip is ignored.
- */
- kClip_StateBit = 0x04,
- /**
- * Disables writing to the color buffer. Useful when performing stencil
- * operations.
- */
- kNoColorWrites_StateBit = 0x08,
- /**
- * Modifies the behavior of edge AA specified by setEdgeAA. If set,
- * will test edge pairs for convexity when rasterizing. Set this if the
- * source polygon is non-convex.
- */
- kEdgeAAConcave_StateBit = 0x10,
- // subclass may use additional bits internally
- kDummyStateBit,
- kLastPublicStateBit = kDummyStateBit-1
- };
-
- /**
- * Sets the stencil settings to use for the next draw.
- * Changing the clip has the side-effect of possibly zeroing
- * out the client settable stencil bits. So multipass algorithms
- * using stencil should not change the clip between passes.
- * @param settings the stencil settings to use.
- */
- void setStencil(const GrStencilSettings& settings) {
- fCurrDrawState.fStencilSettings = settings;
- }
-
- /**
- * Shortcut to disable stencil testing and ops.
- */
- void disableStencil() {
- fCurrDrawState.fStencilSettings.setDisabled();
- }
-
-public:
///////////////////////////////////////////////////////////////////////////
GrDrawTarget();
@@ -140,286 +86,25 @@
*/
const GrClip& getClip() const;
- /**
- * Sets the texture used at the next drawing call
- *
- * @param stage The texture stage for which the texture will be set
- *
- * @param texture The texture to set. Can be NULL though there is no advantage
- * to settings a NULL texture if doing non-textured drawing
- */
- void setTexture(int stage, GrTexture* texture);
+ const GrDrawState& getDrawState() const { return fCurrDrawState; }
+ GrDrawState* drawState() { return &fCurrDrawState; }
- /**
- * Retrieves the currently set texture.
- *
- * @return The currently set texture. The return value will be NULL if no
- * texture has been set, NULL was most recently passed to
- * setTexture, or the last setTexture was destroyed.
- */
- const GrTexture* getTexture(int stage) const;
- GrTexture* getTexture(int stage);
-
- /**
- * Sets the rendertarget used at the next drawing call
- *
- * @param target The render target to set.
- */
- void setRenderTarget(GrRenderTarget* target);
-
- /**
- * Retrieves the currently set rendertarget.
- *
- * @return The currently set render target.
- */
- const GrRenderTarget* getRenderTarget() const;
- GrRenderTarget* getRenderTarget();
-
- /**
- * Sets the sampler state for a stage used in subsequent draws.
- *
- * The sampler state determines how texture coordinates are
- * intepretted and used to sample the texture.
- *
- * @param stage the stage of the sampler to set
- * @param samplerState Specifies the sampler state.
- */
- void setSamplerState(int stage, const GrSamplerState& samplerState);
-
- /**
- * Concats the matrix of a stage's sampler.
- *
- * @param stage the stage of the sampler to set
- * @param matrix the matrix to concat
- */
- void preConcatSamplerMatrix(int stage, const GrMatrix& matrix) {
- GrAssert(stage >= 0 && stage < GrDrawState::kNumStages);
- fCurrDrawState.fSamplerStates[stage].preConcatMatrix(matrix);
+ void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
+ this->drawState()->setBlendFunc(srcCoeff, dstCoeff);
}
/**
- * Shortcut for preConcatSamplerMatrix on all stages in mask with same
- * matrix
- */
- void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) {
- for (int i = 0; i < GrDrawState::kNumStages; ++i) {
- if ((1 << i) & stageMask) {
- this->preConcatSamplerMatrix(i, matrix);
- }
- }
- }
-
- /**
- * Shortcut for preConcatSamplerMatrix on all enabled stages in mask with
- * same matrix
+ * Shortcut for drawState()->preConcatSamplerMatrices() on all enabled
+ * stages
*
- * @param stage the stage of the sampler to set
* @param matrix the matrix to concat
*/
void preConcatEnabledSamplerMatrices(const GrMatrix& matrix) {
StageMask stageMask = this->enabledStages();
- this->preConcatSamplerMatrices(stageMask, matrix);
+ this->drawState()->preConcatSamplerMatrices(stageMask, matrix);
}
/**
- * Gets the matrix of a stage's sampler
- *
- * @param stage the stage to of sampler to get
- * @return the sampler state's matrix
- */
- const GrMatrix& getSamplerMatrix(int stage) const {
- return fCurrDrawState.fSamplerStates[stage].getMatrix();
- }
-
- /**
- * Sets the matrix of a stage's sampler
- *
- * @param stage the stage of sampler set
- * @param matrix the matrix to set
- */
- void setSamplerMatrix(int stage, const GrMatrix& matrix) {
- fCurrDrawState.fSamplerStates[stage].setMatrix(matrix);
- }
-
- /**
- * Sets the matrix applied to veretx positions.
- *
- * In the post-view-matrix space the rectangle [0,w]x[0,h]
- * fully covers the render target. (w and h are the width and height of the
- * the rendertarget.)
- *
- * @param m the matrix used to transform the vertex positions.
- */
- void setViewMatrix(const GrMatrix& m);
-
- /**
- * Multiplies the current view matrix by a matrix
- *
- * After this call V' = V*m where V is the old view matrix,
- * m is the parameter to this function, and V' is the new view matrix.
- * (We consider positions to be column vectors so position vector p is
- * transformed by matrix X as p' = X*p.)
- *
- * @param m the matrix used to modify the view matrix.
- */
- void preConcatViewMatrix(const GrMatrix& m);
-
- /**
- * Multiplies the current view matrix by a matrix
- *
- * After this call V' = m*V where V is the old view matrix,
- * m is the parameter to this function, and V' is the new view matrix.
- * (We consider positions to be column vectors so position vector p is
- * transformed by matrix X as p' = X*p.)
- *
- * @param m the matrix used to modify the view matrix.
- */
- void postConcatViewMatrix(const GrMatrix& m);
-
- /**
- * Retrieves the current view matrix
- * @return the current view matrix.
- */
- const GrMatrix& getViewMatrix() const;
-
- /**
- * Retrieves the inverse of the current view matrix.
- *
- * If the current view matrix is invertible, return true, and if matrix
- * is non-null, copy the inverse into it. If the current view matrix is
- * non-invertible, return false and ignore the matrix parameter.
- *
- * @param matrix if not null, will receive a copy of the current inverse.
- */
- bool getViewInverse(GrMatrix* matrix) const;
-
- /**
- * Sets color for next draw to a premultiplied-alpha color.
- *
- * @param the color to set.
- */
- void setColor(GrColor);
-
- /**
- * Gets the currently set color.
- * @return the current color.
- */
- GrColor getColor() const { return fCurrDrawState.fColor; }
-
- /**
- * Add a color filter that can be represented by a color and a mode.
- */
- void setColorFilter(GrColor, SkXfermode::Mode);
-
- /**
- * Sets the color to be used for the next draw to be
- * (r,g,b,a) = (alpha, alpha, alpha, alpha).
- *
- * @param alpha The alpha value to set as the color.
- */
- void setAlpha(uint8_t alpha);
-
- /**
- * Controls whether clockwise, counterclockwise, or both faces are drawn.
- * @param face the face(s) to draw.
- */
- void setDrawFace(GrDrawState::DrawFace face) {
- fCurrDrawState.fDrawFace = face;
- }
-
- /**
- * A common pattern is to compute a color with the initial stages and then
- * modulate that color by a coverage value in later stage(s) (AA, mask-
- * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
- * computed based on the pre-coverage-modulated color. The division of
- * stages between color-computing and coverage-computing is specified by
- * this method. Initially this is GrDrawState::kNumStages (all stages
- * are color-computing).
- */
- void setFirstCoverageStage(int firstCoverageStage) {
- fCurrDrawState.fFirstCoverageStage = firstCoverageStage;
- }
-
- /**
- * Gets the index of the first coverage-computing stage.
- */
- int getFirstCoverageStage() const {
- return fCurrDrawState.fFirstCoverageStage;
- }
-
- /**
- * Gets whether the target is drawing clockwise, counterclockwise,
- * or both faces.
- * @return the current draw face(s).
- */
- GrDrawState::DrawFace getDrawFace() const {
- return fCurrDrawState.fDrawFace;
- }
-
- /**
- * Enable render state settings.
- *
- * @param flags bitfield of StateBits specifing the states to enable
- */
- void enableState(uint32_t stateBits);
-
- /**
- * Disable render state settings.
- *
- * @param flags bitfield of StateBits specifing the states to disable
- */
- void disableState(uint32_t stateBits);
-
- bool isDitherState() const {
- return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
- }
-
- bool isHWAntialiasState() const {
- return 0 != (fCurrDrawState.fFlagBits & kHWAntialias_StateBit);
- }
-
- bool isClipState() const {
- return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
- }
-
- bool isColorWriteDisabled() const {
- return 0 != (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit);
- }
-
- /**
- * Sets the blending function coeffecients.
- *
- * The blend function will be:
- * D' = sat(S*srcCoef + D*dstCoef)
- *
- * where D is the existing destination color, S is the incoming source
- * color, and D' is the new destination color that will be written. sat()
- * is the saturation function.
- *
- * @param srcCoef coeffecient applied to the src color.
- * @param dstCoef coeffecient applied to the dst color.
- */
- void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff);
-
- /**
- * Sets the blending function constant referenced by the following blending
- * coeffecients:
- * kConstC_BlendCoeff
- * kIConstC_BlendCoeff
- * kConstA_BlendCoeff
- * kIConstA_BlendCoeff
- *
- * @param constant the constant to set
- */
- void setBlendConstant(GrColor constant) { fCurrDrawState.fBlendConstant = constant; }
-
- /**
- * Retrieves the last value set by setBlendConstant()
- * @return the blending constant value
- */
- GrColor getBlendConstant() const { return fCurrDrawState.fBlendConstant; }
-
- /**
* Determines if blending will require a read of a dst given the current
* state set on the draw target
*
@@ -448,15 +133,6 @@
*/
bool canTweakAlphaForCoverage() const;
- /**
- * Determines the interpretation per-vertex edge data when the
- * kEdge_VertexLayoutBit is set (see below). When per-vertex edges are not
- * specified the value of this setting has no effect.
- */
- void setVertexEdgeType(GrDrawState::VertexEdgeType type) {
- fCurrDrawState.fVertexEdgeType = type;
- }
-
/**
* Given the current draw state, vertex layout, and hw support, will HW AA
* lines be used (if line primitive type is drawn)? (Note that lines are
@@ -465,14 +141,6 @@
bool willUseHWAALines() const;
/**
- * Sets the edge data required for edge antialiasing.
- *
- * @param edges 3 * 6 float values, representing the edge
- * equations in Ax + By + C form
- */
- void setEdgeAAData(const GrDrawState::Edge* edges, int numEdges);
-
- /**
* Used to save and restore the GrGpu's drawing state
*/
struct SavedDrawState {
@@ -888,39 +556,6 @@
////////////////////////////////////////////////////////////////////////////
- class AutoViewMatrixRestore : ::GrNoncopyable {
- public:
- AutoViewMatrixRestore() {
- fDrawTarget = NULL;
- }
-
- AutoViewMatrixRestore(GrDrawTarget* target)
- : fDrawTarget(target), fMatrix(fDrawTarget->getViewMatrix()) {
- GrAssert(NULL != target);
- }
-
- void set(GrDrawTarget* target) {
- GrAssert(NULL != target);
- if (NULL != fDrawTarget) {
- fDrawTarget->setViewMatrix(fMatrix);
- }
- fDrawTarget = target;
- fMatrix = target->getViewMatrix();
- }
-
- ~AutoViewMatrixRestore() {
- if (NULL != fDrawTarget) {
- fDrawTarget->setViewMatrix(fMatrix);
- }
- }
-
- private:
- GrDrawTarget* fDrawTarget;
- GrMatrix fMatrix;
- };
-
- ////////////////////////////////////////////////////////////////////////////
-
/**
* Sets the view matrix to I and preconcats all stage matrices enabled in
* mask by the view inverse. Destructor undoes these changes.
@@ -1279,7 +914,8 @@
// given a vertex layout and a draw state, will a stage be used?
static bool StageWillBeUsed(int stage, GrVertexLayout layout,
const GrDrawState& state) {
- return NULL != state.fTextures[stage] && VertexUsesStage(stage, layout);
+ return NULL != state.getTexture(stage) &&
+ VertexUsesStage(stage, layout);
}
bool isStageEnabled(int stage) const {
diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp
index 1583630..eb96c57 100644
--- a/src/gpu/GrGpu.cpp
+++ b/src/gpu/GrGpu.cpp
@@ -185,10 +185,8 @@
// We used to clear down in the GL subclass using a special purpose
// FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
// FBO status.
- GrRenderTarget* oldRT = fCurrDrawState.fRenderTarget;
- fCurrDrawState.fRenderTarget = rt;
+ GrDrawState::AutoRenderTargetRestore artr(this->drawState(), rt);
this->clearStencil();
- fCurrDrawState.fRenderTarget = oldRT;
return true;
} else {
return false;
@@ -230,7 +228,7 @@
}
void GrGpu::clear(const GrIRect* rect, GrColor color) {
- if (NULL == this->getRenderTarget()) {
+ if (NULL == this->getDrawState().getRenderTarget()) {
return;
}
this->handleDirtyContext();
@@ -530,16 +528,18 @@
const GrIRect* r = NULL;
GrIRect clipRect;
- // GrDrawTarget should have filtered this for us
- GrAssert(NULL != fCurrDrawState.fRenderTarget);
+ GrDrawState* drawState = this->drawState();
+ const GrRenderTarget* rt = drawState->getRenderTarget();
- if (fCurrDrawState.fFlagBits & kClip_StateBit) {
- GrRenderTarget& rt = *fCurrDrawState.fRenderTarget;
+ // GrDrawTarget should have filtered this for us
+ GrAssert(NULL != rt);
+
+ if (drawState->isClipState()) {
GrRect bounds;
GrRect rtRect;
rtRect.setLTRB(0, 0,
- GrIntToScalar(rt.width()), GrIntToScalar(rt.height()));
+ GrIntToScalar(rt->width()), GrIntToScalar(rt->height()));
if (fClip.hasConservativeBounds()) {
bounds = fClip.getConservativeBounds();
if (!bounds.intersect(rtRect)) {
@@ -560,15 +560,15 @@
!bounds.isEmpty();
// TODO: dynamically attach a SB when needed.
- GrStencilBuffer* stencilBuffer = rt.getStencilBuffer();
+ GrStencilBuffer* stencilBuffer = rt->getStencilBuffer();
if (fClipInStencil && NULL == stencilBuffer) {
return false;
}
if (fClipInStencil &&
- stencilBuffer->mustRenderClip(fClip, rt.width(), rt.height())) {
+ stencilBuffer->mustRenderClip(fClip, rt->width(), rt->height())) {
- stencilBuffer->setLastClip(fClip, rt.width(), rt.height());
+ stencilBuffer->setLastClip(fClip, rt->width(), rt->height());
// we set the current clip to the bounds so that our recursive
// draws are scissored to them. We use the copy of the complex clip
@@ -580,12 +580,12 @@
AutoStateRestore asr(this);
AutoGeometryPush agp(this);
- this->setViewMatrix(GrMatrix::I());
+ drawState->setViewMatrix(GrMatrix::I());
this->flushScissor(NULL);
#if !VISUALIZE_COMPLEX_CLIP
- this->enableState(kNoColorWrites_StateBit);
+ drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
#else
- this->disableState(kNoColorWrites_StateBit);
+ drawState->disableState(GrDrawState::kNoColorWrites_StateBit);
#endif
int count = clip.getElementCount();
int clipBit = stencilBuffer->bits();
@@ -606,7 +606,7 @@
GrPathFill fill;
bool fillInverted;
// enabled at bottom of loop
- this->disableState(kModifyStencilClip_StateBit);
+ drawState->disableState(kModifyStencilClip_StateBit);
bool canRenderDirectToStencil; // can the clip element be drawn
// directly to the stencil buffer
@@ -664,11 +664,11 @@
};
SET_RANDOM_COLOR
if (kRect_ClipType == clip.getElementType(c)) {
- this->setStencil(gDrawToStencil);
+ *drawState->stencil() = gDrawToStencil;
this->drawSimpleRect(clip.getRect(c), NULL, 0);
} else {
if (canRenderDirectToStencil) {
- this->setStencil(gDrawToStencil);
+ *drawState->stencil() = gDrawToStencil;
pr->drawPath(0);
} else {
pr->drawPathToStencil();
@@ -678,9 +678,9 @@
// now we modify the clip bit by rendering either the clip
// element directly or a bounding rect of the entire clip.
- this->enableState(kModifyStencilClip_StateBit);
+ drawState->enableState(kModifyStencilClip_StateBit);
for (int p = 0; p < passes; ++p) {
- this->setStencil(stencilSettings[p]);
+ *drawState->stencil() = stencilSettings[p];
if (canDrawDirectToClip) {
if (kRect_ClipType == clip.getElementType(c)) {
SET_RANDOM_COLOR
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index 11bf153..11f5083 100644
--- a/src/gpu/GrGpu.h
+++ b/src/gpu/GrGpu.h
@@ -327,8 +327,8 @@
}
protected:
- enum PrivateStateBits {
- kFirstBit = (kLastPublicStateBit << 1),
+ enum PrivateDrawStateStateBits {
+ kFirstBit = (GrDrawState::kLastPublicStateBit << 1),
kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
// stencil bits used for
diff --git a/src/gpu/GrGpuGL.cpp b/src/gpu/GrGpuGL.cpp
index 9f7e4ec..2a8634f 100644
--- a/src/gpu/GrGpuGL.cpp
+++ b/src/gpu/GrGpuGL.cpp
@@ -480,7 +480,7 @@
GL_CALL(Disable(GR_GL_CULL_FACE));
GL_CALL(FrontFace(GR_GL_CCW));
- fHWDrawState.fDrawFace = GrDrawState::kBoth_DrawFace;
+ fHWDrawState.setDrawFace(GrDrawState::kBoth_DrawFace);
GL_CALL(Disable(GR_GL_DITHER));
if (kDesktop_GrGLBinding == this->glBinding()) {
@@ -492,7 +492,7 @@
}
GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
- fHWDrawState.fFlagBits = 0;
+ fHWDrawState.resetStateFlags();
// we only ever use lines in hairline mode
GL_CALL(LineWidth(1));
@@ -501,24 +501,22 @@
fActiveTextureUnitIdx = -1;
// illegal values
- //fHWDrawState.fSrcBlend = (GrBlendCoeff)(uint8_t)-1;
- fHWDrawState.fSrcBlend = (GrBlendCoeff)0xFF;
- fHWDrawState.fDstBlend = (GrBlendCoeff)(uint8_t)-1;
+ fHWDrawState.setBlendFunc((GrBlendCoeff)0xFF, (GrBlendCoeff)0xFF);
- fHWDrawState.fBlendConstant = 0x00000000;
+ fHWDrawState.setBlendConstant(0x00000000);
GL_CALL(BlendColor(0,0,0,0));
- fHWDrawState.fColor = GrColor_ILLEGAL;
+ fHWDrawState.setColor(GrColor_ILLEGAL);
- fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix();
+ fHWDrawState.setViewMatrix(GrMatrix::InvalidMatrix());
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- fHWDrawState.fTextures[s] = NULL;
- fHWDrawState.fSamplerStates[s].setRadial2Params(-GR_ScalarMax,
- -GR_ScalarMax,
- true);
- fHWDrawState.fSamplerStates[s].setMatrix(GrMatrix::InvalidMatrix());
- fHWDrawState.fSamplerStates[s].setConvolutionParams(0, NULL, NULL);
+ fHWDrawState.setTexture(s, NULL);
+ fHWDrawState.sampler(s)->setRadial2Params(-GR_ScalarMax,
+ -GR_ScalarMax,
+ true);
+ fHWDrawState.sampler(s)->setMatrix(GrMatrix::InvalidMatrix());
+ fHWDrawState.sampler(s)->setConvolutionParams(0, NULL, NULL);
}
fHWBounds.fScissorRect.invalidate();
@@ -526,7 +524,7 @@
GL_CALL(Disable(GR_GL_SCISSOR_TEST));
fHWBounds.fViewportRect.invalidate();
- fHWDrawState.fStencilSettings.invalidate();
+ fHWDrawState.stencil()->invalidate();
fHWStencilClip = false;
fClipInStencil = false;
@@ -536,7 +534,7 @@
fHWGeometryState.fArrayPtrsDirty = true;
GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
- fHWDrawState.fRenderTarget = NULL;
+ fHWDrawState.setRenderTarget(NULL);
// we assume these values
if (this->glCaps().fUnpackRowLengthSupport) {
@@ -1191,7 +1189,7 @@
GrGLStencilBuffer* glsb = (GrGLStencilBuffer*) sb;
GrGLuint rb = glsb->renderbufferID();
- fHWDrawState.fRenderTarget = NULL;
+ fHWDrawState.setRenderTarget(NULL);
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, fbo));
GL_CALL(FramebufferRenderbuffer(GR_GL_FRAMEBUFFER,
GR_GL_STENCIL_ATTACHMENT,
@@ -1276,9 +1274,12 @@
}
void GrGpuGL::flushScissor(const GrIRect* rect) {
- GrAssert(NULL != fCurrDrawState.fRenderTarget);
- const GrGLIRect& vp =
- ((GrGLRenderTarget*)fCurrDrawState.fRenderTarget)->getViewport();
+ const GrDrawState& drawState = this->getDrawState();
+ const GrGLRenderTarget* rt =
+ static_cast<const GrGLRenderTarget*>(drawState.getRenderTarget());
+
+ GrAssert(NULL != rt);
+ const GrGLIRect& vp = rt->getViewport();
GrGLIRect scissor;
if (NULL != rect) {
@@ -1307,15 +1308,16 @@
}
void GrGpuGL::onClear(const GrIRect* rect, GrColor color) {
+ const GrDrawState& drawState = this->getDrawState();
+ const GrRenderTarget* rt = drawState.getRenderTarget();
// parent class should never let us get here with no RT
- GrAssert(NULL != fCurrDrawState.fRenderTarget);
+ GrAssert(NULL != rt);
GrIRect clippedRect;
if (NULL != rect) {
// flushScissor expects rect to be clipped to the target.
clippedRect = *rect;
- GrIRect rtRect = SkIRect::MakeWH(fCurrDrawState.fRenderTarget->width(),
- fCurrDrawState.fRenderTarget->height());
+ GrIRect rtRect = SkIRect::MakeWH(rt->width(), rt->height());
if (clippedRect.intersect(rtRect)) {
rect = &clippedRect;
} else {
@@ -1329,7 +1331,7 @@
static const GrGLfloat scale255 = 1.f / 255.f;
a = GrColorUnpackA(color) * scale255;
GrGLfloat scaleRGB = scale255;
- if (GrPixelConfigIsUnpremultiplied(fCurrDrawState.fRenderTarget->config())) {
+ if (GrPixelConfigIsUnpremultiplied(rt->config())) {
scaleRGB *= a;
}
r = GrColorUnpackR(color) * scaleRGB;
@@ -1337,13 +1339,13 @@
b = GrColorUnpackB(color) * scaleRGB;
GL_CALL(ColorMask(GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE, GR_GL_TRUE));
- fHWDrawState.fFlagBits &= ~kNoColorWrites_StateBit;
+ fHWDrawState.disableState(GrDrawState::kNoColorWrites_StateBit);
GL_CALL(ClearColor(r, g, b, a));
GL_CALL(Clear(GR_GL_COLOR_BUFFER_BIT));
}
void GrGpuGL::clearStencil() {
- if (NULL == fCurrDrawState.fRenderTarget) {
+ if (NULL == this->getDrawState().getRenderTarget()) {
return;
}
@@ -1356,17 +1358,18 @@
GL_CALL(StencilMask(0xffffffff));
GL_CALL(ClearStencil(0));
GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
- fHWDrawState.fStencilSettings.invalidate();
+ fHWDrawState.stencil()->invalidate();
}
void GrGpuGL::clearStencilClip(const GrIRect& rect, bool insideClip) {
- GrAssert(NULL != fCurrDrawState.fRenderTarget);
+ const GrDrawState& drawState = this->getDrawState();
+ const GrRenderTarget* rt = drawState.getRenderTarget();
+ GrAssert(NULL != rt);
// this should only be called internally when we know we have a
// stencil buffer.
- GrAssert(NULL != fCurrDrawState.fRenderTarget->getStencilBuffer());
- GrGLint stencilBitCount =
- fCurrDrawState.fRenderTarget->getStencilBuffer()->bits();
+ GrAssert(NULL != rt->getStencilBuffer());
+ GrGLint stencilBitCount = rt->getStencilBuffer()->bits();
#if 0
GrAssert(stencilBitCount > 0);
GrGLint clipStencilMask = (1 << (stencilBitCount - 1));
@@ -1389,7 +1392,7 @@
GL_CALL(StencilMask(clipStencilMask));
GL_CALL(ClearStencil(value));
GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
- fHWDrawState.fStencilSettings.invalidate();
+ fHWDrawState.stencil()->invalidate();
}
void GrGpuGL::onForceRenderTargetFlush() {
@@ -1445,13 +1448,12 @@
// resolve the render target if necessary
GrGLRenderTarget* tgt = static_cast<GrGLRenderTarget*>(target);
- GrAutoTPtrValueRestore<GrRenderTarget*> autoTargetRestore;
+ GrDrawState::AutoRenderTargetRestore artr;
switch (tgt->getResolveType()) {
case GrGLRenderTarget::kCantResolve_ResolveType:
return false;
case GrGLRenderTarget::kAutoResolves_ResolveType:
- autoTargetRestore.save(&fCurrDrawState.fRenderTarget);
- fCurrDrawState.fRenderTarget = target;
+ artr.set(this->drawState(), target);
this->flushRenderTarget(&GrIRect::EmptyIRect());
break;
case GrGLRenderTarget::kCanResolve_ResolveType:
@@ -1549,10 +1551,11 @@
void GrGpuGL::flushRenderTarget(const GrIRect* bound) {
- GrAssert(NULL != fCurrDrawState.fRenderTarget);
+ GrGLRenderTarget* rt =
+ static_cast<GrGLRenderTarget*>(this->drawState()->getRenderTarget());
+ GrAssert(NULL != rt);
- GrGLRenderTarget* rt = (GrGLRenderTarget*)fCurrDrawState.fRenderTarget;
- if (fHWDrawState.fRenderTarget != fCurrDrawState.fRenderTarget) {
+ if (fHWDrawState.getRenderTarget() != rt) {
GL_CALL(BindFramebuffer(GR_GL_FRAMEBUFFER, rt->renderFBOID()));
#if GR_COLLECT_STATS
++fStats.fRenderTargetChngCnt;
@@ -1565,7 +1568,7 @@
}
#endif
fDirtyFlags.fRenderTargetChanged = true;
- fHWDrawState.fRenderTarget = fCurrDrawState.fRenderTarget;
+ fHWDrawState.setRenderTarget(rt);
const GrGLIRect& vp = rt->getViewport();
if (fHWBounds.fViewportRect != vp) {
vp.pushToGLViewport(this->glInterface());
@@ -1682,7 +1685,7 @@
#endif
// make sure we go through flushRenderTarget() since we've modified
// the bound DRAW FBO ID.
- fHWDrawState.fRenderTarget = NULL;
+ fHWDrawState.setRenderTarget(NULL);
const GrGLIRect& vp = rt->getViewport();
const GrIRect dirtyRect = rt->getResolveRect();
GrGLIRect r;
@@ -1754,21 +1757,25 @@
GR_STATIC_ASSERT(7 == kInvert_StencilOp);
void GrGpuGL::flushStencil() {
- const GrStencilSettings* settings = &fCurrDrawState.fStencilSettings;
+ const GrDrawState& drawState = this->getDrawState();
+
+ const GrStencilSettings* settings = &drawState.getStencil();
// use stencil for clipping if clipping is enabled and the clip
// has been written into the stencil.
- bool stencilClip = fClipInStencil &&
- (kClip_StateBit & fCurrDrawState.fFlagBits);
+ bool stencilClip = fClipInStencil && drawState.isClipState();
+ bool drawClipToStencil =
+ drawState.isStateFlagEnabled(kModifyStencilClip_StateBit);
bool stencilChange = fHWStencilClip != stencilClip ||
- fHWDrawState.fStencilSettings != *settings ||
- ((fHWDrawState.fFlagBits & kModifyStencilClip_StateBit) !=
- (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit));
+ fHWDrawState.getStencil() != *settings ||
+ (fHWDrawState.isStateFlagEnabled(kModifyStencilClip_StateBit) !=
+ drawClipToStencil);
if (stencilChange) {
- // we can't simultaneously perform stencil-clipping and modify the stencil clip
- GrAssert(!stencilClip || !(fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit));
+ // we can't simultaneously perform stencil-clipping and
+ // modify the stencil clip
+ GrAssert(!stencilClip || !drawClipToStencil);
if (settings->isDisabled()) {
if (stencilClip) {
@@ -1793,15 +1800,14 @@
}
#endif
int stencilBits = 0;
- GrStencilBuffer* stencilBuffer =
- fCurrDrawState.fRenderTarget->getStencilBuffer();
+ GrStencilBuffer* stencilBuffer =
+ drawState.getRenderTarget()->getStencilBuffer();
if (NULL != stencilBuffer) {
stencilBits = stencilBuffer->bits();
}
// TODO: dynamically attach a stencil buffer
GrAssert(stencilBits ||
- (GrStencilSettings::gDisabled ==
- fCurrDrawState.fStencilSettings));
+ (GrStencilSettings::gDisabled == *settings));
GrGLuint clipStencilMask = 0;
GrGLuint userStencilMask = ~0;
@@ -1815,8 +1821,7 @@
unsigned int frontWriteMask = settings->fFrontWriteMask;
GrGLenum frontFunc;
- if (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit) {
-
+ if (drawClipToStencil) {
GrAssert(settings->fFrontFunc < kBasicStencilFuncCount);
frontFunc = grToGLStencilFunc[settings->fFrontFunc];
} else {
@@ -1847,7 +1852,7 @@
unsigned int backWriteMask = settings->fBackWriteMask;
- if (fCurrDrawState.fFlagBits & kModifyStencilClip_StateBit) {
+ if (drawClipToStencil) {
GrAssert(settings->fBackFunc < kBasicStencilFuncCount);
backFunc = grToGLStencilFunc[settings->fBackFunc];
} else {
@@ -1885,12 +1890,13 @@
grToGLStencilOp[settings->fFrontPassOp]));
}
}
- fHWDrawState.fStencilSettings = fCurrDrawState.fStencilSettings;
+ *fHWDrawState.stencil() = *settings;
fHWStencilClip = stencilClip;
}
}
void GrGpuGL::flushAAState(GrPrimitiveType type) {
+ const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
if (kDesktop_GrGLBinding == this->glBinding()) {
// ES doesn't support toggling GL_MULTISAMPLE and doesn't have
// smooth lines.
@@ -1906,13 +1912,13 @@
GL_CALL(Disable(GR_GL_LINE_SMOOTH));
fHWAAState.fSmoothLineEnabled = false;
}
- if (fCurrDrawState.fRenderTarget->isMultisampled() &&
+ if (rt->isMultisampled() &&
fHWAAState.fMSAAEnabled) {
GL_CALL(Disable(GR_GL_MULTISAMPLE));
fHWAAState.fMSAAEnabled = false;
}
- } else if (fCurrDrawState.fRenderTarget->isMultisampled() &&
- SkToBool(kHWAntialias_StateBit & fCurrDrawState.fFlagBits) !=
+ } else if (rt->isMultisampled() &&
+ this->getDrawState().isHWAntialiasState() !=
fHWAAState.fMSAAEnabled) {
if (fHWAAState.fMSAAEnabled) {
GL_CALL(Disable(GR_GL_MULTISAMPLE));
@@ -1933,12 +1939,11 @@
GL_CALL(Enable(GR_GL_BLEND));
fHWBlendDisabled = false;
}
- if (kSA_BlendCoeff != fHWDrawState.fSrcBlend ||
- kISA_BlendCoeff != fHWDrawState.fDstBlend) {
+ if (kSA_BlendCoeff != fHWDrawState.getSrcBlendCoeff() ||
+ kISA_BlendCoeff != fHWDrawState.getDstBlendCoeff()) {
GL_CALL(BlendFunc(gXfermodeCoeff2Blend[kSA_BlendCoeff],
gXfermodeCoeff2Blend[kISA_BlendCoeff]));
- fHWDrawState.fSrcBlend = kSA_BlendCoeff;
- fHWDrawState.fDstBlend = kISA_BlendCoeff;
+ fHWDrawState.setBlendFunc(kSA_BlendCoeff, kISA_BlendCoeff);
}
} else {
// any optimization to disable blending should
@@ -1955,25 +1960,25 @@
fHWBlendDisabled = blendOff;
}
if (!blendOff) {
- if (fHWDrawState.fSrcBlend != srcCoeff ||
- fHWDrawState.fDstBlend != dstCoeff) {
+ if (fHWDrawState.getSrcBlendCoeff() != srcCoeff ||
+ fHWDrawState.getDstBlendCoeff() != dstCoeff) {
GL_CALL(BlendFunc(gXfermodeCoeff2Blend[srcCoeff],
gXfermodeCoeff2Blend[dstCoeff]));
- fHWDrawState.fSrcBlend = srcCoeff;
- fHWDrawState.fDstBlend = dstCoeff;
+ fHWDrawState.setBlendFunc(srcCoeff, dstCoeff);
}
+ GrColor blendConst = fCurrDrawState.getBlendConstant();
if ((BlendCoeffReferencesConstant(srcCoeff) ||
BlendCoeffReferencesConstant(dstCoeff)) &&
- fHWDrawState.fBlendConstant != fCurrDrawState.fBlendConstant) {
+ fHWDrawState.getBlendConstant() != blendConst) {
float c[] = {
- GrColorUnpackR(fCurrDrawState.fBlendConstant) / 255.f,
- GrColorUnpackG(fCurrDrawState.fBlendConstant) / 255.f,
- GrColorUnpackB(fCurrDrawState.fBlendConstant) / 255.f,
- GrColorUnpackA(fCurrDrawState.fBlendConstant) / 255.f
+ GrColorUnpackR(blendConst) / 255.f,
+ GrColorUnpackG(blendConst) / 255.f,
+ GrColorUnpackB(blendConst) / 255.f,
+ GrColorUnpackA(blendConst) / 255.f
};
GL_CALL(BlendColor(c[0], c[1], c[2], c[3]));
- fHWDrawState.fBlendConstant = fCurrDrawState.fBlendConstant;
+ fHWDrawState.setBlendConstant(blendConst);
}
}
}
@@ -2031,14 +2036,16 @@
bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
+ GrDrawState* drawState = this->drawState();
// GrGpu::setupClipAndFlushState should have already checked this
// and bailed if not true.
- GrAssert(NULL != fCurrDrawState.fRenderTarget);
+ GrAssert(NULL != drawState->getRenderTarget());
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
// bind texture and set sampler state
if (this->isStageEnabled(s)) {
- GrGLTexture* nextTexture = (GrGLTexture*)fCurrDrawState.fTextures[s];
+ GrGLTexture* nextTexture =
+ static_cast<GrGLTexture*>(drawState->getTexture(s));
// true for now, but maybe not with GrEffect.
GrAssert(NULL != nextTexture);
@@ -2052,20 +2059,20 @@
resolveRenderTarget(texRT);
}
- if (fHWDrawState.fTextures[s] != nextTexture) {
+ if (fHWDrawState.getTexture(s) != nextTexture) {
setTextureUnit(s);
GL_CALL(BindTexture(GR_GL_TEXTURE_2D, nextTexture->textureID()));
#if GR_COLLECT_STATS
++fStats.fTextureChngCnt;
#endif
//GrPrintf("---- bindtexture %d\n", nextTexture->textureID());
- fHWDrawState.fTextures[s] = nextTexture;
+ fHWDrawState.setTexture(s, nextTexture);
// The texture matrix has to compensate for texture width/height
// and NPOT-embedded-in-POT
fDirtyFlags.fTextureChangedMask |= (1 << s);
}
- const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
+ const GrSamplerState& sampler = drawState->getSampler(s);
ResetTimestamp timestamp;
const GrGLTexture::TexParams& oldTexParams =
nextTexture->getCachedTexParams(×tamp);
@@ -2117,7 +2124,7 @@
GrIRect* rect = NULL;
GrIRect clipBounds;
- if ((fCurrDrawState.fFlagBits & kClip_StateBit) &&
+ if (drawState->isClipState() &&
fClip.hasConservativeBounds()) {
fClip.getConservativeBounds().roundOut(&clipBounds);
rect = &clipBounds;
@@ -2125,19 +2132,18 @@
this->flushRenderTarget(rect);
this->flushAAState(type);
- if ((fCurrDrawState.fFlagBits & kDither_StateBit) !=
- (fHWDrawState.fFlagBits & kDither_StateBit)) {
- if (fCurrDrawState.fFlagBits & kDither_StateBit) {
+ if (drawState->isDitherState() != fHWDrawState.isDitherState()) {
+ if (drawState->isDitherState()) {
GL_CALL(Enable(GR_GL_DITHER));
} else {
GL_CALL(Disable(GR_GL_DITHER));
}
}
- if ((fCurrDrawState.fFlagBits & kNoColorWrites_StateBit) !=
- (fHWDrawState.fFlagBits & kNoColorWrites_StateBit)) {
+ if (drawState->isColorWriteDisabled() !=
+ fHWDrawState.isColorWriteDisabled()) {
GrGLenum mask;
- if (fCurrDrawState.fFlagBits & kNoColorWrites_StateBit) {
+ if (drawState->isColorWriteDisabled()) {
mask = GR_GL_FALSE;
} else {
mask = GR_GL_TRUE;
@@ -2145,8 +2151,8 @@
GL_CALL(ColorMask(mask, mask, mask, mask));
}
- if (fHWDrawState.fDrawFace != fCurrDrawState.fDrawFace) {
- switch (fCurrDrawState.fDrawFace) {
+ if (fHWDrawState.getDrawFace() != drawState->getDrawFace()) {
+ switch (fCurrDrawState.getDrawFace()) {
case GrDrawState::kCCW_DrawFace:
GL_CALL(Enable(GR_GL_CULL_FACE));
GL_CALL(CullFace(GR_GL_BACK));
@@ -2161,24 +2167,26 @@
default:
GrCrash("Unknown draw face.");
}
- fHWDrawState.fDrawFace = fCurrDrawState.fDrawFace;
+ fHWDrawState.setDrawFace(drawState->getDrawFace());
}
#if GR_DEBUG
// check for circular rendering
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
GrAssert(!this->isStageEnabled(s) ||
- NULL == fCurrDrawState.fRenderTarget ||
- NULL == fCurrDrawState.fTextures[s] ||
- fCurrDrawState.fTextures[s]->asRenderTarget() !=
- fCurrDrawState.fRenderTarget);
+ NULL == drawState->getRenderTarget() ||
+ NULL == drawState->getTexture(s) ||
+ drawState->getTexture(s)->asRenderTarget() !=
+ drawState->getRenderTarget());
}
#endif
- flushStencil();
+ this->flushStencil();
- // flushStencil may look at the private state bits, so keep it before this.
- fHWDrawState.fFlagBits = fCurrDrawState.fFlagBits;
+ // This copy must happen after flushStencil() is called. flushStencil()
+ // relies on detecting when the kModifyStencilClip_StateBit state has
+ // changed since the last draw.
+ fHWDrawState.copyStateFlags(*drawState);
return true;
}
@@ -2210,22 +2218,24 @@
void GrGpuGL::notifyRenderTargetDelete(GrRenderTarget* renderTarget) {
GrAssert(NULL != renderTarget);
- if (fCurrDrawState.fRenderTarget == renderTarget) {
- fCurrDrawState.fRenderTarget = NULL;
+ GrDrawState* drawState = this->drawState();
+ if (drawState->getRenderTarget() == renderTarget) {
+ drawState->setRenderTarget(NULL);
}
- if (fHWDrawState.fRenderTarget == renderTarget) {
- fHWDrawState.fRenderTarget = NULL;
+ if (fHWDrawState.getRenderTarget() == renderTarget) {
+ fHWDrawState.setRenderTarget(NULL);
}
}
void GrGpuGL::notifyTextureDelete(GrGLTexture* texture) {
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- if (fCurrDrawState.fTextures[s] == texture) {
- fCurrDrawState.fTextures[s] = NULL;
+ GrDrawState* drawState = this->drawState();
+ if (drawState->getTexture(s) == texture) {
+ fCurrDrawState.setTexture(s, NULL);
}
- if (fHWDrawState.fTextures[s] == texture) {
+ if (fHWDrawState.getTexture(s) == texture) {
// deleting bound texture does implied bind to 0
- fHWDrawState.fTextures[s] = NULL;
+ fHWDrawState.setTexture(s, NULL);
}
}
}
diff --git a/src/gpu/GrGpuGLShaders.cpp b/src/gpu/GrGpuGLShaders.cpp
index 9018a4e..5534d05 100644
--- a/src/gpu/GrGpuGLShaders.cpp
+++ b/src/gpu/GrGpuGLShaders.cpp
@@ -338,12 +338,33 @@
delete fProgramCache;
}
+const GrMatrix& GrGpuGLShaders::getHWViewMatrix() {
+ GrAssert(fProgramData);
+
+ if (GrGLProgram::kSetAsAttribute ==
+ fProgramData->fUniLocations.fViewMatrixUni) {
+ return fHWDrawState.getViewMatrix();
+ } else {
+ return fProgramData->fViewMatrix;
+ }
+}
+
+void GrGpuGLShaders::recordHWViewMatrix(const GrMatrix& matrix) {
+ GrAssert(fProgramData);
+ if (GrGLProgram::kSetAsAttribute ==
+ fProgramData->fUniLocations.fViewMatrixUni) {
+ fHWDrawState.setViewMatrix(matrix);
+ } else {
+ fProgramData->fViewMatrix = matrix;
+ }
+}
+
const GrMatrix& GrGpuGLShaders::getHWSamplerMatrix(int stage) {
GrAssert(fProgramData);
if (GrGLProgram::kSetAsAttribute ==
fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni) {
- return fHWDrawState.fSamplerStates[stage].getMatrix();
+ return fHWDrawState.getSampler(stage).getMatrix();
} else {
return fProgramData->fTextureMatrices[stage];
}
@@ -353,7 +374,7 @@
GrAssert(fProgramData);
if (GrGLProgram::kSetAsAttribute ==
fProgramData->fUniLocations.fStages[stage].fTextureMatrixUni) {
- fHWDrawState.fSamplerStates[stage].setMatrix(matrix);
+ fHWDrawState.sampler(stage)->setMatrix(matrix);
} else {
fProgramData->fTextureMatrices[stage] = matrix;
}
@@ -388,47 +409,53 @@
}
void GrGpuGLShaders::flushViewMatrix() {
- GrAssert(NULL != fCurrDrawState.fRenderTarget);
- GrMatrix m;
- m.setAll(
- GrIntToScalar(2) / fCurrDrawState.fRenderTarget->width(), 0, -GR_Scalar1,
- 0,-GrIntToScalar(2) / fCurrDrawState.fRenderTarget->height(), GR_Scalar1,
- 0, 0, GrMatrix::I()[8]);
- m.setConcat(m, fCurrDrawState.fViewMatrix);
+ const GrMatrix& vm = this->getDrawState().getViewMatrix();
+ if (GrGpuGLShaders::getHWViewMatrix() != vm) {
- // ES doesn't allow you to pass true to the transpose param,
- // so do our own transpose
- GrGLfloat mt[] = {
- GrScalarToFloat(m[GrMatrix::kMScaleX]),
- GrScalarToFloat(m[GrMatrix::kMSkewY]),
- GrScalarToFloat(m[GrMatrix::kMPersp0]),
- GrScalarToFloat(m[GrMatrix::kMSkewX]),
- GrScalarToFloat(m[GrMatrix::kMScaleY]),
- GrScalarToFloat(m[GrMatrix::kMPersp1]),
- GrScalarToFloat(m[GrMatrix::kMTransX]),
- GrScalarToFloat(m[GrMatrix::kMTransY]),
- GrScalarToFloat(m[GrMatrix::kMPersp2])
- };
+ const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
+ GrAssert(NULL != rt);
+ GrMatrix m;
+ m.setAll(
+ GrIntToScalar(2) / rt->width(), 0, -GR_Scalar1,
+ 0,-GrIntToScalar(2) / rt->height(), GR_Scalar1,
+ 0, 0, GrMatrix::I()[8]);
+ m.setConcat(m, vm);
- if (GrGLProgram::kSetAsAttribute ==
- fProgramData->fUniLocations.fViewMatrixUni) {
- int baseIdx = GrGLProgram::ViewMatrixAttributeIdx();
- GL_CALL(VertexAttrib4fv(baseIdx + 0, mt+0));
- GL_CALL(VertexAttrib4fv(baseIdx + 1, mt+3));
- GL_CALL(VertexAttrib4fv(baseIdx + 2, mt+6));
- } else {
- GrAssert(GrGLProgram::kUnusedUniform !=
- fProgramData->fUniLocations.fViewMatrixUni);
- GL_CALL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni,
- 1, false, mt));
+ // ES doesn't allow you to pass true to the transpose param,
+ // so do our own transpose
+ GrGLfloat mt[] = {
+ GrScalarToFloat(m[GrMatrix::kMScaleX]),
+ GrScalarToFloat(m[GrMatrix::kMSkewY]),
+ GrScalarToFloat(m[GrMatrix::kMPersp0]),
+ GrScalarToFloat(m[GrMatrix::kMSkewX]),
+ GrScalarToFloat(m[GrMatrix::kMScaleY]),
+ GrScalarToFloat(m[GrMatrix::kMPersp1]),
+ GrScalarToFloat(m[GrMatrix::kMTransX]),
+ GrScalarToFloat(m[GrMatrix::kMTransY]),
+ GrScalarToFloat(m[GrMatrix::kMPersp2])
+ };
+
+ if (GrGLProgram::kSetAsAttribute ==
+ fProgramData->fUniLocations.fViewMatrixUni) {
+ int baseIdx = GrGLProgram::ViewMatrixAttributeIdx();
+ GL_CALL(VertexAttrib4fv(baseIdx + 0, mt+0));
+ GL_CALL(VertexAttrib4fv(baseIdx + 1, mt+3));
+ GL_CALL(VertexAttrib4fv(baseIdx + 2, mt+6));
+ } else {
+ GrAssert(GrGLProgram::kUnusedUniform !=
+ fProgramData->fUniLocations.fViewMatrixUni);
+ GL_CALL(UniformMatrix3fv(fProgramData->fUniLocations.fViewMatrixUni,
+ 1, false, mt));
+ }
+ this->recordHWViewMatrix(vm);
}
}
void GrGpuGLShaders::flushTextureDomain(int s) {
const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTexDomUni;
+ const GrDrawState& drawState = this->getDrawState();
if (GrGLProgram::kUnusedUniform != uni) {
- const GrRect &texDom =
- fCurrDrawState.fSamplerStates[s].getTextureDomain();
+ const GrRect &texDom = drawState.getSampler(s).getTextureDomain();
if (((1 << s) & fDirtyFlags.fTextureChangedMask) ||
fProgramData->fTextureDomain[s] != texDom) {
@@ -442,7 +469,8 @@
GrScalarToFloat(texDom.bottom())
};
- GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
+ const GrGLTexture* texture =
+ static_cast<const GrGLTexture*>(drawState.getTexture(s));
GrGLTexture::Orientation orientation = texture->orientation();
// vertical flip if necessary
@@ -461,19 +489,17 @@
void GrGpuGLShaders::flushTextureMatrix(int s) {
const GrGLint& uni = fProgramData->fUniLocations.fStages[s].fTextureMatrixUni;
- GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
+ const GrDrawState& drawState = this->getDrawState();
+ const GrGLTexture* texture =
+ static_cast<const GrGLTexture*>(drawState.getTexture(s));
if (NULL != texture) {
if (GrGLProgram::kUnusedUniform != uni &&
(((1 << s) & fDirtyFlags.fTextureChangedMask) ||
- getHWSamplerMatrix(s) != getSamplerMatrix(s))) {
+ this->getHWSamplerMatrix(s) != drawState.getSampler(s).getMatrix())) {
- GrAssert(NULL != fCurrDrawState.fTextures[s]);
-
- GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
-
- GrMatrix m = getSamplerMatrix(s);
- GrSamplerState::SampleMode mode =
- fCurrDrawState.fSamplerStates[s].getSampleMode();
+ GrMatrix m = drawState.getSampler(s).getMatrix();
+ GrSamplerState::SampleMode mode =
+ drawState.getSampler(s).getSampleMode();
AdjustTextureMatrix(texture, mode, &m);
// ES doesn't allow you to pass true to the transpose param,
@@ -499,7 +525,7 @@
} else {
GL_CALL(UniformMatrix3fv(uni, 1, false, mt));
}
- recordHWSamplerMatrix(s, getSamplerMatrix(s));
+ this->recordHWSamplerMatrix(s, drawState.getSampler(s).getMatrix());
}
}
}
@@ -507,7 +533,7 @@
void GrGpuGLShaders::flushRadial2(int s) {
const int &uni = fProgramData->fUniLocations.fStages[s].fRadial2Uni;
- const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
+ const GrSamplerState& sampler = this->getDrawState().getSampler(s);
if (GrGLProgram::kUnusedUniform != uni &&
(fProgramData->fRadial2CenterX1[s] != sampler.getRadial2CenterX1() ||
fProgramData->fRadial2Radius0[s] != sampler.getRadial2Radius0() ||
@@ -539,7 +565,7 @@
}
void GrGpuGLShaders::flushConvolution(int s) {
- const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
+ const GrSamplerState& sampler = this->getDrawState().getSampler(s);
int kernelUni = fProgramData->fUniLocations.fStages[s].fKernelUni;
if (GrGLProgram::kUnusedUniform != kernelUni) {
GL_CALL(Uniform1fv(kernelUni, sampler.getKernelWidth(),
@@ -554,7 +580,8 @@
void GrGpuGLShaders::flushTexelSize(int s) {
const int& uni = fProgramData->fUniLocations.fStages[s].fNormalizedTexelSizeUni;
if (GrGLProgram::kUnusedUniform != uni) {
- GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
+ const GrGLTexture* texture =
+ static_cast<const GrGLTexture*>(this->getDrawState().getTexture(s));
if (texture->width() != fProgramData->fTextureWidth[s] ||
texture->height() != fProgramData->fTextureHeight[s]) {
@@ -570,13 +597,13 @@
void GrGpuGLShaders::flushEdgeAAData() {
const int& uni = fProgramData->fUniLocations.fEdgesUni;
if (GrGLProgram::kUnusedUniform != uni) {
- int count = fCurrDrawState.fEdgeAANumEdges;
+ int count = this->getDrawState().getNumAAEdges();
GrDrawState::Edge edges[GrDrawState::kMaxEdges];
// Flip the edges in Y
float height =
- static_cast<float>(fCurrDrawState.fRenderTarget->height());
+ static_cast<float>(this->getDrawState().getRenderTarget()->height());
for (int i = 0; i < count; ++i) {
- edges[i] = fCurrDrawState.fEdgeAAEdges[i];
+ edges[i] = this->getDrawState().getAAEdges()[i];
float b = edges[i].fY;
edges[i].fY = -b;
edges[i].fZ += b * height;
@@ -596,19 +623,21 @@
void GrGpuGLShaders::flushColor(GrColor color) {
const ProgramDesc& desc = fCurrentProgram.getDesc();
+ const GrDrawState& drawState = this->getDrawState();
+
if (this->getGeomSrc().fVertexLayout & kColor_VertexLayoutBit) {
// color will be specified per-vertex as an attribute
// invalidate the const vertex attrib color
- fHWDrawState.fColor = GrColor_ILLEGAL;
+ fHWDrawState.setColor(GrColor_ILLEGAL);
} else {
switch (desc.fColorInput) {
case ProgramDesc::kAttribute_ColorInput:
- if (fHWDrawState.fColor != color) {
+ if (fHWDrawState.getColor() != color) {
// OpenGL ES only supports the float varities of glVertexAttrib
float c[] = GR_COLOR_TO_VEC4(color);
GL_CALL(VertexAttrib4fv(GrGLProgram::ColorAttributeIdx(),
c));
- fHWDrawState.fColor = color;
+ fHWDrawState.setColor(color);
}
break;
case ProgramDesc::kUniform_ColorInput:
@@ -632,10 +661,10 @@
if (fProgramData->fUniLocations.fColorFilterUni
!= GrGLProgram::kUnusedUniform
&& fProgramData->fColorFilterColor
- != fCurrDrawState.fColorFilterColor) {
- float c[] = GR_COLOR_TO_VEC4(fCurrDrawState.fColorFilterColor);
+ != drawState.getColorFilterColor()) {
+ float c[] = GR_COLOR_TO_VEC4(drawState.getColorFilterColor());
GL_CALL(Uniform4fv(fProgramData->fUniLocations.fColorFilterUni, 1, c));
- fProgramData->fColorFilterColor = fCurrDrawState.fColorFilterColor;
+ fProgramData->fColorFilterColor = drawState.getColorFilterColor();
}
}
@@ -645,10 +674,12 @@
return false;
}
+ const GrDrawState& drawState = this->getDrawState();
+
if (fDirtyFlags.fRenderTargetChanged) {
// our coords are in pixel space and the GL matrices map to NDC
// so if the viewport changed, our matrix is now wrong.
- fHWDrawState.fViewMatrix = GrMatrix::InvalidMatrix();
+ fHWDrawState.setViewMatrix(GrMatrix::InvalidMatrix());
// we assume all shader matrices may be wrong after viewport changes
fProgramCache->invalidateViewMatrices();
}
@@ -680,22 +711,11 @@
} else if (blendOpts & kEmitCoverage_BlendOptFlag) {
color = 0xffffffff;
} else {
- color = fCurrDrawState.fColor;
+ color = drawState.getColor();
}
this->flushColor(color);
- GrMatrix* currViewMatrix;
- if (GrGLProgram::kSetAsAttribute ==
- fProgramData->fUniLocations.fViewMatrixUni) {
- currViewMatrix = &fHWDrawState.fViewMatrix;
- } else {
- currViewMatrix = &fProgramData->fViewMatrix;
- }
-
- if (*currViewMatrix != fCurrDrawState.fViewMatrix) {
- flushViewMatrix();
- *currViewMatrix = fCurrDrawState.fViewMatrix;
- }
+ this->flushViewMatrix();
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
this->flushTextureMatrix(s);
@@ -857,6 +877,7 @@
BlendOptFlags blendOpts,
GrBlendCoeff dstCoeff) {
ProgramDesc& desc = fCurrentProgram.fProgramDesc;
+ const GrDrawState& drawState = this->getDrawState();
// This should already have been caught
GrAssert(!(kSkipDraw_BlendOptFlag & blendOpts));
@@ -885,7 +906,7 @@
desc.fColorFilterXfermode = skipColor ?
SkXfermode::kDst_Mode :
- fCurrDrawState.fColorFilterXfermode;
+ drawState.getColorFilterMode();
// no reason to do edge aa or look at per-vertex coverage if coverage is
// ignored
@@ -897,7 +918,7 @@
bool colorIsTransBlack = SkToBool(blendOpts & kEmitTransBlack_BlendOptFlag);
bool colorIsSolidWhite = (blendOpts & kEmitCoverage_BlendOptFlag) ||
(!requiresAttributeColors &&
- 0xffffffff == fCurrDrawState.fColor);
+ 0xffffffff == drawState.getColor());
if (GR_AGGRESSIVE_SHADER_OPTS && colorIsTransBlack) {
desc.fColorInput = ProgramDesc::kTransBlack_ColorInput;
} else if (GR_AGGRESSIVE_SHADER_OPTS && colorIsSolidWhite) {
@@ -908,16 +929,15 @@
desc.fColorInput = ProgramDesc::kAttribute_ColorInput;
}
- desc.fEdgeAANumEdges = skipCoverage ? 0 : fCurrDrawState.fEdgeAANumEdges;
+ desc.fEdgeAANumEdges = skipCoverage ? 0 : drawState.getNumAAEdges();
desc.fEdgeAAConcave = desc.fEdgeAANumEdges > 0 &&
- SkToBool(fCurrDrawState.fFlagBits &
- kEdgeAAConcave_StateBit);
+ drawState.isConcaveEdgeAAState();
int lastEnabledStage = -1;
if (!skipCoverage && (desc.fVertexLayout &
GrDrawTarget::kEdge_VertexLayoutBit)) {
- desc.fVertexEdgeType = fCurrDrawState.fVertexEdgeType;
+ desc.fVertexEdgeType = drawState.getVertexEdgeType();
} else {
// use canonical value when not set to avoid cache misses
desc.fVertexEdgeType = GrDrawState::kHairLine_EdgeType;
@@ -929,19 +949,20 @@
stage.fOptFlags = 0;
stage.setEnabled(this->isStageEnabled(s));
- bool skip = s < fCurrDrawState.fFirstCoverageStage ? skipColor :
+ bool skip = s < drawState.getFirstCoverageStage() ? skipColor :
skipCoverage;
if (!skip && stage.isEnabled()) {
lastEnabledStage = s;
- GrGLTexture* texture = (GrGLTexture*) fCurrDrawState.fTextures[s];
+ const GrGLTexture* texture =
+ static_cast<const GrGLTexture*>(drawState.getTexture(s));
GrAssert(NULL != texture);
- const GrSamplerState& sampler = fCurrDrawState.fSamplerStates[s];
+ const GrSamplerState& sampler = drawState.getSampler(s);
// we matrix to invert when orientation is TopDown, so make sure
// we aren't in that case before flagging as identity.
if (TextureMatrixIsIdentity(texture, sampler)) {
stage.fOptFlags |= StageDesc::kIdentityMatrix_OptFlagBit;
- } else if (!getSamplerMatrix(s).hasPerspective()) {
+ } else if (!sampler.getMatrix().hasPerspective()) {
stage.fOptFlags |= StageDesc::kNoPerspective_OptFlagBit;
}
switch (sampler.getSampleMode()) {
@@ -1024,7 +1045,7 @@
}
}
- if (GrPixelConfigIsUnpremultiplied(fCurrDrawState.fRenderTarget->config())) {
+ if (GrPixelConfigIsUnpremultiplied(drawState.getRenderTarget()->config())) {
desc.fOutputPM = ProgramDesc::kNo_OutputPM;
} else {
desc.fOutputPM = ProgramDesc::kYes_OutputPM;
@@ -1046,9 +1067,9 @@
// immaterial.
int firstCoverageStage = GrDrawState::kNumStages;
desc.fFirstCoverageStage = GrDrawState::kNumStages;
- bool hasCoverage = fCurrDrawState.fFirstCoverageStage <= lastEnabledStage;
+ bool hasCoverage = drawState.getFirstCoverageStage() <= lastEnabledStage;
if (hasCoverage) {
- firstCoverageStage = fCurrDrawState.fFirstCoverageStage;
+ firstCoverageStage = drawState.getFirstCoverageStage();
}
// other coverage inputs
diff --git a/src/gpu/GrGpuGLShaders.h b/src/gpu/GrGpuGLShaders.h
index baa5d9d..3671296 100644
--- a/src/gpu/GrGpuGLShaders.h
+++ b/src/gpu/GrGpuGLShaders.h
@@ -46,6 +46,8 @@
class ProgramCache;
// Helpers to make code more readable
+ const GrMatrix& getHWViewMatrix();
+ void recordHWViewMatrix(const GrMatrix& matrix);
const GrMatrix& getHWSamplerMatrix(int stage);
void recordHWSamplerMatrix(int stage, const GrMatrix& matrix);
diff --git a/src/gpu/GrInOrderDrawBuffer.cpp b/src/gpu/GrInOrderDrawBuffer.cpp
index 340cff1..cbe153c 100644
--- a/src/gpu/GrInOrderDrawBuffer.cpp
+++ b/src/gpu/GrInOrderDrawBuffer.cpp
@@ -9,6 +9,7 @@
#include "GrInOrderDrawBuffer.h"
+#include "GrRenderTarget.h"
#include "GrTexture.h"
#include "GrBufferAllocPool.h"
#include "GrIndexBuffer.h"
@@ -78,6 +79,8 @@
GrAssert(!(fDraws.empty() && fCurrQuad));
GrAssert(!(0 != fMaxQuads && NULL == fQuadIndexBuffer));
+ GrDrawState* drawState = this->drawState();
+
// if we have a quad IB then either append to the previous run of
// rects or start a new run
if (fMaxQuads) {
@@ -89,9 +92,8 @@
GrPrintf("Failed to get space for vertices!\n");
return;
}
- AutoViewMatrixRestore avmr(this);
- GrMatrix combinedMatrix = this->getViewMatrix();
- this->setViewMatrix(GrMatrix::I());
+ GrMatrix combinedMatrix = drawState->getViewMatrix();
+ GrDrawState::AutoViewMatrixRestore avmr(drawState, GrMatrix::I());
if (NULL != matrix) {
combinedMatrix.preConcat(*matrix);
}
@@ -102,14 +104,14 @@
// simply because the clip has changed if the clip doesn't affect
// the rect.
bool disabledClip = false;
- if (this->isClipState() && fClip.isRect()) {
+ if (drawState->isClipState() && fClip.isRect()) {
GrRect clipRect = fClip.getRect(0);
// If the clip rect touches the edge of the viewport, extended it
// out (close) to infinity to avoid bogus intersections.
// We might consider a more exact clip to viewport if this
// conservative test fails.
- const GrRenderTarget* target = this->getRenderTarget();
+ const GrRenderTarget* target = drawState->getRenderTarget();
if (0 >= clipRect.fLeft) {
clipRect.fLeft = GR_ScalarMin;
}
@@ -132,7 +134,7 @@
}
}
if (insideClip) {
- this->disableState(kClip_StateBit);
+ drawState->disableState(GrDrawState::kClip_StateBit);
disabledClip = true;
}
}
@@ -176,7 +178,7 @@
fLastRectVertexLayout = layout;
}
if (disabledClip) {
- this->enableState(kClip_StateBit);
+ drawState->enableState(GrDrawState::kClip_StateBit);
}
} else {
INHERITED::drawRect(rect, matrix, stageMask, srcRects, srcMatrices);
@@ -310,8 +312,8 @@
// the current render target. If we get that smart we have to make sure
// those draws aren't read before this clear (render-to-texture).
r.setLTRB(0, 0,
- this->getRenderTarget()->width(),
- this->getRenderTarget()->height());
+ this->getDrawState().getRenderTarget()->width(),
+ this->getDrawState().getRenderTarget()->height());
rect = &r;
}
Clear& clr = fClears.push_back();
@@ -328,9 +330,9 @@
for (uint32_t i = 0; i < numStates; ++i) {
const GrDrawState& dstate = this->accessSavedDrawState(fStates[i]);
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- GrSafeUnref(dstate.fTextures[s]);
+ GrSafeUnref(dstate.getTexture(s));
}
- GrSafeUnref(dstate.fRenderTarget);
+ GrSafeUnref(dstate.getRenderTarget());
}
int numDraws = fDraws.count();
for (int d = 0; d < numDraws; ++d) {
@@ -593,15 +595,16 @@
}
void GrInOrderDrawBuffer::pushState() {
+ const GrDrawState& drawState = this->getDrawState();
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
- GrSafeRef(fCurrDrawState.fTextures[s]);
+ GrSafeRef(drawState.getTexture(s));
}
- GrSafeRef(fCurrDrawState.fRenderTarget);
+ GrSafeRef(drawState.getRenderTarget());
this->saveCurrentDrawState(&fStates.push_back());
}
bool GrInOrderDrawBuffer::needsNewClip() const {
- if (fCurrDrawState.fFlagBits & kClip_StateBit) {
+ if (this->getDrawState().isClipState()) {
if (fClips.empty() || (fClipSet && fClips.back() != fClip)) {
return true;
}
diff --git a/src/gpu/GrTesselatedPathRenderer.cpp b/src/gpu/GrTesselatedPathRenderer.cpp
index b6612d1..f7fd8e4 100644
--- a/src/gpu/GrTesselatedPathRenderer.cpp
+++ b/src/gpu/GrTesselatedPathRenderer.cpp
@@ -12,6 +12,7 @@
#include "GrDrawState.h"
#include "GrPathUtils.h"
#include "GrPoint.h"
+#include "GrRenderTarget.h"
#include "GrTDArray.h"
#include "SkTemplates.h"
@@ -348,10 +349,11 @@
void GrTesselatedPathRenderer::drawPath(GrDrawState::StageMask stageMask) {
GrDrawTarget::AutoStateRestore asr(fTarget);
+ GrDrawState* drawState = fTarget->drawState();
// face culling doesn't make sense here
- GrAssert(GrDrawState::kBoth_DrawFace == fTarget->getDrawFace());
+ GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());
- GrMatrix viewM = fTarget->getViewMatrix();
+ GrMatrix viewM = drawState->getViewMatrix();
GrScalar tol = GR_Scalar1;
tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, fPath->getBounds());
@@ -433,12 +435,12 @@
if (inverted) {
GrRect bounds;
- GrAssert(NULL != fTarget->getRenderTarget());
+ GrAssert(NULL != drawState->getRenderTarget());
bounds.setLTRB(0, 0,
- GrIntToScalar(fTarget->getRenderTarget()->width()),
- GrIntToScalar(fTarget->getRenderTarget()->height()));
+ GrIntToScalar(drawState->getRenderTarget()->width()),
+ GrIntToScalar(drawState->getRenderTarget()->height()));
GrMatrix vmi;
- if (fTarget->getViewInverse(&vmi)) {
+ if (drawState->getViewInverse(&vmi)) {
vmi.mapRect(&bounds);
}
*vert++ = GrPoint::Make(bounds.fLeft, bounds.fTop);
@@ -460,8 +462,8 @@
if (subpathCnt == 1 && !inverted && fPath->isConvex()) {
if (fAntiAlias) {
GrEdgeArray edges;
- GrMatrix inverse, matrix = fTarget->getViewMatrix();
- fTarget->getViewInverse(&inverse);
+ GrMatrix inverse, matrix = drawState->getViewMatrix();
+ drawState->getViewInverse(&inverse);
count = computeEdgesAndIntersect(matrix, inverse, base, count, &edges, 0.0f);
size_t maxEdges = fTarget->getMaxEdges();
@@ -471,7 +473,7 @@
if (count <= maxEdges) {
// All edges fit; upload all edges and draw all verts as a fan
fTarget->setVertexSourceToArray(layout, base, count);
- fTarget->setEdgeAAData(&edges[0], count);
+ drawState->setEdgeAAData(&edges[0], count);
fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count);
} else {
// Upload "maxEdges" edges and verts at a time, and draw as
@@ -481,11 +483,11 @@
base[i] = base[0];
int size = GR_CT_MIN(count - i, maxEdges);
fTarget->setVertexSourceToArray(layout, &base[i], size);
- fTarget->setEdgeAAData(&edges[i], size);
+ drawState->setEdgeAAData(&edges[i], size);
fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, size);
}
}
- fTarget->setEdgeAAData(NULL, 0);
+ drawState->setEdgeAAData(NULL, 0);
} else {
fTarget->setVertexSourceToArray(layout, base, count);
fTarget->drawNonIndexed(kTriangleFan_PrimitiveType, 0, count);
@@ -498,8 +500,8 @@
GrBoundaryTess btess(count, fill_type_to_glu_winding_rule(fFill));
btess.addVertices(base, subpathVertCount, subpathCnt);
- GrMatrix inverse, matrix = fTarget->getViewMatrix();
- if (!fTarget->getViewInverse(&inverse)) {
+ GrMatrix inverse, matrix = drawState->getViewMatrix();
+ if (!drawState->getViewInverse(&inverse)) {
return;
}
@@ -534,7 +536,7 @@
}
// Draw the resulting polys and upload their edge data.
- fTarget->enableState(GrDrawTarget::kEdgeAAConcave_StateBit);
+ drawState->enableState(GrDrawState::kEdgeAAConcave_StateBit);
const GrPointArray& vertices = ptess.vertices();
const GrIndexArray& indices = ptess.indices();
const GrDrawState::Edge* edges = ptess.edges();
@@ -567,12 +569,12 @@
tri_edges[t++] = edge4;
tri_edges[t++] = edge5;
}
- fTarget->setEdgeAAData(&tri_edges[0], t);
+ drawState->setEdgeAAData(&tri_edges[0], t);
fTarget->setVertexSourceToArray(layout, &tri_verts[0], 3);
fTarget->drawNonIndexed(kTriangles_PrimitiveType, 0, 3);
}
- fTarget->setEdgeAAData(NULL, 0);
- fTarget->disableState(GrDrawTarget::kEdgeAAConcave_StateBit);
+ drawState->setEdgeAAData(NULL, 0);
+ drawState->disableState(GrDrawState::kEdgeAAConcave_StateBit);
return;
}
diff --git a/src/gpu/GrTextContext.cpp b/src/gpu/GrTextContext.cpp
index 4b78d4a..3b3841b 100644
--- a/src/gpu/GrTextContext.cpp
+++ b/src/gpu/GrTextContext.cpp
@@ -25,7 +25,7 @@
void GrTextContext::flushGlyphs() {
if (fCurrVertex > 0) {
GrDrawTarget::AutoStateRestore asr(fDrawTarget);
-
+ GrDrawState* drawState = fDrawTarget->drawState();
// setup our sampler state for our text texture/atlas
GrSamplerState::Filter filter;
if (fExtMatrix.isIdentity()) {
@@ -35,12 +35,12 @@
}
GrSamplerState sampler(GrSamplerState::kRepeat_WrapMode,
filter);
- fDrawTarget->setSamplerState(kGlyphMaskStage, sampler);
+ drawState->setSampler(kGlyphMaskStage, sampler);
GrAssert(GrIsALIGN4(fCurrVertex));
int nIndices = fCurrVertex + (fCurrVertex >> 1);
GrAssert(fCurrTexture);
- fDrawTarget->setTexture(kGlyphMaskStage, fCurrTexture);
+ drawState->setTexture(kGlyphMaskStage, fCurrTexture);
if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
if (kOne_BlendCoeff != fPaint.fSrcBlendCoeff ||
@@ -49,15 +49,15 @@
GrPrintf("LCD Text will not draw correctly.\n");
}
// setup blend so that we get mask * paintColor + (1-mask)*dstColor
- fDrawTarget->setBlendConstant(fPaint.fColor);
+ drawState->setBlendConstant(fPaint.fColor);
fDrawTarget->setBlendFunc(kConstC_BlendCoeff, kISC_BlendCoeff);
// don't modulate by the paint's color in the frag since we're
// already doing it via the blend const.
- fDrawTarget->setColor(0xffffffff);
+ drawState->setColor(0xffffffff);
} else {
// set back to normal in case we took LCD path previously.
fDrawTarget->setBlendFunc(fPaint.fSrcBlendCoeff, fPaint.fDstBlendCoeff);
- fDrawTarget->setColor(fPaint.fColor);
+ drawState->setColor(fPaint.fColor);
}
fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());