diff options
author | 2016-07-08 11:31:22 -0700 | |
---|---|---|
committer | 2016-07-08 11:31:23 -0700 | |
commit | 6cc9006a907bf166b94468bf5c0e915cc0b14532 (patch) | |
tree | d968ab914a08e8dda52df5e88a2d9cf23156d362 /include/gpu/GrClip.h | |
parent | 8e9e45a69b804ee6b817baf1657e5efa0636ff52 (diff) |
Use clipped bounds for reordering decisions
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2137543002
NOTREECHECKS=true
NOPRESUBMIT=true
Review-Url: https://codereview.chromium.org/2137543002
Diffstat (limited to 'include/gpu/GrClip.h')
-rw-r--r-- | include/gpu/GrClip.h | 79 |
1 files changed, 69 insertions, 10 deletions
diff --git a/include/gpu/GrClip.h b/include/gpu/GrClip.h index 26aab7005b..e58528114e 100644 --- a/include/gpu/GrClip.h +++ b/include/gpu/GrClip.h @@ -21,48 +21,78 @@ class GrPipelineBuilder; */ class GrAppliedClip : public SkNoncopyable { public: - GrAppliedClip() : fHasStencilClip(false) {} + GrAppliedClip() : fHasStencilClip(false), fDeviceBounds(SkRect::MakeLargest()) {} GrFragmentProcessor* getClipCoverageFragmentProcessor() const { return fClipCoverageFP.get(); } const GrScissorState& scissorState() const { return fScissorState; } bool hasStencilClip() const { return fHasStencilClip; } - void makeStencil(bool hasStencil) { + void makeStencil(bool hasStencil, const SkRect& deviceBounds) { fClipCoverageFP = nullptr; fScissorState.setDisabled(); fHasStencilClip = hasStencil; + fDeviceBounds = deviceBounds; } - void makeScissoredStencil(bool hasStencil, const SkIRect& scissor) { + /** + * The device bounds of the clip defaults to the scissor rect, but a tighter bounds (based + * on the known effect of the stencil values) can be provided. + */ + void makeScissoredStencil(const SkIRect& scissor, const SkRect* deviceBounds = nullptr) { fClipCoverageFP = nullptr; fScissorState.set(scissor); - fHasStencilClip = hasStencil; + fHasStencilClip = true; + if (deviceBounds) { + fDeviceBounds = *deviceBounds; + SkASSERT(scissor.contains(*deviceBounds)) + } else { + fDeviceBounds = SkRect::Make(scissor); + } } - void makeFPBased(sk_sp<GrFragmentProcessor> fp) { + void makeFPBased(sk_sp<GrFragmentProcessor> fp, const SkRect& deviceBounds) { fClipCoverageFP = fp; fScissorState.setDisabled(); fHasStencilClip = false; + fDeviceBounds = deviceBounds; } void makeScissored(SkIRect& scissor) { fClipCoverageFP.reset(); fScissorState.set(scissor); fHasStencilClip = false; + fDeviceBounds = SkRect::Make(scissor); } - void makeScissoredFPBased(sk_sp<GrFragmentProcessor> fp, SkIRect& scissor) { + /** + * The device bounds of the clip defaults to the scissor rect, but a tighter bounds (based + * on the known effect of the fragment processor) can be provided. + */ + void makeScissoredFPBased(sk_sp<GrFragmentProcessor> fp, const SkIRect& scissor, + const SkRect* deviceBounds = nullptr) { fClipCoverageFP = fp; fScissorState.set(scissor); fHasStencilClip = false; + if (deviceBounds) { + fDeviceBounds = *deviceBounds; + SkASSERT(scissor.contains(*deviceBounds)) + } else { + fDeviceBounds = SkRect::Make(scissor); + } } + /** + * Returns the device bounds of the applied clip. Ideally this considers the combined effect of + * all clipping techniques in play (scissor, stencil, and/or coverage fp). + */ + const SkRect& deviceBounds() const { return fDeviceBounds; } + private: sk_sp<GrFragmentProcessor> fClipCoverageFP; GrScissorState fScissorState; bool fHasStencilClip; - + SkRect fDeviceBounds; typedef SkNoncopyable INHERITED; }; @@ -99,20 +129,48 @@ private: */ class GrFixedClip final : public GrClip { public: - GrFixedClip() : fHasStencilClip(false) {} - GrFixedClip(const SkIRect& scissorRect) : fScissorState(scissorRect), fHasStencilClip(false) {} + GrFixedClip() : fDeviceBounds(SkRect::MakeLargest()), fHasStencilClip(false) {} + GrFixedClip(const SkIRect& scissorRect) + : fScissorState(scissorRect) + , fDeviceBounds(SkRect::Make(scissorRect)) + , fHasStencilClip(false) {} void reset() { fScissorState.setDisabled(); + fDeviceBounds.setLargest(); fHasStencilClip = false; } void reset(const SkIRect& scissorRect) { fScissorState.set(scissorRect); + fDeviceBounds = SkRect::Make(scissorRect); fHasStencilClip = false; } - void enableStencilClip(bool enable) { fHasStencilClip = enable; } + /** + * Enables stenciling. The stencil bounds is the device space bounds where the stencil test + * may pass. + */ + void enableStencilClip(const SkRect& stencilBounds) { + fHasStencilClip = true; + fDeviceBounds = stencilBounds; + if (fScissorState.enabled()) { + const SkIRect& s = fScissorState.rect(); + fDeviceBounds.fLeft = SkTMax(fDeviceBounds.fLeft, SkIntToScalar(s.fLeft)); + fDeviceBounds.fTop = SkTMax(fDeviceBounds.fTop, SkIntToScalar(s.fTop)); + fDeviceBounds.fRight = SkTMin(fDeviceBounds.fRight, SkIntToScalar(s.fRight)); + fDeviceBounds.fBottom = SkTMin(fDeviceBounds.fBottom, SkIntToScalar(s.fBottom)); + } + } + + void disableStencilClip() { + fHasStencilClip = false; + if (fScissorState.enabled()) { + fDeviceBounds = SkRect::Make(fScissorState.rect()); + } else { + fDeviceBounds.setLargest(); + } + } const GrScissorState& scissorState() const { return fScissorState; } bool hasStencilClip() const { return fHasStencilClip; } @@ -126,6 +184,7 @@ private: const SkRect* devBounds, GrAppliedClip* out) const final; GrScissorState fScissorState; + SkRect fDeviceBounds; bool fHasStencilClip; }; |