Line data Source code
1 : /*
2 : * Copyright 2015 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 GrClearOp_DEFINED
9 : #define GrClearOp_DEFINED
10 :
11 : #include "GrFixedClip.h"
12 : #include "GrGpu.h"
13 : #include "GrGpuCommandBuffer.h"
14 : #include "GrOp.h"
15 : #include "GrOpFlushState.h"
16 : #include "GrRenderTarget.h"
17 :
18 0 : class GrClearOp final : public GrOp {
19 : public:
20 0 : DEFINE_OP_CLASS_ID
21 :
22 : // MDB TODO: replace the renderTargetContext with just the renderTargetProxy.
23 : // For now, we need the renderTargetContext for its accessRenderTarget powers.
24 0 : static std::unique_ptr<GrClearOp> Make(const GrFixedClip& clip, GrColor color,
25 : GrRenderTargetContext* rtc) {
26 0 : const SkIRect rtRect = SkIRect::MakeWH(rtc->width(), rtc->height());
27 0 : if (clip.scissorEnabled() && !SkIRect::Intersects(clip.scissorRect(), rtRect)) {
28 0 : return nullptr;
29 : }
30 :
31 : // MDB TODO: remove this. In this hybrid state we need to be sure the RT is instantiable
32 : // so it can carry the IO refs. In the future we will just get the proxy and
33 : // it carry the IO refs.
34 0 : if (!rtc->accessRenderTarget()) {
35 0 : return nullptr;
36 : }
37 :
38 0 : return std::unique_ptr<GrClearOp>(new GrClearOp(clip, color, rtc));
39 : }
40 :
41 : // MDB TODO: replace the renderTargetContext with just the renderTargetProxy.
42 0 : static std::unique_ptr<GrClearOp> Make(const SkIRect& rect, GrColor color,
43 : GrRenderTargetContext* rtc,
44 : bool fullScreen) {
45 0 : SkASSERT(fullScreen || !rect.isEmpty());
46 :
47 : // MDB TODO: remove this. See above comment.
48 0 : if (!rtc->accessRenderTarget()) {
49 0 : return nullptr;
50 : }
51 :
52 0 : return std::unique_ptr<GrClearOp>(new GrClearOp(rect, color, rtc, fullScreen));
53 : }
54 :
55 0 : const char* name() const override { return "Clear"; }
56 :
57 0 : SkString dumpInfo() const override {
58 0 : SkString string;
59 0 : string.appendf("rtID: %d proxyID: %d Scissor [",
60 0 : fRenderTarget.get()->uniqueID().asUInt(),
61 0 : fProxyUniqueID.asUInt());
62 0 : if (fClip.scissorEnabled()) {
63 0 : const SkIRect& r = fClip.scissorRect();
64 0 : string.appendf("L: %d, T: %d, R: %d, B: %d", r.fLeft, r.fTop, r.fRight, r.fBottom);
65 : } else {
66 0 : string.append("disabled");
67 : }
68 0 : string.appendf("], Color: 0x%08x ", fColor);
69 0 : string.append(INHERITED::dumpInfo());
70 0 : return string;
71 : }
72 :
73 0 : void setColor(GrColor color) { fColor = color; }
74 :
75 : private:
76 0 : GrClearOp(const GrFixedClip& clip, GrColor color, GrRenderTargetContext* rtc)
77 0 : : INHERITED(ClassID())
78 : , fClip(clip)
79 : , fColor(color)
80 0 : , fProxyUniqueID(rtc->asSurfaceProxy()->uniqueID()) {
81 :
82 0 : GrSurfaceProxy* proxy = rtc->asSurfaceProxy();
83 0 : const SkIRect rtRect = SkIRect::MakeWH(proxy->width(), proxy->height());
84 0 : if (fClip.scissorEnabled()) {
85 : // Don't let scissors extend outside the RT. This may improve op combining.
86 0 : if (!fClip.intersect(rtRect)) {
87 0 : SkASSERT(0); // should be caught upstream
88 0 : fClip = GrFixedClip(SkIRect::MakeEmpty());
89 : }
90 :
91 0 : if (GrResourceProvider::IsFunctionallyExact(proxy) && fClip.scissorRect() == rtRect) {
92 0 : fClip.disableScissor();
93 : }
94 : }
95 0 : this->setBounds(SkRect::Make(fClip.scissorEnabled() ? fClip.scissorRect() : rtRect),
96 0 : HasAABloat::kNo, IsZeroArea::kNo);
97 0 : fRenderTarget.reset(rtc->accessRenderTarget());
98 0 : }
99 :
100 0 : GrClearOp(const SkIRect& rect, GrColor color, GrRenderTargetContext* rtc, bool fullScreen)
101 0 : : INHERITED(ClassID())
102 : , fClip(GrFixedClip(rect))
103 : , fColor(color)
104 0 : , fProxyUniqueID(rtc->asSurfaceProxy()->uniqueID()) {
105 :
106 0 : if (fullScreen) {
107 0 : fClip.disableScissor();
108 : }
109 0 : this->setBounds(SkRect::Make(rect), HasAABloat::kNo, IsZeroArea::kNo);
110 0 : fRenderTarget.reset(rtc->accessRenderTarget());
111 0 : }
112 :
113 0 : bool onCombineIfPossible(GrOp* t, const GrCaps& caps) override {
114 : // This could be much more complicated. Currently we look at cases where the new clear
115 : // contains the old clear, or when the new clear is a subset of the old clear and is the
116 : // same color.
117 0 : GrClearOp* cb = t->cast<GrClearOp>();
118 0 : SkASSERT(cb->fRenderTarget == fRenderTarget);
119 0 : SkASSERT(cb->fProxyUniqueID == fProxyUniqueID);
120 0 : if (fClip.windowRectsState() != cb->fClip.windowRectsState()) {
121 0 : return false;
122 : }
123 0 : if (cb->contains(this)) {
124 0 : fClip = cb->fClip;
125 0 : this->replaceBounds(*t);
126 0 : fColor = cb->fColor;
127 0 : return true;
128 0 : } else if (cb->fColor == fColor && this->contains(cb)) {
129 0 : return true;
130 : }
131 0 : return false;
132 : }
133 :
134 0 : bool contains(const GrClearOp* that) const {
135 : // The constructor ensures that scissor gets disabled on any clip that fills the entire RT.
136 0 : return !fClip.scissorEnabled() ||
137 0 : (that->fClip.scissorEnabled() &&
138 0 : fClip.scissorRect().contains(that->fClip.scissorRect()));
139 : }
140 :
141 0 : void onPrepare(GrOpFlushState*) override {}
142 :
143 0 : void onExecute(GrOpFlushState* state) override {
144 : // MDB TODO: instantiate the renderTarget from the proxy in here
145 0 : state->commandBuffer()->clear(fRenderTarget.get(), fClip, fColor);
146 0 : }
147 :
148 : GrFixedClip fClip;
149 : GrColor fColor;
150 :
151 : // MDB TODO: remove this. When the renderTargetProxy carries the refs this will be redundant.
152 : GrSurfaceProxy::UniqueID fProxyUniqueID;
153 : GrPendingIOResource<GrRenderTarget, kWrite_GrIOType> fRenderTarget;
154 :
155 : typedef GrOp INHERITED;
156 : };
157 :
158 : #endif
|