本文整理汇总了C++中GrRenderTarget::height方法的典型用法代码示例。如果您正苦于以下问题:C++ GrRenderTarget::height方法的具体用法?C++ GrRenderTarget::height怎么用?C++ GrRenderTarget::height使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类GrRenderTarget
的用法示例。
在下文中一共展示了GrRenderTarget::height方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: set_dynamic_scissor_state
void set_dynamic_scissor_state(GrVkGpu* gpu,
GrVkCommandBuffer* cmdBuffer,
const GrPipeline& pipeline,
const GrRenderTarget& target) {
// We always use one scissor and if it is disabled we just make it the size of the RT
const GrScissorState& scissorState = pipeline.getScissorState();
VkRect2D scissor;
if (scissorState.enabled() &&
!scissorState.rect().contains(0, 0, target.width(), target.height())) {
// This all assumes the scissorState has previously been clipped to the device space render
// target.
scissor.offset.x = scissorState.rect().fLeft;
scissor.extent.width = scissorState.rect().width();
if (kTopLeft_GrSurfaceOrigin == target.origin()) {
scissor.offset.y = scissorState.rect().fTop;
} else {
SkASSERT(kBottomLeft_GrSurfaceOrigin == target.origin());
scissor.offset.y = target.height() - scissorState.rect().fBottom;
}
scissor.extent.height = scissorState.rect().height();
SkASSERT(scissor.offset.x >= 0);
SkASSERT(scissor.offset.x + scissor.extent.width <= (uint32_t)target.width());
SkASSERT(scissor.offset.y >= 0);
SkASSERT(scissor.offset.y + scissor.extent.height <= (uint32_t)target.height());
} else {
scissor.extent.width = target.width();
scissor.extent.height = target.height();
scissor.offset.x = 0;
scissor.offset.y = 0;
}
cmdBuffer->setScissor(gpu, 0, 1, &scissor);
}
示例2: setRenderTargetState
void GrGLProgram::setRenderTargetState(const GrPrimitiveProcessor& primProc,
const GrRenderTargetProxy* proxy) {
GrRenderTarget* rt = proxy->priv().peekRenderTarget();
// Load the RT height uniform if it is needed to y-flip gl_FragCoord.
if (fBuiltinUniformHandles.fRTHeightUni.isValid() &&
fRenderTargetState.fRenderTargetSize.fHeight != rt->height()) {
fProgramDataManager.set1f(fBuiltinUniformHandles.fRTHeightUni, SkIntToScalar(rt->height()));
}
// set RT adjustment
SkISize size;
size.set(rt->width(), rt->height());
if (!primProc.isPathRendering()) {
if (fRenderTargetState.fRenderTargetOrigin != proxy->origin() ||
fRenderTargetState.fRenderTargetSize != size) {
fRenderTargetState.fRenderTargetSize = size;
fRenderTargetState.fRenderTargetOrigin = proxy->origin();
float rtAdjustmentVec[4];
fRenderTargetState.getRTAdjustmentVec(rtAdjustmentVec);
fProgramDataManager.set4fv(fBuiltinUniformHandles.fRTAdjustmentUni, 1, rtAdjustmentVec);
}
} else {
SkASSERT(fGpu->glCaps().shaderCaps()->pathRenderingSupport());
const GrPathProcessor& pathProc = primProc.cast<GrPathProcessor>();
fGpu->glPathRendering()->setProjectionMatrix(pathProc.viewMatrix(),
size, proxy->origin());
}
}
示例3: setupScissorClip
bool GrClipMaskManager::setupScissorClip(const GrPipelineBuilder& pipelineBuilder,
GrPipelineBuilder::AutoRestoreStencil* ars,
const SkIRect& clipScissor,
const SkRect* devBounds,
GrAppliedClip* out) {
if (kRespectClip_StencilClipMode == fClipMode) {
fClipMode = kIgnoreClip_StencilClipMode;
}
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
SkIRect devBoundsScissor;
const SkIRect* scissor = &clipScissor;
bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds;
if (doDevBoundsClip) {
devBounds->roundOut(&devBoundsScissor);
if (devBoundsScissor.intersect(clipScissor)) {
scissor = &devBoundsScissor;
}
}
if (scissor->contains(clipSpaceRTIBounds)) {
// This counts as wide open
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
if (clipSpaceRTIBounds.intersect(*scissor)) {
out->fScissorState.set(clipSpaceRTIBounds);
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
return false;
}
示例4: onDrawPath
bool GrAAHairLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
SkIRect devClipBounds;
GrRenderTarget* rt = args.fPipelineBuilder->getRenderTarget();
args.fPipelineBuilder->clip().getConservativeBounds(rt->width(), rt->height(), &devClipBounds);
SkAutoTUnref<GrDrawBatch> batch(create_hairline_batch(args.fColor, *args.fViewMatrix, *args.fPath,
*args.fStroke, devClipBounds));
args.fTarget->drawBatch(*args.fPipelineBuilder, batch);
return true;
}
示例5: onDrawPath
bool GrAAHairLinePathRenderer::onDrawPath(const DrawPathArgs& args) {
GR_AUDIT_TRAIL_AUTO_FRAME(args.fTarget->getAuditTrail(),"GrAAHairlinePathRenderer::onDrawPath");
SkIRect devClipBounds;
GrRenderTarget* rt = args.fPipelineBuilder->getRenderTarget();
args.fClip->getConservativeBounds(rt->width(), rt->height(), &devClipBounds);
SkAutoTUnref<GrDrawBatch> batch(create_hairline_batch(args.fColor, *args.fViewMatrix, *args.fPath,
*args.fStyle, devClipBounds));
args.fTarget->drawBatch(*args.fPipelineBuilder, *args.fClip, batch);
return true;
}
示例6: 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;
}
示例7: set_dynamic_viewport_state
void set_dynamic_viewport_state(GrVkGpu* gpu,
GrVkCommandBuffer* cmdBuffer,
const GrRenderTarget& target) {
// We always use one viewport the size of the RT
VkViewport viewport;
viewport.x = 0.0f;
viewport.y = 0.0f;
viewport.width = SkIntToScalar(target.width());
viewport.height = SkIntToScalar(target.height());
viewport.minDepth = 0.0f;
viewport.maxDepth = 1.0f;
cmdBuffer->setViewport(gpu, 0, 1, &viewport);
}
示例8: check_rendertarget
static void check_rendertarget(skiatest::Reporter* reporter,
const GrCaps& caps,
GrResourceProvider* provider,
GrRenderTargetProxy* rtProxy,
int numSamples,
SkBackingFit fit,
int expectedMaxWindowRects) {
REPORTER_ASSERT(reporter, rtProxy->maxWindowRectangles(caps) == expectedMaxWindowRects);
REPORTER_ASSERT(reporter, rtProxy->numStencilSamples() == numSamples);
GrSurfaceProxy::UniqueID idBefore = rtProxy->uniqueID();
bool preinstantiated = rtProxy->isInstantiated();
REPORTER_ASSERT(reporter, rtProxy->instantiate(provider));
GrRenderTarget* rt = rtProxy->peekRenderTarget();
REPORTER_ASSERT(reporter, rtProxy->uniqueID() == idBefore);
// Deferred resources should always have a different ID from their instantiated rendertarget
if (preinstantiated) {
REPORTER_ASSERT(reporter, rtProxy->uniqueID().asUInt() == rt->uniqueID().asUInt());
} else {
REPORTER_ASSERT(reporter, rtProxy->uniqueID().asUInt() != rt->uniqueID().asUInt());
}
if (SkBackingFit::kExact == fit) {
REPORTER_ASSERT(reporter, rt->width() == rtProxy->width());
REPORTER_ASSERT(reporter, rt->height() == rtProxy->height());
} else {
REPORTER_ASSERT(reporter, rt->width() >= rtProxy->width());
REPORTER_ASSERT(reporter, rt->height() >= rtProxy->height());
}
REPORTER_ASSERT(reporter, rt->config() == rtProxy->config());
REPORTER_ASSERT(reporter, rt->fsaaType() == rtProxy->fsaaType());
REPORTER_ASSERT(reporter, rt->numColorSamples() == rtProxy->numColorSamples());
REPORTER_ASSERT(reporter, rt->numStencilSamples() == rtProxy->numStencilSamples());
REPORTER_ASSERT(reporter, rt->surfacePriv().flags() == rtProxy->testingOnly_getFlags());
}
示例9: 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);
//.........这里部分代码省略.........
示例10: setupClipAndFlushState
bool GrGpu::setupClipAndFlushState(GrPrimitiveType type) {
const GrIRect* r = NULL;
GrIRect clipRect;
GrDrawState* drawState = this->drawState();
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, GrDrawTarget::kReset_ASRInit);
drawState = this->drawState();
drawState->setRenderTarget(rt);
AutoGeometryPush agp(this);
this->flushScissor(NULL);
#if !VISUALIZE_COMPLEX_CLIP
drawState->enableState(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;
if (kRect_ClipType == clip.getElementType(c)) {
canRenderDirectToStencil = true;
fill = kEvenOdd_PathFill;
fillInverted = false;
// there is no point in intersecting a screen filling
// rectangle.
//.........这里部分代码省略.........
示例11: 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::AutoStateRestore asr(fGpu, GrDrawTarget::kReset_ASRInit);
drawState = fGpu->drawState();
drawState->setRenderTarget(rt);
GrDrawTarget::AutoGeometryPush agp(fGpu);
// 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));
GrIRect devRTRect = GrIRect::MakeWH(rt->width(), rt->height());
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();
SkPath::FillType 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, 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;
SkStroke stroke;
stroke.setDoFill(true);
SkRegion::Op op = element->getOp();
GrPathRenderer* pr = NULL;
SkTCopyOnFirstWrite<SkPath> clipPath;
if (Element::kRect_Type == element->getType()) {
stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
fill = SkPath::kEvenOdd_FillType;
fillInverted = false;
} else {
GrAssert(Element::kPath_Type == element->getType());
clipPath.init(element->getPath());
fill = clipPath->getFillType();
fillInverted = clipPath->isInverseFillType();
if (fillInverted) {
clipPath.writable()->toggleInverseFillType();
fill = clipPath->getFillType();
}
pr = this->getContext()->getPathRenderer(*clipPath,
stroke,
fGpu,
false,
GrPathRendererChain::kStencilOnly_DrawType,
&stencilSupport);
//.........这里部分代码省略.........
示例12: setupClipping
////////////////////////////////////////////////////////////////////////////////
// sort out what kind of clip mask needs to be created: alpha, stencil,
// scissor, or entirely software
bool GrClipMaskManager::setupClipping(GrPipelineBuilder* pipelineBuilder,
GrPipelineBuilder::AutoRestoreFragmentProcessors* arfp,
GrPipelineBuilder::AutoRestoreStencil* ars,
GrScissorState* scissorState,
const SkRect* devBounds) {
fCurrClipMaskType = kNone_ClipMaskType;
if (kRespectClip_StencilClipMode == fClipMode) {
fClipMode = kIgnoreClip_StencilClipMode;
}
GrReducedClip::ElementList elements(16);
int32_t genID = 0;
GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialState;
SkIRect clipSpaceIBounds;
bool requiresAA = false;
GrRenderTarget* rt = pipelineBuilder->getRenderTarget();
// GrDrawTarget should have filtered this for us
SkASSERT(rt);
SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
const GrClip& clip = pipelineBuilder->clip();
if (clip.isWideOpen(clipSpaceRTIBounds)) {
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
// The clip mask manager always draws with a single IRect so we special case that logic here
// Image filters just use a rect, so we also special case that logic
switch (clip.clipType()) {
case GrClip::kWideOpen_ClipType:
SkFAIL("Should have caught this with clip.isWideOpen()");
return true;
case GrClip::kIRect_ClipType: {
SkIRect scissor = clip.irect();
if (scissor.intersect(clipSpaceRTIBounds)) {
scissorState->set(scissor);
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
return false;
}
case GrClip::kClipStack_ClipType: {
clipSpaceRTIBounds.offset(clip.origin());
GrReducedClip::ReduceClipStack(*clip.clipStack(),
clipSpaceRTIBounds,
&elements,
&genID,
&initialState,
&clipSpaceIBounds,
&requiresAA);
if (elements.isEmpty()) {
if (GrReducedClip::kAllIn_InitialState == initialState) {
if (clipSpaceIBounds == clipSpaceRTIBounds) {
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
} else {
return false;
}
}
}
break;
}
// An element count of 4 was chosen because of the common pattern in Blink of:
// isect RR
// diff RR
// isect convex_poly
// isect convex_poly
// when drawing rounded div borders. This could probably be tuned based on a
// configuration's relative costs of switching RTs to generate a mask vs
// longer shaders.
if (elements.count() <= 4) {
SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX),
SkIntToScalar(-clip.origin().fY)
};
if (elements.isEmpty() ||
(requiresAA && this->installClipEffects(pipelineBuilder, arfp, elements, clipToRTOffset,
devBounds))) {
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(-clip.origin());
if (NULL == devBounds ||
!SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
scissorState->set(scissorSpaceIBounds);
}
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
}
// If MSAA is enabled we can do everything in the stencil buffer.
if (0 == rt->numSamples() && requiresAA) {
GrTexture* result = NULL;
// The top-left of the mask corresponds to the top-left corner of the bounds.
SkVector clipToMaskOffset = {
//.........这里部分代码省略.........
示例13: drawBatch
void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder,
const GrClip& clip,
GrDrawBatch* batch) {
// Setup clip
GrAppliedClip appliedClip;
if (!clip.apply(fClipMaskManager, pipelineBuilder, &batch->bounds(), &appliedClip)) {
return;
}
GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps;
if (appliedClip.clipCoverageFragmentProcessor()) {
arfps.set(&pipelineBuilder);
arfps.addCoverageFragmentProcessor(appliedClip.clipCoverageFragmentProcessor());
}
GrPipeline::CreateArgs args;
args.fPipelineBuilder = &pipelineBuilder;
args.fCaps = this->caps();
args.fScissor = &appliedClip.scissorState();
args.fHasStencilClip = appliedClip.hasStencilClip();
if (pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip()) {
if (!fResourceProvider->attachStencilAttachment(pipelineBuilder.getRenderTarget())) {
SkDebugf("ERROR creating stencil attachment. Draw skipped.\n");
return;
}
}
batch->getPipelineOptimizations(&args.fOpts);
GrScissorState finalScissor;
if (args.fOpts.fOverrides.fUsePLSDstRead || fClipBatchToBounds) {
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
GrGLIRect viewport;
viewport.fLeft = 0;
viewport.fBottom = 0;
viewport.fWidth = rt->width();
viewport.fHeight = rt->height();
SkIRect ibounds;
ibounds.fLeft = SkTPin(SkScalarFloorToInt(batch->bounds().fLeft), viewport.fLeft,
viewport.fWidth);
ibounds.fTop = SkTPin(SkScalarFloorToInt(batch->bounds().fTop), viewport.fBottom,
viewport.fHeight);
ibounds.fRight = SkTPin(SkScalarCeilToInt(batch->bounds().fRight), viewport.fLeft,
viewport.fWidth);
ibounds.fBottom = SkTPin(SkScalarCeilToInt(batch->bounds().fBottom), viewport.fBottom,
viewport.fHeight);
if (appliedClip.scissorState().enabled()) {
const SkIRect& scissorRect = appliedClip.scissorState().rect();
if (!ibounds.intersect(scissorRect)) {
return;
}
}
finalScissor.set(ibounds);
args.fScissor = &finalScissor;
}
args.fOpts.fColorPOI.completeCalculations(pipelineBuilder.fColorFragmentProcessors.begin(),
pipelineBuilder.numColorFragmentProcessors());
args.fOpts.fCoveragePOI.completeCalculations(
pipelineBuilder.fCoverageFragmentProcessors.begin(),
pipelineBuilder.numCoverageFragmentProcessors());
if (!this->setupDstReadIfNecessary(pipelineBuilder, clip, args.fOpts, &args.fDstTexture,
batch->bounds())) {
return;
}
if (!batch->installPipeline(args)) {
return;
}
#ifdef ENABLE_MDB
SkASSERT(fRenderTarget);
batch->pipeline()->addDependenciesTo(fRenderTarget);
#endif
this->recordBatch(batch);
}
示例14: 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;
}
示例15: setupClipping
////////////////////////////////////////////////////////////////////////////////
// sort out what kind of clip mask needs to be created: alpha, stencil,
// scissor, or entirely software
bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
GrPipelineBuilder::AutoRestoreStencil* ars,
GrScissorState* scissorState,
const SkRect* devBounds,
GrAppliedClip* out) {
if (kRespectClip_StencilClipMode == fClipMode) {
fClipMode = kIgnoreClip_StencilClipMode;
}
GrReducedClip::ElementList elements(16);
int32_t genID = 0;
GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialState;
SkIRect clipSpaceIBounds;
bool requiresAA = false;
GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
// GrDrawTarget should have filtered this for us
SkASSERT(rt);
SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
const GrClip& clip = pipelineBuilder.clip();
if (clip.isWideOpen(clipSpaceRTIBounds)) {
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
// The clip mask manager always draws with a single IRect so we special case that logic here
// Image filters just use a rect, so we also special case that logic
switch (clip.clipType()) {
case GrClip::kWideOpen_ClipType:
SkFAIL("Should have caught this with clip.isWideOpen()");
return true;
case GrClip::kIRect_ClipType: {
SkIRect scissor = clip.irect();
if (scissor.intersect(clipSpaceRTIBounds)) {
scissorState->set(scissor);
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
return false;
}
case GrClip::kClipStack_ClipType: {
clipSpaceRTIBounds.offset(clip.origin());
GrReducedClip::ReduceClipStack(*clip.clipStack(),
clipSpaceRTIBounds,
&elements,
&genID,
&initialState,
&clipSpaceIBounds,
&requiresAA);
if (elements.isEmpty()) {
if (GrReducedClip::kAllIn_InitialState == initialState) {
if (clipSpaceIBounds == clipSpaceRTIBounds) {
this->setPipelineBuilderStencil(pipelineBuilder, ars);
return true;
}
} else {
return false;
}
}
} break;
}
// An element count of 4 was chosen because of the common pattern in Blink of:
// isect RR
// diff RR
// isect convex_poly
// isect convex_poly
// when drawing rounded div borders. This could probably be tuned based on a
// configuration's relative costs of switching RTs to generate a mask vs
// longer shaders.
if (elements.count() <= kMaxAnalyticElements) {
SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX),
SkIntToScalar(-clip.origin().fY) };
// When there are multiple color samples we want to do per-sample clipping, not compute
// a fractional pixel coverage.
bool disallowAnalyticAA = pipelineBuilder.getRenderTarget()->isUnifiedMultisampled();
const GrFragmentProcessor* clipFP = nullptr;
if (elements.isEmpty() ||
(requiresAA && !disallowAnalyticAA &&
SkToBool(clipFP = this->getAnalyticClipProcessor(elements, clipToRTOffset, devBounds)))) {
SkIRect scissorSpaceIBounds(clipSpaceIBounds);
scissorSpaceIBounds.offset(-clip.origin());
if (nullptr == devBounds ||
!SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
scissorState->set(scissorSpaceIBounds);
}
this->setPipelineBuilderStencil(pipelineBuilder, ars);
out->fClipCoverageFP.reset(clipFP);
return true;
}
}
// If MSAA is enabled we can do everything in the stencil buffer.
if (0 == rt->numStencilSamples() && requiresAA) {
SkAutoTUnref<GrTexture> result;
//.........这里部分代码省略.........