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

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

Issue 2246113002: Convert GrAppliedClip interface to builder style (Closed) Base URL: https://skia.googlesource.com/skia.git@fixstencilpath
Patch Set: Convert GrAppliedClip interface to builder style Created 4 years, 4 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/GrClipStackClip.h ('k') | src/gpu/GrDrawTarget.cpp » ('j') | 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 2016 Google Inc. 2 * Copyright 2016 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 "GrClipStackClip.h" 8 #include "GrClipStackClip.h"
9 9
10 #include "GrDrawingManager.h" 10 #include "GrDrawingManager.h"
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 *resultFP = nullptr; 235 *resultFP = nullptr;
236 if (fps.count()) { 236 if (fps.count()) {
237 *resultFP = GrFragmentProcessor::RunInSeries(fps.begin(), fps.count()); 237 *resultFP = GrFragmentProcessor::RunInSeries(fps.begin(), fps.count());
238 } 238 }
239 return true; 239 return true;
240 } 240 }
241 241
242 //////////////////////////////////////////////////////////////////////////////// 242 ////////////////////////////////////////////////////////////////////////////////
243 // sort out what kind of clip mask needs to be created: alpha, stencil, 243 // sort out what kind of clip mask needs to be created: alpha, stencil,
244 // scissor, or entirely software 244 // scissor, or entirely software
245 bool GrClipStackClip::apply(GrContext* context, 245 bool GrClipStackClip::apply(GrContext* context, GrDrawContext* drawContext, bool useHWAA,
246 GrDrawContext* drawContext, 246 bool hasUserStencilSettings, GrAppliedClip* out) con st {
247 const SkRect* origDevBounds,
248 bool useHWAA,
249 bool hasUserStencilSettings,
250 GrAppliedClip* out) const {
251 if (!fStack || fStack->isWideOpen()) { 247 if (!fStack || fStack->isWideOpen()) {
252 return true; 248 return true;
253 } 249 }
254 250
255 SkRect devBounds = SkRect::MakeIWH(drawContext->width(), drawContext->height ()); 251 SkRect devBounds = SkRect::MakeIWH(drawContext->width(), drawContext->height ());
256 if (origDevBounds && !devBounds.intersect(*origDevBounds)) { 252 if (!devBounds.intersect(out->clippedDrawBounds())) {
257 return false; 253 return false;
258 } 254 }
259 255
260 const SkScalar clipX = SkIntToScalar(fOrigin.x()), 256 const SkScalar clipX = SkIntToScalar(fOrigin.x()),
261 clipY = SkIntToScalar(fOrigin.y()); 257 clipY = SkIntToScalar(fOrigin.y());
262 258
263 SkRect clipSpaceDevBounds = devBounds.makeOffset(clipX, clipY); 259 SkRect clipSpaceDevBounds = devBounds.makeOffset(clipX, clipY);
264 const GrReducedClip reducedClip(*fStack, clipSpaceDevBounds); 260 const GrReducedClip reducedClip(*fStack, clipSpaceDevBounds);
265 261
262 if (reducedClip.hasIBounds() &&
263 !GrClip::IsInsideClip(reducedClip.ibounds(), clipSpaceDevBounds)) {
264 SkIRect scissorSpaceIBounds(reducedClip.ibounds());
265 scissorSpaceIBounds.offset(-fOrigin);
266 out->addScissor(scissorSpaceIBounds);
267 }
268
266 if (reducedClip.elements().isEmpty()) { 269 if (reducedClip.elements().isEmpty()) {
267 if (GrReducedClip::InitialState::kAllOut == reducedClip.initialState()) { 270 return InitialState::kAllIn == reducedClip.initialState();
268 return false;
269 }
270 if (!GrClip::IsInsideClip(reducedClip.iBounds(), clipSpaceDevBounds)) {
271 SkIRect scissorSpaceIBounds(reducedClip.iBounds());
272 scissorSpaceIBounds.offset(-fOrigin);
273 out->makeScissored(scissorSpaceIBounds);
274 }
275 return true;
276 } 271 }
277 272
273 SkASSERT(reducedClip.hasIBounds());
274
278 // An element count of 4 was chosen because of the common pattern in Blink o f: 275 // An element count of 4 was chosen because of the common pattern in Blink o f:
279 // isect RR 276 // isect RR
280 // diff RR 277 // diff RR
281 // isect convex_poly 278 // isect convex_poly
282 // isect convex_poly 279 // isect convex_poly
283 // when drawing rounded div borders. This could probably be tuned based on a 280 // 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 281 // configuration's relative costs of switching RTs to generate a mask vs
285 // longer shaders. 282 // longer shaders.
286 if (reducedClip.elements().count() <= kMaxAnalyticElements) { 283 if (reducedClip.elements().count() <= kMaxAnalyticElements) {
287 // When there are multiple samples we want to do per-sample clipping, no t compute a 284 // When there are multiple samples we want to do per-sample clipping, no t compute a
288 // fractional pixel coverage. 285 // fractional pixel coverage.
289 bool disallowAnalyticAA = drawContext->isStencilBufferMultisampled(); 286 bool disallowAnalyticAA = drawContext->isStencilBufferMultisampled();
290 if (disallowAnalyticAA && !drawContext->numColorSamples()) { 287 if (disallowAnalyticAA && !drawContext->numColorSamples()) {
291 // With a single color sample, any coverage info is lost from color once it hits the 288 // With a single color sample, any coverage info is lost from color once it hits the
292 // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe 289 // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe
293 // is multisampled. 290 // is multisampled.
294 disallowAnalyticAA = useHWAA || hasUserStencilSettings; 291 disallowAnalyticAA = useHWAA || hasUserStencilSettings;
295 } 292 }
296 sk_sp<GrFragmentProcessor> clipFP; 293 sk_sp<GrFragmentProcessor> clipFP;
297 if (reducedClip.requiresAA() && 294 if (reducedClip.requiresAA() &&
298 get_analytic_clip_processor(reducedClip.elements(), disallowAnalytic AA, 295 get_analytic_clip_processor(reducedClip.elements(), disallowAnalytic AA,
299 {-clipX, -clipY}, devBounds, &clipFP)) { 296 {-clipX, -clipY}, devBounds, &clipFP)) {
300 SkIRect scissorSpaceIBounds(reducedClip.iBounds()); 297 out->addCoverageFP(std::move(clipFP));
301 scissorSpaceIBounds.offset(-fOrigin);
302 if (GrClip::IsInsideClip(scissorSpaceIBounds, devBounds)) {
303 out->makeFPBased(std::move(clipFP), SkRect::Make(scissorSpaceIBo unds));
304 } else {
305 out->makeScissoredFPBased(std::move(clipFP), scissorSpaceIBounds );
306 }
307 return true; 298 return true;
308 } 299 }
309 } 300 }
310 301
311 // If the stencil buffer is multisampled we can use it to do everything. 302 // If the stencil buffer is multisampled we can use it to do everything.
312 if (!drawContext->isStencilBufferMultisampled() && reducedClip.requiresAA()) { 303 if (!drawContext->isStencilBufferMultisampled() && reducedClip.requiresAA()) {
313 sk_sp<GrTexture> result; 304 sk_sp<GrTexture> result;
314 305
315 // The top-left of the mask corresponds to the top-left corner of the bo unds. 306 // The top-left of the mask corresponds to the top-left corner of the bo unds.
316 SkVector clipToMaskOffset = { 307 SkVector clipToMaskOffset = {
317 SkIntToScalar(-reducedClip.left()), 308 SkIntToScalar(-reducedClip.left()),
318 SkIntToScalar(-reducedClip.top()) 309 SkIntToScalar(-reducedClip.top())
319 }; 310 };
320 311
321 if (UseSWOnlyPath(context, hasUserStencilSettings, drawContext, 312 if (UseSWOnlyPath(context, hasUserStencilSettings, drawContext,
322 clipToMaskOffset, reducedClip.elements())) { 313 clipToMaskOffset, reducedClip.elements())) {
323 // The clip geometry is complex enough that it will be more efficien t to create it 314 // The clip geometry is complex enough that it will be more efficien t to create it
324 // entirely in software 315 // entirely in software
325 result = CreateSoftwareClipMask(context->textureProvider(), reducedC lip, 316 result = CreateSoftwareClipMask(context->textureProvider(), reducedC lip,
326 clipToMaskOffset); 317 clipToMaskOffset);
327 } else { 318 } else {
328 result = CreateAlphaClipMask(context, reducedClip, clipToMaskOffset) ; 319 result = CreateAlphaClipMask(context, reducedClip, clipToMaskOffset) ;
329 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug 320 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug
330 SkASSERT(result); 321 SkASSERT(result);
331 } 322 }
332 323
333 if (result) { 324 if (result) {
334 // The mask's top left coord should be pinned to the rounded-out top left corner of 325 // The mask's top left coord should be pinned to the rounded-out top left corner of
335 // clipSpace bounds. We determine the mask's position WRT to the ren der target here. 326 // clipSpace bounds. We determine the mask's position WRT to the ren der target here.
336 SkIRect rtSpaceMaskBounds = reducedClip.iBounds(); 327 SkIRect rtSpaceMaskBounds = reducedClip.ibounds();
337 rtSpaceMaskBounds.offset(-fOrigin); 328 rtSpaceMaskBounds.offset(-fOrigin);
338 out->makeFPBased(create_fp_for_mask(result.get(), rtSpaceMaskBounds) , 329 out->addCoverageFP(create_fp_for_mask(result.get(), rtSpaceMaskBound s));
339 SkRect::Make(rtSpaceMaskBounds));
340 return true; 330 return true;
341 } 331 }
342 // if alpha clip mask creation fails fall through to the non-AA code pat hs 332 // if alpha clip mask creation fails fall through to the non-AA code pat hs
343 } 333 }
344 334
345 // use the stencil clip if we can't represent the clip as a rectangle. 335 // use the stencil clip if we can't represent the clip as a rectangle.
346 SkIPoint clipSpaceToStencilSpaceOffset = -fOrigin; 336 SkIPoint clipSpaceToStencilSpaceOffset = -fOrigin;
347 CreateStencilClipMask(context, drawContext, reducedClip, clipSpaceToStencilS paceOffset); 337 CreateStencilClipMask(context, drawContext, reducedClip, clipSpaceToStencilS paceOffset);
348 338 out->addStencilClip();
349 // This must occur after createStencilClipMask. That function may change the scissor. Also, it
350 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must
351 // use both stencil and scissor test to the bounds for the final draw.
352 if (GrClip::IsInsideClip(reducedClip.iBounds(), clipSpaceDevBounds)) {
353 out->makeStencil(true, devBounds);
354 } else {
355 SkIRect scissorSpaceIBounds(reducedClip.iBounds());
356 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
357 out->makeScissoredStencil(scissorSpaceIBounds);
358 }
359 return true; 339 return true;
360 } 340 }
361 341
362 static bool stencil_element(GrDrawContext* dc, 342 static bool stencil_element(GrDrawContext* dc,
363 const GrFixedClip& clip, 343 const GrFixedClip& clip,
364 const GrUserStencilSettings* ss, 344 const GrUserStencilSettings* ss,
365 const SkMatrix& viewMatrix, 345 const SkMatrix& viewMatrix,
366 const SkClipStack::Element* element) { 346 const SkClipStack::Element* element) {
367 347
368 // TODO: Draw rrects directly here. 348 // TODO: Draw rrects directly here.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
431 builder[0] = clipGenID; 411 builder[0] = clipGenID;
432 builder[1] = SkToU16(bounds.fLeft) | (SkToU16(bounds.fRight) << 16); 412 builder[1] = SkToU16(bounds.fLeft) | (SkToU16(bounds.fRight) << 16);
433 builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16); 413 builder[2] = SkToU16(bounds.fTop) | (SkToU16(bounds.fBottom) << 16);
434 } 414 }
435 415
436 sk_sp<GrTexture> GrClipStackClip::CreateAlphaClipMask(GrContext* context, 416 sk_sp<GrTexture> GrClipStackClip::CreateAlphaClipMask(GrContext* context,
437 const GrReducedClip& reduc edClip, 417 const GrReducedClip& reduc edClip,
438 const SkVector& clipToMask Offset) { 418 const SkVector& clipToMask Offset) {
439 GrResourceProvider* resourceProvider = context->resourceProvider(); 419 GrResourceProvider* resourceProvider = context->resourceProvider();
440 GrUniqueKey key; 420 GrUniqueKey key;
441 GetClipMaskKey(reducedClip.genID(), reducedClip.iBounds(), &key); 421 GetClipMaskKey(reducedClip.genID(), reducedClip.ibounds(), &key);
442 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key) ) { 422 if (GrTexture* texture = resourceProvider->findAndRefTextureByUniqueKey(key) ) {
443 return sk_sp<GrTexture>(texture); 423 return sk_sp<GrTexture>(texture);
444 } 424 }
445 425
446 // There's no texture in the cache. Let's try to allocate it then. 426 // There's no texture in the cache. Let's try to allocate it then.
447 GrPixelConfig config = kRGBA_8888_GrPixelConfig; 427 GrPixelConfig config = kRGBA_8888_GrPixelConfig;
448 if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { 428 if (context->caps()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
449 config = kAlpha_8_GrPixelConfig; 429 config = kAlpha_8_GrPixelConfig;
450 } 430 }
451 431
452 sk_sp<GrDrawContext> dc(context->makeDrawContext(SkBackingFit::kApprox, 432 sk_sp<GrDrawContext> dc(context->makeDrawContext(SkBackingFit::kApprox,
453 reducedClip.width(), 433 reducedClip.width(),
454 reducedClip.height(), 434 reducedClip.height(),
455 config, nullptr)); 435 config, nullptr));
456 if (!dc) { 436 if (!dc) {
457 return nullptr; 437 return nullptr;
458 } 438 }
459 439
460 // The texture may be larger than necessary, this rect represents the part o f the texture 440 // The texture may be larger than necessary, this rect represents the part o f the texture
461 // we populate with a rasterization of the clip. 441 // we populate with a rasterization of the clip.
462 SkIRect maskSpaceIBounds = SkIRect::MakeWH(reducedClip.width(), reducedClip. height()); 442 SkIRect maskSpaceIBounds = SkIRect::MakeWH(reducedClip.width(), reducedClip. height());
463 443
464 // The scratch texture that we are drawing into can be substantially larger than the mask. Only 444 // The scratch texture that we are drawing into can be substantially larger than the mask. Only
465 // clear the part that we care about. 445 // clear the part that we care about.
466 dc->clear(&maskSpaceIBounds, 446 dc->clear(&maskSpaceIBounds, InitialState::kAllIn == reducedClip.initialStat e() ? -1 : 0, true);
467 GrReducedClip::InitialState::kAllIn == reducedClip.initialState() ? -1 : 0,
468 true);
469 447
470 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip 448 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
471 // space. 449 // space.
472 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY); 450 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY);
473 451
474 // It is important that we use maskSpaceIBounds as the stencil rect in the b elow loop. 452 // It is important that we use maskSpaceIBounds as the stencil rect in the b elow loop.
475 // The second pass that zeros the stencil buffer renders the rect maskSpaceI Bounds so the first 453 // The second pass that zeros the stencil buffer renders the rect maskSpaceI Bounds so the first
476 // pass must not set values outside of this bounds or stencil values outside the rect won't be 454 // pass must not set values outside of this bounds or stencil values outside the rect won't be
477 // cleared. 455 // cleared.
478 456
(...skipping 27 matching lines...) Expand all
506 0x0000, 484 0x0000,
507 GrUserStencilTest::kEqual, 485 GrUserStencilTest::kEqual,
508 0xffff, 486 0xffff,
509 GrUserStencilOp::kZero, 487 GrUserStencilOp::kZero,
510 GrUserStencilOp::kZero, 488 GrUserStencilOp::kZero,
511 0xffff>() 489 0xffff>()
512 ); 490 );
513 if (!dc->drawContextPriv().drawAndStencilRect(clip, &kDrawOutsideEle ment, 491 if (!dc->drawContextPriv().drawAndStencilRect(clip, &kDrawOutsideEle ment,
514 op, !invert, false, 492 op, !invert, false,
515 translate, 493 translate,
516 SkRect::Make(reducedCl ip.iBounds()))) { 494 SkRect::Make(reducedCl ip.ibounds()))) {
517 return nullptr; 495 return nullptr;
518 } 496 }
519 } else { 497 } else {
520 // all the remaining ops can just be directly draw into the accumula tion buffer 498 // all the remaining ops can just be directly draw into the accumula tion buffer
521 GrPaint paint; 499 GrPaint paint;
522 paint.setAntiAlias(element->isAA()); 500 paint.setAntiAlias(element->isAA());
523 paint.setCoverageSetOpXPFactory(op, false); 501 paint.setCoverageSetOpXPFactory(op, false);
524 502
525 draw_element(dc.get(), GrNoClip(), paint, translate, element); 503 draw_element(dc.get(), GrNoClip(), paint, translate, element);
526 } 504 }
(...skipping 14 matching lines...) Expand all
541 const SkIPoint& clipSpaceToStencilOf fset) { 519 const SkIPoint& clipSpaceToStencilOf fset) {
542 SkASSERT(drawContext); 520 SkASSERT(drawContext);
543 521
544 GrStencilAttachment* stencilAttachment = context->resourceProvider()->attach StencilAttachment( 522 GrStencilAttachment* stencilAttachment = context->resourceProvider()->attach StencilAttachment(
545 drawContext->accessRenderTar get()); 523 drawContext->accessRenderTar get());
546 if (nullptr == stencilAttachment) { 524 if (nullptr == stencilAttachment) {
547 return false; 525 return false;
548 } 526 }
549 527
550 // TODO: these need to be swapped over to using a StencilAttachmentProxy 528 // TODO: these need to be swapped over to using a StencilAttachmentProxy
551 if (stencilAttachment->mustRenderClip(reducedClip.genID(), reducedClip.iBoun ds(), 529 if (stencilAttachment->mustRenderClip(reducedClip.genID(), reducedClip.iboun ds(),
552 clipSpaceToStencilOffset)) { 530 clipSpaceToStencilOffset)) {
553 stencilAttachment->setLastClip(reducedClip.genID(), reducedClip.iBounds( ), 531 stencilAttachment->setLastClip(reducedClip.genID(), reducedClip.ibounds( ),
554 clipSpaceToStencilOffset); 532 clipSpaceToStencilOffset);
555 // Set the matrix so that rendered clip elements are transformed from cl ip to stencil space. 533 // Set the matrix so that rendered clip elements are transformed from cl ip to stencil space.
556 SkVector translate = { 534 SkVector translate = {
557 SkIntToScalar(clipSpaceToStencilOffset.fX), 535 SkIntToScalar(clipSpaceToStencilOffset.fX),
558 SkIntToScalar(clipSpaceToStencilOffset.fY) 536 SkIntToScalar(clipSpaceToStencilOffset.fY)
559 }; 537 };
560 SkMatrix viewMatrix; 538 SkMatrix viewMatrix;
561 viewMatrix.setTranslate(translate); 539 viewMatrix.setTranslate(translate);
562 540
563 // We set the current clip to the bounds so that our recursive draws are scissored to them. 541 // We set the current clip to the bounds so that our recursive draws are scissored to them.
564 SkIRect stencilSpaceIBounds(reducedClip.iBounds()); 542 SkIRect stencilSpaceIBounds(reducedClip.ibounds());
565 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); 543 stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
566 GrFixedClip clip(stencilSpaceIBounds); 544 GrFixedClip clip(stencilSpaceIBounds);
567 545
568 bool insideClip = GrReducedClip::InitialState::kAllIn == reducedClip.ini tialState(); 546 bool insideClip = InitialState::kAllIn == reducedClip.initialState();
569 drawContext->drawContextPriv().clearStencilClip(stencilSpaceIBounds, ins ideClip); 547 drawContext->drawContextPriv().clearStencilClip(stencilSpaceIBounds, ins ideClip);
570 548
571 // walk through each clip element and perform its set op 549 // walk through each clip element and perform its set op
572 // with the existing clip. 550 // with the existing clip.
573 for (ElementList::Iter iter(reducedClip.elements()); iter.get(); iter.ne xt()) { 551 for (ElementList::Iter iter(reducedClip.elements()); iter.get(); iter.ne xt()) {
574 const Element* element = iter.get(); 552 const Element* element = iter.get();
575 bool useHWAA = element->isAA() && drawContext->isStencilBufferMultis ampled(); 553 bool useHWAA = element->isAA() && drawContext->isStencilBufferMultis ampled();
576 554
577 bool fillInverted = false; 555 bool fillInverted = false;
578 // enabled at bottom of loop 556 // enabled at bottom of loop
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 args.fClip = &clip; 642 args.fClip = &clip;
665 args.fViewMatrix = &viewMatrix; 643 args.fViewMatrix = &viewMatrix;
666 args.fIsAA = element->isAA(); 644 args.fIsAA = element->isAA();
667 args.fShape = &shape; 645 args.fShape = &shape;
668 pr->stencilPath(args); 646 pr->stencilPath(args);
669 } 647 }
670 } 648 }
671 } 649 }
672 } 650 }
673 651
652 // Just enable stencil clip. The passes choose whether or not they w ill actually use it.
653 clip.enableStencilClip();
654
674 // now we modify the clip bit by rendering either the clip 655 // now we modify the clip bit by rendering either the clip
675 // element directly or a bounding rect of the entire clip. 656 // element directly or a bounding rect of the entire clip.
676 for (GrUserStencilSettings const* const* pass = stencilPasses; *pass ; ++pass) { 657 for (GrUserStencilSettings const* const* pass = stencilPasses; *pass ; ++pass) {
677
678 if (drawDirectToClip) { 658 if (drawDirectToClip) {
679 if (Element::kRect_Type == element->getType()) { 659 if (Element::kRect_Type == element->getType()) {
680 clip.enableStencilClip(element->getRect().makeOffset(tra nslate.fX,
681 tra nslate.fY));
682 drawContext->drawContextPriv().stencilRect(clip, *pass, useHWAA, viewMatrix, 660 drawContext->drawContextPriv().stencilRect(clip, *pass, useHWAA, viewMatrix,
683 element->getR ect()); 661 element->getR ect());
684 } else { 662 } else {
685 GrShape shape(clipPath, GrStyle::SimpleFill()); 663 GrShape shape(clipPath, GrStyle::SimpleFill());
686 GrPaint paint; 664 GrPaint paint;
687 SkRect bounds = clipPath.getBounds();
688 bounds.offset(translate.fX, translate.fY);
689 clip.enableStencilClip(bounds);
690 paint.setXPFactory(GrDisableColorXPFactory::Make()); 665 paint.setXPFactory(GrDisableColorXPFactory::Make());
691 paint.setAntiAlias(element->isAA()); 666 paint.setAntiAlias(element->isAA());
692 GrPathRenderer::DrawPathArgs args; 667 GrPathRenderer::DrawPathArgs args;
693 args.fResourceProvider = context->resourceProvider(); 668 args.fResourceProvider = context->resourceProvider();
694 args.fPaint = &paint; 669 args.fPaint = &paint;
695 args.fUserStencilSettings = *pass; 670 args.fUserStencilSettings = *pass;
696 args.fDrawContext = drawContext; 671 args.fDrawContext = drawContext;
697 args.fClip = &clip; 672 args.fClip = &clip;
698 args.fViewMatrix = &viewMatrix; 673 args.fViewMatrix = &viewMatrix;
699 args.fShape = &shape; 674 args.fShape = &shape;
700 args.fAntiAlias = false; 675 args.fAntiAlias = false;
701 args.fGammaCorrect = false; 676 args.fGammaCorrect = false;
702 pr->drawPath(args); 677 pr->drawPath(args);
703 } 678 }
704 } else { 679 } else {
705 // The view matrix is setup to do clip space -> stencil spac e translation, so 680 // The view matrix is setup to do clip space -> stencil spac e translation, so
706 // draw rect in clip space. 681 // draw rect in clip space.
707 SkRect bounds = SkRect::Make(reducedClip.iBounds());
708 bounds.offset(translate.fX, translate.fY);
709 clip.enableStencilClip(bounds);
710 drawContext->drawContextPriv().stencilRect(clip, *pass, fals e, viewMatrix, 682 drawContext->drawContextPriv().stencilRect(clip, *pass, fals e, viewMatrix,
711 SkRect::Make(redu cedClip.iBounds())); 683 SkRect::Make(redu cedClip.ibounds()));
712 } 684 }
713 } 685 }
714 } 686 }
715 } 687 }
716 return true; 688 return true;
717 } 689 }
718 690
719 //////////////////////////////////////////////////////////////////////////////// 691 ////////////////////////////////////////////////////////////////////////////////
720 sk_sp<GrTexture> GrClipStackClip::CreateSoftwareClipMask(GrTextureProvider* texP rovider, 692 sk_sp<GrTexture> GrClipStackClip::CreateSoftwareClipMask(GrTextureProvider* texP rovider,
721 const GrReducedClip& re ducedClip, 693 const GrReducedClip& re ducedClip,
722 const SkVector& clipToM askOffset) { 694 const SkVector& clipToM askOffset) {
723 GrUniqueKey key; 695 GrUniqueKey key;
724 GetClipMaskKey(reducedClip.genID(), reducedClip.iBounds(), &key); 696 GetClipMaskKey(reducedClip.genID(), reducedClip.ibounds(), &key);
725 if (GrTexture* texture = texProvider->findAndRefTextureByUniqueKey(key)) { 697 if (GrTexture* texture = texProvider->findAndRefTextureByUniqueKey(key)) {
726 return sk_sp<GrTexture>(texture); 698 return sk_sp<GrTexture>(texture);
727 } 699 }
728 700
729 // The mask texture may be larger than necessary. We round out the clip spac e bounds and pin 701 // The mask texture may be larger than necessary. We round out the clip spac e bounds and pin
730 // the top left corner of the resulting rect to the top left of the texture. 702 // the top left corner of the resulting rect to the top left of the texture.
731 SkIRect maskSpaceIBounds = SkIRect::MakeWH(reducedClip.width(), reducedClip. height()); 703 SkIRect maskSpaceIBounds = SkIRect::MakeWH(reducedClip.width(), reducedClip. height());
732 704
733 GrSWMaskHelper helper(texProvider); 705 GrSWMaskHelper helper(texProvider);
734 706
735 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip 707 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
736 // space. 708 // space.
737 SkMatrix translate; 709 SkMatrix translate;
738 translate.setTranslate(clipToMaskOffset); 710 translate.setTranslate(clipToMaskOffset);
739 711
740 helper.init(maskSpaceIBounds, &translate); 712 helper.init(maskSpaceIBounds, &translate);
741 helper.clear(GrReducedClip::InitialState::kAllIn == reducedClip.initialState () ? 0xFF : 0x00); 713 helper.clear(InitialState::kAllIn == reducedClip.initialState() ? 0xFF : 0x0 0);
742 714
743 for (ElementList::Iter iter(reducedClip.elements()); iter.get(); iter.next() ) { 715 for (ElementList::Iter iter(reducedClip.elements()); iter.get(); iter.next() ) {
744 const Element* element = iter.get(); 716 const Element* element = iter.get();
745 SkRegion::Op op = element->getOp(); 717 SkRegion::Op op = element->getOp();
746 718
747 if (SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) { 719 if (SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) {
748 // Intersect and reverse difference require modifying pixels outside of the geometry 720 // Intersect and reverse difference require modifying pixels outside of the geometry
749 // that is being "drawn". In both cases we erase all the pixels outs ide of the geometry 721 // that is being "drawn". In both cases we erase all the pixels outs ide of the geometry
750 // but leave the pixels inside the geometry alone. For reverse diffe rence we invert all 722 // but leave the pixels inside the geometry alone. For reverse diffe rence we invert all
751 // the pixels before clearing the ones outside the geometry. 723 // the pixels before clearing the ones outside the geometry.
752 if (SkRegion::kReverseDifference_Op == op) { 724 if (SkRegion::kReverseDifference_Op == op) {
753 SkRect temp = SkRect::Make(reducedClip.iBounds()); 725 SkRect temp = SkRect::Make(reducedClip.ibounds());
754 // invert the entire scene 726 // invert the entire scene
755 helper.drawRect(temp, SkRegion::kXOR_Op, false, 0xFF); 727 helper.drawRect(temp, SkRegion::kXOR_Op, false, 0xFF);
756 } 728 }
757 SkPath clipPath; 729 SkPath clipPath;
758 element->asPath(&clipPath); 730 element->asPath(&clipPath);
759 clipPath.toggleInverseFillType(); 731 clipPath.toggleInverseFillType();
760 GrShape shape(clipPath, GrStyle::SimpleFill()); 732 GrShape shape(clipPath, GrStyle::SimpleFill());
761 helper.drawShape(shape, SkRegion::kReplace_Op, element->isAA(), 0x00 ); 733 helper.drawShape(shape, SkRegion::kReplace_Op, element->isAA(), 0x00 );
762 continue; 734 continue;
763 } 735 }
(...skipping 19 matching lines...) Expand all
783 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc)); 755 sk_sp<GrTexture> result(texProvider->createApproxTexture(desc));
784 if (!result) { 756 if (!result) {
785 return nullptr; 757 return nullptr;
786 } 758 }
787 result->resourcePriv().setUniqueKey(key); 759 result->resourcePriv().setUniqueKey(key);
788 760
789 helper.toTexture(result.get()); 761 helper.toTexture(result.get());
790 762
791 return result; 763 return result;
792 } 764 }
OLDNEW
« no previous file with comments | « src/gpu/GrClipStackClip.h ('k') | src/gpu/GrDrawTarget.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698