diff options
Diffstat (limited to 'include/gpu/GrClip.h')
-rw-r--r-- | include/gpu/GrClip.h | 125 |
1 files changed, 24 insertions, 101 deletions
diff --git a/include/gpu/GrClip.h b/include/gpu/GrClip.h index 5f0a881653..9db76f0942 100644 --- a/include/gpu/GrClip.h +++ b/include/gpu/GrClip.h @@ -19,78 +19,43 @@ class GrDrawContext; */ class GrAppliedClip : public SkNoncopyable { public: - GrAppliedClip() : fHasStencilClip(false), fDeviceBounds(SkRect::MakeLargest()) {} - GrFragmentProcessor* getClipCoverageFragmentProcessor() const { - return fClipCoverageFP.get(); + GrAppliedClip(const SkRect& drawBounds) + : fHasStencilClip(false) + , fClippedDrawBounds(drawBounds) { } + const GrScissorState& scissorState() const { return fScissorState; } + GrFragmentProcessor* clipCoverageFragmentProcessor() const { return fClipCoverageFP.get(); } bool hasStencilClip() const { return fHasStencilClip; } - void makeStencil(bool hasStencil, const SkRect& deviceBounds) { - fClipCoverageFP = nullptr; - fScissorState.setDisabled(); - fHasStencilClip = hasStencil; - fDeviceBounds = deviceBounds; - } - /** - * 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. + * Intersects the applied clip with the provided rect. Returns false if the draw became empty. */ - void makeScissoredStencil(const SkIRect& scissor, const SkRect* deviceBounds = nullptr) { - fClipCoverageFP = nullptr; - fScissorState.set(scissor); - fHasStencilClip = true; - if (deviceBounds) { - fDeviceBounds = *deviceBounds; - SkASSERT(scissor.contains(*deviceBounds)); - } else { - fDeviceBounds = SkRect::Make(scissor); - } + bool addScissor(const SkIRect& irect) { + return fScissorState.intersect(irect) && fClippedDrawBounds.intersect(SkRect::Make(irect)); } - void makeFPBased(sk_sp<GrFragmentProcessor> fp, const SkRect& deviceBounds) { + void addCoverageFP(sk_sp<GrFragmentProcessor> fp) { + SkASSERT(!fClipCoverageFP); fClipCoverageFP = fp; - fScissorState.setDisabled(); - fHasStencilClip = false; - fDeviceBounds = deviceBounds; } - void makeScissored(SkIRect& scissor) { - fClipCoverageFP.reset(); - fScissorState.set(scissor); - fHasStencilClip = false; - fDeviceBounds = SkRect::Make(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); - } + void addStencilClip() { + SkASSERT(!fHasStencilClip); + fHasStencilClip = true; } /** - * 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). + * Returns the device bounds of the draw after clip has been applied. TODO: Ideally this would + * consider the combined effect of all clipping techniques in play (scissor, stencil, fp, etc.). */ - const SkRect& deviceBounds() const { return fDeviceBounds; } + const SkRect& clippedDrawBounds() const { return fClippedDrawBounds; } private: - sk_sp<GrFragmentProcessor> fClipCoverageFP; GrScissorState fScissorState; + sk_sp<GrFragmentProcessor> fClipCoverageFP; bool fHasStencilClip; - SkRect fDeviceBounds; + SkRect fClippedDrawBounds; typedef SkNoncopyable INHERITED; }; @@ -103,11 +68,7 @@ public: virtual bool quickContains(const SkRect&) const = 0; virtual void getConservativeBounds(int width, int height, SkIRect* devResult, bool* isIntersectionOfRects = nullptr) const = 0; - virtual bool apply(GrContext*, - GrDrawContext*, - const SkRect* devBounds, - bool useHWAA, - bool hasUserStencilSettings, + virtual bool apply(GrContext*, GrDrawContext*, bool useHWAA, bool hasUserStencilSettings, GrAppliedClip* out) const = 0; virtual ~GrClip() {} @@ -192,12 +153,7 @@ private: bool quickContains(const SkRect&) const final { return true; } void getConservativeBounds(int width, int height, SkIRect* devResult, bool* isIntersectionOfRects) const final; - bool apply(GrContext*, - GrDrawContext*, - const SkRect* /* devBounds */, - bool /* useHWAA */, - bool /* hasUserStencilSettings */, - GrAppliedClip* /* out */) const final { return true; } + bool apply(GrContext*, GrDrawContext*, bool, bool, GrAppliedClip*) const final { return true; } }; /** @@ -206,66 +162,33 @@ private: */ class GrFixedClip final : public GrClip { public: - GrFixedClip() : fDeviceBounds(SkRect::MakeLargest()), fHasStencilClip(false) {} + GrFixedClip() : 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; } - /** - * 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; } + void enableStencilClip() { fHasStencilClip = true; } + void disableStencilClip() { fHasStencilClip = false; } bool quickContains(const SkRect&) const final; void getConservativeBounds(int width, int height, SkIRect* devResult, bool* isIntersectionOfRects) const final; private: - bool apply(GrContext*, - GrDrawContext*, - const SkRect* devBounds, - bool useHWAA, - bool hasUserStencilSettings, + bool apply(GrContext*, GrDrawContext*, bool useHWAA, bool hasUserStencilSettings, GrAppliedClip* out) const final; GrScissorState fScissorState; - SkRect fDeviceBounds; bool fHasStencilClip; }; |