本文整理汇总了C++中GrDrawState::getRenderTarget方法的典型用法代码示例。如果您正苦于以下问题:C++ GrDrawState::getRenderTarget方法的具体用法?C++ GrDrawState::getRenderTarget怎么用?C++ GrDrawState::getRenderTarget使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GrDrawState
的用法示例。
在下文中一共展示了GrDrawState::getRenderTarget方法的13个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: 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.next()) {
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()) {
if (clip->fDoAA) {
drawState->enableState(GrDrawState::kHWAntialias_StateBit);
} else {
drawState->disableState(GrDrawState::kHWAntialias_StateBit);
}
}
// 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;
//.........这里部分代码省略.........
示例2: drawPaths
void GrGLPathRendering::drawPaths(const GrPathRange* pathRange, const uint32_t indices[], int count,
const float transforms[], PathTransformType transformsType,
SkPath::FillType fill) {
SkASSERT(fGpu->caps()->pathRenderingSupport());
SkASSERT(NULL != fGpu->drawState()->getRenderTarget());
SkASSERT(NULL != fGpu->drawState()->getRenderTarget()->getStencilBuffer());
GrGLuint baseID = static_cast<const GrGLPathRange*>(pathRange)->basePathID();
this->flushPathStencilSettings(fill);
SkASSERT(!fHWPathStencilSettings.isTwoSided());
const SkStrokeRec& stroke = pathRange->getStroke();
SkPath::FillType nonInvertedFill =
SkPath::ConvertToNonInverseFillType(fill);
GrGLenum fillMode =
gr_stencil_op_to_gl_path_rendering_fill_mode(
fHWPathStencilSettings.passOp(GrStencilSettings::kFront_Face));
GrGLint writeMask =
fHWPathStencilSettings.writeMask(GrStencilSettings::kFront_Face);
if (nonInvertedFill == fill) {
if (stroke.needToApply()) {
if (SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
GL_CALL(StencilFillPathInstanced(
count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode,
writeMask, gXformType2GLType[transformsType],
transforms));
}
this->stencilThenCoverStrokePathInstanced(
count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff, writeMask,
GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
gXformType2GLType[transformsType], transforms);
} else {
this->stencilThenCoverFillPathInstanced(
count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode, writeMask,
GR_GL_BOUNDING_BOX_OF_BOUNDING_BOXES,
gXformType2GLType[transformsType], transforms);
}
} else {
if (stroke.isFillStyle() || SkStrokeRec::kStrokeAndFill_Style == stroke.getStyle()) {
GL_CALL(StencilFillPathInstanced(
count, GR_GL_UNSIGNED_INT, indices, baseID, fillMode,
writeMask, gXformType2GLType[transformsType],
transforms));
}
if (stroke.needToApply()) {
GL_CALL(StencilStrokePathInstanced(
count, GR_GL_UNSIGNED_INT, indices, baseID, 0xffff,
writeMask, gXformType2GLType[transformsType],
transforms));
}
GrDrawState* drawState = fGpu->drawState();
GrDrawState::AutoViewMatrixRestore avmr;
SkRect bounds = SkRect::MakeLTRB(0, 0,
SkIntToScalar(drawState->getRenderTarget()->width()),
SkIntToScalar(drawState->getRenderTarget()->height()));
SkMatrix vmi;
// 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.
SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
bounds.outset(bloat, bloat);
} else {
avmr.setIdentity(drawState);
}
fGpu->drawSimpleRect(bounds);
}
}
示例3: Build
//.........这里部分代码省略.........
} else if (defaultToUniformInputs && !requiresColorAttrib && inputColorIsUsed) {
header->fColorInput = kUniform_ColorInput;
} else {
header->fColorInput = kAttribute_ColorInput;
header->fRequiresVertexShader = true;
}
bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverageColor();
if ((covIsSolidWhite || !inputCoverageIsUsed) && !skipCoverage) {
header->fCoverageInput = kAllOnes_ColorInput;
} else if (defaultToUniformInputs && !requiresCoverageAttrib && inputCoverageIsUsed) {
header->fCoverageInput = kUniform_ColorInput;
} else {
header->fCoverageInput = kAttribute_ColorInput;
header->fRequiresVertexShader = true;
}
if (readsDst) {
SkASSERT(NULL != dstCopy || gpu->caps()->dstReadInShaderSupport());
const GrTexture* dstCopyTexture = NULL;
if (NULL != dstCopy) {
dstCopyTexture = dstCopy->texture();
}
header->fDstReadKey = GrGLFragmentShaderBuilder::KeyForDstRead(dstCopyTexture,
gpu->glCaps());
SkASSERT(0 != header->fDstReadKey);
} else {
header->fDstReadKey = 0;
}
if (readFragPosition) {
header->fFragPosKey = GrGLFragmentShaderBuilder::KeyForFragmentPosition(
drawState.getRenderTarget(), gpu->glCaps());
} else {
header->fFragPosKey = 0;
}
// Record attribute indices
header->fPositionAttributeIndex = drawState.positionAttributeIndex();
header->fLocalCoordAttributeIndex = drawState.localCoordAttributeIndex();
// For constant color and coverage we need an attribute with an index beyond those already set
int availableAttributeIndex = drawState.getVertexAttribCount();
if (requiresColorAttrib) {
header->fColorAttributeIndex = drawState.colorVertexAttributeIndex();
} else if (GrGLProgramDesc::kAttribute_ColorInput == header->fColorInput) {
SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
header->fColorAttributeIndex = availableAttributeIndex;
availableAttributeIndex++;
} else {
header->fColorAttributeIndex = -1;
}
if (requiresCoverageAttrib) {
header->fCoverageAttributeIndex = drawState.coverageVertexAttributeIndex();
} else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) {
SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
header->fCoverageAttributeIndex = availableAttributeIndex;
} else {
header->fCoverageAttributeIndex = -1;
}
// Here we deal with whether/how we handle color and coverage separately.
// Set this default and then possibly change our mind if there is coverage.
示例4: setupClipping
////////////////////////////////////////////////////////////////////////////////
// sort out what kind of clip mask needs to be created: alpha, stencil,
// scissor, or entirely software
bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn) {
fCurrClipMaskType = kNone_ClipMaskType;
GrDrawState* drawState = fGpu->drawState();
if (!drawState->isClipState() || clipDataIn->fClipStack->isWideOpen()) {
fGpu->disableScissor();
this->setGpuStencil();
return true;
}
GrRenderTarget* rt = drawState->getRenderTarget();
// GrDrawTarget should have filtered this for us
GrAssert(NULL != rt);
GrIRect devClipBounds;
bool isIntersectionOfRects = false;
clipDataIn->getConservativeBounds(rt, &devClipBounds,
&isIntersectionOfRects);
if (devClipBounds.isEmpty()) {
return false;
}
bool requiresAA = requires_AA(*clipDataIn->fClipStack);
#if GR_SW_CLIP
// If MSAA is enabled we can do everything in the stencil buffer.
// Otherwise check if we should just create the entire clip mask
// in software (this will only happen if the clip mask is anti-aliased
// and too complex for the gpu to handle in its entirety)
if (0 == rt->numSamples() &&
requiresAA &&
this->useSWOnlyPath(*clipDataIn->fClipStack)) {
// The clip geometry is complex enough that it will be more
// efficient to create it entirely in software
GrTexture* result = NULL;
GrIRect devBound;
if (this->createSoftwareClipMask(*clipDataIn, &result, &devBound)) {
setup_drawstate_aaclip(fGpu, result, devBound);
fGpu->disableScissor();
this->setGpuStencil();
return true;
}
// if SW clip mask creation fails fall through to the other
// two possible methods (bottoming out at stencil clipping)
}
#endif // GR_SW_CLIP
#if GR_AA_CLIP
// If MSAA is enabled use the (faster) stencil path for AA clipping
// otherwise the alpha clip mask is our only option
if (0 == rt->numSamples() && requiresAA) {
// Since we are going to create a destination texture of the correct
// size for the mask (rather than being bound by the size of the
// render target) we aren't going to use scissoring like the stencil
// path does (see scissorSettings below)
GrTexture* result = NULL;
GrIRect devBound;
if (this->createAlphaClipMask(*clipDataIn, &result, &devBound)) {
setup_drawstate_aaclip(fGpu, result, devBound);
fGpu->disableScissor();
this->setGpuStencil();
return true;
}
// if alpha clip mask creation fails fall through to the stencil
// buffer method
}
#endif // GR_AA_CLIP
// Either a hard (stencil buffer) clip was explicitly requested or
// an antialiased clip couldn't be created. In either case, free up
// the texture in the antialiased mask cache.
// TODO: this may require more investigation. Ganesh performs a lot of
// utility draws (e.g., clears, InOrderDrawBuffer playbacks) that hit
// the stencil buffer path. These may be "incorrectly" clearing the
// AA cache.
fAACache.reset();
// If the clip is a rectangle then just set the scissor. Otherwise, create
// a stencil mask.
if (isIntersectionOfRects) {
fGpu->enableScissor(devClipBounds);
this->setGpuStencil();
return true;
}
// use the stencil clip if we can't represent the clip as a rectangle.
bool useStencil = !clipDataIn->fClipStack->isWideOpen() &&
!devClipBounds.isEmpty();
if (useStencil) {
this->createStencilClipMask(*clipDataIn, devClipBounds);
}
// This must occur after createStencilClipMask. That function may change
// the scissor. Also, it only guarantees that the stencil mask is correct
//.........这里部分代码省略.........
示例5: Build
//.........这里部分代码省略.........
} else if (defaultToUniformInputs && !requiresColorAttrib) {
header->fColorInput = kUniform_ColorInput;
} else {
header->fColorInput = kAttribute_ColorInput;
header->fHasVertexCode = true;
}
bool covIsSolidWhite = !requiresCoverageAttrib && 0xffffffff == drawState.getCoverageColor();
if (skipCoverage) {
header->fCoverageInput = kTransBlack_ColorInput;
} else if (covIsSolidWhite || !inputCoverageIsUsed) {
header->fCoverageInput = kSolidWhite_ColorInput;
} else if (defaultToUniformInputs && !requiresCoverageAttrib) {
header->fCoverageInput = kUniform_ColorInput;
} else {
header->fCoverageInput = kAttribute_ColorInput;
header->fHasVertexCode = true;
}
if (readsDst) {
SkASSERT(NULL != dstCopy || gpu->caps()->dstReadInShaderSupport());
const GrTexture* dstCopyTexture = NULL;
if (NULL != dstCopy) {
dstCopyTexture = dstCopy->texture();
}
header->fDstReadKey = GrGLShaderBuilder::KeyForDstRead(dstCopyTexture, gpu->glCaps());
SkASSERT(0 != header->fDstReadKey);
} else {
header->fDstReadKey = 0;
}
if (readFragPosition) {
header->fFragPosKey = GrGLShaderBuilder::KeyForFragmentPosition(drawState.getRenderTarget(),
gpu->glCaps());
} else {
header->fFragPosKey = 0;
}
// Record attribute indices
header->fPositionAttributeIndex = drawState.positionAttributeIndex();
header->fLocalCoordAttributeIndex = drawState.localCoordAttributeIndex();
// For constant color and coverage we need an attribute with an index beyond those already set
int availableAttributeIndex = drawState.getVertexAttribCount();
if (requiresColorAttrib) {
header->fColorAttributeIndex = drawState.colorVertexAttributeIndex();
} else if (GrGLProgramDesc::kAttribute_ColorInput == header->fColorInput) {
SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
header->fColorAttributeIndex = availableAttributeIndex;
availableAttributeIndex++;
} else {
header->fColorAttributeIndex = -1;
}
if (requiresCoverageAttrib) {
header->fCoverageAttributeIndex = drawState.coverageVertexAttributeIndex();
} else if (GrGLProgramDesc::kAttribute_ColorInput == header->fCoverageInput) {
SkASSERT(availableAttributeIndex < GrDrawState::kMaxVertexAttribCnt);
header->fCoverageAttributeIndex = availableAttributeIndex;
} else {
header->fCoverageAttributeIndex = -1;
}
// Here we deal with whether/how we handle color and coverage separately.
示例6: onDrawPath
bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
const SkStroke& stroke,
GrDrawTarget* target,
bool antiAlias) {
GrAssert(!antiAlias);
GrAssert(0 != stroke.getWidthIfStroked());
GrDrawState* drawState = target->drawState();
GrAssert(drawState->getStencil().isDisabled());
SkAutoTUnref<GrPath> p(fGpu->createPath(path));
SkPath::FillType nonInvertedFill = SkPath::NonInverseFill(path.getFillType());
target->stencilPath(p, stroke, 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();
SkScalar bloat = drawState->getViewMatrix().getMaxStretch() * SK_ScalarHalf;
GrDrawState::AutoDeviceCoordDraw adcd;
if (nonInvertedFill == path.getFillType()) {
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);
SkMatrix vmi;
bounds.setLTRB(0, 0,
SkIntToScalar(drawState->getRenderTarget()->width()),
SkIntToScalar(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;
}
示例7: internalDrawPath
//.........这里部分代码省略.........
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;
drawFace[1] = GrDrawState::kCCW_DrawFace;
passCount = 3;
}
if (stencilOnly) {
lastPassIsBounds = false;
--passCount;
} else {
lastPassIsBounds = true;
drawFace[passCount-1] = GrDrawState::kBoth_DrawFace;
if (reverse) {
passes[passCount-1] = &gInvWindColorPass;
} else {
passes[passCount-1] = &gWindColorPass;
}
}
break;
default:
GrAssert(!"Unknown path fFill!");
return false;
}
}
}
{
for (int p = 0; p < passCount; ++p) {
drawState->setDrawFace(drawFace[p]);
if (NULL != passes[p]) {
*drawState->stencil() = *passes[p];
}
if (lastPassIsBounds && (p == passCount-1)) {
if (!colorWritesWereDisabled) {
drawState->disableState(GrDrawState::kNoColorWrites_StateBit);
}
GrRect bounds;
GrDrawState::AutoDeviceCoordDraw adcd;
if (reverse) {
GrAssert(NULL != drawState->getRenderTarget());
// draw over the whole world.
bounds.setLTRB(0, 0,
GrIntToScalar(drawState->getRenderTarget()->width()),
GrIntToScalar(drawState->getRenderTarget()->height()));
GrMatrix vmi;
// mapRect through persp matrix may not be correct
if (!drawState->getViewMatrix().hasPerspective() &&
drawState->getViewInverse(&vmi)) {
vmi.mapRect(&bounds);
} else {
adcd.set(drawState);
}
} else {
bounds = path.getBounds();
}
GrDrawTarget::AutoGeometryPush agp(target);
target->drawSimpleRect(bounds, NULL);
} else {
if (passCount > 1) {
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
}
if (indexCnt) {
target->drawIndexed(primType, 0, 0,
vertexCnt, indexCnt);
} else {
target->drawNonIndexed(primType, 0, vertexCnt);
}
}
}
}
return true;
}
示例8: 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
//.........这里部分代码省略.........
示例9: onDrawPath
bool GrStencilAndCoverPathRenderer::onDrawPath(const SkPath& path,
const SkStrokeRec& stroke,
GrDrawTarget* target,
bool antiAlias) {
SkASSERT(!antiAlias);
SkASSERT(!stroke.isHairlineStyle());
GrDrawState* drawState = target->drawState();
SkASSERT(drawState->getStencil().isDisabled());
SkAutoTUnref<GrPath> p(get_gr_path(fGpu, path, stroke));
if (path.isInverseFillType()) {
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);
drawState->setStencil(kInvertedStencilPass);
// fake inverse with a stencil and cover
target->stencilPath(p, convert_skpath_filltype(path.getFillType()));
GrDrawState::AutoViewMatrixRestore avmr;
SkRect bounds = SkRect::MakeLTRB(0, 0,
SkIntToScalar(drawState->getRenderTarget()->width()),
SkIntToScalar(drawState->getRenderTarget()->height()));
SkMatrix vmi;
// 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.
SkScalar bloat = drawState->getViewMatrix().getMaxScale() * SK_ScalarHalf;
bounds.outset(bloat, bloat);
} else {
avmr.setIdentity(drawState);
}
target->drawSimpleRect(bounds);
} else {
GR_STATIC_CONST_SAME_STENCIL(kStencilPass,
kZero_StencilOp,
kZero_StencilOp,
kNotEqual_StencilFunc,
0xffff,
0x0000,
0xffff);
drawState->setStencil(kStencilPass);
target->drawPath(p, convert_skpath_filltype(path.getFillType()));
}
target->drawState()->stencil()->setDisabled();
return true;
}
示例10: drawRect
void GrInOrderDrawBuffer::drawRect(const GrRect& rect,
const SkMatrix* matrix,
const GrRect* srcRects[],
const SkMatrix* srcMatrices[]) {
GrAssert(!(NULL == fQuadIndexBuffer && fCurrQuad));
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) {
bool appendToPreviousDraw = false;
GrVertexLayout layout = GetRectVertexLayout(srcRects);
// Batching across colors means we move the draw color into the
// rect's vertex colors to allow greater batching (a lot of rects
// in a row differing only in color is a common occurence in tables).
bool batchAcrossColors = true;
if (!this->getCaps().dualSourceBlendingSupport()) {
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
if (this->getDrawState().isStageEnabled(s)) {
// We disable batching across colors when there is a texture
// present because (by pushing the the color to the vertices)
// Ganesh loses track of the rect's opacity. This, in turn, can
// cause some of the blending optimizations to be disabled. This
// becomes a huge problem on some of the smaller devices where
// shader derivatives and dual source blending aren't supported.
// In those cases paths are often drawn to a texture and then
// drawn as a texture (using this method). Because dual source
// blending is disabled (and the blend optimizations are short
// circuited) some of the more esoteric blend modes can no longer
// be supported.
// TODO: add tracking of batchAcrossColors's opacity
batchAcrossColors = false;
break;
}
}
}
if (batchAcrossColors) {
layout |= GrDrawState::kColor_VertexLayoutBit;
}
AutoReleaseGeometry geo(this, layout, 4, 0);
if (!geo.succeeded()) {
GrPrintf("Failed to get space for vertices!\n");
return;
}
SkMatrix combinedMatrix = drawState->getViewMatrix();
// We go to device space so that matrix changes allow us to concat
// rect draws. When the caller has provided explicit source rects
// then we don't want to modify the stages' matrices. Otherwise
// we have to account for the view matrix change in the stage
// matrices.
uint32_t explicitCoordMask = 0;
if (srcRects) {
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
if (srcRects[s]) {
explicitCoordMask |= (1 << s);
}
}
}
GrDrawState::AutoDeviceCoordDraw adcd(this->drawState(), explicitCoordMask);
if (!adcd.succeeded()) {
return;
}
if (NULL != matrix) {
combinedMatrix.preConcat(*matrix);
}
SetRectVertices(rect, &combinedMatrix, srcRects, srcMatrices,
this->getDrawState().getColor(), layout, geo.vertices());
// Now that the paint's color is stored in the vertices set it to
// white so that the following code can batch all the rects regardless
// of paint color
GrDrawState::AutoColorRestore acr(this->drawState(),
batchAcrossColors ? SK_ColorWHITE
: this->getDrawState().getColor());
// we don't want to miss an opportunity to batch rects together
// simply because the clip has changed if the clip doesn't affect
// the rect.
bool disabledClip = false;
if (drawState->isClipState()) {
GrRect devClipRect;
bool isIntersectionOfRects = false;
const GrClipData* clip = this->getClip();
clip->fClipStack->getConservativeBounds(-clip->fOrigin.fX,
-clip->fOrigin.fY,
drawState->getRenderTarget()->width(),
drawState->getRenderTarget()->height(),
&devClipRect,
&isIntersectionOfRects);
//.........这里部分代码省略.........
示例11: onDrawPath
//.........这里部分代码省略.........
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;
}
if (stencilOnly) {
lastPassIsBounds = false;
--passCount;
} else {
lastPassIsBounds = true;
drawFace[passCount-1] = GrDrawState::kBoth_DrawFace;
if (reverse) {
passes[passCount-1] = &gInvWindColorPass;
} else {
passes[passCount-1] = &gWindColorPass;
}
}
break;
default:
GrAssert(!"Unknown path fFill!");
return;
}
}
}
{
for (int p = 0; p < passCount; ++p) {
drawState->setDrawFace(drawFace[p]);
if (NULL != passes[p]) {
*drawState->stencil() = *passes[p];
}
if (lastPassIsBounds && (p == passCount-1)) {
if (!colorWritesWereDisabled) {
drawState->disableState(GrDrawState::kNoColorWrites_StateBit);
}
GrRect bounds;
if (reverse) {
GrAssert(NULL != drawState->getRenderTarget());
// draw over the whole world.
bounds.setLTRB(0, 0,
GrIntToScalar(drawState->getRenderTarget()->width()),
GrIntToScalar(drawState->getRenderTarget()->height()));
GrMatrix vmi;
// mapRect through persp matrix may not be correct
if (!drawState->getViewMatrix().hasPerspective() &&
drawState->getViewInverse(&vmi)) {
vmi.mapRect(&bounds);
} else {
if (stageMask) {
if (!drawState->getViewInverse(&vmi)) {
GrPrintf("Could not invert matrix.");
return;
}
drawState->preConcatSamplerMatrices(stageMask, vmi);
}
drawState->setViewMatrix(GrMatrix::I());
}
} else {
bounds = fPath->getBounds();
bounds.offset(fTranslate);
}
GrDrawTarget::AutoGeometryPush agp(fTarget);
fTarget->drawSimpleRect(bounds, NULL, stageMask);
} else {
if (passCount > 1) {
drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
}
if (fUseIndexedDraw) {
fTarget->drawIndexed(fPrimitiveType, 0, 0,
fVertexCnt, fIndexCnt);
} else {
int baseVertex = 0;
for (int sp = 0; sp < fSubpathCount; ++sp) {
fTarget->drawNonIndexed(fPrimitiveType, baseVertex,
fSubpathVertCount[sp]);
baseVertex += fSubpathVertCount[sp];
}
}
}
}
}
}
示例12: 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->getContext()->getPathRenderer(*clipPath,
fill, gpu, false,
true);
if (NULL == pr) {
fClipMaskInStencil = false;
gpu->setClip(clipCopy); // restore to the original
return false;
}
//.........这里部分代码省略.........
示例13: createClipMask
////////////////////////////////////////////////////////////////////////////////
// sort out what kind of clip mask needs to be created: alpha, stencil,
// scissor, or entirely software
bool GrClipMaskManager::createClipMask(GrGpu* gpu,
const GrClip& clipIn,
ScissoringSettings* scissorSettings) {
GrAssert(scissorSettings);
scissorSettings->fEnableScissoring = false;
fClipMaskInStencil = false;
fClipMaskInAlpha = false;
GrDrawState* drawState = gpu->drawState();
if (!drawState->isClipState()) {
return true;
}
GrRenderTarget* rt = drawState->getRenderTarget();
// GrDrawTarget should have filtered this for us
GrAssert(NULL != rt);
#if GR_SW_CLIP
// If MSAA is enabled we can do everything in the stencil buffer.
// Otherwise check if we should just create the entire clip mask
// in software (this will only happen if the clip mask is anti-aliased
// and too complex for the gpu to handle in its entirety)
if (0 == rt->numSamples() && useSWOnlyPath(gpu, clipIn)) {
// The clip geometry is complex enough that it will be more
// efficient to create it entirely in software
GrTexture* result = NULL;
GrIRect bound;
if (this->createSoftwareClipMask(gpu, clipIn, &result, &bound)) {
fClipMaskInAlpha = true;
setup_drawstate_aaclip(gpu, result, bound);
return true;
}
// if SW clip mask creation fails fall through to the other
// two possible methods (bottoming out at stencil clipping)
}
#endif // GR_SW_CLIP
#if GR_AA_CLIP
// If MSAA is enabled use the (faster) stencil path for AA clipping
// otherwise the alpha clip mask is our only option
if (0 == rt->numSamples() && clipIn.requiresAA()) {
// Since we are going to create a destination texture of the correct
// size for the mask (rather than being bound by the size of the
// render target) we aren't going to use scissoring like the stencil
// path does (see scissorSettings below)
GrTexture* result = NULL;
GrIRect bound;
if (this->createAlphaClipMask(gpu, clipIn, &result, &bound)) {
fClipMaskInAlpha = true;
setup_drawstate_aaclip(gpu, result, bound);
return true;
}
// if alpha clip mask creation fails fall through to the stencil
// buffer method
}
#endif // GR_AA_CLIP
// Either a hard (stencil buffer) clip was explicitly requested or
// an antialiased clip couldn't be created. In either case, free up
// the texture in the antialiased mask cache.
// TODO: this may require more investigation. Ganesh performs a lot of
// utility draws (e.g., clears, InOrderDrawBuffer playbacks) that hit
// the stencil buffer path. These may be "incorrectly" clearing the
// AA cache.
fAACache.reset();
GrRect bounds;
GrRect rtRect;
rtRect.setLTRB(0, 0,
GrIntToScalar(rt->width()), GrIntToScalar(rt->height()));
if (clipIn.hasConservativeBounds()) {
bounds = clipIn.getConservativeBounds();
if (!bounds.intersect(rtRect)) {
bounds.setEmpty();
}
} else {
bounds = rtRect;
}
bounds.roundOut(&scissorSettings->fScissorRect);
if (scissorSettings->fScissorRect.isEmpty()) {
scissorSettings->fScissorRect.setLTRB(0,0,0,0);
// TODO: I think we can do an early exit here - after refactoring try:
// set fEnableScissoring to true but leave fClipMaskInStencil false
// and return - everything is going to be scissored away anyway!
}
scissorSettings->fEnableScissoring = true;
// use the stencil clip if we can't represent the clip as a rectangle.
fClipMaskInStencil = !clipIn.isRect() && !clipIn.isEmpty() &&
//.........这里部分代码省略.........