本文整理汇总了C++中GrDrawState::stencil方法的典型用法代码示例。如果您正苦于以下问题:C++ GrDrawState::stencil方法的具体用法?C++ GrDrawState::stencil怎么用?C++ GrDrawState::stencil使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GrDrawState
的用法示例。
在下文中一共展示了GrDrawState::stencil方法的8个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: setupClipAndFlushState
bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
const GrIRect* r = NULL;
GrIRect clipRect;
GrDrawState* drawState = this->drawState();
const GrRenderTarget* rt = drawState->getRenderTarget();
// 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()));
if (fClip.hasConservativeBounds()) {
bounds = fClip.getConservativeBounds();
if (!bounds.intersect(rtRect)) {
bounds.setEmpty();
}
} else {
bounds = rtRect;
}
bounds.roundOut(&clipRect);
if (clipRect.isEmpty()) {
clipRect.setLTRB(0,0,0,0);
}
r = &clipRect;
// use the stencil clip if we can't represent the clip as a rectangle.
fClipInStencil = !fClip.isRect() && !fClip.isEmpty() &&
!bounds.isEmpty();
// TODO: dynamically attach a SB when needed.
GrStencilBuffer* stencilBuffer = rt->getStencilBuffer();
if (fClipInStencil && NULL == stencilBuffer) {
return false;
}
if (fClipInStencil &&
stencilBuffer->mustRenderClip(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
// we just stashed on the SB to render from. We set it back after
// we finish drawing it into the stencil.
const GrClip& clip = stencilBuffer->getLastClip();
fClip.setFromRect(bounds);
AutoStateRestore asr(this);
AutoGeometryPush agp(this);
drawState->setViewMatrix(GrMatrix::I());
this->flushScissor(NULL);
#if !VISUALIZE_COMPLEX_CLIP
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
#else
drawState->disableState(GrDrawState::kNoColorWrites_StateBit);
#endif
int count = clip.getElementCount();
int clipBit = stencilBuffer->bits();
SkASSERT((clipBit <= 16) &&
"Ganesh only handles 16b or smaller stencil buffers");
clipBit = (1 << (clipBit-1));
bool clearToInside;
GrSetOp startOp = kReplace_SetOp; // suppress warning
int start = process_initial_clip_elements(clip,
rtRect,
&clearToInside,
&startOp);
this->clearStencilClip(clipRect, clearToInside);
// walk through each clip element and perform its set op
// with the existing clip.
for (int c = start; c < count; ++c) {
GrPathFill fill;
bool fillInverted;
// enabled at bottom of loop
drawState->disableState(kModifyStencilClip_StateBit);
bool canRenderDirectToStencil; // can the clip element be drawn
// directly to the stencil buffer
// with a non-inverted fill rule
// without extra passes to
// resolve in/out status.
GrPathRenderer* pr = NULL;
const GrPath* clipPath = NULL;
GrPathRenderer::AutoClearPath arp;
if (kRect_ClipType == clip.getElementType(c)) {
canRenderDirectToStencil = true;
fill = kEvenOdd_PathFill;
fillInverted = false;
// there is no point in intersecting a screen filling
//.........这里部分代码省略.........
示例2: createStencilClipMask
////////////////////////////////////////////////////////////////////////////////
// Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
// (as opposed to canvas) coordinates
bool GrClipMaskManager::createStencilClipMask(const GrClipData& clipDataIn,
const GrIRect& devClipBounds) {
GrAssert(kNone_ClipMaskType == fCurrClipMaskType);
GrDrawState* drawState = fGpu->drawState();
GrAssert(drawState->isClipState());
GrRenderTarget* rt = drawState->getRenderTarget();
GrAssert(NULL != rt);
// TODO: dynamically attach a SB when needed.
GrStencilBuffer* stencilBuffer = rt->getStencilBuffer();
if (NULL == stencilBuffer) {
return false;
}
if (stencilBuffer->mustRenderClip(clipDataIn, rt->width(), rt->height())) {
stencilBuffer->setLastClip(clipDataIn, 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
// we just stashed on the SB to render from. We set it back after
// we finish drawing it into the stencil.
const GrClipData* oldClipData = fGpu->getClip();
// The origin of 'newClipData' is (0, 0) so it is okay to place
// a device-coordinate bound in 'newClipStack'
SkClipStack newClipStack(devClipBounds);
GrClipData newClipData;
newClipData.fClipStack = &newClipStack;
fGpu->setClip(&newClipData);
GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit);
drawState = fGpu->drawState();
drawState->setRenderTarget(rt);
GrDrawTarget::AutoGeometryPush agp(fGpu);
if (0 != clipDataIn.fOrigin.fX || 0 != clipDataIn.fOrigin.fY) {
// Add the saveLayer's offset to the view matrix rather than
// offset each individual draw
drawState->viewMatrix()->setTranslate(
SkIntToScalar(-clipDataIn.fOrigin.fX),
SkIntToScalar(-clipDataIn.fOrigin.fY));
}
#if !VISUALIZE_COMPLEX_CLIP
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
#endif
int clipBit = stencilBuffer->bits();
SkASSERT((clipBit <= 16) &&
"Ganesh only handles 16b or smaller stencil buffers");
clipBit = (1 << (clipBit-1));
GrIRect devRTRect = GrIRect::MakeWH(rt->width(), rt->height());
bool clearToInside;
SkRegion::Op firstOp = SkRegion::kReplace_Op; // suppress warning
SkClipStack::Iter iter(*oldClipData->fClipStack,
SkClipStack::Iter::kBottom_IterStart);
const SkClipStack::Iter::Clip* clip = process_initial_clip_elements(&iter,
devRTRect,
&clearToInside,
&firstOp,
clipDataIn);
fGpu->clearStencilClip(devClipBounds, clearToInside);
bool first = true;
// walk through each clip element and perform its set op
// with the existing clip.
for ( ; NULL != clip; clip = iter.nextCombined()) {
GrPathFill fill;
bool fillInverted = false;
// enabled at bottom of loop
drawState->disableState(GrGpu::kModifyStencilClip_StateBit);
// if the target is MSAA then we want MSAA enabled when the clip is soft
if (rt->isMultisampled()) {
drawState->setState(GrDrawState::kHWAntialias_StateBit, clip->fDoAA);
}
// Can the clip element be drawn directly to the stencil buffer
// with a non-inverted fill rule without extra passes to
// resolve in/out status?
bool canRenderDirectToStencil = false;
SkRegion::Op op = clip->fOp;
if (first) {
first = false;
op = firstOp;
}
GrPathRenderer* pr = NULL;
//.........这里部分代码省略.........
示例3: createStencilClipMask
////////////////////////////////////////////////////////////////////////////////
// Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
// (as opposed to canvas) coordinates
bool GrClipMaskManager::createStencilClipMask(InitialState initialState,
const ElementList& elements,
const SkIRect& clipSpaceIBounds,
const SkIPoint& clipSpaceToStencilOffset) {
GrAssert(kNone_ClipMaskType == fCurrClipMaskType);
GrDrawState* drawState = fGpu->drawState();
GrAssert(drawState->isClipState());
GrRenderTarget* rt = drawState->getRenderTarget();
GrAssert(NULL != rt);
// TODO: dynamically attach a SB when needed.
GrStencilBuffer* stencilBuffer = rt->getStencilBuffer();
if (NULL == stencilBuffer) {
return false;
}
int32_t genID = elements.tail()->getGenID();
if (stencilBuffer->mustRenderClip(genID, clipSpaceIBounds, clipSpaceToStencilOffset)) {
stencilBuffer->setLastClip(genID, clipSpaceIBounds, clipSpaceToStencilOffset);
GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit);
drawState = fGpu->drawState();
drawState->setRenderTarget(rt);
// We set the current clip to the bounds so that our recursive draws are scissored to them.
SkIRect stencilSpaceIBounds(clipSpaceIBounds);
stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
GrDrawTarget::AutoClipRestore acr(fGpu, stencilSpaceIBounds);
drawState->enableState(GrDrawState::kClip_StateBit);
// Set the matrix so that rendered clip elements are transformed from clip to stencil space.
SkVector translate = {
SkIntToScalar(clipSpaceToStencilOffset.fX),
SkIntToScalar(clipSpaceToStencilOffset.fY)
};
drawState->viewMatrix()->setTranslate(translate);
#if !VISUALIZE_COMPLEX_CLIP
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
#endif
int clipBit = stencilBuffer->bits();
SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers");
clipBit = (1 << (clipBit-1));
fGpu->clearStencilClip(stencilSpaceIBounds, kAllIn_InitialState == initialState);
// walk through each clip element and perform its set op
// with the existing clip.
for (ElementList::Iter iter(elements.headIter()); NULL != iter.get(); iter.next()) {
const Element* element = iter.get();
bool fillInverted = false;
// enabled at bottom of loop
drawState->disableState(GrGpu::kModifyStencilClip_StateBit);
// if the target is MSAA then we want MSAA enabled when the clip is soft
if (rt->isMultisampled()) {
drawState->setState(GrDrawState::kHWAntialias_StateBit, element->isAA());
}
// This will be used to determine whether the clip shape can be rendered into the
// stencil with arbitrary stencil settings.
GrPathRenderer::StencilSupport stencilSupport;
SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
SkRegion::Op op = element->getOp();
GrPathRenderer* pr = NULL;
SkTCopyOnFirstWrite<SkPath> clipPath;
if (Element::kRect_Type == element->getType()) {
stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
fillInverted = false;
} else {
GrAssert(Element::kPath_Type == element->getType());
clipPath.init(element->getPath());
fillInverted = clipPath->isInverseFillType();
if (fillInverted) {
clipPath.writable()->toggleInverseFillType();
}
pr = this->getContext()->getPathRenderer(*clipPath,
stroke,
fGpu,
false,
GrPathRendererChain::kStencilOnly_DrawType,
&stencilSupport);
if (NULL == pr) {
return false;
}
}
int passes;
GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClipPasses];
//.........这里部分代码省略.........
示例4: createStencilClipMask
////////////////////////////////////////////////////////////////////////////////
// Create a 1-bit clip mask in the stencil buffer
bool GrClipMaskManager::createStencilClipMask(GrGpu* gpu,
const GrClip& clipIn,
const GrRect& bounds,
ScissoringSettings* scissorSettings) {
GrAssert(fClipMaskInStencil);
GrDrawState* drawState = gpu->drawState();
GrAssert(drawState->isClipState());
GrRenderTarget* rt = drawState->getRenderTarget();
GrAssert(NULL != rt);
// TODO: dynamically attach a SB when needed.
GrStencilBuffer* stencilBuffer = rt->getStencilBuffer();
if (NULL == stencilBuffer) {
return false;
}
if (stencilBuffer->mustRenderClip(clipIn, rt->width(), rt->height())) {
stencilBuffer->setLastClip(clipIn, 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
// we just stashed on the SB to render from. We set it back after
// we finish drawing it into the stencil.
const GrClip& clipCopy = stencilBuffer->getLastClip();
gpu->setClip(GrClip(bounds));
GrDrawTarget::AutoStateRestore asr(gpu, GrDrawTarget::kReset_ASRInit);
drawState = gpu->drawState();
drawState->setRenderTarget(rt);
GrDrawTarget::AutoGeometryPush agp(gpu);
gpu->disableScissor();
#if !VISUALIZE_COMPLEX_CLIP
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
#endif
int count = clipCopy.getElementCount();
int clipBit = stencilBuffer->bits();
SkASSERT((clipBit <= 16) &&
"Ganesh only handles 16b or smaller stencil buffers");
clipBit = (1 << (clipBit-1));
GrIRect rtRect = GrIRect::MakeWH(rt->width(), rt->height());
bool clearToInside;
SkRegion::Op startOp = SkRegion::kReplace_Op; // suppress warning
int start = process_initial_clip_elements(clipCopy,
rtRect,
&clearToInside,
&startOp);
gpu->clearStencilClip(scissorSettings->fScissorRect, clearToInside);
// walk through each clip element and perform its set op
// with the existing clip.
for (int c = start; c < count; ++c) {
GrPathFill fill;
bool fillInverted;
// enabled at bottom of loop
drawState->disableState(GrGpu::kModifyStencilClip_StateBit);
bool canRenderDirectToStencil; // can the clip element be drawn
// directly to the stencil buffer
// with a non-inverted fill rule
// without extra passes to
// resolve in/out status.
SkRegion::Op op = (c == start) ? startOp : clipCopy.getOp(c);
GrPathRenderer* pr = NULL;
const SkPath* clipPath = NULL;
if (kRect_ClipType == clipCopy.getElementType(c)) {
canRenderDirectToStencil = true;
fill = kEvenOdd_PathFill;
fillInverted = false;
// there is no point in intersecting a screen filling
// rectangle.
if (SkRegion::kIntersect_Op == op &&
contains(clipCopy.getRect(c), rtRect)) {
continue;
}
} else {
fill = clipCopy.getPathFill(c);
fillInverted = GrIsFillInverted(fill);
fill = GrNonInvertedFill(fill);
clipPath = &clipCopy.getPath(c);
pr = this->getClipPathRenderer(gpu, *clipPath, fill, false);
if (NULL == pr) {
fClipMaskInStencil = false;
gpu->setClip(clipCopy); // restore to the original
return false;
}
canRenderDirectToStencil =
!pr->requiresStencilPass(*clipPath, fill, gpu);
//.........这里部分代码省略.........
示例5: onDrawPath
bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
GrPathFill fill,
GrDrawTarget* target,
bool antiAlias) {
GrAssert(!antiAlias);
GrAssert(kHairLine_GrPathFill != fill);
GrDrawState* drawState = target->drawState();
GrAssert(drawState->getStencil().isDisabled());
SkAutoTUnref<GrPath> p(fGpu->createPath(path));
GrPathFill nonInvertedFill = GrNonInvertedFill(fill);
target->stencilPath(p, nonInvertedFill);
// TODO: Use built in cover operation rather than a rect draw. This will require making our
// fragment shaders be able to eat varyings generated by a matrix.
// fill the path, zero out the stencil
GrRect bounds = p->getBounds();
GrScalar bloat = drawState->getViewMatrix().getMaxStretch() * GR_ScalarHalf;
GrDrawState::AutoDeviceCoordDraw adcd;
if (nonInvertedFill == fill) {
GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
kZero_StencilOp,
kZero_StencilOp,
kNotEqual_StencilFunc,
0xffff,
0x0000,
0xffff);
*drawState->stencil() = kStencilPass;
} else {
GR_STATIC_CONST_SAME_STENCIL(kInvertedStencilPass,
kZero_StencilOp,
kZero_StencilOp,
// We know our rect will hit pixels outside the clip and the user bits will be 0
// outside the clip. So we can't just fill where the user bits are 0. We also need to
// check that the clip bit is set.
kEqualIfInClip_StencilFunc,
0xffff,
0x0000,
0xffff);
GrMatrix vmi;
bounds.setLTRB(0, 0,
GrIntToScalar(drawState->getRenderTarget()->width()),
GrIntToScalar(drawState->getRenderTarget()->height()));
// mapRect through persp matrix may not be correct
if (!drawState->getViewMatrix().hasPerspective() && drawState->getViewInverse(&vmi)) {
vmi.mapRect(&bounds);
// theoretically could set bloat = 0, instead leave it because of matrix inversion
// precision.
} else {
adcd.set(drawState);
bloat = 0;
}
*drawState->stencil() = kInvertedStencilPass;
}
bounds.outset(bloat, bloat);
target->drawSimpleRect(bounds, NULL);
target->drawState()->stencil()->setDisabled();
return true;
}
示例6: internalDrawPath
bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path,
const SkStrokeRec& origStroke,
GrDrawTarget* target,
bool stencilOnly) {
SkMatrix viewM = target->getDrawState().getViewMatrix();
SkTCopyOnFirstWrite<SkStrokeRec> stroke(origStroke);
SkScalar hairlineCoverage;
if (IsStrokeHairlineOrEquivalent(*stroke, target->getDrawState().getViewMatrix(),
&hairlineCoverage)) {
uint8_t newCoverage = SkScalarRoundToInt(hairlineCoverage *
target->getDrawState().getCoverage());
target->drawState()->setCoverage(newCoverage);
if (!stroke->isHairlineStyle()) {
stroke.writable()->setHairlineStyle();
}
}
SkScalar tol = SK_Scalar1;
tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds());
int vertexCnt;
int indexCnt;
GrPrimitiveType primType;
GrDrawTarget::AutoReleaseGeometry arg;
if (!this->createGeom(path,
*stroke,
tol,
target,
&primType,
&vertexCnt,
&indexCnt,
&arg)) {
return false;
}
SkASSERT(NULL != target);
GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit);
GrDrawState* drawState = target->drawState();
bool colorWritesWereDisabled = drawState->isColorWriteDisabled();
// face culling doesn't make sense here
SkASSERT(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());
int passCount = 0;
const GrStencilSettings* passes[3];
GrDrawState::DrawFace drawFace[3];
bool reverse = false;
bool lastPassIsBounds;
if (stroke->isHairlineStyle()) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
} else {
passes[0] = NULL;
}
lastPassIsBounds = false;
drawFace[0] = GrDrawState::kBoth_DrawFace;
} else {
if (single_pass_path(path, *stroke)) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
} else {
passes[0] = NULL;
}
drawFace[0] = GrDrawState::kBoth_DrawFace;
lastPassIsBounds = false;
} else {
switch (path.getFillType()) {
case SkPath::kInverseEvenOdd_FillType:
reverse = true;
// fallthrough
case SkPath::kEvenOdd_FillType:
passes[0] = &gEOStencilPass;
if (stencilOnly) {
passCount = 1;
lastPassIsBounds = false;
} else {
passCount = 2;
lastPassIsBounds = true;
if (reverse) {
passes[1] = &gInvEOColorPass;
} else {
passes[1] = &gEOColorPass;
}
}
drawFace[0] = drawFace[1] = GrDrawState::kBoth_DrawFace;
break;
case SkPath::kInverseWinding_FillType:
reverse = true;
// fallthrough
case SkPath::kWinding_FillType:
if (fSeparateStencil) {
if (fStencilWrapOps) {
passes[0] = &gWindStencilSeparateWithWrap;
} else {
//.........这里部分代码省略.........
示例7: internalDrawPath
bool GrDefaultPathRenderer::internalDrawPath(const SkPath& path,
GrPathFill fill,
GrDrawTarget* target,
bool stencilOnly) {
GrMatrix viewM = target->getDrawState().getViewMatrix();
GrScalar tol = GR_Scalar1;
tol = GrPathUtils::scaleToleranceToSrc(tol, viewM, path.getBounds());
int vertexCnt;
int indexCnt;
GrPrimitiveType primType;
GrDrawTarget::AutoReleaseGeometry arg;
if (!this->createGeom(path,
fill,
tol,
target,
&primType,
&vertexCnt,
&indexCnt,
&arg)) {
return false;
}
GrAssert(NULL != target);
GrDrawTarget::AutoStateRestore asr(target, GrDrawTarget::kPreserve_ASRInit);
GrDrawState* drawState = target->drawState();
bool colorWritesWereDisabled = drawState->isColorWriteDisabled();
// face culling doesn't make sense here
GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());
int passCount = 0;
const GrStencilSettings* passes[3];
GrDrawState::DrawFace drawFace[3];
bool reverse = false;
bool lastPassIsBounds;
if (kHairLine_GrPathFill == fill) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
} else {
passes[0] = NULL;
}
lastPassIsBounds = false;
drawFace[0] = GrDrawState::kBoth_DrawFace;
} else {
if (single_pass_path(path, fill)) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
} else {
passes[0] = NULL;
}
drawFace[0] = GrDrawState::kBoth_DrawFace;
lastPassIsBounds = false;
} else {
switch (fill) {
case kInverseEvenOdd_GrPathFill:
reverse = true;
// fallthrough
case kEvenOdd_GrPathFill:
passes[0] = &gEOStencilPass;
if (stencilOnly) {
passCount = 1;
lastPassIsBounds = false;
} else {
passCount = 2;
lastPassIsBounds = true;
if (reverse) {
passes[1] = &gInvEOColorPass;
} else {
passes[1] = &gEOColorPass;
}
}
drawFace[0] = drawFace[1] = GrDrawState::kBoth_DrawFace;
break;
case kInverseWinding_GrPathFill:
reverse = true;
// fallthrough
case kWinding_GrPathFill:
if (fSeparateStencil) {
if (fStencilWrapOps) {
passes[0] = &gWindStencilSeparateWithWrap;
} else {
passes[0] = &gWindStencilSeparateNoWrap;
}
passCount = 2;
drawFace[0] = GrDrawState::kBoth_DrawFace;
} else {
if (fStencilWrapOps) {
passes[0] = &gWindSingleStencilWithWrapInc;
passes[1] = &gWindSingleStencilWithWrapDec;
} else {
passes[0] = &gWindSingleStencilNoWrapInc;
passes[1] = &gWindSingleStencilNoWrapDec;
}
// which is cw and which is ccw is arbitrary.
drawFace[0] = GrDrawState::kCW_DrawFace;
//.........这里部分代码省略.........
示例8: onDrawPath
void GrDefaultPathRenderer::onDrawPath(GrDrawState::StageMask stageMask,
bool stencilOnly) {
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
// us to change the vertex layout after reserveVertexSpace(). We won't
// actually change the vertex data when the layout changes since all the
// stages reference the positions (rather than having separate tex coords)
// and we don't ever have per-vert colors. In practice our call sites
// won't change the stages in use inside a setPath / removePath pair. But
// it is a silly limitation of the GrDrawTarget design that should be fixed.
if (tol != fPreviousSrcTol ||
stageMask != fPreviousStages) {
if (!this->createGeom(tol, stageMask)) {
return;
}
}
GrAssert(NULL != fTarget);
GrDrawTarget::AutoStateRestore asr(fTarget);
bool colorWritesWereDisabled = drawState->isColorWriteDisabled();
// face culling doesn't make sense here
GrAssert(GrDrawState::kBoth_DrawFace == drawState->getDrawFace());
int passCount = 0;
const GrStencilSettings* passes[3];
GrDrawState::DrawFace drawFace[3];
bool reverse = false;
bool lastPassIsBounds;
if (kHairLine_PathFill == fFill) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
} else {
passes[0] = NULL;
}
lastPassIsBounds = false;
drawFace[0] = GrDrawState::kBoth_DrawFace;
} else {
if (single_pass_path(*fTarget, *fPath, fFill)) {
passCount = 1;
if (stencilOnly) {
passes[0] = &gDirectToStencil;
} else {
passes[0] = NULL;
}
drawFace[0] = GrDrawState::kBoth_DrawFace;
lastPassIsBounds = false;
} else {
switch (fFill) {
case kInverseEvenOdd_PathFill:
reverse = true;
// fallthrough
case kEvenOdd_PathFill:
passes[0] = &gEOStencilPass;
if (stencilOnly) {
passCount = 1;
lastPassIsBounds = false;
} else {
passCount = 2;
lastPassIsBounds = true;
if (reverse) {
passes[1] = &gInvEOColorPass;
} else {
passes[1] = &gEOColorPass;
}
}
drawFace[0] = drawFace[1] = GrDrawState::kBoth_DrawFace;
break;
case kInverseWinding_PathFill:
reverse = true;
// fallthrough
case kWinding_PathFill:
if (fSeparateStencil) {
if (fStencilWrapOps) {
passes[0] = &gWindStencilSeparateWithWrap;
} else {
passes[0] = &gWindStencilSeparateNoWrap;
}
passCount = 2;
drawFace[0] = GrDrawState::kBoth_DrawFace;
} else {
if (fStencilWrapOps) {
passes[0] = &gWindSingleStencilWithWrapInc;
passes[1] = &gWindSingleStencilWithWrapDec;
} else {
passes[0] = &gWindSingleStencilNoWrapInc;
passes[1] = &gWindSingleStencilNoWrapDec;
}
// which is cw and which is ccw is arbitrary.
drawFace[0] = GrDrawState::kCW_DrawFace;
drawFace[1] = GrDrawState::kCCW_DrawFace;
passCount = 3;
//.........这里部分代码省略.........