Chromium Code Reviews| Index: include/gpu/GrClip.h |
| diff --git a/include/gpu/GrClip.h b/include/gpu/GrClip.h |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..c7b05122c69697bfe33de877e7dda69c5d4009e4 |
| --- /dev/null |
| +++ b/include/gpu/GrClip.h |
| @@ -0,0 +1,177 @@ |
| +/* |
| + * Copyright 2010 Google Inc. |
| + * |
| + * Use of this source code is governed by a BSD-style license that can be |
| + * found in the LICENSE file. |
| + */ |
| + |
| +#ifndef GrClip_DEFINED |
| +#define GrClip_DEFINED |
| + |
| +#include "SkClipStack.h" |
| +#include "GrSurface.h" |
| + |
| +struct SkIRect; |
| + |
| +/** |
| + * GrClip encapsulates the information required to construct the clip |
| + * masks. 'A GrClip is either wide open, just an IRect, just a Rect(TODO), a full clipstack, or |
| + * empty. If a clipstack than fOrigin' is only non-zero when saveLayer has been called |
|
bsalomon
2015/02/23 22:04:19
get rid of empty or mark as todo?
|
| + * with an offset bounding box. The clips in 'fClipStack' are in |
|
bsalomon
2015/02/23 22:04:19
The origin thing is confusing...
Howabout...
"""
|
| + * device coordinates (i.e., they have been translated by -fOrigin w.r.t. |
| + * the canvas' device coordinates). |
| + * |
| + * NOTE: GrClip *must* point to a const clipstack |
| + */ |
| +class GrClip : SkNoncopyable { |
| +public: |
| + GrClip() : fClipType(kWideOpen_ClipType) {} |
| + GrClip(const SkIRect& rect) : fClipType(kIRect_ClipType) { |
| + fClip.fIRect = rect; |
| + } |
| + ~GrClip() { this->reset(); } |
| + |
| + const GrClip& operator=(const GrClip& other) { |
| + this->reset(); |
| + fClipType = other.fClipType; |
| + switch (other.fClipType) { |
| + default: |
| + SkFAIL("Incomplete Switch\n"); |
| + case kWideOpen_ClipType: |
| + break; |
| + case kClipStack_ClipType: |
| + fClip.fClipStack.fStack = SkRef(other.clipStack()); |
| + fClip.fClipStack.fOrigin = other.origin(); |
| + break; |
| + case kIRect_ClipType: |
| + fClip.fIRect = other.irect(); |
| + break; |
| + } |
| + return *this; |
| + } |
| + |
| + bool operator==(const GrClip& other) const { |
| + if (this->clipType() != other.clipType()) { |
| + return false; |
| + } |
| + |
| + switch (fClipType) { |
| + default: |
| + SkFAIL("Incomplete Switch\n"); |
| + return false; |
| + 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; |
| + } |
| + } |
| + |
| + bool operator!=(const GrClip& other) const { |
| + return !(*this == other); |
| + } |
| + |
| + const SkClipStack* clipStack() const { |
| + SkASSERT(kClipStack_ClipType == fClipType); |
| + return fClip.fClipStack.fStack; |
| + } |
| + |
| + void setClipStack(const SkClipStack* clipStack, const SkIPoint* origin = NULL) { |
| + if (clipStack->isWideOpen()) { |
| + fClipType = kWideOpen_ClipType; |
| + } else { |
| + fClipType = kClipStack_ClipType; |
| + fClip.fClipStack.fStack = SkRef(clipStack); |
| + if (origin) { |
| + fClip.fClipStack.fOrigin = *origin; |
| + } else { |
| + fClip.fClipStack.fOrigin.setZero(); |
| + } |
| + } |
| + } |
| + |
| + const SkIRect& irect() const { |
| + SkASSERT(kIRect_ClipType == fClipType); |
| + return fClip.fIRect; |
| + } |
| + |
| + void reset() { |
| + if (kClipStack_ClipType == fClipType) { |
| + fClip.fClipStack.fStack->unref(); |
| + fClip.fClipStack.fStack = NULL; |
| + } |
| + fClipType = kUninitialized_ClipType; |
| + } |
| + |
| + const SkIPoint& origin() const { |
| + SkASSERT(kClipStack_ClipType == fClipType); |
| + return fClip.fClipStack.fOrigin; |
| + } |
| + |
| + bool isWideOpen(const SkRect& rect) const { |
| + return (kWideOpen_ClipType == fClipType) || |
| + (kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen()) || |
| + (kIRect_ClipType == fClipType && this->irect().contains(rect)); |
| + } |
| + |
| + bool isWideOpen(const SkIRect& rect) const { |
| + return (kWideOpen_ClipType == fClipType) || |
| + (kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen()) || |
| + (kIRect_ClipType == fClipType && this->irect().contains(rect)); |
| + } |
| + |
| + bool isWideOpen() const { |
| + return (kWideOpen_ClipType == fClipType) || |
| + (kClipStack_ClipType == fClipType && this->clipStack()->isWideOpen()) || |
| + (kIRect_ClipType == fClipType && this->irect().isEmpty()); |
| + } |
| + |
| + void getConservativeBounds(const GrSurface* surface, |
| + SkIRect* devResult, |
| + bool* isIntersectionOfRects = NULL) const { |
| + this->getConservativeBounds(surface->width(), surface->height(), |
| + devResult, isIntersectionOfRects); |
| + } |
| + |
| + void getConservativeBounds(int width, int height, |
| + SkIRect* devResult, |
| + bool* isIntersectionOfRects = NULL) const; |
| + |
| + static const GrClip& WideOpen() { |
| + static GrClip clip; |
| + return clip; |
| + } |
| + |
| + enum ClipType { |
| + kClipStack_ClipType, |
| + kWideOpen_ClipType, |
| + kIRect_ClipType, |
| + kUninitialized_ClipType, |
| + }; |
| + |
| + ClipType clipType() const { return fClipType; } |
| + |
| +private: |
| + union Clip { |
| + struct ClipStack { |
| + const SkClipStack* fStack; |
| + SkIPoint fOrigin; |
| + } fClipStack; |
| + SkIRect fIRect; |
| + } fClip; |
| + |
| + ClipType fClipType; |
| +}; |
| + |
| +#endif |