OLD | NEW |
---|---|
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 "GrAAConvexPathRenderer.h" | 9 #include "GrAAConvexPathRenderer.h" |
10 #include "GrAAHairLinePathRenderer.h" | 10 #include "GrAAHairLinePathRenderer.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
49 mat, | 49 mat, |
50 GrTextureDomain::MakeTexelDomain(result, d omainTexels), | 50 GrTextureDomain::MakeTexelDomain(result, d omainTexels), |
51 GrTextureDomain::kDecal_Mode, | 51 GrTextureDomain::kDecal_Mode, |
52 GrTextureParams::kNone_FilterMode, | 52 GrTextureParams::kNone_FilterMode, |
53 kDevice_GrCoordSet))->unref(); | 53 kDevice_GrCoordSet))->unref(); |
54 } | 54 } |
55 | 55 |
56 bool path_needs_SW_renderer(GrContext* context, | 56 bool path_needs_SW_renderer(GrContext* context, |
57 const GrDrawTarget* gpu, | 57 const GrDrawTarget* gpu, |
58 const GrDrawState* drawState, | 58 const GrDrawState* drawState, |
59 const SkMatrix& viewMatrix, | |
59 const SkPath& origPath, | 60 const SkPath& origPath, |
60 const SkStrokeRec& stroke, | 61 const SkStrokeRec& stroke, |
61 bool doAA) { | 62 bool doAA) { |
62 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b uffer | 63 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b uffer |
63 SkTCopyOnFirstWrite<SkPath> path(origPath); | 64 SkTCopyOnFirstWrite<SkPath> path(origPath); |
64 if (path->isInverseFillType()) { | 65 if (path->isInverseFillType()) { |
65 path.writable()->toggleInverseFillType(); | 66 path.writable()->toggleInverseFillType(); |
66 } | 67 } |
67 // last (false) parameter disallows use of the SW path renderer | 68 // last (false) parameter disallows use of the SW path renderer |
68 GrPathRendererChain::DrawType type = doAA ? | 69 GrPathRendererChain::DrawType type = doAA ? |
69 GrPathRendererChain::kColorAntiAlias_Dr awType : | 70 GrPathRendererChain::kColorAntiAlias_Dr awType : |
70 GrPathRendererChain::kColor_DrawType; | 71 GrPathRendererChain::kColor_DrawType; |
71 | 72 |
72 return NULL == context->getPathRenderer(gpu, drawState, *path, stroke, false , type); | 73 return NULL == context->getPathRenderer(gpu, drawState, viewMatrix, *path, s troke, false, type); |
73 } | 74 } |
74 } | 75 } |
75 | 76 |
76 /* | 77 /* |
77 * This method traverses the clip stack to see if the GrSoftwarePathRenderer | 78 * This method traverses the clip stack to see if the GrSoftwarePathRenderer |
78 * will be used on any element. If so, it returns true to indicate that the | 79 * will be used on any element. If so, it returns true to indicate that the |
79 * entire clip should be rendered in SW and then uploaded en masse to the gpu. | 80 * entire clip should be rendered in SW and then uploaded en masse to the gpu. |
80 */ | 81 */ |
81 bool GrClipMaskManager::useSWOnlyPath(const GrDrawState* drawState, | 82 bool GrClipMaskManager::useSWOnlyPath(const GrDrawState* drawState, |
83 const SkMatrix& viewMatrix, | |
82 const GrReducedClip::ElementList& elements ) { | 84 const GrReducedClip::ElementList& elements ) { |
83 // TODO: generalize this function so that when | 85 // TODO: generalize this function so that when |
84 // a clip gets complex enough it can just be done in SW regardless | 86 // a clip gets complex enough it can just be done in SW regardless |
85 // of whether it would invoke the GrSoftwarePathRenderer. | 87 // of whether it would invoke the GrSoftwarePathRenderer. |
86 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 88 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
87 | 89 |
88 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { | 90 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { |
89 const Element* element = iter.get(); | 91 const Element* element = iter.get(); |
90 // rects can always be drawn directly w/o using the software path | 92 // rects can always be drawn directly w/o using the software path |
91 // Skip rrects once we're drawing them directly. | 93 // Skip rrects once we're drawing them directly. |
92 if (Element::kRect_Type != element->getType()) { | 94 if (Element::kRect_Type != element->getType()) { |
93 SkPath path; | 95 SkPath path; |
94 element->asPath(&path); | 96 element->asPath(&path); |
95 if (path_needs_SW_renderer(this->getContext(), fClipTarget, drawStat e, path, stroke, | 97 if (path_needs_SW_renderer(this->getContext(), fClipTarget, drawStat e, viewMatrix, |
bsalomon
2014/12/29 18:35:46
So AFAICT you tunneled the original draw's matrix
joshualitt
2014/12/29 19:23:38
Brian, are you sure about this?
I could be wrong
bsalomon
2014/12/29 19:29:01
Hmm... that seems incorrect. If we were using the
| |
96 element->isAA())) { | 98 path, stroke, element->isAA())) { |
97 return true; | 99 return true; |
98 } | 100 } |
99 } | 101 } |
100 } | 102 } |
101 return false; | 103 return false; |
102 } | 104 } |
103 | 105 |
104 bool GrClipMaskManager::installClipEffects(GrDrawState* drawState, | 106 bool GrClipMaskManager::installClipEffects(GrDrawState* drawState, |
105 GrDrawState::AutoRestoreEffects* are, | 107 GrDrawState::AutoRestoreEffects* are, |
106 const GrReducedClip::ElementList& ele ments, | 108 const GrReducedClip::ElementList& ele ments, |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
195 } | 197 } |
196 | 198 |
197 //////////////////////////////////////////////////////////////////////////////// | 199 //////////////////////////////////////////////////////////////////////////////// |
198 // sort out what kind of clip mask needs to be created: alpha, stencil, | 200 // sort out what kind of clip mask needs to be created: alpha, stencil, |
199 // scissor, or entirely software | 201 // scissor, or entirely software |
200 bool GrClipMaskManager::setupClipping(GrDrawState* drawState, | 202 bool GrClipMaskManager::setupClipping(GrDrawState* drawState, |
201 GrDrawState::AutoRestoreEffects* are, | 203 GrDrawState::AutoRestoreEffects* are, |
202 GrDrawState::AutoRestoreStencil* ars, | 204 GrDrawState::AutoRestoreStencil* ars, |
203 GrScissorState* scissorState, | 205 GrScissorState* scissorState, |
204 const GrClipData* clipDataIn, | 206 const GrClipData* clipDataIn, |
207 const SkMatrix& viewMatrix, | |
205 const SkRect* devBounds) { | 208 const SkRect* devBounds) { |
206 fCurrClipMaskType = kNone_ClipMaskType; | 209 fCurrClipMaskType = kNone_ClipMaskType; |
207 if (kRespectClip_StencilClipMode == fClipMode) { | 210 if (kRespectClip_StencilClipMode == fClipMode) { |
208 fClipMode = kIgnoreClip_StencilClipMode; | 211 fClipMode = kIgnoreClip_StencilClipMode; |
209 } | 212 } |
210 | 213 |
211 GrReducedClip::ElementList elements(16); | 214 GrReducedClip::ElementList elements(16); |
212 int32_t genID; | 215 int32_t genID; |
213 GrReducedClip::InitialState initialState; | 216 GrReducedClip::InitialState initialState; |
214 SkIRect clipSpaceIBounds; | 217 SkIRect clipSpaceIBounds; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
266 this->setDrawStateStencil(drawState, ars); | 269 this->setDrawStateStencil(drawState, ars); |
267 return true; | 270 return true; |
268 } | 271 } |
269 } | 272 } |
270 | 273 |
271 #if GR_AA_CLIP | 274 #if GR_AA_CLIP |
272 // If MSAA is enabled we can do everything in the stencil buffer. | 275 // If MSAA is enabled we can do everything in the stencil buffer. |
273 if (0 == rt->numSamples() && requiresAA) { | 276 if (0 == rt->numSamples() && requiresAA) { |
274 GrTexture* result = NULL; | 277 GrTexture* result = NULL; |
275 | 278 |
276 if (this->useSWOnlyPath(drawState, elements)) { | 279 if (this->useSWOnlyPath(drawState, viewMatrix, elements)) { |
277 // The clip geometry is complex enough that it will be more efficien t to create it | 280 // The clip geometry is complex enough that it will be more efficien t to create it |
278 // entirely in software | 281 // entirely in software |
279 result = this->createSoftwareClipMask(genID, | 282 result = this->createSoftwareClipMask(genID, |
280 initialState, | 283 initialState, |
281 elements, | 284 elements, |
282 clipSpaceIBounds); | 285 clipSpaceIBounds); |
283 } else { | 286 } else { |
284 result = this->createAlphaClipMask(genID, | 287 result = this->createAlphaClipMask(genID, |
285 initialState, | 288 initialState, |
286 elements, | 289 elements, |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
330 //////////////////////////////////////////////////////////////////////////////// | 333 //////////////////////////////////////////////////////////////////////////////// |
331 // Set a coverage drawing XPF on the drawState for the given op and invertCovera ge mode | 334 // Set a coverage drawing XPF on the drawState for the given op and invertCovera ge mode |
332 void set_coverage_drawing_xpf(SkRegion::Op op, bool invertCoverage, GrDrawState* drawState) { | 335 void set_coverage_drawing_xpf(SkRegion::Op op, bool invertCoverage, GrDrawState* drawState) { |
333 SkASSERT(op <= SkRegion::kLastOp); | 336 SkASSERT(op <= SkRegion::kLastOp); |
334 drawState->setCoverageSetOpXPFactory(op, invertCoverage); | 337 drawState->setCoverageSetOpXPFactory(op, invertCoverage); |
335 } | 338 } |
336 } | 339 } |
337 | 340 |
338 //////////////////////////////////////////////////////////////////////////////// | 341 //////////////////////////////////////////////////////////////////////////////// |
339 bool GrClipMaskManager::drawElement(GrDrawState* drawState, | 342 bool GrClipMaskManager::drawElement(GrDrawState* drawState, |
343 const SkMatrix& viewMatrix, | |
340 GrTexture* target, | 344 GrTexture* target, |
341 const SkClipStack::Element* element, | 345 const SkClipStack::Element* element, |
342 GrPathRenderer* pr) { | 346 GrPathRenderer* pr) { |
343 GrDrawTarget::AutoGeometryPush agp(fClipTarget); | 347 GrDrawTarget::AutoGeometryPush agp(fClipTarget); |
344 | 348 |
345 drawState->setRenderTarget(target->asRenderTarget()); | 349 drawState->setRenderTarget(target->asRenderTarget()); |
346 | 350 |
347 // The color we use to draw does not matter since we will always be using a GrCoverageSetOpXP | 351 // The color we use to draw does not matter since we will always be using a GrCoverageSetOpXP |
348 // which ignores color. | 352 // which ignores color. |
349 GrColor color = GrColor_WHITE; | 353 GrColor color = GrColor_WHITE; |
350 | 354 |
351 // TODO: Draw rrects directly here. | 355 // TODO: Draw rrects directly here. |
352 switch (element->getType()) { | 356 switch (element->getType()) { |
353 case Element::kEmpty_Type: | 357 case Element::kEmpty_Type: |
354 SkDEBUGFAIL("Should never get here with an empty element."); | 358 SkDEBUGFAIL("Should never get here with an empty element."); |
355 break; | 359 break; |
356 case Element::kRect_Type: | 360 case Element::kRect_Type: |
357 // TODO: Do rects directly to the accumulator using a aa-rect GrProc essor that covers | 361 // TODO: Do rects directly to the accumulator using a aa-rect GrProc essor that covers |
358 // the entire mask bounds and writes 0 outside the rect. | 362 // the entire mask bounds and writes 0 outside the rect. |
359 if (element->isAA()) { | 363 if (element->isAA()) { |
364 SkMatrix invert; | |
365 if (!viewMatrix.invert(&invert)) { | |
366 SkDebugf("Could not invert\n"); | |
367 return false; | |
368 } | |
369 SkRect devRect = element->getRect(); | |
370 viewMatrix.mapRect(&devRect); | |
360 this->getContext()->getAARectRenderer()->fillAARect(fClipTarget, | 371 this->getContext()->getAARectRenderer()->fillAARect(fClipTarget, |
361 drawState, | 372 drawState, |
362 color, | 373 color, |
363 SkMatrix::I( ), | 374 viewMatrix, |
375 invert, | |
364 element->get Rect(), | 376 element->get Rect(), |
365 SkMatrix::I( ), | 377 devRect); |
366 element->get Rect()); | |
367 } else { | 378 } else { |
368 fClipTarget->drawSimpleRect(drawState, color, element->getRect() ); | 379 fClipTarget->drawSimpleRect(drawState, color, viewMatrix, elemen t->getRect()); |
369 } | 380 } |
370 return true; | 381 return true; |
371 default: { | 382 default: { |
372 SkPath path; | 383 SkPath path; |
373 element->asPath(&path); | 384 element->asPath(&path); |
374 path.setIsVolatile(true); | 385 path.setIsVolatile(true); |
375 if (path.isInverseFillType()) { | 386 if (path.isInverseFillType()) { |
376 path.toggleInverseFillType(); | 387 path.toggleInverseFillType(); |
377 } | 388 } |
378 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 389 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
379 if (NULL == pr) { | 390 if (NULL == pr) { |
380 GrPathRendererChain::DrawType type; | 391 GrPathRendererChain::DrawType type; |
381 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr awType : | 392 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr awType : |
382 GrPathRendererChain::kColor_DrawType; | 393 GrPathRendererChain::kColor_DrawType; |
383 pr = this->getContext()->getPathRenderer(fClipTarget, drawState, path, stroke, | 394 pr = this->getContext()->getPathRenderer(fClipTarget, drawState, viewMatrix, path, |
384 false, type); | 395 stroke, false, type); |
385 } | 396 } |
386 if (NULL == pr) { | 397 if (NULL == pr) { |
387 return false; | 398 return false; |
388 } | 399 } |
389 | 400 |
390 pr->drawPath(fClipTarget, drawState, color, path, stroke, element->i sAA()); | 401 pr->drawPath(fClipTarget, drawState, color, viewMatrix, path, stroke , element->isAA()); |
391 break; | 402 break; |
392 } | 403 } |
393 } | 404 } |
394 return true; | 405 return true; |
395 } | 406 } |
396 | 407 |
397 bool GrClipMaskManager::canStencilAndDrawElement(GrDrawState* drawState, | 408 bool GrClipMaskManager::canStencilAndDrawElement(GrDrawState* drawState, |
398 GrTexture* target, | 409 GrTexture* target, |
399 GrPathRenderer** pr, | 410 GrPathRenderer** pr, |
400 const SkClipStack::Element* ele ment) { | 411 const SkClipStack::Element* ele ment) { |
401 drawState->setRenderTarget(target->asRenderTarget()); | 412 drawState->setRenderTarget(target->asRenderTarget()); |
402 | 413 |
403 if (Element::kRect_Type == element->getType()) { | 414 if (Element::kRect_Type == element->getType()) { |
404 return true; | 415 return true; |
405 } else { | 416 } else { |
406 // We shouldn't get here with an empty clip element. | 417 // We shouldn't get here with an empty clip element. |
407 SkASSERT(Element::kEmpty_Type != element->getType()); | 418 SkASSERT(Element::kEmpty_Type != element->getType()); |
408 SkPath path; | 419 SkPath path; |
409 element->asPath(&path); | 420 element->asPath(&path); |
410 if (path.isInverseFillType()) { | 421 if (path.isInverseFillType()) { |
411 path.toggleInverseFillType(); | 422 path.toggleInverseFillType(); |
412 } | 423 } |
413 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); | 424 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); |
414 GrPathRendererChain::DrawType type = element->isAA() ? | 425 GrPathRendererChain::DrawType type = element->isAA() ? |
415 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : | 426 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : |
416 GrPathRendererChain::kStencilAndColor_DrawType; | 427 GrPathRendererChain::kStencilAndColor_DrawType; |
417 *pr = this->getContext()->getPathRenderer(fClipTarget, drawState, path, stroke, false, | 428 *pr = this->getContext()->getPathRenderer(fClipTarget, drawState, SkMatr ix::I(), path, |
418 type); | 429 stroke, false, type); |
419 return SkToBool(*pr); | 430 return SkToBool(*pr); |
420 } | 431 } |
421 } | 432 } |
422 | 433 |
423 void GrClipMaskManager::mergeMask(GrDrawState* drawState, | 434 void GrClipMaskManager::mergeMask(GrDrawState* drawState, |
424 GrTexture* dstMask, | 435 GrTexture* dstMask, |
425 GrTexture* srcMask, | 436 GrTexture* srcMask, |
426 SkRegion::Op op, | 437 SkRegion::Op op, |
427 const SkIRect& dstBound, | 438 const SkIRect& dstBound, |
428 const SkIRect& srcBound) { | 439 const SkIRect& srcBound) { |
429 drawState->setRenderTarget(dstMask->asRenderTarget()); | 440 drawState->setRenderTarget(dstMask->asRenderTarget()); |
430 | 441 |
431 // We want to invert the coverage here | 442 // We want to invert the coverage here |
432 set_coverage_drawing_xpf(op, false, drawState); | 443 set_coverage_drawing_xpf(op, false, drawState); |
433 | 444 |
434 SkMatrix sampleM; | 445 SkMatrix sampleM; |
435 sampleM.setIDiv(srcMask->width(), srcMask->height()); | 446 sampleM.setIDiv(srcMask->width(), srcMask->height()); |
436 | 447 |
437 drawState->addCoverageProcessor( | 448 drawState->addCoverageProcessor( |
438 GrTextureDomainEffect::Create(srcMask, | 449 GrTextureDomainEffect::Create(srcMask, |
439 sampleM, | 450 sampleM, |
440 GrTextureDomain::MakeTexelDomain(srcMask, srcBound), | 451 GrTextureDomain::MakeTexelDomain(srcMask, srcBound), |
441 GrTextureDomain::kDecal_Mode, | 452 GrTextureDomain::kDecal_Mode, |
442 GrTextureParams::kNone_FilterMode))->unref (); | 453 GrTextureParams::kNone_FilterMode))->unref (); |
443 // The color passed in here does not matter since the coverageSetOpXP won't read it. | 454 // The color passed in here does not matter since the coverageSetOpXP won't read it. |
444 fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkRect::Make(dstBound) ); | 455 fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkMatrix::I(), SkRect: :Make(dstBound)); |
445 } | 456 } |
446 | 457 |
447 GrTexture* GrClipMaskManager::createTempMask(int width, int height) { | 458 GrTexture* GrClipMaskManager::createTempMask(int width, int height) { |
448 GrSurfaceDesc desc; | 459 GrSurfaceDesc desc; |
449 desc.fFlags = kRenderTarget_GrSurfaceFlag; | 460 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
450 desc.fWidth = width; | 461 desc.fWidth = width; |
451 desc.fHeight = height; | 462 desc.fHeight = height; |
452 if (this->getContext()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { | 463 if (this->getContext()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { |
453 desc.fConfig = kAlpha_8_GrPixelConfig; | 464 desc.fConfig = kAlpha_8_GrPixelConfig; |
454 } else { | 465 } else { |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
542 // cleared. | 553 // cleared. |
543 GrDrawTarget::AutoClipRestore acr(fClipTarget, maskSpaceIBounds); | 554 GrDrawTarget::AutoClipRestore acr(fClipTarget, maskSpaceIBounds); |
544 SkAutoTUnref<GrTexture> temp; | 555 SkAutoTUnref<GrTexture> temp; |
545 | 556 |
546 // walk through each clip element and perform its set op | 557 // walk through each clip element and perform its set op |
547 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) { | 558 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) { |
548 const Element* element = iter.get(); | 559 const Element* element = iter.get(); |
549 SkRegion::Op op = element->getOp(); | 560 SkRegion::Op op = element->getOp(); |
550 bool invert = element->isInverseFilled(); | 561 bool invert = element->isInverseFilled(); |
551 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) { | 562 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) { |
552 GrDrawState drawState(translate); | 563 GrDrawState drawState; |
553 drawState.enableState(GrDrawState::kClip_StateBit); | 564 drawState.enableState(GrDrawState::kClip_StateBit); |
554 | 565 |
555 GrPathRenderer* pr = NULL; | 566 GrPathRenderer* pr = NULL; |
556 bool useTemp = !this->canStencilAndDrawElement(&drawState, result, & pr, element); | 567 bool useTemp = !this->canStencilAndDrawElement(&drawState, result, & pr, element); |
557 GrTexture* dst; | 568 GrTexture* dst; |
558 // This is the bounds of the clip element in the space of the alpha- mask. The temporary | 569 // This is the bounds of the clip element in the space of the alpha- mask. The temporary |
559 // mask buffer can be substantially larger than the actually clip st ack element. We | 570 // mask buffer can be substantially larger than the actually clip st ack element. We |
560 // touch the minimum number of pixels necessary and use decal mode t o combine it with | 571 // touch the minimum number of pixels necessary and use decal mode t o combine it with |
561 // the accumulator. | 572 // the accumulator. |
562 SkIRect maskSpaceElementIBounds; | 573 SkIRect maskSpaceElementIBounds; |
(...skipping 30 matching lines...) Expand all Loading... | |
593 kReplace_StencilOp, | 604 kReplace_StencilOp, |
594 kReplace_StencilOp, | 605 kReplace_StencilOp, |
595 kAlways_StencilFunc, | 606 kAlways_StencilFunc, |
596 0xffff, | 607 0xffff, |
597 0xffff, | 608 0xffff, |
598 0xffff); | 609 0xffff); |
599 drawState.setStencil(kStencilInElement); | 610 drawState.setStencil(kStencilInElement); |
600 set_coverage_drawing_xpf(op, invert, &drawState); | 611 set_coverage_drawing_xpf(op, invert, &drawState); |
601 } | 612 } |
602 | 613 |
603 if (!this->drawElement(&drawState, dst, element, pr)) { | 614 if (!this->drawElement(&drawState, translate, dst, element, pr)) { |
604 fAACache.reset(); | 615 fAACache.reset(); |
605 return NULL; | 616 return NULL; |
606 } | 617 } |
607 | 618 |
608 if (useTemp) { | 619 if (useTemp) { |
609 GrDrawState backgroundDrawState; | 620 GrDrawState backgroundDrawState; |
610 backgroundDrawState.enableState(GrDrawState::kClip_StateBit); | 621 backgroundDrawState.enableState(GrDrawState::kClip_StateBit); |
611 backgroundDrawState.setRenderTarget(result->asRenderTarget()); | 622 backgroundDrawState.setRenderTarget(result->asRenderTarget()); |
612 | 623 |
613 // Now draw into the accumulator using the real operation and th e temp buffer as a | 624 // Now draw into the accumulator using the real operation and th e temp buffer as a |
614 // texture | 625 // texture |
615 this->mergeMask(&backgroundDrawState, | 626 this->mergeMask(&backgroundDrawState, |
616 result, | 627 result, |
617 temp, | 628 temp, |
618 op, | 629 op, |
619 maskSpaceIBounds, | 630 maskSpaceIBounds, |
620 maskSpaceElementIBounds); | 631 maskSpaceElementIBounds); |
621 } else { | 632 } else { |
622 GrDrawState backgroundDrawState(translate); | 633 GrDrawState backgroundDrawState; |
623 backgroundDrawState.enableState(GrDrawState::kClip_StateBit); | 634 backgroundDrawState.enableState(GrDrawState::kClip_StateBit); |
624 backgroundDrawState.setRenderTarget(result->asRenderTarget()); | 635 backgroundDrawState.setRenderTarget(result->asRenderTarget()); |
625 | 636 |
626 set_coverage_drawing_xpf(op, !invert, &backgroundDrawState); | 637 set_coverage_drawing_xpf(op, !invert, &backgroundDrawState); |
627 // Draw to the exterior pixels (those with a zero stencil value) . | 638 // Draw to the exterior pixels (those with a zero stencil value) . |
628 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, | 639 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, |
629 kZero_StencilOp, | 640 kZero_StencilOp, |
630 kZero_StencilOp, | 641 kZero_StencilOp, |
631 kEqual_StencilFunc, | 642 kEqual_StencilFunc, |
632 0xffff, | 643 0xffff, |
633 0x0000, | 644 0x0000, |
634 0xffff); | 645 0xffff); |
635 backgroundDrawState.setStencil(kDrawOutsideElement); | 646 backgroundDrawState.setStencil(kDrawOutsideElement); |
636 // The color passed in here does not matter since the coverageSe tOpXP won't read it. | 647 // The color passed in here does not matter since the coverageSe tOpXP won't read it. |
637 fClipTarget->drawSimpleRect(&backgroundDrawState, GrColor_WHITE, clipSpaceIBounds); | 648 fClipTarget->drawSimpleRect(&backgroundDrawState, GrColor_WHITE, translate, |
649 clipSpaceIBounds); | |
638 } | 650 } |
639 } else { | 651 } else { |
640 GrDrawState drawState(translate); | 652 GrDrawState drawState; |
641 drawState.enableState(GrDrawState::kClip_StateBit); | 653 drawState.enableState(GrDrawState::kClip_StateBit); |
642 | 654 |
643 // all the remaining ops can just be directly draw into the accumula tion buffer | 655 // all the remaining ops can just be directly draw into the accumula tion buffer |
644 set_coverage_drawing_xpf(op, false, &drawState); | 656 set_coverage_drawing_xpf(op, false, &drawState); |
645 // The color passed in here does not matter since the coverageSetOpX P won't read it. | 657 // The color passed in here does not matter since the coverageSetOpX P won't read it. |
646 this->drawElement(&drawState, result, element); | 658 this->drawElement(&drawState, translate, result, element); |
647 } | 659 } |
648 } | 660 } |
649 | 661 |
650 fCurrClipMaskType = kAlpha_ClipMaskType; | 662 fCurrClipMaskType = kAlpha_ClipMaskType; |
651 return result; | 663 return result; |
652 } | 664 } |
653 | 665 |
654 //////////////////////////////////////////////////////////////////////////////// | 666 //////////////////////////////////////////////////////////////////////////////// |
655 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device | 667 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device |
656 // (as opposed to canvas) coordinates | 668 // (as opposed to canvas) coordinates |
(...skipping 12 matching lines...) Expand all Loading... | |
669 return false; | 681 return false; |
670 } | 682 } |
671 | 683 |
672 if (stencilBuffer->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpace ToStencilOffset)) { | 684 if (stencilBuffer->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpace ToStencilOffset)) { |
673 stencilBuffer->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToS tencilOffset); | 685 stencilBuffer->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToS tencilOffset); |
674 // Set the matrix so that rendered clip elements are transformed from cl ip to stencil space. | 686 // Set the matrix so that rendered clip elements are transformed from cl ip to stencil space. |
675 SkVector translate = { | 687 SkVector translate = { |
676 SkIntToScalar(clipSpaceToStencilOffset.fX), | 688 SkIntToScalar(clipSpaceToStencilOffset.fX), |
677 SkIntToScalar(clipSpaceToStencilOffset.fY) | 689 SkIntToScalar(clipSpaceToStencilOffset.fY) |
678 }; | 690 }; |
679 SkMatrix matrix; | 691 SkMatrix viewMatrix; |
680 matrix.setTranslate(translate); | 692 viewMatrix.setTranslate(translate); |
681 | 693 |
682 // We set the current clip to the bounds so that our recursive draws are scissored to them. | 694 // We set the current clip to the bounds so that our recursive draws are scissored to them. |
683 SkIRect stencilSpaceIBounds(clipSpaceIBounds); | 695 SkIRect stencilSpaceIBounds(clipSpaceIBounds); |
684 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); | 696 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); |
685 GrDrawTarget::AutoClipRestore acr(fClipTarget, stencilSpaceIBounds); | 697 GrDrawTarget::AutoClipRestore acr(fClipTarget, stencilSpaceIBounds); |
686 | 698 |
687 int clipBit = stencilBuffer->bits(); | 699 int clipBit = stencilBuffer->bits(); |
688 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers"); | 700 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers"); |
689 clipBit = (1 << (clipBit-1)); | 701 clipBit = (1 << (clipBit-1)); |
690 | 702 |
691 fClipTarget->clearStencilClip(stencilSpaceIBounds, | 703 fClipTarget->clearStencilClip(stencilSpaceIBounds, |
692 GrReducedClip::kAllIn_InitialState == init ialState, | 704 GrReducedClip::kAllIn_InitialState == init ialState, |
693 rt); | 705 rt); |
694 | 706 |
695 // walk through each clip element and perform its set op | 707 // walk through each clip element and perform its set op |
696 // with the existing clip. | 708 // with the existing clip. |
697 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) { | 709 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) { |
698 const Element* element = iter.get(); | 710 const Element* element = iter.get(); |
699 | 711 |
700 GrDrawState drawState(matrix); | 712 GrDrawState drawState; |
701 drawState.setRenderTarget(rt); | 713 drawState.setRenderTarget(rt); |
702 drawState.enableState(GrDrawState::kClip_StateBit); | 714 drawState.enableState(GrDrawState::kClip_StateBit); |
703 | 715 |
704 drawState.setDisableColorXPFactory(); | 716 drawState.setDisableColorXPFactory(); |
705 | 717 |
706 // if the target is MSAA then we want MSAA enabled when the clip is soft | 718 // if the target is MSAA then we want MSAA enabled when the clip is soft |
707 if (rt->isMultisampled()) { | 719 if (rt->isMultisampled()) { |
708 drawState.setState(GrDrawState::kHWAntialias_StateBit, element-> isAA()); | 720 drawState.setState(GrDrawState::kHWAntialias_StateBit, element-> isAA()); |
709 } | 721 } |
710 | 722 |
(...skipping 14 matching lines...) Expand all Loading... | |
725 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; | 737 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; |
726 fillInverted = false; | 738 fillInverted = false; |
727 } else { | 739 } else { |
728 element->asPath(&clipPath); | 740 element->asPath(&clipPath); |
729 fillInverted = clipPath.isInverseFillType(); | 741 fillInverted = clipPath.isInverseFillType(); |
730 if (fillInverted) { | 742 if (fillInverted) { |
731 clipPath.toggleInverseFillType(); | 743 clipPath.toggleInverseFillType(); |
732 } | 744 } |
733 pr = this->getContext()->getPathRenderer(fClipTarget, | 745 pr = this->getContext()->getPathRenderer(fClipTarget, |
734 &drawState, | 746 &drawState, |
747 viewMatrix, | |
735 clipPath, | 748 clipPath, |
736 stroke, | 749 stroke, |
737 false, | 750 false, |
738 GrPathRendererChain::kS tencilOnly_DrawType, | 751 GrPathRendererChain::kS tencilOnly_DrawType, |
739 &stencilSupport); | 752 &stencilSupport); |
740 if (NULL == pr) { | 753 if (NULL == pr) { |
741 return false; | 754 return false; |
742 } | 755 } |
743 } | 756 } |
744 | 757 |
(...skipping 17 matching lines...) Expand all Loading... | |
762 if (!canDrawDirectToClip) { | 775 if (!canDrawDirectToClip) { |
763 GR_STATIC_CONST_SAME_STENCIL(gDrawToStencil, | 776 GR_STATIC_CONST_SAME_STENCIL(gDrawToStencil, |
764 kIncClamp_StencilOp, | 777 kIncClamp_StencilOp, |
765 kIncClamp_StencilOp, | 778 kIncClamp_StencilOp, |
766 kAlways_StencilFunc, | 779 kAlways_StencilFunc, |
767 0xffff, | 780 0xffff, |
768 0x0000, | 781 0x0000, |
769 0xffff); | 782 0xffff); |
770 if (Element::kRect_Type == element->getType()) { | 783 if (Element::kRect_Type == element->getType()) { |
771 *drawState.stencil() = gDrawToStencil; | 784 *drawState.stencil() = gDrawToStencil; |
772 fClipTarget->drawSimpleRect(&drawState, GrColor_WHITE, eleme nt->getRect()); | 785 fClipTarget->drawSimpleRect(&drawState, GrColor_WHITE, viewM atrix, |
786 element->getRect()); | |
773 } else { | 787 } else { |
774 if (!clipPath.isEmpty()) { | 788 if (!clipPath.isEmpty()) { |
775 GrDrawTarget::AutoGeometryPush agp(fClipTarget); | 789 GrDrawTarget::AutoGeometryPush agp(fClipTarget); |
776 if (canRenderDirectToStencil) { | 790 if (canRenderDirectToStencil) { |
777 *drawState.stencil() = gDrawToStencil; | 791 *drawState.stencil() = gDrawToStencil; |
778 pr->drawPath(fClipTarget, &drawState, GrColor_WHITE, clipPath, stroke, | 792 pr->drawPath(fClipTarget, &drawState, GrColor_WHITE, viewMatrix, |
779 false); | 793 clipPath, stroke, false); |
780 } else { | 794 } else { |
781 pr->stencilPath(fClipTarget, &drawState, clipPath, s troke); | 795 pr->stencilPath(fClipTarget, &drawState, viewMatrix, clipPath, stroke); |
782 } | 796 } |
783 } | 797 } |
784 } | 798 } |
785 } | 799 } |
786 | 800 |
787 // now we modify the clip bit by rendering either the clip | 801 // now we modify the clip bit by rendering either the clip |
788 // element directly or a bounding rect of the entire clip. | 802 // element directly or a bounding rect of the entire clip. |
789 fClipMode = kModifyClip_StencilClipMode; | 803 fClipMode = kModifyClip_StencilClipMode; |
790 for (int p = 0; p < passes; ++p) { | 804 for (int p = 0; p < passes; ++p) { |
791 GrDrawState drawStateCopy(drawState); | 805 GrDrawState drawStateCopy(drawState); |
792 *drawStateCopy.stencil() = stencilSettings[p]; | 806 *drawStateCopy.stencil() = stencilSettings[p]; |
793 | 807 |
794 if (canDrawDirectToClip) { | 808 if (canDrawDirectToClip) { |
795 if (Element::kRect_Type == element->getType()) { | 809 if (Element::kRect_Type == element->getType()) { |
796 fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHIT E, | 810 fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHIT E, viewMatrix, |
797 element->getRect()); | 811 element->getRect()); |
798 } else { | 812 } else { |
799 GrDrawTarget::AutoGeometryPush agp(fClipTarget); | 813 GrDrawTarget::AutoGeometryPush agp(fClipTarget); |
800 pr->drawPath(fClipTarget, &drawStateCopy, GrColor_WHITE, clipPath, stroke, false); | 814 pr->drawPath(fClipTarget, &drawStateCopy, GrColor_WHITE, viewMatrix, |
815 clipPath, stroke, false); | |
801 } | 816 } |
802 } else { | 817 } else { |
803 // The view matrix is setup to do clip space -> stencil spac e translation, so | 818 // The view matrix is setup to do clip space -> stencil spac e translation, so |
804 // draw rect in clip space. | 819 // draw rect in clip space. |
805 fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE, | 820 fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE, v iewMatrix, |
806 SkRect::Make(clipSpaceIBounds)); | 821 SkRect::Make(clipSpaceIBounds)); |
807 } | 822 } |
808 } | 823 } |
809 } | 824 } |
810 } | 825 } |
811 // set this last because recursive draws may overwrite it back to kNone. | 826 // set this last because recursive draws may overwrite it back to kNone. |
812 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); | 827 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); |
813 fCurrClipMaskType = kStencil_ClipMaskType; | 828 fCurrClipMaskType = kStencil_ClipMaskType; |
814 fClipMode = kRespectClip_StencilClipMode; | 829 fClipMode = kRespectClip_StencilClipMode; |
815 return true; | 830 return true; |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1066 } | 1081 } |
1067 | 1082 |
1068 void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBu ffer, | 1083 void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBu ffer, |
1069 GrStencilSettings* settings) { | 1084 GrStencilSettings* settings) { |
1070 // TODO: dynamically attach a stencil buffer | 1085 // TODO: dynamically attach a stencil buffer |
1071 if (stencilBuffer) { | 1086 if (stencilBuffer) { |
1072 int stencilBits = stencilBuffer->bits(); | 1087 int stencilBits = stencilBuffer->bits(); |
1073 this->adjustStencilParams(settings, fClipMode, stencilBits); | 1088 this->adjustStencilParams(settings, fClipMode, stencilBits); |
1074 } | 1089 } |
1075 } | 1090 } |
OLD | NEW |