Cleanup of r2830.
git-svn-id: http://skia.googlecode.com/svn/trunk@2841 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
b6e161937b
commit
8f9cbd62ec
@ -602,8 +602,8 @@ void add_line(const SkPoint p[2],
|
||||
}
|
||||
|
||||
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 @@ bool GrAAHairLinePathRenderer::createGeom(GrDrawState::StageMask stageMask) {
|
||||
// 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 @@ bool GrAAHairLinePathRenderer::createGeom(GrDrawState::StageMask stageMask) {
|
||||
}
|
||||
}
|
||||
|
||||
GrMatrix viewM = fTarget->getViewMatrix();
|
||||
GrMatrix viewM = drawState.getViewMatrix();
|
||||
|
||||
PREALLOC_PTARRAY(128) lines;
|
||||
PREALLOC_PTARRAY(128) quads;
|
||||
@ -672,7 +672,7 @@ bool GrAAHairLinePathRenderer::createGeom(GrDrawState::StageMask stageMask) {
|
||||
}
|
||||
|
||||
fPreviousStages = stageMask;
|
||||
fPreviousViewMatrix = fTarget->getViewMatrix();
|
||||
fPreviousViewMatrix = drawState.getViewMatrix();
|
||||
fPreviousRTHeight = rtHeight;
|
||||
fClipRect = clip;
|
||||
fPreviousTranslate = fTranslate;
|
||||
@ -685,14 +685,16 @@ void GrAAHairLinePathRenderer::drawPath(GrDrawState::StageMask stageMask) {
|
||||
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 @@ void GrAAHairLinePathRenderer::drawPath(GrDrawState::StageMask stageMask) {
|
||||
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 @@ void GrAAHairLinePathRenderer::drawPath(GrDrawState::StageMask stageMask) {
|
||||
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
|
||||
|
@ -218,20 +218,22 @@ void gen_stencil_key_values(const GrStencilBuffer* sb,
|
||||
// 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 @@ GrContext::TextureCacheEntry GrContext::createAndLockTexture(TextureKey key,
|
||||
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 @@ GrContext::TextureCacheEntry GrContext::createAndLockTexture(TextureKey key,
|
||||
}
|
||||
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 @@ const GrClip& GrContext::getClip() const { return fGpu->getClip(); }
|
||||
|
||||
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 @@ void GrContext::drawPaint(const GrPaint& paint) {
|
||||
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 @@ bool GrContext::doOffscreenAA(GrDrawTarget* target,
|
||||
(!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 @@ void GrContext::setupOffscreenAAPass1(GrDrawTarget* target,
|
||||
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 @@ void GrContext::doOffscreenAAPass2(GrDrawTarget* target,
|
||||
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 @@ void GrContext::doOffscreenAAPass2(GrDrawTarget* target,
|
||||
|
||||
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 @@ static GrVertexLayout aa_rect_layout(const GrDrawTarget* target,
|
||||
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 @@ void GrContext::fillAARect(GrDrawTarget* target,
|
||||
if (useVertexCoverage) {
|
||||
innerColor = 0xffffffff;
|
||||
} else {
|
||||
innerColor = target->getColor();
|
||||
innerColor = target->getDrawState().getColor();
|
||||
}
|
||||
|
||||
verts += 4 * vsize;
|
||||
@ -1158,7 +1163,7 @@ void GrContext::strokeAARect(GrDrawTarget* target,
|
||||
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 @@ static bool apply_aa_to_rect(GrDrawTarget* target,
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (target->getRenderTarget()->isMultisampled()) {
|
||||
const GrDrawState& drawState = target->getDrawState();
|
||||
if (drawState.getRenderTarget()->isMultisampled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1223,7 +1228,7 @@ static bool apply_aa_to_rect(GrDrawTarget* target,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!target->getViewMatrix().preservesAxisAlignment()) {
|
||||
if (!drawState.getViewMatrix().preservesAxisAlignment()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1232,7 +1237,7 @@ static bool apply_aa_to_rect(GrDrawTarget* target,
|
||||
return false;
|
||||
}
|
||||
|
||||
*combinedMatrix = target->getViewMatrix();
|
||||
*combinedMatrix = drawState.getViewMatrix();
|
||||
if (NULL != matrix) {
|
||||
combinedMatrix->preConcat(*matrix);
|
||||
GrAssert(combinedMatrix->preservesAxisAlignment());
|
||||
@ -1267,14 +1272,7 @@ void GrContext::drawRect(const GrPaint& paint,
|
||||
&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 @@ void GrContext::drawRect(const GrPaint& paint,
|
||||
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 @@ void GrContext::drawRect(const GrPaint& paint,
|
||||
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 @@ void GrContext::drawRect(const GrPaint& paint,
|
||||
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 @@ void GrContext::drawRectToRect(const GrPaint& paint,
|
||||
|
||||
#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 @@ void GrContext::drawRectToRect(const GrPaint& paint,
|
||||
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 @@ void GrContext::drawRectToRect(const GrPaint& paint,
|
||||
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 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path,
|
||||
|
||||
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 @@ void GrContext::drawPath(const GrPaint& paint, const GrPath& path,
|
||||
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 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target,
|
||||
ASSERT_OWNED_RESOURCE(target);
|
||||
|
||||
if (NULL == target) {
|
||||
target = fGpu->getRenderTarget();
|
||||
target = fGpu->drawState()->getRenderTarget();
|
||||
if (NULL == target) {
|
||||
return false;
|
||||
}
|
||||
@ -1782,8 +1780,8 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target,
|
||||
|
||||
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 @@ bool GrContext::internalReadRenderTargetPixels(GrRenderTarget* target,
|
||||
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 @@ void GrContext::copyTexture(GrTexture* src, GrRenderTarget* dst) {
|
||||
|
||||
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 @@ void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target,
|
||||
ASSERT_OWNED_RESOURCE(target);
|
||||
|
||||
if (NULL == target) {
|
||||
target = fGpu->getRenderTarget();
|
||||
target = fGpu->drawState()->getRenderTarget();
|
||||
if (NULL == target) {
|
||||
return;
|
||||
}
|
||||
@ -1890,12 +1889,13 @@ void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target,
|
||||
|
||||
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 @@ void GrContext::internalWriteRenderTargetPixels(GrRenderTarget* target,
|
||||
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::internalWriteRenderTargetPixels(GrRenderTarget* target,
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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 @@ GrPathRenderer* GrContext::getPathRenderer(const GrPath& path,
|
||||
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 @@ void GrContext::convolve(GrTexture* texture,
|
||||
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);
|
||||
}
|
||||
|
@ -190,7 +190,8 @@ static inline bool single_pass_path(const GrDrawTarget& target,
|
||||
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 @@ FINISHED:
|
||||
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 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
|
||||
|
||||
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 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
|
||||
|
||||
{
|
||||
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 @@ void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
|
||||
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,
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include "GrColor.h"
|
||||
#include "GrMatrix.h"
|
||||
#include "GrNoncopyable.h"
|
||||
#include "GrSamplerState.h"
|
||||
#include "GrStencil.h"
|
||||
|
||||
@ -45,13 +46,433 @@ struct GrDrawState {
|
||||
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.
|
||||
@ -65,6 +486,19 @@ struct GrDrawState {
|
||||
kHairQuad_EdgeType
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -91,53 +525,146 @@ struct GrDrawState {
|
||||
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 @@ struct GrDrawState {
|
||||
}
|
||||
|
||||
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 @@ private:
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -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 @@ const GrClip& GrDrawTarget::getClip() const {
|
||||
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 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
|
||||
}
|
||||
}
|
||||
#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 @@ bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
|
||||
// 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 @@ bool GrDrawTarget::canTweakAlphaForCoverage() const {
|
||||
* 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 @@ GrDrawTarget::getBlendOpts(bool forceCoverage,
|
||||
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 @@ GrDrawTarget::getBlendOpts(bool forceCoverage,
|
||||
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 @@ GrDrawTarget::getBlendOpts(bool forceCoverage,
|
||||
// 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 @@ GrDrawTarget::getBlendOpts(bool forceCoverage,
|
||||
|
||||
// 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 @@ bool GrDrawTarget::willUseHWAALines() const {
|
||||
// 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 @@ bool GrDrawTarget::drawWillReadDst() const {
|
||||
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::AutoDeviceCoordDraw::AutoDeviceCoordDraw(
|
||||
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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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 @@ public:
|
||||
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,285 +86,24 @@ public:
|
||||
*/
|
||||
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 @@ public:
|
||||
*/
|
||||
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
|
||||
@ -464,14 +140,6 @@ public:
|
||||
*/
|
||||
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
|
||||
*/
|
||||
@ -888,39 +556,6 @@ public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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 @@ protected:
|
||||
// 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 {
|
||||
|
@ -185,10 +185,8 @@ bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
|
||||
// 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 @@ GrIndexBuffer* GrGpu::createIndexBuffer(uint32_t size, bool dynamic) {
|
||||
}
|
||||
|
||||
void GrGpu::clear(const GrIRect* rect, GrColor color) {
|
||||
if (NULL == this->getRenderTarget()) {
|
||||
if (NULL == this->getDrawState().getRenderTarget()) {
|
||||
return;
|
||||
}
|
||||
this->handleDirtyContext();
|
||||
@ -530,16 +528,18 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
|
||||
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 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
|
||||
!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 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
|
||||
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 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
|
||||
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 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
|
||||
};
|
||||
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 @@ bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
|
||||
|
||||
// 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
|
||||
|
@ -327,8 +327,8 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
enum PrivateStateBits {
|
||||
kFirstBit = (kLastPublicStateBit << 1),
|
||||
enum PrivateDrawStateStateBits {
|
||||
kFirstBit = (GrDrawState::kLastPublicStateBit << 1),
|
||||
|
||||
kModifyStencilClip_StateBit = kFirstBit, // allows draws to modify
|
||||
// stencil bits used for
|
||||
|
@ -480,7 +480,7 @@ void GrGpuGL::onResetContext() {
|
||||
|
||||
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 @@ void GrGpuGL::onResetContext() {
|
||||
}
|
||||
|
||||
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 @@ void GrGpuGL::onResetContext() {
|
||||
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 @@ void GrGpuGL::onResetContext() {
|
||||
GL_CALL(Disable(GR_GL_SCISSOR_TEST));
|
||||
fHWBounds.fViewportRect.invalidate();
|
||||
|
||||
fHWDrawState.fStencilSettings.invalidate();
|
||||
fHWDrawState.stencil()->invalidate();
|
||||
fHWStencilClip = false;
|
||||
fClipInStencil = false;
|
||||
|
||||
@ -536,7 +534,7 @@ void GrGpuGL::onResetContext() {
|
||||
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 @@ bool GrGpuGL::attachStencilBufferToRenderTarget(GrStencilBuffer* sb,
|
||||
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 @@ GrIndexBuffer* GrGpuGL::onCreateIndexBuffer(uint32_t size, bool dynamic) {
|
||||
}
|
||||
|
||||
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::flushScissor(const GrIRect* rect) {
|
||||
}
|
||||
|
||||
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 @@ void GrGpuGL::onClear(const GrIRect* rect, GrColor color) {
|
||||
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 @@ void GrGpuGL::onClear(const GrIRect* rect, GrColor color) {
|
||||
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 @@ void GrGpuGL::clearStencil() {
|
||||
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 @@ void GrGpuGL::clearStencilClip(const GrIRect& rect, bool insideClip) {
|
||||
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 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
|
||||
|
||||
// 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 @@ bool GrGpuGL::onReadPixels(GrRenderTarget* target,
|
||||
|
||||
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 @@ void GrGpuGL::flushRenderTarget(const GrIRect* bound) {
|
||||
}
|
||||
#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 @@ void GrGpuGL::resolveRenderTarget(GrGLRenderTarget* rt) {
|
||||
#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(6 == kZero_StencilOp);
|
||||
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 @@ void GrGpuGL::flushStencil() {
|
||||
}
|
||||
#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 @@ void GrGpuGL::flushStencil() {
|
||||
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 @@ void GrGpuGL::flushStencil() {
|
||||
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 @@ void GrGpuGL::flushStencil() {
|
||||
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 @@ void GrGpuGL::flushAAState(GrPrimitiveType type) {
|
||||
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 @@ void GrGpuGL::flushBlend(GrPrimitiveType type,
|
||||
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 @@ void GrGpuGL::flushBlend(GrPrimitiveType type,
|
||||
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 @@ void set_tex_swizzle(GrGLenum swizzle[4], const GrGLInterface* gl) {
|
||||
|
||||
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 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
|
||||
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 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
|
||||
|
||||
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 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
|
||||
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 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
|
||||
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 @@ bool GrGpuGL::flushGLStateCommon(GrPrimitiveType type) {
|
||||
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::notifyIndexBufferDelete(const GrGLIndexBuffer* buffer) {
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -338,12 +338,33 @@ GrGpuGLShaders::~GrGpuGLShaders() {
|
||||
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 @@ void GrGpuGLShaders::recordHWSamplerMatrix(int stage, const GrMatrix& matrix) {
|
||||
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::onResetContext() {
|
||||
}
|
||||
|
||||
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 @@ void GrGpuGLShaders::flushTextureDomain(int s) {
|
||||
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::flushTextureDomain(int s) {
|
||||
|
||||
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 @@ void GrGpuGLShaders::flushTextureMatrix(int s) {
|
||||
} 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::flushTextureMatrix(int s) {
|
||||
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::flushRadial2(int s) {
|
||||
}
|
||||
|
||||
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::flushConvolution(int s) {
|
||||
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::flushTexelSize(int s) {
|
||||
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 @@ static const float ONE_OVER_255 = 1.f / 255.f;
|
||||
|
||||
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 @@ void GrGpuGLShaders::flushColor(GrColor color) {
|
||||
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 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
|
||||
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 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
|
||||
} 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 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
|
||||
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 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
|
||||
|
||||
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 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
|
||||
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 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
|
||||
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 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
|
||||
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 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
|
||||
}
|
||||
}
|
||||
|
||||
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 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
|
||||
// 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
|
||||
|
@ -46,6 +46,8 @@ private:
|
||||
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);
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
|
||||
#include "GrInOrderDrawBuffer.h"
|
||||
#include "GrRenderTarget.h"
|
||||
#include "GrTexture.h"
|
||||
#include "GrBufferAllocPool.h"
|
||||
#include "GrIndexBuffer.h"
|
||||
@ -78,6 +79,8 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
|
||||
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 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
|
||||
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 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
|
||||
// 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 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
|
||||
}
|
||||
}
|
||||
if (insideClip) {
|
||||
this->disableState(kClip_StateBit);
|
||||
drawState->disableState(GrDrawState::kClip_StateBit);
|
||||
disabledClip = true;
|
||||
}
|
||||
}
|
||||
@ -176,7 +178,7 @@ void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
|
||||
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 @@ void GrInOrderDrawBuffer::clear(const GrIRect* rect, GrColor color) {
|
||||
// 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 @@ void GrInOrderDrawBuffer::reset() {
|
||||
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 @@ bool GrInOrderDrawBuffer::needsNewState() const {
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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 @@ static size_t computeEdgesAndIntersect(const GrMatrix& matrix,
|
||||
|
||||
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 @@ FINISHED:
|
||||
|
||||
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 @@ FINISHED:
|
||||
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 @@ FINISHED:
|
||||
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 @@ FINISHED:
|
||||
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 @@ FINISHED:
|
||||
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 @@ FINISHED:
|
||||
}
|
||||
|
||||
// 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 @@ FINISHED:
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ enum {
|
||||
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 @@ void GrTextContext::flushGlyphs() {
|
||||
}
|
||||
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 @@ void GrTextContext::flushGlyphs() {
|
||||
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());
|
||||
|
Loading…
Reference in New Issue
Block a user