1/*
2 * Copyright 2017 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrStencilClip_DEFINED
9#define GrStencilClip_DEFINED
10
11#include "src/gpu/GrAppliedClip.h"
12#include "src/gpu/GrFixedClip.h"
13
14/**
15 * Implements GrHardClip with the currently-existing stencil buffer contents and GrFixedClip.
16 */
17class GrStencilClip final : public GrHardClip {
18public:
19 explicit GrStencilClip(const SkISize& rtDims, uint32_t stencilStackID = SK_InvalidGenID)
20 : fFixedClip(rtDims)
21 , fStencilStackID(stencilStackID) {}
22
23 GrStencilClip(const SkISize& rtDims, const SkIRect& scissorRect,
24 uint32_t stencilStackID = SK_InvalidGenID)
25 : fFixedClip(rtDims, scissorRect)
26 , fStencilStackID(stencilStackID) {}
27
28 const GrFixedClip& fixedClip() const { return fFixedClip; }
29 GrFixedClip& fixedClip() { return fFixedClip; }
30
31 uint32_t stencilStackID() const { return fStencilStackID; }
32 bool hasStencilClip() const { return SK_InvalidGenID != fStencilStackID; }
33 void setStencilClip(uint32_t stencilStackID) { fStencilStackID = stencilStackID; }
34
35 SkIRect getConservativeBounds() const final {
36 return fFixedClip.getConservativeBounds();
37 }
38
39 Effect apply(GrAppliedHardClip* out, SkIRect* bounds) const final {
40 Effect effect = fFixedClip.apply(out, bounds);
41 if (effect == Effect::kClippedOut) {
42 // Stencil won't bring back coverage
43 return Effect::kClippedOut;
44 }
45 if (this->hasStencilClip()) {
46 out->addStencilClip(fStencilStackID);
47 effect = Effect::kClipped;
48 }
49 return effect;
50 }
51
52 PreClipResult preApply(const SkRect& drawBounds, GrAA aa) const final {
53 if (this->hasStencilClip()) {
54 return this->INHERITED::preApply(drawBounds, aa);
55 } else {
56 return fFixedClip.preApply(drawBounds, aa);
57 }
58 }
59
60private:
61 GrFixedClip fFixedClip;
62 uint32_t fStencilStackID;
63
64 typedef GrClip INHERITED;
65};
66
67#endif
68