Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Unified Diff: include/gpu/GrClip.h

Issue 1971343002: Convert GrClip to an abstract base class (Closed) Base URL: https://skia.googlesource.com/skia.git@upload2_clipout
Patch Set: fix crash Created 4 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gm/texdata.cpp ('k') | include/gpu/GrTypesPriv.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: include/gpu/GrClip.h
diff --git a/include/gpu/GrClip.h b/include/gpu/GrClip.h
index fd8b970e39dc8861695181a369429a0a71d60240..68a4eb92241df7286f212c507f72ea38fbe0d2ce 100644
--- a/include/gpu/GrClip.h
+++ b/include/gpu/GrClip.h
@@ -8,185 +8,125 @@
#ifndef GrClip_DEFINED
#define GrClip_DEFINED
+#include "GrFragmentProcessor.h"
+#include "GrTypesPriv.h"
#include "SkClipStack.h"
-struct SkIRect;
+class GrClipMaskManager;
+class GrPipelineBuilder;
/**
- * GrClip encapsulates the information required to construct the clip
- * masks. 'A GrClip is either wide open, just an IRect, just a Rect, or a full clipstack.
- * If the clip is a clipstack than the origin is used to translate the stack with
- * respect to device coordinates. This allows us to use a clip stack that is
- * specified for a root device with a layer device that is restricted to a subset
- * of the original canvas. For other clip types the origin will always be (0,0).
- *
- * NOTE: GrClip *must* point to a const clipstack
+ * Produced by GrClip. It provides a set of modifications to the drawing state that are used to
+ * create the final GrPipeline for a GrBatch.
*/
-class GrClip : SkNoncopyable {
+class GrAppliedClip {
public:
- GrClip() : fClipType(kWideOpen_ClipType) {
- fOrigin.setZero();
- }
+ GrAppliedClip() : fHasStencilClip(false) {}
+ const GrFragmentProcessor* clipCoverageFragmentProcessor() const { return fClipCoverageFP; }
+ const GrScissorState& scissorState() const { return fScissorState; }
+ bool hasStencilClip() const { return fHasStencilClip; }
- GrClip(const SkIRect& rect) : fClipType(kIRect_ClipType) {
- fOrigin.setZero();
- fClip.fIRect = rect;
- }
+private:
+ SkAutoTUnref<const GrFragmentProcessor> fClipCoverageFP;
+ GrScissorState fScissorState;
+ bool fHasStencilClip;
- GrClip(const SkRect& rect) : fClipType(kIRect_ClipType) {
- fOrigin.setZero();
- fClip.fIRect.fLeft = SkScalarRoundToInt(rect.fLeft);
- fClip.fIRect.fTop = SkScalarRoundToInt(rect.fTop);
- fClip.fIRect.fRight = SkScalarRoundToInt(rect.fRight);
- fClip.fIRect.fBottom = SkScalarRoundToInt(rect.fBottom);
- }
+ friend class GrFixedClip;
+ friend class GrClipMaskManager;
- ~GrClip() { this->reset(); }
-
- const GrClip& operator=(const GrClip& other) {
- this->reset();
- fClipType = other.fClipType;
- switch (other.fClipType) {
- case kWideOpen_ClipType:
- fOrigin.setZero();
- break;
- case kClipStack_ClipType:
- fClip.fStack = SkRef(other.clipStack());
- fOrigin = other.origin();
- break;
- case kIRect_ClipType:
- fClip.fIRect = other.irect();
- fOrigin.setZero();
- break;
- }
- return *this;
- }
+ typedef SkNoncopyable INHERITED;
+};
- bool operator==(const GrClip& other) const {
- if (this->clipType() != other.clipType()) {
- return false;
- }
-
- switch (fClipType) {
- case kWideOpen_ClipType:
- return true;
- case kClipStack_ClipType:
- if (this->origin() != other.origin()) {
- return false;
- }
-
- if (this->clipStack() && other.clipStack()) {
- return *this->clipStack() == *other.clipStack();
- } else {
- return this->clipStack() == other.clipStack();
- }
- break;
- case kIRect_ClipType:
- return this->irect() == other.irect();
- break;
- }
- SkFAIL("This should not occur\n");
- return false;
- }
+/**
+ * GrClip is an abstract base class for applying a clip. It constructs a clip mask if necessary, and
+ * fills out a GrAppliedClip instructing the caller on how to set up the draw state.
+ */
+class GrClip {
+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(GrClipMaskManager*, const GrPipelineBuilder&, const SkRect* devBounds,
+ GrAppliedClip*) const = 0;
- bool operator!=(const GrClip& other) const {
- return !(*this == other);
- }
+ virtual ~GrClip() {}
+};
- const SkClipStack* clipStack() const {
- SkASSERT(kClipStack_ClipType == fClipType);
- return fClip.fStack;
- }
+/**
+ * Specialized implementation for no clip.
+ */
+class GrNoClip final : public GrClip {
+private:
+ bool quickContains(const SkRect&) const final { return true; }
+ void getConservativeBounds(int width, int height, SkIRect* devResult,
+ bool* isIntersectionOfRects) const final;
+ bool apply(GrClipMaskManager*, const GrPipelineBuilder&,
+ const SkRect*, GrAppliedClip*) const final { return true; }
+};
- void setClipStack(const SkClipStack* clipStack, const SkIPoint* origin = NULL) {
- this->reset();
- if (clipStack->isWideOpen()) {
- fClipType = kWideOpen_ClipType;
- fOrigin.setZero();
- } else {
- fClipType = kClipStack_ClipType;
- fClip.fStack = SkRef(clipStack);
- if (origin) {
- fOrigin = *origin;
- } else {
- fOrigin.setZero();
- }
- }
- }
+/**
+ * GrFixedClip is a clip that can be represented by fixed-function hardware. It never modifies the
+ * stencil buffer itself, but can be configured to use whatever clip is already there.
+ */
+class GrFixedClip final : public GrClip {
+public:
+ GrFixedClip() : fHasStencilClip(false) {}
+ GrFixedClip(const SkIRect& scissorRect) : fScissorState(scissorRect), fHasStencilClip(false) {}
- void setIRect(const SkIRect& irect) {
- this->reset();
- fClipType = kIRect_ClipType;
- fOrigin.setZero();
- fClip.fIRect = irect;
+ void reset() {
+ fScissorState.setDisabled();
+ fHasStencilClip = false;
}
- const SkIRect& irect() const {
- SkASSERT(kIRect_ClipType == fClipType);
- return fClip.fIRect;
+ void reset(const SkIRect& scissorRect) {
+ fScissorState.set(scissorRect);
+ fHasStencilClip = false;
}
- void reset() {
- if (kClipStack_ClipType == fClipType) {
- fClip.fStack->unref();
- fClip.fStack = NULL;
- }
- fClipType = kWideOpen_ClipType;
- fOrigin.setZero();
- }
+ void enableStencilClip(bool enable) { fHasStencilClip = enable; }
- // We support this for all cliptypes to simplify the logic a bit in clip mask manager.
- // non clipstack clip types MUST have a (0,0) origin
- const SkIPoint& origin() const {
- SkASSERT(fClipType == kClipStack_ClipType || (fOrigin.fX == 0 && fOrigin.fY == 0));
- return fOrigin;
- }
+ const GrScissorState& scissorState() const { return fScissorState; }
+ bool hasStencilClip() const { return fHasStencilClip; }
- bool isWideOpen(const SkRect& rect) const {
- return (kWideOpen_ClipType == fClipType) ||
- (kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen()) ||
- (kIRect_ClipType == fClipType && this->irect().contains(rect));
- }
+ bool quickContains(const SkRect&) const final;
+ void getConservativeBounds(int width, int height, SkIRect* devResult,
+ bool* isIntersectionOfRects) const final;
- bool isWideOpen(const SkIRect& rect) const {
- return (kWideOpen_ClipType == fClipType) ||
- (kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen()) ||
- (kIRect_ClipType == fClipType && this->irect().contains(rect));
- }
+private:
+ bool apply(GrClipMaskManager*, const GrPipelineBuilder&,
+ const SkRect* devBounds, GrAppliedClip* out) const final;
- bool isWideOpen() const {
- return (kWideOpen_ClipType == fClipType) ||
- (kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen());
- }
+ GrScissorState fScissorState;
+ bool fHasStencilClip;
+};
- bool quickContains(const SkRect& rect) const {
- return (kWideOpen_ClipType == fClipType) ||
- (kClipStack_ClipType == fClipType && this->clipStack()->quickContains(rect)) ||
- (kIRect_ClipType == fClipType && this->irect().contains(rect));
+/**
+ * GrClipStackClip can apply a generic SkClipStack to the draw state. It may generate clip masks or
+ * write to the stencil buffer during apply().
+ */
+class GrClipStackClip final : public GrClip {
+public:
+ GrClipStackClip(const SkClipStack* stack = nullptr, const SkIPoint* origin = nullptr) {
+ this->reset(stack, origin);
}
- void getConservativeBounds(int width, int height,
- SkIRect* devResult,
- bool* isIntersectionOfRects = NULL) const;
-
- static const GrClip& WideOpen();
+ void reset(const SkClipStack* stack = nullptr, const SkIPoint* origin = nullptr) {
+ fOrigin = origin ? *origin : SkIPoint::Make(0, 0);
+ fStack.reset(SkSafeRef(stack));
+ }
- enum ClipType {
- kClipStack_ClipType,
- kWideOpen_ClipType,
- kIRect_ClipType,
- };
+ const SkIPoint& origin() const { return fOrigin; }
+ const SkClipStack* clipStack() const { return fStack; }
- ClipType clipType() const { return fClipType; }
+ bool quickContains(const SkRect&) const final;
+ void getConservativeBounds(int width, int height, SkIRect* devResult,
+ bool* isIntersectionOfRects) const final;
+ bool apply(GrClipMaskManager*, const GrPipelineBuilder&,
+ const SkRect* devBounds, GrAppliedClip*) const final;
private:
- union Clip {
- const SkClipStack* fStack;
- SkIRect fIRect;
- } fClip;
-
- SkIPoint fOrigin;
- ClipType fClipType;
+ SkIPoint fOrigin;
+ SkAutoTUnref<const SkClipStack> fStack;
};
#endif
« no previous file with comments | « gm/texdata.cpp ('k') | include/gpu/GrTypesPriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698