Don't use analytic clip FPs when drawing to stencil
It doesn't make sense to multiply by coverage when drawing to stencil.
This could theoretically work with FPs that discard and/or modify
the sample mask, but for the time being an analytic FP means one that
calculates a coverage value.
Bug: skia:7190
Change-Id: I44140a5823f8683ec08244bdf9d369f51fa05dd9
Reviewed-on: https://skia-review.googlesource.com/68362
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Chris Dalton <csmartdalton@google.com>
diff --git a/src/gpu/GrClip.h b/src/gpu/GrClip.h
index bd7d8a1..7358e67 100644
--- a/src/gpu/GrClip.h
+++ b/src/gpu/GrClip.h
@@ -8,13 +8,12 @@
#ifndef GrClip_DEFINED
#define GrClip_DEFINED
-#include "GrTypes.h"
+#include "GrAppliedClip.h"
+#include "GrRenderTargetContext.h"
#include "SkRRect.h"
#include "SkRect.h"
-class GrAppliedClip;
class GrContext;
-class GrRenderTargetContext;
/**
* GrClip is an abstract base class for applying a clip. It constructs a clip mask if necessary, and
@@ -37,8 +36,7 @@
* skipped as it is fully clipped out.
*/
virtual bool apply(GrContext*, GrRenderTargetContext*, bool useHWAA,
- bool hasUserStencilSettings, GrAppliedClip* result,
- SkRect* bounds) const = 0;
+ bool hasUserStencilSettings, GrAppliedClip*, SkRect* bounds) const = 0;
virtual ~GrClip() {}
@@ -133,10 +131,32 @@
}
};
+
+/**
+ * GrHardClip never uses coverage FPs. It can only enforce the clip using the already-existing
+ * stencil buffer contents and/or fixed-function state like scissor. Always aliased if MSAA is off.
+ */
+class GrHardClip : public GrClip {
+public:
+ /**
+ * Sets the appropriate hardware state modifications on GrAppliedHardClip that will implement
+ * the clip. On input 'bounds' is a conservative bounds of the draw that is to be clipped. After
+ * return 'bounds' has been intersected with a conservative bounds of the clip. A return value
+ * of false indicates that the draw can be skipped as it is fully clipped out.
+ */
+ virtual bool apply(int rtWidth, int rtHeight, GrAppliedHardClip* out, SkRect* bounds) const = 0;
+
+private:
+ bool apply(GrContext*, GrRenderTargetContext* rtc, bool useHWAA, bool hasUserStencilSettings,
+ GrAppliedClip* out, SkRect* bounds) const final {
+ return this->apply(rtc->width(), rtc->height(), &out->hardClip(), bounds);
+ }
+};
+
/**
* Specialized implementation for no clip.
*/
-class GrNoClip final : public GrClip {
+class GrNoClip final : public GrHardClip {
private:
bool quickContains(const SkRect&) const final { return true; }
bool quickContains(const SkRRect&) const final { return true; }
@@ -147,10 +167,7 @@
*isIntersectionOfRects = true;
}
}
- bool apply(GrContext*, GrRenderTargetContext*, bool, bool, GrAppliedClip*,
- SkRect*) const final {
- return true;
- }
+ bool apply(int rtWidth, int rtHeight, GrAppliedHardClip*, SkRect*) const final { return true; }
bool isRRect(const SkRect&, SkRRect*, GrAA*) const override { return false; }
};