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

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

Issue 815553003: Move ViewMatrix off of drawstate (Closed) Base URL: https://skia.googlesource.com/skia.git@remove-fragment-stage
Patch Set: more cleaning Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrContext.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 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
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 SkVector& clipToMaskOffset,
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
90 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
91 // space.
92 SkMatrix translate;
93 translate.setTranslate(clipToMaskOffset);
94
88 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { 95 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
89 const Element* element = iter.get(); 96 const Element* element = iter.get();
90 // rects can always be drawn directly w/o using the software path 97 // rects can always be drawn directly w/o using the software path
91 // Skip rrects once we're drawing them directly. 98 // Skip rrects once we're drawing them directly.
92 if (Element::kRect_Type != element->getType()) { 99 if (Element::kRect_Type != element->getType()) {
93 SkPath path; 100 SkPath path;
94 element->asPath(&path); 101 element->asPath(&path);
95 if (path_needs_SW_renderer(this->getContext(), fClipTarget, drawStat e, path, stroke, 102 if (path_needs_SW_renderer(this->getContext(), fClipTarget, drawStat e, translate,
96 element->isAA())) { 103 path, stroke, element->isAA())) {
97 return true; 104 return true;
98 } 105 }
99 } 106 }
100 } 107 }
101 return false; 108 return false;
102 } 109 }
103 110
104 bool GrClipMaskManager::installClipEffects(GrDrawState* drawState, 111 bool GrClipMaskManager::installClipEffects(GrDrawState* drawState,
105 GrDrawState::AutoRestoreEffects* are, 112 GrDrawState::AutoRestoreEffects* are,
106 const GrReducedClip::ElementList& ele ments, 113 const GrReducedClip::ElementList& ele ments,
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 this->setDrawStateStencil(drawState, ars); 273 this->setDrawStateStencil(drawState, ars);
267 return true; 274 return true;
268 } 275 }
269 } 276 }
270 277
271 #if GR_AA_CLIP 278 #if GR_AA_CLIP
272 // If MSAA is enabled we can do everything in the stencil buffer. 279 // If MSAA is enabled we can do everything in the stencil buffer.
273 if (0 == rt->numSamples() && requiresAA) { 280 if (0 == rt->numSamples() && requiresAA) {
274 GrTexture* result = NULL; 281 GrTexture* result = NULL;
275 282
276 if (this->useSWOnlyPath(drawState, elements)) { 283 // The top-left of the mask corresponds to the top-left corner of the bo unds.
284 SkVector clipToMaskOffset = {
285 SkIntToScalar(-clipSpaceIBounds.fLeft),
286 SkIntToScalar(-clipSpaceIBounds.fTop)
287 };
288
289 if (this->useSWOnlyPath(drawState, clipToMaskOffset, elements)) {
277 // The clip geometry is complex enough that it will be more efficien t to create it 290 // The clip geometry is complex enough that it will be more efficien t to create it
278 // entirely in software 291 // entirely in software
279 result = this->createSoftwareClipMask(genID, 292 result = this->createSoftwareClipMask(genID,
280 initialState, 293 initialState,
281 elements, 294 elements,
295 clipToMaskOffset,
282 clipSpaceIBounds); 296 clipSpaceIBounds);
283 } else { 297 } else {
284 result = this->createAlphaClipMask(genID, 298 result = this->createAlphaClipMask(genID,
285 initialState, 299 initialState,
286 elements, 300 elements,
301 clipToMaskOffset,
287 clipSpaceIBounds); 302 clipSpaceIBounds);
288 } 303 }
289 304
290 if (result) { 305 if (result) {
291 // The mask's top left coord should be pinned to the rounded-out top left corner of 306 // The mask's top left coord should be pinned to the rounded-out top left corner of
292 // clipSpace bounds. We determine the mask's position WRT to the ren der target here. 307 // clipSpace bounds. We determine the mask's position WRT to the ren der target here.
293 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; 308 SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
294 rtSpaceMaskBounds.offset(-clipDataIn->fOrigin); 309 rtSpaceMaskBounds.offset(-clipDataIn->fOrigin);
295 setup_drawstate_aaclip(rtSpaceMaskBounds, drawState, result); 310 setup_drawstate_aaclip(rtSpaceMaskBounds, drawState, result);
296 this->setDrawStateStencil(drawState, ars); 311 this->setDrawStateStencil(drawState, ars);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
330 //////////////////////////////////////////////////////////////////////////////// 345 ////////////////////////////////////////////////////////////////////////////////
331 // Set a coverage drawing XPF on the drawState for the given op and invertCovera ge mode 346 // 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) { 347 void set_coverage_drawing_xpf(SkRegion::Op op, bool invertCoverage, GrDrawState* drawState) {
333 SkASSERT(op <= SkRegion::kLastOp); 348 SkASSERT(op <= SkRegion::kLastOp);
334 drawState->setCoverageSetOpXPFactory(op, invertCoverage); 349 drawState->setCoverageSetOpXPFactory(op, invertCoverage);
335 } 350 }
336 } 351 }
337 352
338 //////////////////////////////////////////////////////////////////////////////// 353 ////////////////////////////////////////////////////////////////////////////////
339 bool GrClipMaskManager::drawElement(GrDrawState* drawState, 354 bool GrClipMaskManager::drawElement(GrDrawState* drawState,
355 const SkMatrix& viewMatrix,
340 GrTexture* target, 356 GrTexture* target,
341 const SkClipStack::Element* element, 357 const SkClipStack::Element* element,
342 GrPathRenderer* pr) { 358 GrPathRenderer* pr) {
343 GrDrawTarget::AutoGeometryPush agp(fClipTarget); 359 GrDrawTarget::AutoGeometryPush agp(fClipTarget);
344 360
345 drawState->setRenderTarget(target->asRenderTarget()); 361 drawState->setRenderTarget(target->asRenderTarget());
346 362
347 // The color we use to draw does not matter since we will always be using a GrCoverageSetOpXP 363 // The color we use to draw does not matter since we will always be using a GrCoverageSetOpXP
348 // which ignores color. 364 // which ignores color.
349 GrColor color = GrColor_WHITE; 365 GrColor color = GrColor_WHITE;
350 366
351 // TODO: Draw rrects directly here. 367 // TODO: Draw rrects directly here.
352 switch (element->getType()) { 368 switch (element->getType()) {
353 case Element::kEmpty_Type: 369 case Element::kEmpty_Type:
354 SkDEBUGFAIL("Should never get here with an empty element."); 370 SkDEBUGFAIL("Should never get here with an empty element.");
355 break; 371 break;
356 case Element::kRect_Type: 372 case Element::kRect_Type:
357 // TODO: Do rects directly to the accumulator using a aa-rect GrProc essor that covers 373 // 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. 374 // the entire mask bounds and writes 0 outside the rect.
359 if (element->isAA()) { 375 if (element->isAA()) {
376 SkRect devRect = element->getRect();
377 viewMatrix.mapRect(&devRect);
360 this->getContext()->getAARectRenderer()->fillAARect(fClipTarget, 378 this->getContext()->getAARectRenderer()->fillAARect(fClipTarget,
361 drawState, 379 drawState,
362 color, 380 color,
363 SkMatrix::I( ), 381 viewMatrix,
364 element->get Rect(), 382 element->get Rect(),
365 SkMatrix::I( ), 383 devRect);
366 element->get Rect());
367 } else { 384 } else {
368 fClipTarget->drawSimpleRect(drawState, color, element->getRect() ); 385 fClipTarget->drawSimpleRect(drawState, color, viewMatrix, elemen t->getRect());
369 } 386 }
370 return true; 387 return true;
371 default: { 388 default: {
372 SkPath path; 389 SkPath path;
373 element->asPath(&path); 390 element->asPath(&path);
374 path.setIsVolatile(true); 391 path.setIsVolatile(true);
375 if (path.isInverseFillType()) { 392 if (path.isInverseFillType()) {
376 path.toggleInverseFillType(); 393 path.toggleInverseFillType();
377 } 394 }
378 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 395 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
379 if (NULL == pr) { 396 if (NULL == pr) {
380 GrPathRendererChain::DrawType type; 397 GrPathRendererChain::DrawType type;
381 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr awType : 398 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr awType :
382 GrPathRendererChain::kColor_DrawType; 399 GrPathRendererChain::kColor_DrawType;
383 pr = this->getContext()->getPathRenderer(fClipTarget, drawState, path, stroke, 400 pr = this->getContext()->getPathRenderer(fClipTarget, drawState, viewMatrix, path,
384 false, type); 401 stroke, false, type);
385 } 402 }
386 if (NULL == pr) { 403 if (NULL == pr) {
387 return false; 404 return false;
388 } 405 }
389 406
390 pr->drawPath(fClipTarget, drawState, color, path, stroke, element->i sAA()); 407 pr->drawPath(fClipTarget, drawState, color, viewMatrix, path, stroke , element->isAA());
391 break; 408 break;
392 } 409 }
393 } 410 }
394 return true; 411 return true;
395 } 412 }
396 413
397 bool GrClipMaskManager::canStencilAndDrawElement(GrDrawState* drawState, 414 bool GrClipMaskManager::canStencilAndDrawElement(GrDrawState* drawState,
398 GrTexture* target, 415 GrTexture* target,
399 GrPathRenderer** pr, 416 GrPathRenderer** pr,
400 const SkClipStack::Element* ele ment) { 417 const SkClipStack::Element* ele ment) {
401 drawState->setRenderTarget(target->asRenderTarget()); 418 drawState->setRenderTarget(target->asRenderTarget());
402 419
403 if (Element::kRect_Type == element->getType()) { 420 if (Element::kRect_Type == element->getType()) {
404 return true; 421 return true;
405 } else { 422 } else {
406 // We shouldn't get here with an empty clip element. 423 // We shouldn't get here with an empty clip element.
407 SkASSERT(Element::kEmpty_Type != element->getType()); 424 SkASSERT(Element::kEmpty_Type != element->getType());
408 SkPath path; 425 SkPath path;
409 element->asPath(&path); 426 element->asPath(&path);
410 if (path.isInverseFillType()) { 427 if (path.isInverseFillType()) {
411 path.toggleInverseFillType(); 428 path.toggleInverseFillType();
412 } 429 }
413 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 430 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
414 GrPathRendererChain::DrawType type = element->isAA() ? 431 GrPathRendererChain::DrawType type = element->isAA() ?
415 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : 432 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
416 GrPathRendererChain::kStencilAndColor_DrawType; 433 GrPathRendererChain::kStencilAndColor_DrawType;
417 *pr = this->getContext()->getPathRenderer(fClipTarget, drawState, path, stroke, false, 434 *pr = this->getContext()->getPathRenderer(fClipTarget, drawState, SkMatr ix::I(), path,
418 type); 435 stroke, false, type);
419 return SkToBool(*pr); 436 return SkToBool(*pr);
420 } 437 }
421 } 438 }
422 439
423 void GrClipMaskManager::mergeMask(GrDrawState* drawState, 440 void GrClipMaskManager::mergeMask(GrDrawState* drawState,
424 GrTexture* dstMask, 441 GrTexture* dstMask,
425 GrTexture* srcMask, 442 GrTexture* srcMask,
426 SkRegion::Op op, 443 SkRegion::Op op,
427 const SkIRect& dstBound, 444 const SkIRect& dstBound,
428 const SkIRect& srcBound) { 445 const SkIRect& srcBound) {
429 drawState->setRenderTarget(dstMask->asRenderTarget()); 446 drawState->setRenderTarget(dstMask->asRenderTarget());
430 447
431 // We want to invert the coverage here 448 // We want to invert the coverage here
432 set_coverage_drawing_xpf(op, false, drawState); 449 set_coverage_drawing_xpf(op, false, drawState);
433 450
434 SkMatrix sampleM; 451 SkMatrix sampleM;
435 sampleM.setIDiv(srcMask->width(), srcMask->height()); 452 sampleM.setIDiv(srcMask->width(), srcMask->height());
436 453
437 drawState->addCoverageProcessor( 454 drawState->addCoverageProcessor(
438 GrTextureDomainEffect::Create(srcMask, 455 GrTextureDomainEffect::Create(srcMask,
439 sampleM, 456 sampleM,
440 GrTextureDomain::MakeTexelDomain(srcMask, srcBound), 457 GrTextureDomain::MakeTexelDomain(srcMask, srcBound),
441 GrTextureDomain::kDecal_Mode, 458 GrTextureDomain::kDecal_Mode,
442 GrTextureParams::kNone_FilterMode))->unref (); 459 GrTextureParams::kNone_FilterMode))->unref ();
443 // The color passed in here does not matter since the coverageSetOpXP won't read it. 460 // The color passed in here does not matter since the coverageSetOpXP won't read it.
444 fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkRect::Make(dstBound) ); 461 fClipTarget->drawSimpleRect(drawState, GrColor_WHITE, SkMatrix::I(), SkRect: :Make(dstBound));
445 } 462 }
446 463
447 GrTexture* GrClipMaskManager::createTempMask(int width, int height) { 464 GrTexture* GrClipMaskManager::createTempMask(int width, int height) {
448 GrSurfaceDesc desc; 465 GrSurfaceDesc desc;
449 desc.fFlags = kRenderTarget_GrSurfaceFlag; 466 desc.fFlags = kRenderTarget_GrSurfaceFlag;
450 desc.fWidth = width; 467 desc.fWidth = width;
451 desc.fHeight = height; 468 desc.fHeight = height;
452 if (this->getContext()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) { 469 if (this->getContext()->isConfigRenderable(kAlpha_8_GrPixelConfig, false)) {
453 desc.fConfig = kAlpha_8_GrPixelConfig; 470 desc.fConfig = kAlpha_8_GrPixelConfig;
454 } else { 471 } else {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 509
493 fAACache.acquireMask(elementsGenID, desc, clipSpaceIBounds); 510 fAACache.acquireMask(elementsGenID, desc, clipSpaceIBounds);
494 return fAACache.getLastMask(); 511 return fAACache.getLastMask();
495 } 512 }
496 513
497 //////////////////////////////////////////////////////////////////////////////// 514 ////////////////////////////////////////////////////////////////////////////////
498 // Create a 8-bit clip mask in alpha 515 // Create a 8-bit clip mask in alpha
499 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID, 516 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
500 GrReducedClip::InitialState in itialState, 517 GrReducedClip::InitialState in itialState,
501 const GrReducedClip::ElementLi st& elements, 518 const GrReducedClip::ElementLi st& elements,
519 const SkVector& clipToMaskOffs et,
502 const SkIRect& clipSpaceIBound s) { 520 const SkIRect& clipSpaceIBound s) {
503 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); 521 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
504 522
505 // First, check for cached texture 523 // First, check for cached texture
506 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun ds); 524 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun ds);
507 if (result) { 525 if (result) {
508 fCurrClipMaskType = kAlpha_ClipMaskType; 526 fCurrClipMaskType = kAlpha_ClipMaskType;
509 return result; 527 return result;
510 } 528 }
511 529
512 // There's no texture in the cache. Let's try to allocate it then. 530 // There's no texture in the cache. Let's try to allocate it then.
513 result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, false); 531 result = this->allocMaskTexture(elementsGenID, clipSpaceIBounds, false);
514 if (NULL == result) { 532 if (NULL == result) {
515 fAACache.reset(); 533 fAACache.reset();
516 return NULL; 534 return NULL;
517 } 535 }
518 536
519 // The top-left of the mask corresponds to the top-left corner of the bounds . 537 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
520 SkVector clipToMaskOffset = { 538 // space.
521 SkIntToScalar(-clipSpaceIBounds.fLeft), 539 SkMatrix translate;
522 SkIntToScalar(-clipSpaceIBounds.fTop) 540 translate.setTranslate(clipToMaskOffset);
523 }; 541
524 // The texture may be larger than necessary, this rect represents the part o f the texture 542 // The texture may be larger than necessary, this rect represents the part o f the texture
525 // we populate with a rasterization of the clip. 543 // we populate with a rasterization of the clip.
526 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); 544 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height());
527 545
528 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip space.
529 SkMatrix translate;
530 translate.setTranslate(clipToMaskOffset);
531
532 // The scratch texture that we are drawing into can be substantially larger than the mask. Only 546 // The scratch texture that we are drawing into can be substantially larger than the mask. Only
533 // clear the part that we care about. 547 // clear the part that we care about.
534 fClipTarget->clear(&maskSpaceIBounds, 548 fClipTarget->clear(&maskSpaceIBounds,
535 GrReducedClip::kAllIn_InitialState == initialState ? 0xff ffffff : 0x00000000, 549 GrReducedClip::kAllIn_InitialState == initialState ? 0xff ffffff : 0x00000000,
536 true, 550 true,
537 result->asRenderTarget()); 551 result->asRenderTarget());
538 552
539 // When we use the stencil in the below loop it is important to have this cl ip installed. 553 // When we use the stencil in the below loop it is important to have this cl ip installed.
540 // The second pass that zeros the stencil buffer renders the rect maskSpaceI Bounds so the first 554 // The second pass that zeros the stencil buffer renders the rect maskSpaceI Bounds so the first
541 // pass must not set values outside of this bounds or stencil values outside the rect won't be 555 // pass must not set values outside of this bounds or stencil values outside the rect won't be
542 // cleared. 556 // cleared.
543 GrDrawTarget::AutoClipRestore acr(fClipTarget, maskSpaceIBounds); 557 GrDrawTarget::AutoClipRestore acr(fClipTarget, maskSpaceIBounds);
544 SkAutoTUnref<GrTexture> temp; 558 SkAutoTUnref<GrTexture> temp;
545 559
546 // walk through each clip element and perform its set op 560 // walk through each clip element and perform its set op
547 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) { 561 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) {
548 const Element* element = iter.get(); 562 const Element* element = iter.get();
549 SkRegion::Op op = element->getOp(); 563 SkRegion::Op op = element->getOp();
550 bool invert = element->isInverseFilled(); 564 bool invert = element->isInverseFilled();
551 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) { 565 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) {
552 GrDrawState drawState(translate); 566 GrDrawState drawState;
553 drawState.enableState(GrDrawState::kClip_StateBit); 567 drawState.enableState(GrDrawState::kClip_StateBit);
554 568
555 GrPathRenderer* pr = NULL; 569 GrPathRenderer* pr = NULL;
556 bool useTemp = !this->canStencilAndDrawElement(&drawState, result, & pr, element); 570 bool useTemp = !this->canStencilAndDrawElement(&drawState, result, & pr, element);
557 GrTexture* dst; 571 GrTexture* dst;
558 // This is the bounds of the clip element in the space of the alpha- mask. The temporary 572 // 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 573 // 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 574 // touch the minimum number of pixels necessary and use decal mode t o combine it with
561 // the accumulator. 575 // the accumulator.
562 SkIRect maskSpaceElementIBounds; 576 SkIRect maskSpaceElementIBounds;
(...skipping 30 matching lines...) Expand all
593 kReplace_StencilOp, 607 kReplace_StencilOp,
594 kReplace_StencilOp, 608 kReplace_StencilOp,
595 kAlways_StencilFunc, 609 kAlways_StencilFunc,
596 0xffff, 610 0xffff,
597 0xffff, 611 0xffff,
598 0xffff); 612 0xffff);
599 drawState.setStencil(kStencilInElement); 613 drawState.setStencil(kStencilInElement);
600 set_coverage_drawing_xpf(op, invert, &drawState); 614 set_coverage_drawing_xpf(op, invert, &drawState);
601 } 615 }
602 616
603 if (!this->drawElement(&drawState, dst, element, pr)) { 617 if (!this->drawElement(&drawState, translate, dst, element, pr)) {
604 fAACache.reset(); 618 fAACache.reset();
605 return NULL; 619 return NULL;
606 } 620 }
607 621
608 if (useTemp) { 622 if (useTemp) {
609 GrDrawState backgroundDrawState; 623 GrDrawState backgroundDrawState;
610 backgroundDrawState.enableState(GrDrawState::kClip_StateBit); 624 backgroundDrawState.enableState(GrDrawState::kClip_StateBit);
611 backgroundDrawState.setRenderTarget(result->asRenderTarget()); 625 backgroundDrawState.setRenderTarget(result->asRenderTarget());
612 626
613 // Now draw into the accumulator using the real operation and th e temp buffer as a 627 // Now draw into the accumulator using the real operation and th e temp buffer as a
614 // texture 628 // texture
615 this->mergeMask(&backgroundDrawState, 629 this->mergeMask(&backgroundDrawState,
616 result, 630 result,
617 temp, 631 temp,
618 op, 632 op,
619 maskSpaceIBounds, 633 maskSpaceIBounds,
620 maskSpaceElementIBounds); 634 maskSpaceElementIBounds);
621 } else { 635 } else {
622 GrDrawState backgroundDrawState(translate); 636 GrDrawState backgroundDrawState;
623 backgroundDrawState.enableState(GrDrawState::kClip_StateBit); 637 backgroundDrawState.enableState(GrDrawState::kClip_StateBit);
624 backgroundDrawState.setRenderTarget(result->asRenderTarget()); 638 backgroundDrawState.setRenderTarget(result->asRenderTarget());
625 639
626 set_coverage_drawing_xpf(op, !invert, &backgroundDrawState); 640 set_coverage_drawing_xpf(op, !invert, &backgroundDrawState);
627 // Draw to the exterior pixels (those with a zero stencil value) . 641 // Draw to the exterior pixels (those with a zero stencil value) .
628 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, 642 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement,
629 kZero_StencilOp, 643 kZero_StencilOp,
630 kZero_StencilOp, 644 kZero_StencilOp,
631 kEqual_StencilFunc, 645 kEqual_StencilFunc,
632 0xffff, 646 0xffff,
633 0x0000, 647 0x0000,
634 0xffff); 648 0xffff);
635 backgroundDrawState.setStencil(kDrawOutsideElement); 649 backgroundDrawState.setStencil(kDrawOutsideElement);
636 // The color passed in here does not matter since the coverageSe tOpXP won't read it. 650 // The color passed in here does not matter since the coverageSe tOpXP won't read it.
637 fClipTarget->drawSimpleRect(&backgroundDrawState, GrColor_WHITE, clipSpaceIBounds); 651 fClipTarget->drawSimpleRect(&backgroundDrawState, GrColor_WHITE, translate,
652 clipSpaceIBounds);
638 } 653 }
639 } else { 654 } else {
640 GrDrawState drawState(translate); 655 GrDrawState drawState;
641 drawState.enableState(GrDrawState::kClip_StateBit); 656 drawState.enableState(GrDrawState::kClip_StateBit);
642 657
643 // all the remaining ops can just be directly draw into the accumula tion buffer 658 // all the remaining ops can just be directly draw into the accumula tion buffer
644 set_coverage_drawing_xpf(op, false, &drawState); 659 set_coverage_drawing_xpf(op, false, &drawState);
645 // The color passed in here does not matter since the coverageSetOpX P won't read it. 660 // The color passed in here does not matter since the coverageSetOpX P won't read it.
646 this->drawElement(&drawState, result, element); 661 this->drawElement(&drawState, translate, result, element);
647 } 662 }
648 } 663 }
649 664
650 fCurrClipMaskType = kAlpha_ClipMaskType; 665 fCurrClipMaskType = kAlpha_ClipMaskType;
651 return result; 666 return result;
652 } 667 }
653 668
654 //////////////////////////////////////////////////////////////////////////////// 669 ////////////////////////////////////////////////////////////////////////////////
655 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device 670 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
656 // (as opposed to canvas) coordinates 671 // (as opposed to canvas) coordinates
(...skipping 12 matching lines...) Expand all
669 return false; 684 return false;
670 } 685 }
671 686
672 if (stencilBuffer->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpace ToStencilOffset)) { 687 if (stencilBuffer->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpace ToStencilOffset)) {
673 stencilBuffer->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToS tencilOffset); 688 stencilBuffer->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToS tencilOffset);
674 // Set the matrix so that rendered clip elements are transformed from cl ip to stencil space. 689 // Set the matrix so that rendered clip elements are transformed from cl ip to stencil space.
675 SkVector translate = { 690 SkVector translate = {
676 SkIntToScalar(clipSpaceToStencilOffset.fX), 691 SkIntToScalar(clipSpaceToStencilOffset.fX),
677 SkIntToScalar(clipSpaceToStencilOffset.fY) 692 SkIntToScalar(clipSpaceToStencilOffset.fY)
678 }; 693 };
679 SkMatrix matrix; 694 SkMatrix viewMatrix;
680 matrix.setTranslate(translate); 695 viewMatrix.setTranslate(translate);
681 696
682 // We set the current clip to the bounds so that our recursive draws are scissored to them. 697 // We set the current clip to the bounds so that our recursive draws are scissored to them.
683 SkIRect stencilSpaceIBounds(clipSpaceIBounds); 698 SkIRect stencilSpaceIBounds(clipSpaceIBounds);
684 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); 699 stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
685 GrDrawTarget::AutoClipRestore acr(fClipTarget, stencilSpaceIBounds); 700 GrDrawTarget::AutoClipRestore acr(fClipTarget, stencilSpaceIBounds);
686 701
687 int clipBit = stencilBuffer->bits(); 702 int clipBit = stencilBuffer->bits();
688 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers"); 703 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers");
689 clipBit = (1 << (clipBit-1)); 704 clipBit = (1 << (clipBit-1));
690 705
691 fClipTarget->clearStencilClip(stencilSpaceIBounds, 706 fClipTarget->clearStencilClip(stencilSpaceIBounds,
692 GrReducedClip::kAllIn_InitialState == init ialState, 707 GrReducedClip::kAllIn_InitialState == init ialState,
693 rt); 708 rt);
694 709
695 // walk through each clip element and perform its set op 710 // walk through each clip element and perform its set op
696 // with the existing clip. 711 // with the existing clip.
697 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) { 712 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) {
698 const Element* element = iter.get(); 713 const Element* element = iter.get();
699 714
700 GrDrawState drawState(matrix); 715 GrDrawState drawState;
701 drawState.setRenderTarget(rt); 716 drawState.setRenderTarget(rt);
702 drawState.enableState(GrDrawState::kClip_StateBit); 717 drawState.enableState(GrDrawState::kClip_StateBit);
703 718
704 drawState.setDisableColorXPFactory(); 719 drawState.setDisableColorXPFactory();
705 720
706 // if the target is MSAA then we want MSAA enabled when the clip is soft 721 // if the target is MSAA then we want MSAA enabled when the clip is soft
707 if (rt->isMultisampled()) { 722 if (rt->isMultisampled()) {
708 drawState.setState(GrDrawState::kHWAntialias_StateBit, element-> isAA()); 723 drawState.setState(GrDrawState::kHWAntialias_StateBit, element-> isAA());
709 } 724 }
710 725
(...skipping 14 matching lines...) Expand all
725 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; 740 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
726 fillInverted = false; 741 fillInverted = false;
727 } else { 742 } else {
728 element->asPath(&clipPath); 743 element->asPath(&clipPath);
729 fillInverted = clipPath.isInverseFillType(); 744 fillInverted = clipPath.isInverseFillType();
730 if (fillInverted) { 745 if (fillInverted) {
731 clipPath.toggleInverseFillType(); 746 clipPath.toggleInverseFillType();
732 } 747 }
733 pr = this->getContext()->getPathRenderer(fClipTarget, 748 pr = this->getContext()->getPathRenderer(fClipTarget,
734 &drawState, 749 &drawState,
750 viewMatrix,
735 clipPath, 751 clipPath,
736 stroke, 752 stroke,
737 false, 753 false,
738 GrPathRendererChain::kS tencilOnly_DrawType, 754 GrPathRendererChain::kS tencilOnly_DrawType,
739 &stencilSupport); 755 &stencilSupport);
740 if (NULL == pr) { 756 if (NULL == pr) {
741 return false; 757 return false;
742 } 758 }
743 } 759 }
744 760
(...skipping 17 matching lines...) Expand all
762 if (!canDrawDirectToClip) { 778 if (!canDrawDirectToClip) {
763 GR_STATIC_CONST_SAME_STENCIL(gDrawToStencil, 779 GR_STATIC_CONST_SAME_STENCIL(gDrawToStencil,
764 kIncClamp_StencilOp, 780 kIncClamp_StencilOp,
765 kIncClamp_StencilOp, 781 kIncClamp_StencilOp,
766 kAlways_StencilFunc, 782 kAlways_StencilFunc,
767 0xffff, 783 0xffff,
768 0x0000, 784 0x0000,
769 0xffff); 785 0xffff);
770 if (Element::kRect_Type == element->getType()) { 786 if (Element::kRect_Type == element->getType()) {
771 *drawState.stencil() = gDrawToStencil; 787 *drawState.stencil() = gDrawToStencil;
772 fClipTarget->drawSimpleRect(&drawState, GrColor_WHITE, eleme nt->getRect()); 788 fClipTarget->drawSimpleRect(&drawState, GrColor_WHITE, viewM atrix,
789 element->getRect());
773 } else { 790 } else {
774 if (!clipPath.isEmpty()) { 791 if (!clipPath.isEmpty()) {
775 GrDrawTarget::AutoGeometryPush agp(fClipTarget); 792 GrDrawTarget::AutoGeometryPush agp(fClipTarget);
776 if (canRenderDirectToStencil) { 793 if (canRenderDirectToStencil) {
777 *drawState.stencil() = gDrawToStencil; 794 *drawState.stencil() = gDrawToStencil;
778 pr->drawPath(fClipTarget, &drawState, GrColor_WHITE, clipPath, stroke, 795 pr->drawPath(fClipTarget, &drawState, GrColor_WHITE, viewMatrix,
779 false); 796 clipPath, stroke, false);
780 } else { 797 } else {
781 pr->stencilPath(fClipTarget, &drawState, clipPath, s troke); 798 pr->stencilPath(fClipTarget, &drawState, viewMatrix, clipPath, stroke);
782 } 799 }
783 } 800 }
784 } 801 }
785 } 802 }
786 803
787 // now we modify the clip bit by rendering either the clip 804 // now we modify the clip bit by rendering either the clip
788 // element directly or a bounding rect of the entire clip. 805 // element directly or a bounding rect of the entire clip.
789 fClipMode = kModifyClip_StencilClipMode; 806 fClipMode = kModifyClip_StencilClipMode;
790 for (int p = 0; p < passes; ++p) { 807 for (int p = 0; p < passes; ++p) {
791 GrDrawState drawStateCopy(drawState); 808 GrDrawState drawStateCopy(drawState);
792 *drawStateCopy.stencil() = stencilSettings[p]; 809 *drawStateCopy.stencil() = stencilSettings[p];
793 810
794 if (canDrawDirectToClip) { 811 if (canDrawDirectToClip) {
795 if (Element::kRect_Type == element->getType()) { 812 if (Element::kRect_Type == element->getType()) {
796 fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHIT E, 813 fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHIT E, viewMatrix,
797 element->getRect()); 814 element->getRect());
798 } else { 815 } else {
799 GrDrawTarget::AutoGeometryPush agp(fClipTarget); 816 GrDrawTarget::AutoGeometryPush agp(fClipTarget);
800 pr->drawPath(fClipTarget, &drawStateCopy, GrColor_WHITE, clipPath, stroke, false); 817 pr->drawPath(fClipTarget, &drawStateCopy, GrColor_WHITE, viewMatrix,
818 clipPath, stroke, false);
801 } 819 }
802 } else { 820 } else {
803 // The view matrix is setup to do clip space -> stencil spac e translation, so 821 // The view matrix is setup to do clip space -> stencil spac e translation, so
804 // draw rect in clip space. 822 // draw rect in clip space.
805 fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE, 823 fClipTarget->drawSimpleRect(&drawStateCopy, GrColor_WHITE, v iewMatrix,
806 SkRect::Make(clipSpaceIBounds)); 824 SkRect::Make(clipSpaceIBounds));
807 } 825 }
808 } 826 }
809 } 827 }
810 } 828 }
811 // set this last because recursive draws may overwrite it back to kNone. 829 // set this last because recursive draws may overwrite it back to kNone.
812 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); 830 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
813 fCurrClipMaskType = kStencil_ClipMaskType; 831 fCurrClipMaskType = kStencil_ClipMaskType;
814 fClipMode = kRespectClip_StencilClipMode; 832 fClipMode = kRespectClip_StencilClipMode;
815 return true; 833 return true;
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
982 } 1000 }
983 if (!twoSided) { 1001 if (!twoSided) {
984 settings->copyFrontSettingsToBack(); 1002 settings->copyFrontSettingsToBack();
985 } 1003 }
986 } 1004 }
987 1005
988 //////////////////////////////////////////////////////////////////////////////// 1006 ////////////////////////////////////////////////////////////////////////////////
989 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID, 1007 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID,
990 GrReducedClip::InitialState initialState, 1008 GrReducedClip::InitialState initialState,
991 const GrReducedClip::Elemen tList& elements, 1009 const GrReducedClip::Elemen tList& elements,
1010 const SkVector& clipToMaskO ffset,
992 const SkIRect& clipSpaceIBo unds) { 1011 const SkIRect& clipSpaceIBo unds) {
993 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); 1012 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
994 1013
995 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun ds); 1014 GrTexture* result = this->getCachedMaskTexture(elementsGenID, clipSpaceIBoun ds);
996 if (result) { 1015 if (result) {
997 return result; 1016 return result;
998 } 1017 }
999 1018
1000 // The mask texture may be larger than necessary. We round out the clip spac e bounds and pin 1019 // The mask texture may be larger than necessary. We round out the clip spac e bounds and pin
1001 // the top left corner of the resulting rect to the top left of the texture. 1020 // the top left corner of the resulting rect to the top left of the texture.
1002 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); 1021 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height());
1003 1022
1004 GrSWMaskHelper helper(this->getContext()); 1023 GrSWMaskHelper helper(this->getContext());
1005 1024
1006 SkMatrix matrix; 1025 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip
1007 matrix.setTranslate(SkIntToScalar(-clipSpaceIBounds.fLeft), 1026 // space.
1008 SkIntToScalar(-clipSpaceIBounds.fTop)); 1027 SkMatrix translate;
1028 translate.setTranslate(clipToMaskOffset);
1009 1029
1010 helper.init(maskSpaceIBounds, &matrix, false); 1030 helper.init(maskSpaceIBounds, &translate, false);
1011 helper.clear(GrReducedClip::kAllIn_InitialState == initialState ? 0xFF : 0x0 0); 1031 helper.clear(GrReducedClip::kAllIn_InitialState == initialState ? 0xFF : 0x0 0);
1012 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 1032 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
1013 1033
1014 for (GrReducedClip::ElementList::Iter iter(elements.headIter()) ; iter.get() ; iter.next()) { 1034 for (GrReducedClip::ElementList::Iter iter(elements.headIter()) ; iter.get() ; iter.next()) {
1015 const Element* element = iter.get(); 1035 const Element* element = iter.get();
1016 SkRegion::Op op = element->getOp(); 1036 SkRegion::Op op = element->getOp();
1017 1037
1018 if (SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) { 1038 if (SkRegion::kIntersect_Op == op || SkRegion::kReverseDifference_Op == op) {
1019 // Intersect and reverse difference require modifying pixels outside of the geometry 1039 // Intersect and reverse difference require modifying pixels outside of the geometry
1020 // that is being "drawn". In both cases we erase all the pixels outs ide of the geometry 1040 // that is being "drawn". In both cases we erase all the pixels outs ide of the geometry
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1066 } 1086 }
1067 1087
1068 void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBu ffer, 1088 void GrClipMaskManager::adjustPathStencilParams(const GrStencilBuffer* stencilBu ffer,
1069 GrStencilSettings* settings) { 1089 GrStencilSettings* settings) {
1070 // TODO: dynamically attach a stencil buffer 1090 // TODO: dynamically attach a stencil buffer
1071 if (stencilBuffer) { 1091 if (stencilBuffer) {
1072 int stencilBits = stencilBuffer->bits(); 1092 int stencilBits = stencilBuffer->bits();
1073 this->adjustStencilParams(settings, fClipMode, stencilBits); 1093 this->adjustStencilParams(settings, fClipMode, stencilBits);
1074 } 1094 }
1075 } 1095 }
OLDNEW
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698