Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2010 Google Inc. | 2 * Copyright 2010 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #ifndef GrClip_DEFINED | 8 #ifndef GrClip_DEFINED |
| 9 #define GrClip_DEFINED | 9 #define GrClip_DEFINED |
| 10 | 10 |
| 11 #include "GrFragmentProcessor.h" | 11 #include "GrFragmentProcessor.h" |
| 12 #include "GrTypesPriv.h" | 12 #include "GrTypesPriv.h" |
| 13 | 13 |
| 14 class GrDrawContext; | 14 class GrDrawContext; |
| 15 | 15 |
| 16 /** | 16 /** |
| 17 * Produced by GrClip. It provides a set of modifications to the drawing state t hat are used to | 17 * Produced by GrClip. It provides a set of modifications to the drawing state t hat are used to |
| 18 * create the final GrPipeline for a GrBatch. | 18 * create the final GrPipeline for a GrBatch. |
| 19 */ | 19 */ |
| 20 class GrAppliedClip : public SkNoncopyable { | 20 class GrAppliedClip : public SkNoncopyable { |
| 21 public: | 21 public: |
| 22 GrAppliedClip() : fHasStencilClip(false), fDeviceBounds(SkRect::MakeLargest( )) {} | 22 GrAppliedClip(const SkRect& drawBounds) : fHasStencilClip(false), fDeviceBou nds(drawBounds) {} |
| 23 GrFragmentProcessor* getClipCoverageFragmentProcessor() const { | 23 |
| 24 return fClipCoverageFP.get(); | |
| 25 } | |
| 26 const GrScissorState& scissorState() const { return fScissorState; } | 24 const GrScissorState& scissorState() const { return fScissorState; } |
| 25 GrFragmentProcessor* clipCoverageFragmentProcessor() const { return fClipCov erageFP.get(); } | |
| 27 bool hasStencilClip() const { return fHasStencilClip; } | 26 bool hasStencilClip() const { return fHasStencilClip; } |
| 28 | 27 |
| 29 void makeStencil(bool hasStencil, const SkRect& deviceBounds) { | 28 /** |
| 30 fClipCoverageFP = nullptr; | 29 * Intersects the applied clip with the provided rect. Returns false if the draw became empty. |
| 31 fScissorState.setDisabled(); | 30 */ |
| 32 fHasStencilClip = hasStencil; | 31 bool addScissor(const SkIRect& irect) { |
| 33 fDeviceBounds = deviceBounds; | 32 return fScissorState.intersect(irect) && fDeviceBounds.intersect(SkRect: :Make(irect)); |
| 33 } | |
| 34 | |
| 35 void addCoverageFP(sk_sp<GrFragmentProcessor> fp) { | |
| 36 SkASSERT(!fClipCoverageFP); | |
|
csmartdalton
2016/08/15 16:05:25
This can eventually accept the bounding box and in
| |
| 37 fClipCoverageFP = fp; | |
| 38 } | |
| 39 | |
| 40 void addStencilClip() { | |
| 41 SkASSERT(!fHasStencilClip); | |
|
csmartdalton
2016/08/15 16:05:26
ditto
| |
| 42 fHasStencilClip = true; | |
| 34 } | 43 } |
| 35 | 44 |
| 36 /** | 45 /** |
| 37 * The device bounds of the clip defaults to the scissor rect, but a tighter bounds (based | 46 * Returns the device bounds of the draw after clip has been applied. TODO: Ideally this would |
| 38 * on the known effect of the stencil values) can be provided. | 47 * consider the combined effect of all clipping techniques in play (scissor, stencil, fp, etc.). |
| 39 */ | |
| 40 void makeScissoredStencil(const SkIRect& scissor, const SkRect* deviceBounds = nullptr) { | |
| 41 fClipCoverageFP = nullptr; | |
| 42 fScissorState.set(scissor); | |
| 43 fHasStencilClip = true; | |
| 44 if (deviceBounds) { | |
| 45 fDeviceBounds = *deviceBounds; | |
| 46 SkASSERT(scissor.contains(*deviceBounds)); | |
| 47 } else { | |
| 48 fDeviceBounds = SkRect::Make(scissor); | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 void makeFPBased(sk_sp<GrFragmentProcessor> fp, const SkRect& deviceBounds) { | |
| 53 fClipCoverageFP = fp; | |
| 54 fScissorState.setDisabled(); | |
| 55 fHasStencilClip = false; | |
| 56 fDeviceBounds = deviceBounds; | |
| 57 } | |
| 58 | |
| 59 void makeScissored(SkIRect& scissor) { | |
| 60 fClipCoverageFP.reset(); | |
| 61 fScissorState.set(scissor); | |
| 62 fHasStencilClip = false; | |
| 63 fDeviceBounds = SkRect::Make(scissor); | |
| 64 } | |
| 65 | |
| 66 /** | |
| 67 * The device bounds of the clip defaults to the scissor rect, but a tighter bounds (based | |
| 68 * on the known effect of the fragment processor) can be provided. | |
| 69 */ | |
| 70 void makeScissoredFPBased(sk_sp<GrFragmentProcessor> fp, const SkIRect& scis sor, | |
| 71 const SkRect* deviceBounds = nullptr) { | |
| 72 fClipCoverageFP = fp; | |
| 73 fScissorState.set(scissor); | |
| 74 fHasStencilClip = false; | |
| 75 if (deviceBounds) { | |
| 76 fDeviceBounds = *deviceBounds; | |
| 77 SkASSERT(scissor.contains(*deviceBounds)); | |
| 78 } else { | |
| 79 fDeviceBounds = SkRect::Make(scissor); | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 /** | |
| 84 * Returns the device bounds of the applied clip. Ideally this considers the combined effect of | |
| 85 * all clipping techniques in play (scissor, stencil, and/or coverage fp). | |
| 86 */ | 48 */ |
| 87 const SkRect& deviceBounds() const { return fDeviceBounds; } | 49 const SkRect& deviceBounds() const { return fDeviceBounds; } |
| 88 | 50 |
| 89 private: | 51 private: |
| 52 GrScissorState fScissorState; | |
| 90 sk_sp<GrFragmentProcessor> fClipCoverageFP; | 53 sk_sp<GrFragmentProcessor> fClipCoverageFP; |
| 91 GrScissorState fScissorState; | |
| 92 bool fHasStencilClip; | 54 bool fHasStencilClip; |
| 93 SkRect fDeviceBounds; | 55 SkRect fDeviceBounds; |
| 94 typedef SkNoncopyable INHERITED; | 56 typedef SkNoncopyable INHERITED; |
| 95 }; | 57 }; |
| 96 | 58 |
| 97 /** | 59 /** |
| 98 * GrClip is an abstract base class for applying a clip. It constructs a clip ma sk if necessary, and | 60 * GrClip is an abstract base class for applying a clip. It constructs a clip ma sk if necessary, and |
| 99 * fills out a GrAppliedClip instructing the caller on how to set up the draw st ate. | 61 * fills out a GrAppliedClip instructing the caller on how to set up the draw st ate. |
| 100 */ | 62 */ |
| 101 class GrClip { | 63 class GrClip { |
| 102 public: | 64 public: |
| 103 virtual bool quickContains(const SkRect&) const = 0; | 65 virtual bool quickContains(const SkRect&) const = 0; |
| 104 virtual void getConservativeBounds(int width, int height, SkIRect* devResult , | 66 virtual void getConservativeBounds(int width, int height, SkIRect* devResult , |
| 105 bool* isIntersectionOfRects = nullptr) co nst = 0; | 67 bool* isIntersectionOfRects = nullptr) co nst = 0; |
| 106 virtual bool apply(GrContext*, | 68 virtual bool apply(GrContext*, GrDrawContext*, bool useHWAA, bool hasUserSte ncilSettings, |
| 107 GrDrawContext*, | |
| 108 const SkRect* devBounds, | |
| 109 bool useHWAA, | |
| 110 bool hasUserStencilSettings, | |
| 111 GrAppliedClip* out) const = 0; | 69 GrAppliedClip* out) const = 0; |
| 112 | 70 |
| 113 virtual ~GrClip() {} | 71 virtual ~GrClip() {} |
| 114 | 72 |
| 115 /** | 73 /** |
| 116 * This is the maximum distance that a draw may extend beyond a clip's bound ary and still count | 74 * This is the maximum distance that a draw may extend beyond a clip's bound ary and still count |
| 117 * count as "on the other side". We leave some slack because floating point rounding error is | 75 * count as "on the other side". We leave some slack because floating point rounding error is |
| 118 * likely to blame. The rationale for 1e-3 is that in the coverage case (and barring unexpected | 76 * likely to blame. The rationale for 1e-3 is that in the coverage case (and barring unexpected |
| 119 * rounding), as long as coverage stays within 0.5 * 1/256 of its intended v alue it shouldn't | 77 * rounding), as long as coverage stays within 0.5 * 1/256 of its intended v alue it shouldn't |
| 120 * have any effect on the final pixel values. | 78 * have any effect on the final pixel values. |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 185 }; | 143 }; |
| 186 | 144 |
| 187 /** | 145 /** |
| 188 * Specialized implementation for no clip. | 146 * Specialized implementation for no clip. |
| 189 */ | 147 */ |
| 190 class GrNoClip final : public GrClip { | 148 class GrNoClip final : public GrClip { |
| 191 private: | 149 private: |
| 192 bool quickContains(const SkRect&) const final { return true; } | 150 bool quickContains(const SkRect&) const final { return true; } |
| 193 void getConservativeBounds(int width, int height, SkIRect* devResult, | 151 void getConservativeBounds(int width, int height, SkIRect* devResult, |
| 194 bool* isIntersectionOfRects) const final; | 152 bool* isIntersectionOfRects) const final; |
| 195 bool apply(GrContext*, | 153 bool apply(GrContext*, GrDrawContext*, bool, bool, GrAppliedClip*) const fin al { return true; } |
| 196 GrDrawContext*, | |
| 197 const SkRect* /* devBounds */, | |
| 198 bool /* useHWAA */, | |
| 199 bool /* hasUserStencilSettings */, | |
| 200 GrAppliedClip* /* out */) const final { return true; } | |
| 201 }; | 154 }; |
| 202 | 155 |
| 203 /** | 156 /** |
| 204 * GrFixedClip is a clip that can be represented by fixed-function hardware. It never modifies the | 157 * GrFixedClip is a clip that can be represented by fixed-function hardware. It never modifies the |
| 205 * stencil buffer itself, but can be configured to use whatever clip is already there. | 158 * stencil buffer itself, but can be configured to use whatever clip is already there. |
| 206 */ | 159 */ |
| 207 class GrFixedClip final : public GrClip { | 160 class GrFixedClip final : public GrClip { |
| 208 public: | 161 public: |
| 209 GrFixedClip() : fDeviceBounds(SkRect::MakeLargest()), fHasStencilClip(false) {} | 162 GrFixedClip() : fHasStencilClip(false) {} |
| 210 GrFixedClip(const SkIRect& scissorRect) | 163 GrFixedClip(const SkIRect& scissorRect) |
| 211 : fScissorState(scissorRect) | 164 : fScissorState(scissorRect) |
| 212 , fDeviceBounds(SkRect::Make(scissorRect)) | |
| 213 , fHasStencilClip(false) {} | 165 , fHasStencilClip(false) {} |
| 214 | 166 |
| 215 void reset() { | 167 void reset() { |
| 216 fScissorState.setDisabled(); | 168 fScissorState.setDisabled(); |
| 217 fDeviceBounds.setLargest(); | |
| 218 fHasStencilClip = false; | 169 fHasStencilClip = false; |
| 219 } | 170 } |
| 220 | 171 |
| 221 void reset(const SkIRect& scissorRect) { | 172 void reset(const SkIRect& scissorRect) { |
| 222 fScissorState.set(scissorRect); | 173 fScissorState.set(scissorRect); |
| 223 fDeviceBounds = SkRect::Make(scissorRect); | |
| 224 fHasStencilClip = false; | 174 fHasStencilClip = false; |
| 225 } | 175 } |
| 226 | 176 |
| 227 /** | 177 void enableStencilClip() { fHasStencilClip = true; } |
| 228 * Enables stenciling. The stencil bounds is the device space bounds where t he stencil test | 178 void disableStencilClip() { fHasStencilClip = false; } |
| 229 * may pass. | |
| 230 */ | |
| 231 void enableStencilClip(const SkRect& stencilBounds) { | |
| 232 fHasStencilClip = true; | |
| 233 fDeviceBounds = stencilBounds; | |
| 234 if (fScissorState.enabled()) { | |
| 235 const SkIRect& s = fScissorState.rect(); | |
| 236 fDeviceBounds.fLeft = SkTMax(fDeviceBounds.fLeft, SkIntToScalar( s.fLeft)); | |
| 237 fDeviceBounds.fTop = SkTMax(fDeviceBounds.fTop, SkIntToScalar( s.fTop)); | |
| 238 fDeviceBounds.fRight = SkTMin(fDeviceBounds.fRight, SkIntToScalar( s.fRight)); | |
| 239 fDeviceBounds.fBottom = SkTMin(fDeviceBounds.fBottom, SkIntToScalar( s.fBottom)); | |
| 240 } | |
| 241 } | |
| 242 | |
| 243 void disableStencilClip() { | |
| 244 fHasStencilClip = false; | |
| 245 if (fScissorState.enabled()) { | |
| 246 fDeviceBounds = SkRect::Make(fScissorState.rect()); | |
| 247 } else { | |
| 248 fDeviceBounds.setLargest(); | |
| 249 } | |
| 250 } | |
| 251 | |
| 252 const GrScissorState& scissorState() const { return fScissorState; } | |
| 253 bool hasStencilClip() const { return fHasStencilClip; } | |
| 254 | 179 |
| 255 bool quickContains(const SkRect&) const final; | 180 bool quickContains(const SkRect&) const final; |
| 256 void getConservativeBounds(int width, int height, SkIRect* devResult, | 181 void getConservativeBounds(int width, int height, SkIRect* devResult, |
| 257 bool* isIntersectionOfRects) const final; | 182 bool* isIntersectionOfRects) const final; |
| 258 | 183 |
| 259 private: | 184 private: |
| 260 bool apply(GrContext*, | 185 bool apply(GrContext*, GrDrawContext*, bool useHWAA, bool hasUserStencilSett ings, |
| 261 GrDrawContext*, | |
| 262 const SkRect* devBounds, | |
| 263 bool useHWAA, | |
| 264 bool hasUserStencilSettings, | |
| 265 GrAppliedClip* out) const final; | 186 GrAppliedClip* out) const final; |
| 266 | 187 |
| 267 GrScissorState fScissorState; | 188 GrScissorState fScissorState; |
| 268 SkRect fDeviceBounds; | |
|
csmartdalton
2016/08/15 16:05:25
Here we can eventually store a simple SkRect that
| |
| 269 bool fHasStencilClip; | 189 bool fHasStencilClip; |
| 270 }; | 190 }; |
| 271 | 191 |
| 272 #endif | 192 #endif |
| OLD | NEW |