diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/gpu/GrClip.cpp | 30 | ||||
-rw-r--r-- | src/gpu/GrClipStackClip.cpp | 90 | ||||
-rw-r--r-- | src/gpu/GrClipStackClip.h | 6 | ||||
-rw-r--r-- | src/gpu/GrDrawTarget.cpp | 60 | ||||
-rw-r--r-- | src/gpu/GrReducedClip.cpp | 13 | ||||
-rw-r--r-- | src/gpu/GrReducedClip.h | 24 |
6 files changed, 87 insertions, 136 deletions
diff --git a/src/gpu/GrClip.cpp b/src/gpu/GrClip.cpp index 3eccd801b5..ef9c9cdfa6 100644 --- a/src/gpu/GrClip.cpp +++ b/src/gpu/GrClip.cpp @@ -21,10 +21,7 @@ bool GrFixedClip::quickContains(const SkRect& rect) const { if (fHasStencilClip) { return false; } - if (!fScissorState.enabled()) { - return true; - } - return fScissorState.rect().contains(rect); + return !fScissorState.enabled() || GrClip::IsInsideClip(fScissorState.rect(), rect); } void GrFixedClip::getConservativeBounds(int width, int height, SkIRect* devResult, @@ -40,32 +37,25 @@ void GrFixedClip::getConservativeBounds(int width, int height, SkIRect* devResul } } -bool GrFixedClip::apply(GrContext*, - GrDrawContext* drawContext, - const SkRect* devBounds, - bool isHWAntiAlias, - bool hasUserStencilSettings, - GrAppliedClip* out) const { - SkASSERT(!fDeviceBounds.isLargest()); +bool GrFixedClip::apply(GrContext*, GrDrawContext* drawContext, bool isHWAntiAlias, + bool hasUserStencilSettings, GrAppliedClip* out) const { if (fScissorState.enabled()) { SkIRect tightScissor; if (!tightScissor.intersect(fScissorState.rect(), SkIRect::MakeWH(drawContext->width(), drawContext->height()))) { return false; } - if (devBounds && IsOutsideClip(tightScissor, *devBounds)) { + if (IsOutsideClip(tightScissor, out->clippedDrawBounds())) { return false; } - if (!devBounds || !IsInsideClip(fScissorState.rect(), *devBounds)) { - if (fHasStencilClip) { - out->makeScissoredStencil(tightScissor, &fDeviceBounds); - } else { - out->makeScissored(tightScissor); - } - return true; + if (!IsInsideClip(fScissorState.rect(), out->clippedDrawBounds())) { + out->addScissor(tightScissor); } } - out->makeStencil(fHasStencilClip, fDeviceBounds); + if (fHasStencilClip) { + out->addStencilClip(); + } + return true; } diff --git a/src/gpu/GrClipStackClip.cpp b/src/gpu/GrClipStackClip.cpp index e117144eb9..6cb216ee0c 100644 --- a/src/gpu/GrClipStackClip.cpp +++ b/src/gpu/GrClipStackClip.cpp @@ -242,18 +242,14 @@ static bool get_analytic_clip_processor(const ElementList& elements, //////////////////////////////////////////////////////////////////////////////// // sort out what kind of clip mask needs to be created: alpha, stencil, // scissor, or entirely software -bool GrClipStackClip::apply(GrContext* context, - GrDrawContext* drawContext, - const SkRect* origDevBounds, - bool useHWAA, - bool hasUserStencilSettings, - GrAppliedClip* out) const { +bool GrClipStackClip::apply(GrContext* context, GrDrawContext* drawContext, bool useHWAA, + bool hasUserStencilSettings, GrAppliedClip* out) const { if (!fStack || fStack->isWideOpen()) { return true; } SkRect devBounds = SkRect::MakeIWH(drawContext->width(), drawContext->height()); - if (origDevBounds && !devBounds.intersect(*origDevBounds)) { + if (!devBounds.intersect(out->clippedDrawBounds())) { return false; } @@ -263,18 +259,19 @@ bool GrClipStackClip::apply(GrContext* context, SkRect clipSpaceDevBounds = devBounds.makeOffset(clipX, clipY); const GrReducedClip reducedClip(*fStack, clipSpaceDevBounds); + if (reducedClip.hasIBounds() && + !GrClip::IsInsideClip(reducedClip.ibounds(), clipSpaceDevBounds)) { + SkIRect scissorSpaceIBounds(reducedClip.ibounds()); + scissorSpaceIBounds.offset(-fOrigin); + out->addScissor(scissorSpaceIBounds); + } + if (reducedClip.elements().isEmpty()) { - if (GrReducedClip::InitialState::kAllOut == reducedClip.initialState()) { - return false; - } - if (!GrClip::IsInsideClip(reducedClip.iBounds(), clipSpaceDevBounds)) { - SkIRect scissorSpaceIBounds(reducedClip.iBounds()); - scissorSpaceIBounds.offset(-fOrigin); - out->makeScissored(scissorSpaceIBounds); - } - return true; + return InitialState::kAllIn == reducedClip.initialState(); } + SkASSERT(reducedClip.hasIBounds()); + // An element count of 4 was chosen because of the common pattern in Blink of: // isect RR // diff RR @@ -297,13 +294,7 @@ bool GrClipStackClip::apply(GrContext* context, if (reducedClip.requiresAA() && get_analytic_clip_processor(reducedClip.elements(), disallowAnalyticAA, {-clipX, -clipY}, devBounds, &clipFP)) { - SkIRect scissorSpaceIBounds(reducedClip.iBounds()); - scissorSpaceIBounds.offset(-fOrigin); - if (GrClip::IsInsideClip(scissorSpaceIBounds, devBounds)) { - out->makeFPBased(std::move(clipFP), SkRect::Make(scissorSpaceIBounds)); - } else { - out->makeScissoredFPBased(std::move(clipFP), scissorSpaceIBounds); - } + out->addCoverageFP(std::move(clipFP)); return true; } } @@ -333,10 +324,9 @@ bool GrClipStackClip::apply(GrContext* context, if (result) { // The mask's top left coord should be pinned to the rounded-out top left corner of // clipSpace bounds. We determine the mask's position WRT to the render target here. - SkIRect rtSpaceMaskBounds = reducedClip.iBounds(); + SkIRect rtSpaceMaskBounds = reducedClip.ibounds(); rtSpaceMaskBounds.offset(-fOrigin); - out->makeFPBased(create_fp_for_mask(result.get(), rtSpaceMaskBounds), - SkRect::Make(rtSpaceMaskBounds)); + out->addCoverageFP(create_fp_for_mask(result.get(), rtSpaceMaskBounds)); return true; } // if alpha clip mask creation fails fall through to the non-AA code paths @@ -345,17 +335,7 @@ bool GrClipStackClip::apply(GrContext* context, // use the stencil clip if we can't represent the clip as a rectangle. SkIPoint clipSpaceToStencilSpaceOffset = -fOrigin; CreateStencilClipMask(context, drawContext, reducedClip, clipSpaceToStencilSpaceOffset); - - // This must occur after createStencilClipMask. That function may change the scissor. Also, it - // only guarantees that the stencil mask is correct within the bounds it was passed, so we must - // use both stencil and scissor test to the bounds for the final draw. - if (GrClip::IsInsideClip(reducedClip.iBounds(), clipSpaceDevBounds)) { - out->makeStencil(true, devBounds); - } else { - SkIRect scissorSpaceIBounds(reducedClip.iBounds()); - scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); - out->makeScissoredStencil(scissorSpaceIBounds); - } + out->addStencilClip(); return true; } @@ -438,7 +418,7 @@ sk_sp<GrTexture> GrClipStackClip::CreateAlphaClipMask(GrContext* context, const SkVector& clipToMaskOffset) { GrResourceProvider* resourceProvider = context->resourceProvider(); GrUniqueKey key; - GetClipMaskKey(reducedClip.genID(), reducedClip.iBounds(), &key); + GetClipMaskKey(reducedClip.genID(), reducedClip.ibounds(), &key); if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key)) { return sk_sp<GrTexture>(texture); } @@ -463,9 +443,7 @@ sk_sp<GrTexture> GrClipStackClip::CreateAlphaClipMask(GrContext* context, // The scratch texture that we are drawing into can be substantially larger than the mask. Only // clear the part that we care about. - dc->clear(&maskSpaceIBounds, - GrReducedClip::InitialState::kAllIn == reducedClip.initialState() ? -1 : 0, - true); + dc->clear(&maskSpaceIBounds, InitialState::kAllIn == reducedClip.initialState() ? -1 : 0, true); // Set the matrix so that rendered clip elements are transformed to mask space from clip // space. @@ -513,7 +491,7 @@ sk_sp<GrTexture> GrClipStackClip::CreateAlphaClipMask(GrContext* context, if (!dc->drawContextPriv().drawAndStencilRect(clip, &kDrawOutsideElement, op, !invert, false, translate, - SkRect::Make(reducedClip.iBounds()))) { + SkRect::Make(reducedClip.ibounds()))) { return nullptr; } } else { @@ -548,9 +526,9 @@ bool GrClipStackClip::CreateStencilClipMask(GrContext* context, } // TODO: these need to be swapped over to using a StencilAttachmentProxy - if (stencilAttachment->mustRenderClip(reducedClip.genID(), reducedClip.iBounds(), + if (stencilAttachment->mustRenderClip(reducedClip.genID(), reducedClip.ibounds(), clipSpaceToStencilOffset)) { - stencilAttachment->setLastClip(reducedClip.genID(), reducedClip.iBounds(), + stencilAttachment->setLastClip(reducedClip.genID(), reducedClip.ibounds(), clipSpaceToStencilOffset); // Set the matrix so that rendered clip elements are transformed from clip to stencil space. SkVector translate = { @@ -561,11 +539,11 @@ bool GrClipStackClip::CreateStencilClipMask(GrContext* context, viewMatrix.setTranslate(translate); // We set the current clip to the bounds so that our recursive draws are scissored to them. - SkIRect stencilSpaceIBounds(reducedClip.iBounds()); + SkIRect stencilSpaceIBounds(reducedClip.ibounds()); stencilSpaceIBounds.offset(clipSpaceToStencilOffset); GrFixedClip clip(stencilSpaceIBounds); - bool insideClip = GrReducedClip::InitialState::kAllIn == reducedClip.initialState(); + bool insideClip = InitialState::kAllIn == reducedClip.initialState(); drawContext->drawContextPriv().clearStencilClip(stencilSpaceIBounds, insideClip); // walk through each clip element and perform its set op @@ -671,22 +649,19 @@ bool GrClipStackClip::CreateStencilClipMask(GrContext* context, } } + // Just enable stencil clip. The passes choose whether or not they will actually use it. + clip.enableStencilClip(); + // now we modify the clip bit by rendering either the clip // element directly or a bounding rect of the entire clip. for (GrUserStencilSettings const* const* pass = stencilPasses; *pass; ++pass) { - if (drawDirectToClip) { if (Element::kRect_Type == element->getType()) { - clip.enableStencilClip(element->getRect().makeOffset(translate.fX, - translate.fY)); drawContext->drawContextPriv().stencilRect(clip, *pass, useHWAA, viewMatrix, element->getRect()); } else { GrShape shape(clipPath, GrStyle::SimpleFill()); GrPaint paint; - SkRect bounds = clipPath.getBounds(); - bounds.offset(translate.fX, translate.fY); - clip.enableStencilClip(bounds); paint.setXPFactory(GrDisableColorXPFactory::Make()); paint.setAntiAlias(element->isAA()); GrPathRenderer::DrawPathArgs args; @@ -704,11 +679,8 @@ bool GrClipStackClip::CreateStencilClipMask(GrContext* context, } else { // The view matrix is setup to do clip space -> stencil space translation, so // draw rect in clip space. - SkRect bounds = SkRect::Make(reducedClip.iBounds()); - bounds.offset(translate.fX, translate.fY); - clip.enableStencilClip(bounds); drawContext->drawContextPriv().stencilRect(clip, *pass, false, viewMatrix, - SkRect::Make(reducedClip.iBounds())); + SkRect::Make(reducedClip.ibounds())); } } } @@ -721,7 +693,7 @@ sk_sp<GrTexture> GrClipStackClip::CreateSoftwareClipMask(GrTextureProvider* texP const GrReducedClip& reducedClip, const SkVector& clipToMaskOffset) { GrUniqueKey key; - GetClipMaskKey(reducedClip.genID(), reducedClip.iBounds(), &key); + GetClipMaskKey(reducedClip.genID(), reducedClip.ibounds(), &key); if (GrTexture* texture = texProvider->findAndRefTextureByUniqueKey(key)) { return sk_sp<GrTexture>(texture); } @@ -738,7 +710,7 @@ sk_sp<GrTexture> GrClipStackClip::CreateSoftwareClipMask(GrTextureProvider* texP translate.setTranslate(clipToMaskOffset); helper.init(maskSpaceIBounds, &translate); - helper.clear(GrReducedClip::InitialState::kAllIn == reducedClip.initialState() ? 0xFF : 0x00); + helper.clear(InitialState::kAllIn == reducedClip.initialState() ? 0xFF : 0x00); for (ElementList::Iter iter(reducedClip.elements()); iter.get(); iter.next()) { const Element* element = iter.get(); @@ -750,7 +722,7 @@ sk_sp<GrTexture> GrClipStackClip::CreateSoftwareClipMask(GrTextureProvider* texP // but leave the pixels inside the geometry alone. For reverse difference we invert all // the pixels before clearing the ones outside the geometry. if (SkRegion::kReverseDifference_Op == op) { - SkRect temp = SkRect::Make(reducedClip.iBounds()); + SkRect temp = SkRect::Make(reducedClip.ibounds()); // invert the entire scene helper.drawRect(temp, SkRegion::kXOR_Op, false, 0xFF); } diff --git a/src/gpu/GrClipStackClip.h b/src/gpu/GrClipStackClip.h index aaa2f90e3a..98675e62ac 100644 --- a/src/gpu/GrClipStackClip.h +++ b/src/gpu/GrClipStackClip.h @@ -33,11 +33,7 @@ public: bool quickContains(const SkRect&) const final; void getConservativeBounds(int width, int height, SkIRect* devResult, bool* isIntersectionOfRects) const final; - bool apply(GrContext*, - GrDrawContext*, - const SkRect* devBounds, - bool useHWAA, - bool hasUserStencilSettings, + bool apply(GrContext*, GrDrawContext*, bool useHWAA, bool hasUserStencilSettings, GrAppliedClip* out) const final; private: diff --git a/src/gpu/GrDrawTarget.cpp b/src/gpu/GrDrawTarget.cpp index e143f90291..b4142eb40b 100644 --- a/src/gpu/GrDrawTarget.cpp +++ b/src/gpu/GrDrawTarget.cpp @@ -321,51 +321,38 @@ static void batch_bounds(SkRect* bounds, const GrBatch* batch) { } } -static inline bool intersect(SkRect* out, const SkRect& a, const SkRect& b) { - SkASSERT(a.fLeft <= a.fRight && a.fTop <= a.fBottom); - SkASSERT(b.fLeft <= b.fRight && b.fTop <= b.fBottom); - out->fLeft = SkTMax(a.fLeft, b.fLeft); - out->fTop = SkTMax(a.fTop, b.fTop); - out->fRight = SkTMin(a.fRight, b.fRight); - out->fBottom = SkTMin(a.fBottom, b.fBottom); - return (out->fLeft <= out->fRight && out->fTop <= out->fBottom); -} - void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, GrDrawContext* drawContext, const GrClip& clip, GrDrawBatch* batch) { // Setup clip - GrAppliedClip appliedClip; SkRect bounds; batch_bounds(&bounds, batch); - if (!clip.apply(fContext, drawContext, &bounds, - pipelineBuilder.isHWAntialias(), pipelineBuilder.hasUserStencilSettings(), - &appliedClip)) { + GrAppliedClip appliedClip(bounds); + if (!clip.apply(fContext, drawContext, pipelineBuilder.isHWAntialias(), + pipelineBuilder.hasUserStencilSettings(), &appliedClip)) { return; } // TODO: this is the only remaining usage of the AutoRestoreFragmentProcessorState - remove it GrPipelineBuilder::AutoRestoreFragmentProcessorState arfps; - if (appliedClip.getClipCoverageFragmentProcessor()) { + if (appliedClip.clipCoverageFragmentProcessor()) { arfps.set(&pipelineBuilder); - arfps.addCoverageFragmentProcessor(sk_ref_sp(appliedClip.getClipCoverageFragmentProcessor())); + arfps.addCoverageFragmentProcessor(sk_ref_sp(appliedClip.clipCoverageFragmentProcessor())); } - GrPipeline::CreateArgs args; - args.fPipelineBuilder = &pipelineBuilder; - args.fDrawContext = drawContext; - args.fCaps = this->caps(); - args.fScissor = &appliedClip.scissorState(); - args.fHasStencilClip = appliedClip.hasStencilClip(); if (pipelineBuilder.hasUserStencilSettings() || appliedClip.hasStencilClip()) { if (!fResourceProvider->attachStencilAttachment(drawContext->accessRenderTarget())) { SkDebugf("ERROR creating stencil attachment. Draw skipped.\n"); return; } } + + GrPipeline::CreateArgs args; + args.fPipelineBuilder = &pipelineBuilder; + args.fDrawContext = drawContext; + args.fCaps = this->caps(); batch->getPipelineOptimizations(&args.fOpts); - GrScissorState finalScissor; if (args.fOpts.fOverrides.fUsePLSDstRead || fClipBatchToBounds) { GrGLIRect viewport; viewport.fLeft = 0; @@ -381,14 +368,9 @@ void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, 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; - } + if (!appliedClip.addScissor(ibounds)) { + return; } - finalScissor.set(ibounds); - args.fScissor = &finalScissor; } args.fOpts.fColorPOI.completeCalculations( sk_sp_address_as_pointer_address(pipelineBuilder.fColorFragmentProcessors.begin()), @@ -396,6 +378,8 @@ void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, args.fOpts.fCoveragePOI.completeCalculations( sk_sp_address_as_pointer_address(pipelineBuilder.fCoverageFragmentProcessors.begin()), pipelineBuilder.numCoverageFragmentProcessors()); + args.fScissor = &appliedClip.scissorState(); + args.fHasStencilClip = appliedClip.hasStencilClip(); if (!this->setupDstReadIfNecessary(pipelineBuilder, drawContext->accessRenderTarget(), clip, args.fOpts, &args.fDstTexture, batch->bounds())) { @@ -410,9 +394,7 @@ void GrDrawTarget::drawBatch(const GrPipelineBuilder& pipelineBuilder, SkASSERT(fRenderTarget); batch->pipeline()->addDependenciesTo(fRenderTarget); #endif - SkRect clippedBounds; - SkAssertResult(intersect(&clippedBounds, bounds, appliedClip.deviceBounds())); - this->recordBatch(batch, clippedBounds); + this->recordBatch(batch, appliedClip.clippedDrawBounds()); } void GrDrawTarget::stencilPath(GrDrawContext* drawContext, @@ -424,16 +406,20 @@ void GrDrawTarget::stencilPath(GrDrawContext* drawContext, SkASSERT(path); SkASSERT(this->caps()->shaderCaps()->pathRenderingSupport()); + // FIXME: Use path bounds instead of this WAR once + // https://bugs.chromium.org/p/skia/issues/detail?id=5640 is resolved. + SkRect bounds = SkRect::MakeIWH(drawContext->width(), drawContext->height()); + // Setup clip - GrAppliedClip appliedClip; - if (!clip.apply(fContext, drawContext, nullptr, useHWAA, true, &appliedClip)) { + GrAppliedClip appliedClip(bounds); + if (!clip.apply(fContext, drawContext, useHWAA, true, &appliedClip)) { return; } // TODO: respect fClipBatchToBounds if we ever start computing bounds here. // Coverage AA does not make sense when rendering to the stencil buffer. The caller should never // attempt this in a situation that would require coverage AA. - SkASSERT(!appliedClip.getClipCoverageFragmentProcessor()); + SkASSERT(!appliedClip.clipCoverageFragmentProcessor()); GrStencilAttachment* stencilAttachment = fResourceProvider->attachStencilAttachment( drawContext->accessRenderTarget()); @@ -450,7 +436,7 @@ void GrDrawTarget::stencilPath(GrDrawContext* drawContext, appliedClip.scissorState(), drawContext->accessRenderTarget(), path); - this->recordBatch(batch, appliedClip.deviceBounds()); + this->recordBatch(batch, appliedClip.clippedDrawBounds()); batch->unref(); } diff --git a/src/gpu/GrReducedClip.cpp b/src/gpu/GrReducedClip.cpp index f7bac4aa58..132936c64e 100644 --- a/src/gpu/GrReducedClip.cpp +++ b/src/gpu/GrReducedClip.cpp @@ -343,9 +343,7 @@ GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds // generation id. When we make early returns, we do not know what was the generation // id that lead to the state. Make a conservative guess. fGenID = stack.getTopmostGenID(); - - // TODO: instead devise a way of telling the caller to disregard some or all of the clip bounds. - fIBounds = GrClip::GetPixelIBounds(queryBounds); + fHasIBounds = false; if (stack.isWideOpen()) { fInitialState = InitialState::kAllIn; @@ -372,6 +370,7 @@ GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds // The clip is a non-aa rect. This is the one spot where we can actually implement the // clip (using fIBounds) rather than just telling the caller what it should be. stackBounds.round(&fIBounds); + fHasIBounds = true; fInitialState = fIBounds.isEmpty() ? InitialState::kAllOut : InitialState::kAllIn; return; } @@ -380,8 +379,11 @@ GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds return; } - SkAssertResult(fIBounds.intersect(GrClip::GetPixelIBounds(stackBounds))); + SkRect tightBounds; + SkAssertResult(tightBounds.intersect(stackBounds, queryBounds)); + fIBounds = GrClip::GetPixelIBounds(tightBounds); SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOutsideClip above. + fHasIBounds = true; // Implement the clip with an AA rect element. fElements.addToHead(stackBounds, SkRegion::kReplace_Op, true/*doAA*/); @@ -396,10 +398,11 @@ GrReducedClip::GrReducedClip(const SkClipStack& stack, const SkRect& queryBounds // Tighten the query by introducing a new clip at the stack's pixel boundaries. (This new // clip will be enforced by the scissor through fIBounds.) SkAssertResult(tighterQuery.intersect(GrClip::GetPixelBounds(stackBounds))); - fIBounds = GrClip::GetPixelIBounds(tighterQuery); } + fIBounds = GrClip::GetPixelIBounds(tighterQuery); SkASSERT(!fIBounds.isEmpty()); // Empty should have been blocked by IsOutsideClip above. + fHasIBounds = true; // Now that we have determined the bounds to use and filtered out the trivial cases, call the // helper that actually walks the stack. diff --git a/src/gpu/GrReducedClip.h b/src/gpu/GrReducedClip.h index 07e06694a1..d7b7ea8881 100644 --- a/src/gpu/GrReducedClip.h +++ b/src/gpu/GrReducedClip.h @@ -25,14 +25,20 @@ public: int32_t genID() const { return fGenID; } /** - * Bounding box within which the reduced clip is valid. The caller must not draw any pixels - * outside this box. + * If hasIBounds() is true, this is the bounding box within which the reduced clip is valid, and + * the caller must not modify any pixels outside this box. Undefined if hasIBounds() is false. */ - const SkIRect& iBounds() const { return fIBounds; } - int left() const { return this->iBounds().left(); } - int top() const { return this->iBounds().top(); } - int width() const { return this->iBounds().width(); } - int height() const { return this->iBounds().height(); } + const SkIRect& ibounds() const { SkASSERT(fHasIBounds); return fIBounds; } + int left() const { return this->ibounds().left(); } + int top() const { return this->ibounds().top(); } + int width() const { return this->ibounds().width(); } + int height() const { return this->ibounds().height(); } + + /** + * Indicates whether ibounds() are defined. They will always be defined if the elements() are + * nonempty. + */ + bool hasIBounds() const { return fHasIBounds; } typedef SkTLList<SkClipStack::Element, 16> ElementList; @@ -51,14 +57,12 @@ public: kAllOut }; - /** - * The initial state of the clip within iBounds(). - */ InitialState initialState() const { return fInitialState; } private: int32_t fGenID; SkIRect fIBounds; + bool fHasIBounds; ElementList fElements; bool fRequiresAA; InitialState fInitialState; |