| OLD | NEW | 
|---|
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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  Loading... | 
| 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 } | 
| OLD | NEW | 
|---|