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

Side by Side Diff: src/gpu/GrClipMaskManager.cpp

Issue 367013003: Remove the AA requirement for selecting GrEffect-based clipping. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: remove bogus assert Created 6 years, 5 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 unified diff | Download patch
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2012 Google Inc. 3 * Copyright 2012 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "GrClipMaskManager.h" 9 #include "GrClipMaskManager.h"
10 #include "GrAAConvexPathRenderer.h" 10 #include "GrAAConvexPathRenderer.h"
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 return true; 103 return true;
104 } 104 }
105 } 105 }
106 } 106 }
107 return false; 107 return false;
108 } 108 }
109 109
110 bool GrClipMaskManager::installClipEffects(const ElementList& elements, 110 bool GrClipMaskManager::installClipEffects(const ElementList& elements,
111 GrDrawState::AutoRestoreEffects* are, 111 GrDrawState::AutoRestoreEffects* are,
112 const SkVector& clipToRTOffset, 112 const SkVector& clipToRTOffset,
113 const SkRect* drawBounds) { 113 const SkRect* drawBounds,
114 SkIRect* scissorRect) {
115
116 SkASSERT(NULL != scissorRect);
114 117
115 GrDrawState* drawState = fGpu->drawState(); 118 GrDrawState* drawState = fGpu->drawState();
116 SkRect boundsInClipSpace; 119 SkRect boundsInClipSpace;
117 if (NULL != drawBounds) { 120 if (NULL != drawBounds) {
118 boundsInClipSpace = *drawBounds; 121 boundsInClipSpace = *drawBounds;
119 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); 122 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY);
120 } 123 }
121 124
122 are->set(drawState); 125 are->set(drawState);
123 GrRenderTarget* rt = drawState->getRenderTarget(); 126 GrRenderTarget* rt = drawState->getRenderTarget();
124 ElementList::Iter iter(elements); 127 // We iterate from the top of the stack to the bottom. We do this because we select the first
128 // BW rectangle as the scissor. Clients performing hierarchical rendering te nd to use smaller
129 // clips towards the top of the clip stack. Smaller scissor rects can help t iled architectures
130 // skip processing tiles for draws.
131 ElementList::Iter iter(elements, ElementList::Iter::kTail_IterStart);
125 132
126 bool setARE = false; 133 bool setARE = false;
127 bool failed = false; 134 bool failed = false;
128 135
129 while (NULL != iter.get()) { 136 while (NULL != iter.get()) {
130 SkRegion::Op op = iter.get()->getOp(); 137 SkRegion::Op op = iter.get()->getOp();
131 bool invert; 138 bool invert;
132 bool skip = false; 139 bool skip = false;
133 switch (op) { 140 switch (op) {
134 case SkRegion::kReplace_Op: 141 case SkRegion::kReplace_Op:
(...skipping 15 matching lines...) Expand all
150 break; 157 break;
151 } 158 }
152 if (failed) { 159 if (failed) {
153 break; 160 break;
154 } 161 }
155 162
156 if (!skip) { 163 if (!skip) {
157 GrEffectEdgeType edgeType; 164 GrEffectEdgeType edgeType;
158 if (GR_AA_CLIP && iter.get()->isAA()) { 165 if (GR_AA_CLIP && iter.get()->isAA()) {
159 if (rt->isMultisampled()) { 166 if (rt->isMultisampled()) {
160 // Coverage based AA clips don't place nicely with MSAA. 167 // Coverage based AA clips don't play nicely with MSAA.
161 failed = true; 168 failed = true;
162 break; 169 break;
163 } 170 }
164 edgeType = invert ? kInverseFillAA_GrEffectEdgeType : kFillAA_Gr EffectEdgeType; 171 edgeType = invert ? kInverseFillAA_GrEffectEdgeType : kFillAA_Gr EffectEdgeType;
165 } else { 172 } else {
166 edgeType = invert ? kInverseFillBW_GrEffectEdgeType : kFillBW_Gr EffectEdgeType; 173 edgeType = invert ? kInverseFillBW_GrEffectEdgeType : kFillBW_Gr EffectEdgeType;
167 } 174 }
175 // We don't want to exit if we convert a BW rect clip to a scissor.
176 bool failIfNoEffect = true;
168 SkAutoTUnref<GrEffectRef> effect; 177 SkAutoTUnref<GrEffectRef> effect;
169 switch (iter.get()->getType()) { 178 switch (iter.get()->getType()) {
170 case SkClipStack::Element::kPath_Type: 179 case SkClipStack::Element::kPath_Type:
171 effect.reset(GrConvexPolyEffect::Create(edgeType, iter.get() ->getPath(), 180 effect.reset(GrConvexPolyEffect::Create(edgeType, iter.get() ->getPath(),
172 &clipToRTOffset)); 181 &clipToRTOffset));
173 break; 182 break;
174 case SkClipStack::Element::kRRect_Type: { 183 case SkClipStack::Element::kRRect_Type: {
175 SkRRect rrect = iter.get()->getRRect(); 184 SkRRect rrect = iter.get()->getRRect();
176 rrect.offset(clipToRTOffset.fX, clipToRTOffset.fY); 185 rrect.offset(clipToRTOffset.fX, clipToRTOffset.fY);
177 effect.reset(GrRRectEffect::Create(edgeType, rrect)); 186 effect.reset(GrRRectEffect::Create(edgeType, rrect));
178 break; 187 break;
179 } 188 }
180 case SkClipStack::Element::kRect_Type: { 189 case SkClipStack::Element::kRect_Type: {
181 SkRect rect = iter.get()->getRect(); 190 SkRect rect = iter.get()->getRect();
182 rect.offset(clipToRTOffset.fX, clipToRTOffset.fY); 191 rect.offset(clipToRTOffset.fX, clipToRTOffset.fY);
183 effect.reset(GrConvexPolyEffect::Create(edgeType, rect)); 192 if (kFillBW_GrEffectEdgeType == edgeType && scissorRect->isE mpty()) {
193 // This is OK because we only allow clip operations that shrink the clip
194 // to be implemented as effects.
195 rect.roundOut(scissorRect);
196 failIfNoEffect = false;
197 } else {
198 effect.reset(GrConvexPolyEffect::Create(edgeType, rect)) ;
199 }
184 break; 200 break;
185 } 201 }
186 default: 202 default:
187 break; 203 break;
188 } 204 }
189 if (effect) { 205 if (effect) {
190 if (!setARE) { 206 if (!setARE) {
191 are->set(fGpu->drawState()); 207 are->set(fGpu->drawState());
192 setARE = true; 208 setARE = true;
193 } 209 }
194 fGpu->drawState()->addCoverageEffect(effect); 210 fGpu->drawState()->addCoverageEffect(effect);
195 } else { 211 } else if (failIfNoEffect) {
196 failed = true; 212 failed = true;
197 break; 213 break;
198 } 214 }
199 } 215 }
200 iter.next(); 216 iter.prev();
201 } 217 }
202 218
203 if (failed) { 219 if (failed) {
204 are->set(NULL); 220 are->set(NULL);
205 } 221 }
206 222
207 return !failed; 223 return !failed;
208 } 224 }
209 225
226 static inline bool rect_contains_irect(const SkIRect ir, const SkRect& r) {
227 SkASSERT(!ir.isEmpty());
228 return ir.fLeft <= r.fLeft && ir.fTop <= r.fTop &&
229 ir.fRight >= r.fRight && ir.fBottom >= r.fBottom;
230 }
231
210 //////////////////////////////////////////////////////////////////////////////// 232 ////////////////////////////////////////////////////////////////////////////////
211 // sort out what kind of clip mask needs to be created: alpha, stencil, 233 // sort out what kind of clip mask needs to be created: alpha, stencil,
212 // scissor, or entirely software 234 // scissor, or entirely software
213 bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, 235 bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
214 GrDrawState::AutoRestoreEffects* are, 236 GrDrawState::AutoRestoreEffects* are,
215 const SkRect* devBounds) { 237 const SkRect* devBounds) {
216 fCurrClipMaskType = kNone_ClipMaskType; 238 fCurrClipMaskType = kNone_ClipMaskType;
217 239
218 ElementList elements(16); 240 ElementList elements(16);
219 int32_t genID; 241 int32_t genID;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
256 278
257 // An element count of 4 was chosen because of the common pattern in Blink o f: 279 // An element count of 4 was chosen because of the common pattern in Blink o f:
258 // isect RR 280 // isect RR
259 // diff RR 281 // diff RR
260 // isect convex_poly 282 // isect convex_poly
261 // isect convex_poly 283 // isect convex_poly
262 // when drawing rounded div borders. This could probably be tuned based on a 284 // when drawing rounded div borders. This could probably be tuned based on a
263 // configuration's relative costs of switching RTs to generate a mask vs 285 // configuration's relative costs of switching RTs to generate a mask vs
264 // longer shaders. 286 // longer shaders.
265 if (elements.count() <= 4) { 287 if (elements.count() <= 4) {
288 SkIRect scissorRect;
289 scissorRect.setEmpty();
266 SkVector clipToRTOffset = { SkIntToScalar(-clipDataIn->fOrigin.fX), 290 SkVector clipToRTOffset = { SkIntToScalar(-clipDataIn->fOrigin.fX),
267 SkIntToScalar(-clipDataIn->fOrigin.fY) }; 291 SkIntToScalar(-clipDataIn->fOrigin.fY) };
268 if (elements.isEmpty() || 292 if (elements.isEmpty() ||
269 (requiresAA && this->installClipEffects(elements, are, clipToRTOffse t, devBounds))) { 293 this->installClipEffects(elements, are, clipToRTOffset, devBounds, & scissorRect)) {
270 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 294 if (scissorRect.isEmpty()) {
271 scissorSpaceIBounds.offset(-clipDataIn->fOrigin); 295 // We may still want to use a scissor, especially on tiled archi tectures.
272 if (NULL == devBounds || 296 scissorRect = clipSpaceIBounds;
273 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { 297 scissorRect.offset(-clipDataIn->fOrigin);
274 fGpu->enableScissor(scissorSpaceIBounds); 298 if (NULL == devBounds ||
299 !rect_contains_irect(scissorRect, *devBounds)) {
300 fGpu->enableScissor(scissorRect);
301 } else {
302 // When the vertices that will be rendered fit fully inside the clip's bounds
303 // then providing the scissor rect will not help the driver eliminate tiles
304 // from consideration for the draw, but changing the scissor will cause
305 // state changes between draws.
306 fGpu->disableScissor();
307 }
275 } else { 308 } else {
276 fGpu->disableScissor(); 309 scissorRect.fLeft = SkTMax(0, scissorRect.fLeft);
310 scissorRect.fTop = SkTMax(0, scissorRect.fTop);
311 scissorRect.fRight = SkTMin(rt->width(), scissorRect.fRight);
312 scissorRect.fBottom = SkTMin(rt->height(), scissorRect.fBottom);
313 fGpu->enableScissor(scissorRect);
277 } 314 }
278 this->setGpuStencil(); 315 this->setGpuStencil();
279 return true; 316 return true;
280 } 317 }
281 } 318 }
282 319
283 #if GR_AA_CLIP 320 #if GR_AA_CLIP
284 // If MSAA is enabled we can do everything in the stencil buffer. 321 // If MSAA is enabled we can do everything in the stencil buffer.
285 if (0 == rt->numSamples() && requiresAA) { 322 if (0 == rt->numSamples() && requiresAA) {
286 GrTexture* result = NULL; 323 GrTexture* result = NULL;
(...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after
1139 1176
1140 // TODO: dynamically attach a stencil buffer 1177 // TODO: dynamically attach a stencil buffer
1141 int stencilBits = 0; 1178 int stencilBits = 0;
1142 GrStencilBuffer* stencilBuffer = 1179 GrStencilBuffer* stencilBuffer =
1143 drawState.getRenderTarget()->getStencilBuffer(); 1180 drawState.getRenderTarget()->getStencilBuffer();
1144 if (NULL != stencilBuffer) { 1181 if (NULL != stencilBuffer) {
1145 stencilBits = stencilBuffer->bits(); 1182 stencilBits = stencilBuffer->bits();
1146 this->adjustStencilParams(settings, clipMode, stencilBits); 1183 this->adjustStencilParams(settings, clipMode, stencilBits);
1147 } 1184 }
1148 } 1185 }
OLDNEW
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698