本文整理汇总了C++中GrRect::roundOut方法的典型用法代码示例。如果您正苦于以下问题:C++ GrRect::roundOut方法的具体用法?C++ GrRect::roundOut怎么用?C++ GrRect::roundOut使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GrRect
的用法示例。
在下文中一共展示了GrRect::roundOut方法的11个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: fPaint
GrTextContext::GrTextContext(GrContext* context, const GrPaint& paint) : fPaint(paint) {
fContext = context;
fStrike = NULL;
fCurrTexture = NULL;
fCurrVertex = 0;
const GrClipData* clipData = context->getClip();
GrRect devConservativeBound;
clipData->fClipStack->getConservativeBounds(
-clipData->fOrigin.fX,
-clipData->fOrigin.fY,
context->getRenderTarget()->width(),
context->getRenderTarget()->height(),
&devConservativeBound);
devConservativeBound.roundOut(&fClipRect);
fAutoMatrix.setIdentity(fContext, &fPaint);
fDrawTarget = NULL;
fVertices = NULL;
fMaxVertices = 0;
fVertexLayout =
GrDrawTarget::kTextFormat_VertexLayoutBit |
GrDrawTarget::StageTexCoordVertexLayoutBit(kGlyphMaskStage, 0);
}
示例2: clipMaskPreamble
////////////////////////////////////////////////////////////////////////////////
// Shared preamble between gpu and SW-only AA clip mask creation paths.
// Handles caching, determination of clip mask bound & allocation (if needed)
// of the result texture
// Returns true if there is no more work to be done (i.e., we got a cache hit)
bool GrClipMaskManager::clipMaskPreamble(GrGpu* gpu,
const GrClip& clipIn,
GrTexture** result,
GrIRect *resultBounds) {
GrDrawState* origDrawState = gpu->drawState();
GrAssert(origDrawState->isClipState());
GrRenderTarget* rt = origDrawState->getRenderTarget();
GrAssert(NULL != rt);
GrRect rtRect;
rtRect.setLTRB(0, 0,
GrIntToScalar(rt->width()), GrIntToScalar(rt->height()));
// unlike the stencil path the alpha path is not bound to the size of the
// render target - determine the minimum size required for the mask
GrRect bounds;
if (clipIn.hasConservativeBounds()) {
bounds = clipIn.getConservativeBounds();
if (!bounds.intersect(rtRect)) {
// the mask will be empty in this case
GrAssert(false);
bounds.setEmpty();
}
} else {
// still locked to the size of the render target
bounds = rtRect;
}
GrIRect intBounds;
bounds.roundOut(&intBounds);
// need to outset a pixel since the standard bounding box computation
// path doesn't leave any room for antialiasing (esp. w.r.t. rects)
intBounds.outset(1, 1);
// TODO: make sure we don't outset if bounds are still 0,0 @ min
if (fAACache.canReuse(clipIn,
intBounds.width(),
intBounds.height())) {
*result = fAACache.getLastMask();
fAACache.getLastBound(resultBounds);
return true;
}
this->setupCache(clipIn, intBounds);
*resultBounds = intBounds;
return false;
}
示例3: getConservativeBounds
/**
* getConservativeBounds returns the conservative bounding box of the clip
* in device (as opposed to canvas) coordinates. If the bounding box is
* the result of purely intersections of rects (with an initial replace)
* isIntersectionOfRects will be set to true.
*/
void GrClipData::getConservativeBounds(const GrSurface* surface,
GrIRect* devResult,
bool* isIntersectionOfRects) const {
GrRect devBounds;
fClipStack->getConservativeBounds(-fOrigin.fX,
-fOrigin.fY,
surface->width(),
surface->height(),
&devBounds,
isIntersectionOfRects);
devBounds.roundOut(devResult);
}
示例4: 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
//.........这里部分代码省略.........
示例5: createAlphaClipMask
////////////////////////////////////////////////////////////////////////////////
// Create a 8-bit clip mask in alpha
GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t clipStackGenID,
InitialState initialState,
const ElementList& elements,
const SkIRect& clipSpaceIBounds) {
GrAssert(kNone_ClipMaskType == fCurrClipMaskType);
GrTexture* result;
if (this->getMaskTexture(clipStackGenID, clipSpaceIBounds, &result)) {
fCurrClipMaskType = kAlpha_ClipMaskType;
return result;
}
if (NULL == result) {
fAACache.reset();
return NULL;
}
GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRInit);
GrDrawState* drawState = fGpu->drawState();
// The top-left of the mask corresponds to the top-left corner of the bounds.
SkVector clipToMaskOffset = {
SkIntToScalar(-clipSpaceIBounds.fLeft),
SkIntToScalar(-clipSpaceIBounds.fTop)
};
// The texture may be larger than necessary, this rect represents the part of the texture
// we populate with a rasterization of the clip.
SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpaceIBounds.height());
// We're drawing a coverage mask and want coverage to be run through the blend function.
drawState->enableState(GrDrawState::kCoverageDrawing_StateBit);
// Set the matrix so that rendered clip elements are transformed to mask space from clip space.
drawState->viewMatrix()->setTranslate(clipToMaskOffset);
// The scratch texture that we are drawing into can be substantially larger than the mask. Only
// clear the part that we care about.
fGpu->clear(&maskSpaceIBounds,
kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000,
result->asRenderTarget());
// When we use the stencil in the below loop it is important to have this clip installed.
// The second pass that zeros the stencil buffer renders the rect maskSpaceIBounds so the first
// pass must not set values outside of this bounds or stencil values outside the rect won't be
// cleared.
GrDrawTarget::AutoClipRestore acr(fGpu, maskSpaceIBounds);
drawState->enableState(GrDrawState::kClip_StateBit);
GrAutoScratchTexture temp;
// walk through each clip element and perform its set op
for (ElementList::Iter iter = elements.headIter(); iter.get(); iter.next()) {
const Element* element = iter.get();
SkRegion::Op op = element->getOp();
bool invert = element->isInverseFilled();
if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) {
GrPathRenderer* pr = NULL;
bool useTemp = !this->canStencilAndDrawElement(result, element, &pr);
GrTexture* dst;
// This is the bounds of the clip element in the space of the alpha-mask. The temporary
// mask buffer can be substantially larger than the actually clip stack element. We
// touch the minimum number of pixels necessary and use decal mode to combine it with
// the accumulator.
GrIRect maskSpaceElementIBounds;
if (useTemp) {
if (invert) {
maskSpaceElementIBounds = maskSpaceIBounds;
} else {
GrRect elementBounds = element->getBounds();
elementBounds.offset(clipToMaskOffset);
elementBounds.roundOut(&maskSpaceElementIBounds);
}
this->getTemp(maskSpaceIBounds.fRight, maskSpaceIBounds.fBottom, &temp);
if (NULL == temp.texture()) {
fAACache.reset();
return NULL;
}
dst = temp.texture();
// clear the temp target and set blend to replace
fGpu->clear(&maskSpaceElementIBounds,
invert ? 0xffffffff : 0x00000000,
dst->asRenderTarget());
setup_boolean_blendcoeffs(drawState, SkRegion::kReplace_Op);
} else {
// draw directly into the result with the stencil set to make the pixels affected
// by the clip shape be non-zero.
dst = result;
GR_STATIC_CONST_SAME_STENCIL(kStencilInElement,
kReplace_StencilOp,
kReplace_StencilOp,
kAlways_StencilFunc,
0xffff,
0xffff,
0xffff);
drawState->setStencil(kStencilInElement);
//.........这里部分代码省略.........
示例6: createAlphaClipMask
////////////////////////////////////////////////////////////////////////////////
// Create a 8-bit clip mask in alpha
bool GrClipMaskManager::createAlphaClipMask(const GrClipData& clipDataIn,
GrTexture** result,
GrIRect *devResultBounds) {
GrAssert(NULL != devResultBounds);
GrAssert(kNone_ClipMaskType == fCurrClipMaskType);
if (this->clipMaskPreamble(clipDataIn, result, devResultBounds)) {
fCurrClipMaskType = kAlpha_ClipMaskType;
return true;
}
// Note: 'resultBounds' is in device (as opposed to canvas) coordinates
GrTexture* accum = fAACache.getLastMask();
if (NULL == accum) {
fAACache.reset();
return false;
}
GrDrawTarget::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit);
GrDrawState* drawState = fGpu->drawState();
GrDrawTarget::AutoGeometryPush agp(fGpu);
// The mask we generate is translated so that its upper-left corner is at devResultBounds
// upper-left corner in device space.
GrIRect maskResultBounds = GrIRect::MakeWH(devResultBounds->width(), devResultBounds->height());
// Set the matrix so that rendered clip elements are transformed from the space of the clip
// stack to the alpha-mask. This accounts for both translation due to the clip-origin and the
// placement of the mask within the device.
SkVector clipToMaskOffset = {
SkIntToScalar(-devResultBounds->fLeft - clipDataIn.fOrigin.fX),
SkIntToScalar(-devResultBounds->fTop - clipDataIn.fOrigin.fY)
};
drawState->viewMatrix()->setTranslate(clipToMaskOffset);
bool clearToInside;
SkRegion::Op firstOp = SkRegion::kReplace_Op; // suppress warning
SkClipStack::Iter iter(*clipDataIn.fClipStack,
SkClipStack::Iter::kBottom_IterStart);
const SkClipStack::Iter::Clip* clip = process_initial_clip_elements(&iter,
*devResultBounds,
&clearToInside,
&firstOp,
clipDataIn);
// The scratch texture that we are drawing into can be substantially larger than the mask. Only
// clear the part that we care about.
fGpu->clear(&maskResultBounds,
clearToInside ? 0xffffffff : 0x00000000,
accum->asRenderTarget());
bool accumClearedToZero = !clearToInside;
GrAutoScratchTexture temp;
bool first = true;
// walk through each clip element and perform its set op
for ( ; NULL != clip; clip = iter.nextCombined()) {
SkRegion::Op op = clip->fOp;
if (first) {
first = false;
op = firstOp;
}
if (SkRegion::kReplace_Op == op) {
// clear the accumulator and draw the new object directly into it
if (!accumClearedToZero) {
fGpu->clear(&maskResultBounds, 0x00000000, accum->asRenderTarget());
}
setup_boolean_blendcoeffs(drawState, op);
this->drawClipShape(accum, clip, *devResultBounds);
} else if (SkRegion::kReverseDifference_Op == op ||
SkRegion::kIntersect_Op == op) {
// there is no point in intersecting a screen filling rectangle.
if (SkRegion::kIntersect_Op == op && NULL != clip->fRect &&
contains(*clip->fRect, *devResultBounds, clipDataIn.fOrigin)) {
continue;
}
getTemp(*devResultBounds, &temp);
if (NULL == temp.texture()) {
fAACache.reset();
return false;
}
// this is the bounds of the clip element in the space of the alpha-mask. The temporary
// mask buffer can be substantially larger than the actually clip stack element. We
// touch the minimum number of pixels necessary and use decal mode to combine it with
// the accumulator
GrRect elementMaskBounds = clip->getBounds();
elementMaskBounds.offset(clipToMaskOffset);
GrIRect elementMaskIBounds;
elementMaskBounds.roundOut(&elementMaskIBounds);
// clear the temp target & draw into it
//.........这里部分代码省略.........
示例7: 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 (create_mask_in_sw()) {
// 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;
}
}
#endif
#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 (clipIn.requiresAA() && 0 == rt->numSamples()) {
// 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
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() &&
!bounds.isEmpty();
if (fClipMaskInStencil) {
return this->createStencilClipMask(gpu, clipIn, bounds, scissorSettings);
}
return true;
}
示例8: createGeom
bool GrAAHairLinePathRenderer::createGeom(GrDrawTarget::StageBitfield stages) {
int rtHeight = fTarget->getRenderTarget()->height();
GrIRect clip;
if (fTarget->getClip().hasConservativeBounds()) {
GrRect clipRect = fTarget->getClip().getConservativeBounds();
clipRect.roundOut(&clip);
} else {
clip.setLargest();
}
// If none of the inputs that affect generation of path geometry have
// have changed since last previous path draw then we can reuse the
// previous geoemtry.
if (stages == fPreviousStages &&
fPreviousViewMatrix == fTarget->getViewMatrix() &&
fPreviousTranslate == fTranslate &&
rtHeight == fPreviousRTHeight &&
fClipRect == clip) {
return true;
}
GrVertexLayout layout = GrDrawTarget::kEdge_VertexLayoutBit;
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
if ((1 << s) & stages) {
layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(s);
}
}
GrMatrix viewM = fTarget->getViewMatrix();
PREALLOC_PTARRAY(128) lines;
PREALLOC_PTARRAY(128) quads;
IntArray qSubdivs;
fQuadCnt = generate_lines_and_quads(*fPath, viewM, fTranslate, clip,
&lines, &quads, &qSubdivs);
fLineSegmentCnt = lines.count() / 2;
int vertCnt = kVertsPerLineSeg * fLineSegmentCnt + kVertsPerQuad * fQuadCnt;
GrAssert(sizeof(Vertex) == GrDrawTarget::VertexSize(layout));
Vertex* verts;
if (!fTarget->reserveVertexSpace(layout, vertCnt, (void**)&verts)) {
return false;
}
Vertex* base = verts;
const GrMatrix* toDevice = NULL;
const GrMatrix* toSrc = NULL;
GrMatrix ivm;
if (viewM.hasPerspective()) {
if (viewM.invert(&ivm)) {
toDevice = &viewM;
toSrc = &ivm;
}
}
for (int i = 0; i < fLineSegmentCnt; ++i) {
add_line(&lines[2*i], rtHeight, toSrc, &verts);
}
int unsubdivQuadCnt = quads.count() / 3;
for (int i = 0; i < unsubdivQuadCnt; ++i) {
GrAssert(qSubdivs[i] >= 0);
add_quads(&quads[3*i], qSubdivs[i], toDevice, toSrc, &verts);
}
fPreviousStages = stages;
fPreviousViewMatrix = fTarget->getViewMatrix();
fPreviousRTHeight = rtHeight;
fClipRect = clip;
fPreviousTranslate = fTranslate;
return true;
}
示例9: setupClipAndFlushState
bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
const GrIRect* r = NULL;
GrIRect clipRect;
// we check this early because we need a valid
// render target to setup stencil clipping
// before even going into flushGraphicsState
if (NULL == fCurrDrawState.fRenderTarget) {
GrAssert(!"No render target bound.");
return false;
}
if (fCurrDrawState.fFlagBits & kClip_StateBit) {
GrRenderTarget& rt = *fCurrDrawState.fRenderTarget;
GrRect bounds;
GrRect rtRect;
rtRect.setLTRB(0, 0,
GrIntToScalar(rt.width()), GrIntToScalar(rt.height()));
if (fClip.hasConservativeBounds()) {
bounds = fClip.getConservativeBounds();
bounds.intersectWith(rtRect);
} else {
bounds = rtRect;
}
bounds.roundOut(&clipRect);
if (clipRect.isEmpty()) {
clipRect.setLTRB(0,0,0,0);
}
r = &clipRect;
fClipState.fClipInStencil = !fClip.isRect() &&
!fClip.isEmpty() &&
!bounds.isEmpty();
if (fClipState.fClipInStencil &&
(fClipState.fClipIsDirty ||
fClip != rt.fLastStencilClip)) {
rt.fLastStencilClip = fClip;
// 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
// in the rt to render
const GrClip& clip = rt.fLastStencilClip;
fClip.setFromRect(bounds);
AutoStateRestore asr(this);
AutoInternalDrawGeomRestore aidgr(this);
this->setViewMatrix(GrMatrix::I());
this->eraseStencilClip(clipRect);
this->flushScissor(NULL);
#if !VISUALIZE_COMPLEX_CLIP
this->enableState(kNoColorWrites_StateBit);
#else
this->disableState(kNoColorWrites_StateBit);
#endif
int count = clip.getElementCount();
int clipBit = rt.stencilBits();
clipBit = (1 << (clipBit-1));
// often we'll see the first two elements of the clip are
// the full rt size and another element intersected with it.
// We can skip the first full-size rect and save a big rect draw.
int firstElement = 0;
if (clip.getElementCount() > 1 &&
kRect_ClipType == clip.getElementType(0) &&
kIntersect_SetOp == clip.getOp(1)&&
clip.getRect(0).contains(bounds)) {
firstElement = 1;
}
// walk through each clip element and perform its set op
// with the existing clip.
for (int c = firstElement; c < count; ++c) {
GrPathFill fill;
// enabled at bottom of loop
this->disableState(kModifyStencilClip_StateBit);
bool canDrawDirectToClip;
if (kRect_ClipType == clip.getElementType(c)) {
canDrawDirectToClip = true;
fill = kEvenOdd_PathFill;
} else {
fill = clip.getPathFill(c);
GrPathRenderer* pr = this->getPathRenderer();
canDrawDirectToClip = pr->requiresStencilPass(this, clip.getPath(c), fill);
}
GrSetOp op = firstElement == c ? kReplace_SetOp : clip.getOp(c);
int passes;
GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClipPasses];
canDrawDirectToClip = GrStencilSettings::GetClipPasses(op, canDrawDirectToClip,
clipBit, IsFillInverted(fill),
&passes, stencilSettings);
// draw the element to the client stencil bits if necessary
if (!canDrawDirectToClip) {
//.........这里部分代码省略.........
示例10: createGeom
bool GrAAHairLinePathRenderer::createGeom(
const SkPath& path,
const GrVec* translate,
GrDrawTarget* target,
GrDrawState::StageMask stageMask,
int* lineCnt,
int* quadCnt,
GrDrawTarget::AutoReleaseGeometry* arg) {
const GrDrawState& drawState = target->getDrawState();
int rtHeight = drawState.getRenderTarget()->height();
GrIRect clip;
if (target->getClip().hasConservativeBounds()) {
GrRect clipRect = target->getClip().getConservativeBounds();
clipRect.roundOut(&clip);
} else {
clip.setLargest();
}
GrVertexLayout layout = GrDrawTarget::kEdge_VertexLayoutBit;
GrMatrix viewM = drawState.getViewMatrix();
PREALLOC_PTARRAY(128) lines;
PREALLOC_PTARRAY(128) quads;
IntArray qSubdivs;
static const GrVec gZeroVec = {0, 0};
if (NULL == translate) {
translate = &gZeroVec;
}
*quadCnt = generate_lines_and_quads(path, viewM, *translate, clip,
&lines, &quads, &qSubdivs);
*lineCnt = lines.count() / 2;
int vertCnt = kVertsPerLineSeg * *lineCnt + kVertsPerQuad * *quadCnt;
GrAssert(sizeof(Vertex) == GrDrawTarget::VertexSize(layout));
if (!arg->set(target, layout, vertCnt, 0)) {
return false;
}
Vertex* verts = reinterpret_cast<Vertex*>(arg->vertices());
const GrMatrix* toDevice = NULL;
const GrMatrix* toSrc = NULL;
GrMatrix ivm;
if (viewM.hasPerspective()) {
if (viewM.invert(&ivm)) {
toDevice = &viewM;
toSrc = &ivm;
}
}
for (int i = 0; i < *lineCnt; ++i) {
add_line(&lines[2*i], rtHeight, toSrc, &verts);
}
int unsubdivQuadCnt = quads.count() / 3;
for (int i = 0; i < unsubdivQuadCnt; ++i) {
GrAssert(qSubdivs[i] >= 0);
add_quads(&quads[3*i], qSubdivs[i], toDevice, toSrc, &verts);
}
return true;
}
示例11: 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() &&
//.........这里部分代码省略.........