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

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

Issue 2135673002: Don't scissor draws overlapping the render target's edges (Closed) Base URL: https://chromium.googlesource.com/skia.git@hidebounds
Patch Set: Created 4 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 | « include/gpu/GrClip.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 * Copyright 2012 Google Inc. 2 * Copyright 2012 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 #include "GrClipMaskManager.h" 8 #include "GrClipMaskManager.h"
9 #include "GrCaps.h" 9 #include "GrCaps.h"
10 #include "GrDrawingManager.h" 10 #include "GrDrawingManager.h"
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 drawContext, translate, element, nullptr, needsS tencil)) { 139 drawContext, translate, element, nullptr, needsS tencil)) {
140 return true; 140 return true;
141 } 141 }
142 } 142 }
143 return false; 143 return false;
144 } 144 }
145 145
146 static bool get_analytic_clip_processor(const GrReducedClip::ElementList& elemen ts, 146 static bool get_analytic_clip_processor(const GrReducedClip::ElementList& elemen ts,
147 bool abortIfAA, 147 bool abortIfAA,
148 SkVector& clipToRTOffset, 148 SkVector& clipToRTOffset,
149 const SkRect* drawBounds, 149 const SkRect& drawBounds,
150 sk_sp<GrFragmentProcessor>* resultFP) { 150 sk_sp<GrFragmentProcessor>* resultFP) {
151 SkRect boundsInClipSpace; 151 SkRect boundsInClipSpace;
152 if (drawBounds) { 152 boundsInClipSpace = drawBounds.makeOffset(-clipToRTOffset.fX, -clipToRTOffse t.fY);
153 boundsInClipSpace = *drawBounds;
154 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY);
155 }
156 SkASSERT(elements.count() <= kMaxAnalyticElements); 153 SkASSERT(elements.count() <= kMaxAnalyticElements);
157 SkSTArray<kMaxAnalyticElements, sk_sp<GrFragmentProcessor>> fps; 154 SkSTArray<kMaxAnalyticElements, sk_sp<GrFragmentProcessor>> fps;
158 GrReducedClip::ElementList::Iter iter(elements); 155 GrReducedClip::ElementList::Iter iter(elements);
159 while (iter.get()) { 156 while (iter.get()) {
160 SkRegion::Op op = iter.get()->getOp(); 157 SkRegion::Op op = iter.get()->getOp();
161 bool invert; 158 bool invert;
162 bool skip = false; 159 bool skip = false;
163 switch (op) { 160 switch (op) {
164 case SkRegion::kReplace_Op: 161 case SkRegion::kReplace_Op:
165 SkASSERT(iter.get() == elements.head()); 162 SkASSERT(iter.get() == elements.head());
166 // Fallthrough, handled same as intersect. 163 // Fallthrough, handled same as intersect.
167 case SkRegion::kIntersect_Op: 164 case SkRegion::kIntersect_Op:
168 invert = false; 165 invert = false;
169 if (drawBounds && iter.get()->contains(boundsInClipSpace)) { 166 if (iter.get()->contains(boundsInClipSpace)) {
170 skip = true; 167 skip = true;
171 } 168 }
172 break; 169 break;
173 case SkRegion::kDifference_Op: 170 case SkRegion::kDifference_Op:
174 invert = true; 171 invert = true;
175 // We don't currently have a cheap test for whether a rect is fu lly outside an 172 // We don't currently have a cheap test for whether a rect is fu lly outside an
176 // element's primitive, so don't attempt to set skip. 173 // element's primitive, so don't attempt to set skip.
177 break; 174 break;
178 default: 175 default:
179 return false; 176 return false;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 return true; 222 return true;
226 } 223 }
227 224
228 //////////////////////////////////////////////////////////////////////////////// 225 ////////////////////////////////////////////////////////////////////////////////
229 // sort out what kind of clip mask needs to be created: alpha, stencil, 226 // sort out what kind of clip mask needs to be created: alpha, stencil,
230 // scissor, or entirely software 227 // scissor, or entirely software
231 bool GrClipMaskManager::SetupClipping(GrContext* context, 228 bool GrClipMaskManager::SetupClipping(GrContext* context,
232 const GrPipelineBuilder& pipelineBuilder, 229 const GrPipelineBuilder& pipelineBuilder,
233 GrDrawContext* drawContext, 230 GrDrawContext* drawContext,
234 const GrClipStackClip& clip, 231 const GrClipStackClip& clip,
235 const SkRect* devBounds, 232 const SkRect* origDevBounds,
236 GrAppliedClip* out) { 233 GrAppliedClip* out) {
237 if (!clip.clipStack() || clip.clipStack()->isWideOpen()) { 234 if (!clip.clipStack() || clip.clipStack()->isWideOpen()) {
238 return true; 235 return true;
239 } 236 }
240 237
241 GrReducedClip::ElementList elements; 238 GrReducedClip::ElementList elements;
242 int32_t genID = 0; 239 int32_t genID = 0;
243 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat e; 240 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat e;
244 SkIRect clipSpaceIBounds; 241 SkIRect clipSpaceIBounds;
245 bool requiresAA = false; 242 bool requiresAA = false;
246 243
247 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(drawContext->width(), drawConte xt->height());
248 clipSpaceRTIBounds.offset(clip.origin());
249
250 SkIRect clipSpaceReduceQueryBounds; 244 SkIRect clipSpaceReduceQueryBounds;
251 #define DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION 0 245 SkRect devBounds;
252 if (devBounds && !DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION) { 246 if (origDevBounds) {
robertphillips 2016/07/08 14:21:58 Are there any issues with this reject and hairline
bsalomon 2016/07/08 14:25:56 Because of 'empty' rects? No, because GrDT bloats
253 SkIRect devIBounds = devBounds->roundOut(); 247 if (!devBounds.intersect(SkRect::MakeIWH(drawContext->width(), drawConte xt->height()),
254 devIBounds.offset(clip.origin()); 248 *origDevBounds)) {
255 if (!clipSpaceReduceQueryBounds.intersect(clipSpaceRTIBounds, devIBounds )) {
256 return false; 249 return false;
257 } 250 }
251 devBounds.roundOut(&clipSpaceReduceQueryBounds);
252 clipSpaceReduceQueryBounds.offset(clip.origin());
258 } else { 253 } else {
259 clipSpaceReduceQueryBounds = clipSpaceRTIBounds; 254 devBounds = SkRect::MakeIWH(drawContext->width(), drawContext->height()) ;
255 clipSpaceReduceQueryBounds.setXYWH(0, 0, drawContext->width(), drawConte xt->height());
256 clipSpaceReduceQueryBounds.offset(clip.origin());
260 } 257 }
261 GrReducedClip::ReduceClipStack(*clip.clipStack(), 258 GrReducedClip::ReduceClipStack(*clip.clipStack(),
262 clipSpaceReduceQueryBounds, 259 clipSpaceReduceQueryBounds,
263 &elements, 260 &elements,
264 &genID, 261 &genID,
265 &initialState, 262 &initialState,
266 &clipSpaceIBounds, 263 &clipSpaceIBounds,
267 &requiresAA); 264 &requiresAA);
268 if (elements.isEmpty()) { 265 if (elements.isEmpty()) {
269 if (GrReducedClip::kAllIn_InitialState == initialState) { 266 if (GrReducedClip::kAllOut_InitialState == initialState) {
270 if (clipSpaceIBounds == clipSpaceRTIBounds) { 267 return false;
271 return true; 268 } else {
269 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
270 scissorSpaceIBounds.offset(-clip.origin());
271 if (!SkRect::Make(scissorSpaceIBounds).contains(devBounds)) {
272 out->makeScissored(scissorSpaceIBounds);
272 } 273 }
273 } else { 274 return true;
274 return false;
275 } 275 }
276 } 276 }
277 277
278 // An element count of 4 was chosen because of the common pattern in Blink o f: 278 // An element count of 4 was chosen because of the common pattern in Blink o f:
279 // isect RR 279 // isect RR
280 // diff RR 280 // diff RR
281 // isect convex_poly 281 // isect convex_poly
282 // isect convex_poly 282 // isect convex_poly
283 // when drawing rounded div borders. This could probably be tuned based on a 283 // when drawing rounded div borders. This could probably be tuned based on a
284 // configuration's relative costs of switching RTs to generate a mask vs 284 // configuration's relative costs of switching RTs to generate a mask vs
285 // longer shaders. 285 // longer shaders.
286 if (elements.count() <= kMaxAnalyticElements) { 286 if (elements.count() <= kMaxAnalyticElements) {
287 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX), 287 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX),
288 SkIntToScalar(-clip.origin().fY) }; 288 SkIntToScalar(-clip.origin().fY) };
289 // When there are multiple samples we want to do per-sample clipping, no t compute a 289 // When there are multiple samples we want to do per-sample clipping, no t compute a
290 // fractional pixel coverage. 290 // fractional pixel coverage.
291 bool disallowAnalyticAA = drawContext->isStencilBufferMultisampled(); 291 bool disallowAnalyticAA = drawContext->isStencilBufferMultisampled();
292 if (disallowAnalyticAA && !drawContext->numColorSamples()) { 292 if (disallowAnalyticAA && !drawContext->numColorSamples()) {
293 // With a single color sample, any coverage info is lost from color once it hits the 293 // With a single color sample, any coverage info is lost from color once it hits the
294 // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe 294 // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe
295 // is multisampled. 295 // is multisampled.
296 disallowAnalyticAA = pipelineBuilder.isHWAntialias() || 296 disallowAnalyticAA = pipelineBuilder.isHWAntialias() ||
297 pipelineBuilder.hasUserStencilSettings(); 297 pipelineBuilder.hasUserStencilSettings();
298 } 298 }
299 sk_sp<GrFragmentProcessor> clipFP; 299 sk_sp<GrFragmentProcessor> clipFP;
300 if (elements.isEmpty() || 300 if (requiresAA &&
301 (requiresAA && 301 get_analytic_clip_processor(elements, disallowAnalyticAA, clipToRTOf fset, devBounds,
302 get_analytic_clip_processor(elements, disallowAnalyticAA, clipToRTO ffset, devBounds, 302 &clipFP)) {
303 &clipFP))) {
304 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 303 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
305 scissorSpaceIBounds.offset(-clip.origin()); 304 scissorSpaceIBounds.offset(-clip.origin());
306 if (!devBounds || !SkRect::Make(scissorSpaceIBounds).contains(*devBo unds)) { 305 if (!SkRect::Make(scissorSpaceIBounds).contains(devBounds)) {
307 out->makeScissoredFPBased(std::move(clipFP), scissorSpaceIBounds ); 306 out->makeScissoredFPBased(std::move(clipFP), scissorSpaceIBounds );
308 return true; 307 return true;
309 } 308 }
310 out->makeFPBased(std::move(clipFP)); 309 out->makeFPBased(std::move(clipFP));
311 return true; 310 return true;
312 } 311 }
313 } 312 }
314 313
315 // If the stencil buffer is multisampled we can use it to do everything. 314 // If the stencil buffer is multisampled we can use it to do everything.
316 if (!drawContext->isStencilBufferMultisampled() && requiresAA) { 315 if (!drawContext->isStencilBufferMultisampled() && requiresAA) {
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after
798 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); 797 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc));
799 if (!result) { 798 if (!result) {
800 return nullptr; 799 return nullptr;
801 } 800 }
802 result->resourcePriv().setUniqueKey(key); 801 result->resourcePriv().setUniqueKey(key);
803 802
804 helper.toTexture(result.get()); 803 helper.toTexture(result.get());
805 804
806 return result; 805 return result;
807 } 806 }
OLDNEW
« no previous file with comments | « include/gpu/GrClip.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698