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

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

Issue 683933003: Clip mask manager moved to ClipTarget (Closed) Base URL: https://skia.googlesource.com/skia.git@clear_stencil_clip_on_drawinfo
Patch Set: cleanup Created 6 years, 1 month 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
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2012 Google Inc. 3 * Copyright 2012 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "GrClipMaskManager.h" 9 #include "GrClipMaskManager.h"
10 #include "GrAAConvexPathRenderer.h" 10 #include "GrAAConvexPathRenderer.h"
11 #include "GrAAHairLinePathRenderer.h" 11 #include "GrAAHairLinePathRenderer.h"
12 #include "GrAARectRenderer.h" 12 #include "GrAARectRenderer.h"
13 #include "GrDrawTargetCaps.h" 13 #include "GrDrawTargetCaps.h"
14 #include "GrGpu.h"
15 #include "GrPaint.h" 14 #include "GrPaint.h"
16 #include "GrPathRenderer.h" 15 #include "GrPathRenderer.h"
17 #include "GrRenderTarget.h" 16 #include "GrRenderTarget.h"
18 #include "GrStencilBuffer.h" 17 #include "GrStencilBuffer.h"
19 #include "GrSWMaskHelper.h" 18 #include "GrSWMaskHelper.h"
20 #include "SkRasterClip.h" 19 #include "SkRasterClip.h"
21 #include "SkStrokeRec.h" 20 #include "SkStrokeRec.h"
22 #include "SkTLazy.h" 21 #include "SkTLazy.h"
23 #include "effects/GrTextureDomain.h" 22 #include "effects/GrTextureDomain.h"
24 #include "effects/GrConvexPolyEffect.h" 23 #include "effects/GrConvexPolyEffect.h"
25 #include "effects/GrRRectEffect.h" 24 #include "effects/GrRRectEffect.h"
26 25
27 #define GR_AA_CLIP 1 26 #define GR_AA_CLIP 1
28 27
29 typedef SkClipStack::Element Element; 28 typedef SkClipStack::Element Element;
30 29
31 //////////////////////////////////////////////////////////////////////////////// 30 ////////////////////////////////////////////////////////////////////////////////
32 namespace { 31 namespace {
33 // set up the draw state to enable the aa clipping mask. Besides setting up the 32 // set up the draw state to enable the aa clipping mask. Besides setting up the
34 // stage matrix this also alters the vertex layout 33 // stage matrix this also alters the vertex layout
35 void setup_drawstate_aaclip(GrGpu* gpu, 34 void setup_drawstate_aaclip(GrDrawTarget* gpu,
36 GrTexture* result, 35 GrTexture* result,
37 const SkIRect &devBound) { 36 const SkIRect &devBound) {
38 GrDrawState* drawState = gpu->drawState(); 37 GrDrawState* drawState = gpu->drawState();
39 SkASSERT(drawState); 38 SkASSERT(drawState);
40 39
41 SkMatrix mat; 40 SkMatrix mat;
42 // We want to use device coords to compute the texture coordinates. We set o ur matrix to be 41 // We want to use device coords to compute the texture coordinates. We set o ur matrix to be
43 // equal to the view matrix followed by an offset to the devBound, and then a scaling matrix to 42 // equal to the view matrix followed by an offset to the devBound, and then a scaling matrix to
44 // normalized coords. We apply this matrix to the vertex positions rather th an local coords. 43 // normalized coords. We apply this matrix to the vertex positions rather th an local coords.
45 mat.setIDiv(result->width(), result->height()); 44 mat.setIDiv(result->width(), result->height());
46 mat.preTranslate(SkIntToScalar(-devBound.fLeft), 45 mat.preTranslate(SkIntToScalar(-devBound.fLeft),
47 SkIntToScalar(-devBound.fTop)); 46 SkIntToScalar(-devBound.fTop));
48 mat.preConcat(drawState->getViewMatrix()); 47 mat.preConcat(drawState->getViewMatrix());
49 48
50 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height()); 49 SkIRect domainTexels = SkIRect::MakeWH(devBound.width(), devBound.height());
51 // This could be a long-lived effect that is cached with the alpha-mask. 50 // This could be a long-lived effect that is cached with the alpha-mask.
52 drawState->addCoverageProcessor( 51 drawState->addCoverageProcessor(
53 GrTextureDomainEffect::Create(result, 52 GrTextureDomainEffect::Create(result,
54 mat, 53 mat,
55 GrTextureDomain::MakeTexelDomain(result, d omainTexels), 54 GrTextureDomain::MakeTexelDomain(result, d omainTexels),
56 GrTextureDomain::kDecal_Mode, 55 GrTextureDomain::kDecal_Mode,
57 GrTextureParams::kNone_FilterMode, 56 GrTextureParams::kNone_FilterMode,
58 kPosition_GrCoordSet))->unref(); 57 kPosition_GrCoordSet))->unref();
59 } 58 }
60 59
61 bool path_needs_SW_renderer(GrContext* context, 60 bool path_needs_SW_renderer(GrContext* context,
62 GrGpu* gpu, 61 GrDrawTarget* gpu,
63 const SkPath& origPath, 62 const SkPath& origPath,
64 const SkStrokeRec& stroke, 63 const SkStrokeRec& stroke,
65 bool doAA) { 64 bool doAA) {
66 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b uffer 65 // the gpu alpha mask will draw the inverse paths as non-inverse to a temp b uffer
67 SkTCopyOnFirstWrite<SkPath> path(origPath); 66 SkTCopyOnFirstWrite<SkPath> path(origPath);
68 if (path->isInverseFillType()) { 67 if (path->isInverseFillType()) {
69 path.writable()->toggleInverseFillType(); 68 path.writable()->toggleInverseFillType();
70 } 69 }
71 // last (false) parameter disallows use of the SW path renderer 70 // last (false) parameter disallows use of the SW path renderer
72 GrPathRendererChain::DrawType type = doAA ? 71 GrPathRendererChain::DrawType type = doAA ?
(...skipping 17 matching lines...) Expand all
90 // of whether it would invoke the GrSoftwarePathRenderer. 89 // of whether it would invoke the GrSoftwarePathRenderer.
91 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 90 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
92 91
93 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { 92 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
94 const Element* element = iter.get(); 93 const Element* element = iter.get();
95 // rects can always be drawn directly w/o using the software path 94 // rects can always be drawn directly w/o using the software path
96 // Skip rrects once we're drawing them directly. 95 // Skip rrects once we're drawing them directly.
97 if (Element::kRect_Type != element->getType()) { 96 if (Element::kRect_Type != element->getType()) {
98 SkPath path; 97 SkPath path;
99 element->asPath(&path); 98 element->asPath(&path);
100 if (path_needs_SW_renderer(this->getContext(), fGpu, path, stroke, e lement->isAA())) { 99 if (path_needs_SW_renderer(this->getContext(), fClipTarget, path, st roke, element->isAA())) {
101 return true; 100 return true;
102 } 101 }
103 } 102 }
104 } 103 }
105 return false; 104 return false;
106 } 105 }
107 106
108 bool GrClipMaskManager::installClipEffects(const GrReducedClip::ElementList& ele ments, 107 bool GrClipMaskManager::installClipEffects(const GrReducedClip::ElementList& ele ments,
109 GrDrawState::AutoRestoreEffects* are, 108 GrDrawState::AutoRestoreEffects* are,
110 const SkVector& clipToRTOffset, 109 const SkVector& clipToRTOffset,
111 const SkRect* drawBounds) { 110 const SkRect* drawBounds) {
112 111
113 GrDrawState* drawState = fGpu->drawState(); 112 GrDrawState* drawState = fClipTarget->drawState();
114 SkRect boundsInClipSpace; 113 SkRect boundsInClipSpace;
115 if (drawBounds) { 114 if (drawBounds) {
116 boundsInClipSpace = *drawBounds; 115 boundsInClipSpace = *drawBounds;
117 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY); 116 boundsInClipSpace.offset(-clipToRTOffset.fX, -clipToRTOffset.fY);
118 } 117 }
119 118
120 are->set(drawState); 119 are->set(drawState);
121 GrRenderTarget* rt = drawState->getRenderTarget(); 120 GrRenderTarget* rt = drawState->getRenderTarget();
122 GrReducedClip::ElementList::Iter iter(elements); 121 GrReducedClip::ElementList::Iter iter(elements);
123 122
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
181 SkRect rect = iter.get()->getRect(); 180 SkRect rect = iter.get()->getRect();
182 rect.offset(clipToRTOffset.fX, clipToRTOffset.fY); 181 rect.offset(clipToRTOffset.fX, clipToRTOffset.fY);
183 fp.reset(GrConvexPolyEffect::Create(edgeType, rect)); 182 fp.reset(GrConvexPolyEffect::Create(edgeType, rect));
184 break; 183 break;
185 } 184 }
186 default: 185 default:
187 break; 186 break;
188 } 187 }
189 if (fp) { 188 if (fp) {
190 if (!setARE) { 189 if (!setARE) {
191 are->set(fGpu->drawState()); 190 are->set(fClipTarget->drawState());
192 setARE = true; 191 setARE = true;
193 } 192 }
194 fGpu->drawState()->addCoverageProcessor(fp); 193 fClipTarget->drawState()->addCoverageProcessor(fp);
195 } else { 194 } else {
196 failed = true; 195 failed = true;
197 break; 196 break;
198 } 197 }
199 } 198 }
200 iter.next(); 199 iter.next();
201 } 200 }
202 201
203 if (failed) { 202 if (failed) {
204 are->set(NULL); 203 are->set(NULL);
(...skipping 11 matching lines...) Expand all
216 GrDrawState::AutoRestoreStencil* ars, 215 GrDrawState::AutoRestoreStencil* ars,
217 ScissorState* scissorState) { 216 ScissorState* scissorState) {
218 fCurrClipMaskType = kNone_ClipMaskType; 217 fCurrClipMaskType = kNone_ClipMaskType;
219 218
220 GrReducedClip::ElementList elements(16); 219 GrReducedClip::ElementList elements(16);
221 int32_t genID; 220 int32_t genID;
222 GrReducedClip::InitialState initialState; 221 GrReducedClip::InitialState initialState;
223 SkIRect clipSpaceIBounds; 222 SkIRect clipSpaceIBounds;
224 bool requiresAA; 223 bool requiresAA;
225 224
226 GrDrawState* drawState = fGpu->drawState(); 225 GrDrawState* drawState = fClipTarget->drawState();
227 226
228 const GrRenderTarget* rt = drawState->getRenderTarget(); 227 const GrRenderTarget* rt = drawState->getRenderTarget();
229 // GrDrawTarget should have filtered this for us 228 // GrDrawTarget should have filtered this for us
230 SkASSERT(rt); 229 SkASSERT(rt);
231 230
232 bool ignoreClip = !drawState->isClipState() || clipDataIn->fClipStack->isWid eOpen(); 231 bool ignoreClip = !drawState->isClipState() || clipDataIn->fClipStack->isWid eOpen();
233 if (!ignoreClip) { 232 if (!ignoreClip) {
234 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); 233 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
235 clipSpaceRTIBounds.offset(clipDataIn->fOrigin); 234 clipSpaceRTIBounds.offset(clipDataIn->fOrigin);
236 GrReducedClip::ReduceClipStack(*clipDataIn->fClipStack, 235 GrReducedClip::ReduceClipStack(*clipDataIn->fClipStack,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 initialState, 294 initialState,
296 elements, 295 elements,
297 clipSpaceIBounds); 296 clipSpaceIBounds);
298 } 297 }
299 298
300 if (result) { 299 if (result) {
301 // The mask's top left coord should be pinned to the rounded-out top left corner of 300 // The mask's top left coord should be pinned to the rounded-out top left corner of
302 // clipSpace bounds. We determine the mask's position WRT to the ren der target here. 301 // clipSpace bounds. We determine the mask's position WRT to the ren der target here.
303 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; 302 SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
304 rtSpaceMaskBounds.offset(-clipDataIn->fOrigin); 303 rtSpaceMaskBounds.offset(-clipDataIn->fOrigin);
305 are->set(fGpu->drawState()); 304 are->set(fClipTarget->drawState());
306 setup_drawstate_aaclip(fGpu, result, rtSpaceMaskBounds); 305 setup_drawstate_aaclip(fClipTarget, result, rtSpaceMaskBounds);
307 this->setDrawStateStencil(ars); 306 this->setDrawStateStencil(ars);
308 return true; 307 return true;
309 } 308 }
310 // if alpha clip mask creation fails fall through to the non-AA code pat hs 309 // if alpha clip mask creation fails fall through to the non-AA code pat hs
311 } 310 }
312 #endif // GR_AA_CLIP 311 #endif // GR_AA_CLIP
313 312
314 // Either a hard (stencil buffer) clip was explicitly requested or an anti-a liased clip couldn't 313 // Either a hard (stencil buffer) clip was explicitly requested or an anti-a liased clip couldn't
315 // be created. In either case, free up the texture in the anti-aliased mask cache. 314 // be created. In either case, free up the texture in the anti-aliased mask cache.
316 // TODO: this may require more investigation. Ganesh performs a lot of utili ty draws (e.g., 315 // TODO: this may require more investigation. Ganesh performs a lot of utili ty draws (e.g.,
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 break; 376 break;
378 } 377 }
379 } 378 }
380 379
381 } 380 }
382 381
383 //////////////////////////////////////////////////////////////////////////////// 382 ////////////////////////////////////////////////////////////////////////////////
384 bool GrClipMaskManager::drawElement(GrTexture* target, 383 bool GrClipMaskManager::drawElement(GrTexture* target,
385 const SkClipStack::Element* element, 384 const SkClipStack::Element* element,
386 GrPathRenderer* pr) { 385 GrPathRenderer* pr) {
387 GrDrawState* drawState = fGpu->drawState(); 386 GrDrawState* drawState = fClipTarget->drawState();
388 387
389 drawState->setRenderTarget(target->asRenderTarget()); 388 drawState->setRenderTarget(target->asRenderTarget());
390 389
391 // TODO: Draw rrects directly here. 390 // TODO: Draw rrects directly here.
392 switch (element->getType()) { 391 switch (element->getType()) {
393 case Element::kEmpty_Type: 392 case Element::kEmpty_Type:
394 SkDEBUGFAIL("Should never get here with an empty element."); 393 SkDEBUGFAIL("Should never get here with an empty element.");
395 break; 394 break;
396 case Element::kRect_Type: 395 case Element::kRect_Type:
397 // TODO: Do rects directly to the accumulator using a aa-rect GrProc essor that covers 396 // TODO: Do rects directly to the accumulator using a aa-rect GrProc essor that covers
398 // the entire mask bounds and writes 0 outside the rect. 397 // the entire mask bounds and writes 0 outside the rect.
399 if (element->isAA()) { 398 if (element->isAA()) {
400 this->getContext()->getAARectRenderer()->fillAARect(fGpu, 399 this->getContext()->getAARectRenderer()->fillAARect(fClipTarget,
401 element->get Rect(), 400 element->get Rect(),
402 SkMatrix::I( ), 401 SkMatrix::I( ),
403 element->get Rect()); 402 element->get Rect());
404 } else { 403 } else {
405 fGpu->drawSimpleRect(element->getRect()); 404 fClipTarget->drawSimpleRect(element->getRect());
406 } 405 }
407 return true; 406 return true;
408 default: { 407 default: {
409 SkPath path; 408 SkPath path;
410 element->asPath(&path); 409 element->asPath(&path);
411 path.setIsVolatile(true); 410 path.setIsVolatile(true);
412 if (path.isInverseFillType()) { 411 if (path.isInverseFillType()) {
413 path.toggleInverseFillType(); 412 path.toggleInverseFillType();
414 } 413 }
415 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 414 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
416 if (NULL == pr) { 415 if (NULL == pr) {
417 GrPathRendererChain::DrawType type; 416 GrPathRendererChain::DrawType type;
418 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr awType : 417 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr awType :
419 GrPathRendererChain::kColor_DrawType; 418 GrPathRendererChain::kColor_DrawType;
420 pr = this->getContext()->getPathRenderer(path, stroke, fGpu, fal se, type); 419 pr = this->getContext()->getPathRenderer(path, stroke, fClipTarg et, false, type);
421 } 420 }
422 if (NULL == pr) { 421 if (NULL == pr) {
423 return false; 422 return false;
424 } 423 }
425 pr->drawPath(path, stroke, fGpu, element->isAA()); 424 pr->drawPath(path, stroke, fClipTarget, element->isAA());
426 break; 425 break;
427 } 426 }
428 } 427 }
429 return true; 428 return true;
430 } 429 }
431 430
432 bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, 431 bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target,
433 const SkClipStack::Element* ele ment, 432 const SkClipStack::Element* ele ment,
434 GrPathRenderer** pr) { 433 GrPathRenderer** pr) {
435 GrDrawState* drawState = fGpu->drawState(); 434 GrDrawState* drawState = fClipTarget->drawState();
436 drawState->setRenderTarget(target->asRenderTarget()); 435 drawState->setRenderTarget(target->asRenderTarget());
437 436
438 if (Element::kRect_Type == element->getType()) { 437 if (Element::kRect_Type == element->getType()) {
439 return true; 438 return true;
440 } else { 439 } else {
441 // We shouldn't get here with an empty clip element. 440 // We shouldn't get here with an empty clip element.
442 SkASSERT(Element::kEmpty_Type != element->getType()); 441 SkASSERT(Element::kEmpty_Type != element->getType());
443 SkPath path; 442 SkPath path;
444 element->asPath(&path); 443 element->asPath(&path);
445 if (path.isInverseFillType()) { 444 if (path.isInverseFillType()) {
446 path.toggleInverseFillType(); 445 path.toggleInverseFillType();
447 } 446 }
448 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 447 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
449 GrPathRendererChain::DrawType type = element->isAA() ? 448 GrPathRendererChain::DrawType type = element->isAA() ?
450 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType : 449 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
451 GrPathRendererChain::kStencilAndColor_DrawType; 450 GrPathRendererChain::kStencilAndColor_DrawType;
452 *pr = this->getContext()->getPathRenderer(path, stroke, fGpu, false, typ e); 451 *pr = this->getContext()->getPathRenderer(path, stroke, fClipTarget, fal se, type);
453 return SkToBool(*pr); 452 return SkToBool(*pr);
454 } 453 }
455 } 454 }
456 455
457 void GrClipMaskManager::mergeMask(GrTexture* dstMask, 456 void GrClipMaskManager::mergeMask(GrTexture* dstMask,
458 GrTexture* srcMask, 457 GrTexture* srcMask,
459 SkRegion::Op op, 458 SkRegion::Op op,
460 const SkIRect& dstBound, 459 const SkIRect& dstBound,
461 const SkIRect& srcBound) { 460 const SkIRect& srcBound) {
462 GrDrawState::AutoViewMatrixRestore avmr; 461 GrDrawState::AutoViewMatrixRestore avmr;
463 GrDrawState* drawState = fGpu->drawState(); 462 GrDrawState* drawState = fClipTarget->drawState();
464 SkAssertResult(avmr.setIdentity(drawState)); 463 SkAssertResult(avmr.setIdentity(drawState));
465 GrDrawState::AutoRestoreEffects are(drawState); 464 GrDrawState::AutoRestoreEffects are(drawState);
466 465
467 drawState->setRenderTarget(dstMask->asRenderTarget()); 466 drawState->setRenderTarget(dstMask->asRenderTarget());
468 467
469 setup_boolean_blendcoeffs(drawState, op); 468 setup_boolean_blendcoeffs(drawState, op);
470 469
471 SkMatrix sampleM; 470 SkMatrix sampleM;
472 sampleM.setIDiv(srcMask->width(), srcMask->height()); 471 sampleM.setIDiv(srcMask->width(), srcMask->height());
473 472
474 drawState->addColorProcessor( 473 drawState->addColorProcessor(
475 GrTextureDomainEffect::Create(srcMask, 474 GrTextureDomainEffect::Create(srcMask,
476 sampleM, 475 sampleM,
477 GrTextureDomain::MakeTexelDomain(srcMask, srcBound), 476 GrTextureDomain::MakeTexelDomain(srcMask, srcBound),
478 GrTextureDomain::kDecal_Mode, 477 GrTextureDomain::kDecal_Mode,
479 GrTextureParams::kNone_FilterMode))->unref (); 478 GrTextureParams::kNone_FilterMode))->unref ();
480 fGpu->drawSimpleRect(SkRect::Make(dstBound)); 479 fClipTarget->drawSimpleRect(SkRect::Make(dstBound));
481 } 480 }
482 481
483 GrTexture* GrClipMaskManager::createTempMask(int width, int height) { 482 GrTexture* GrClipMaskManager::createTempMask(int width, int height) {
484 GrTextureDesc desc; 483 GrTextureDesc desc;
485 desc.fFlags = kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit; 484 desc.fFlags = kRenderTarget_GrTextureFlagBit|kNoStencil_GrTextureFlagBit;
486 desc.fWidth = width; 485 desc.fWidth = width;
487 desc.fHeight = height; 486 desc.fHeight = height;
488 desc.fConfig = kAlpha_8_GrPixelConfig; 487 desc.fConfig = kAlpha_8_GrPixelConfig;
489 488
490 return fGpu->getContext()->refScratchTexture(desc, GrContext::kApprox_Scratc hTexMatch); 489 return this->getContext()->refScratchTexture(desc, GrContext::kApprox_Scratc hTexMatch);
491 } 490 }
492 491
493 //////////////////////////////////////////////////////////////////////////////// 492 ////////////////////////////////////////////////////////////////////////////////
494 // Return the texture currently in the cache if it exists. Otherwise, return NUL L 493 // Return the texture currently in the cache if it exists. Otherwise, return NUL L
495 GrTexture* GrClipMaskManager::getCachedMaskTexture(int32_t elementsGenID, 494 GrTexture* GrClipMaskManager::getCachedMaskTexture(int32_t elementsGenID,
496 const SkIRect& clipSpaceIBoun ds) { 495 const SkIRect& clipSpaceIBoun ds) {
497 bool cached = fAACache.canReuse(elementsGenID, clipSpaceIBounds); 496 bool cached = fAACache.canReuse(elementsGenID, clipSpaceIBounds);
498 if (!cached) { 497 if (!cached) {
499 return NULL; 498 return NULL;
500 } 499 }
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 SkIntToScalar(-clipSpaceIBounds.fLeft), 552 SkIntToScalar(-clipSpaceIBounds.fLeft),
554 SkIntToScalar(-clipSpaceIBounds.fTop) 553 SkIntToScalar(-clipSpaceIBounds.fTop)
555 }; 554 };
556 // The texture may be larger than necessary, this rect represents the part o f the texture 555 // The texture may be larger than necessary, this rect represents the part o f the texture
557 // we populate with a rasterization of the clip. 556 // we populate with a rasterization of the clip.
558 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height()); 557 SkIRect maskSpaceIBounds = SkIRect::MakeWH(clipSpaceIBounds.width(), clipSpa ceIBounds.height());
559 558
560 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip space. 559 // Set the matrix so that rendered clip elements are transformed to mask spa ce from clip space.
561 SkMatrix translate; 560 SkMatrix translate;
562 translate.setTranslate(clipToMaskOffset); 561 translate.setTranslate(clipToMaskOffset);
563 GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ASRI nit, &translate); 562 GrDrawTarget::AutoGeometryAndStatePush agasp(fClipTarget, GrDrawTarget::kRes et_ASRInit, &translate);
564 563
565 GrDrawState* drawState = fGpu->drawState(); 564 GrDrawState* drawState = fClipTarget->drawState();
566 565
567 // We're drawing a coverage mask and want coverage to be run through the ble nd function. 566 // We're drawing a coverage mask and want coverage to be run through the ble nd function.
568 drawState->enableState(GrDrawState::kCoverageDrawing_StateBit); 567 drawState->enableState(GrDrawState::kCoverageDrawing_StateBit);
569 568
570 // The scratch texture that we are drawing into can be substantially larger than the mask. Only 569 // The scratch texture that we are drawing into can be substantially larger than the mask. Only
571 // clear the part that we care about. 570 // clear the part that we care about.
572 fGpu->clear(&maskSpaceIBounds, 571 fClipTarget->clear(&maskSpaceIBounds,
573 GrReducedClip::kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000, 572 GrReducedClip::kAllIn_InitialState == initialState ? 0xffffffff : 0x00000000,
574 true, 573 true,
575 result->asRenderTarget()); 574 result->asRenderTarget());
576 575
577 // When we use the stencil in the below loop it is important to have this cl ip installed. 576 // When we use the stencil in the below loop it is important to have this cl ip installed.
578 // The second pass that zeros the stencil buffer renders the rect maskSpaceI Bounds so the first 577 // The second pass that zeros the stencil buffer renders the rect maskSpaceI Bounds so the first
579 // pass must not set values outside of this bounds or stencil values outside the rect won't be 578 // pass must not set values outside of this bounds or stencil values outside the rect won't be
580 // cleared. 579 // cleared.
581 GrDrawTarget::AutoClipRestore acr(fGpu, maskSpaceIBounds); 580 GrDrawTarget::AutoClipRestore acr(fClipTarget, maskSpaceIBounds);
582 drawState->enableState(GrDrawState::kClip_StateBit); 581 drawState->enableState(GrDrawState::kClip_StateBit);
583 582
584 SkAutoTUnref<GrTexture> temp; 583 SkAutoTUnref<GrTexture> temp;
585 // walk through each clip element and perform its set op 584 // walk through each clip element and perform its set op
586 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) { 585 for (GrReducedClip::ElementList::Iter iter = elements.headIter(); iter.get() ; iter.next()) {
587 const Element* element = iter.get(); 586 const Element* element = iter.get();
588 SkRegion::Op op = element->getOp(); 587 SkRegion::Op op = element->getOp();
589 bool invert = element->isInverseFilled(); 588 bool invert = element->isInverseFilled();
590 589
591 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) { 590 if (invert || SkRegion::kIntersect_Op == op || SkRegion::kReverseDiffere nce_Op == op) {
(...skipping 18 matching lines...) Expand all
610 if (!temp) { 609 if (!temp) {
611 temp.reset(this->createTempMask(maskSpaceIBounds.fRight, 610 temp.reset(this->createTempMask(maskSpaceIBounds.fRight,
612 maskSpaceIBounds.fBottom)); 611 maskSpaceIBounds.fBottom));
613 if (!temp) { 612 if (!temp) {
614 fAACache.reset(); 613 fAACache.reset();
615 return NULL; 614 return NULL;
616 } 615 }
617 } 616 }
618 dst = temp; 617 dst = temp;
619 // clear the temp target and set blend to replace 618 // clear the temp target and set blend to replace
620 fGpu->clear(&maskSpaceElementIBounds, 619 fClipTarget->clear(&maskSpaceElementIBounds,
621 invert ? 0xffffffff : 0x00000000, 620 invert ? 0xffffffff : 0x00000000,
622 true, 621 true,
623 dst->asRenderTarget()); 622 dst->asRenderTarget());
624 setup_boolean_blendcoeffs(drawState, SkRegion::kReplace_Op); 623 setup_boolean_blendcoeffs(drawState, SkRegion::kReplace_Op);
625 624
626 } else { 625 } else {
627 // draw directly into the result with the stencil set to make th e pixels affected 626 // draw directly into the result with the stencil set to make th e pixels affected
628 // by the clip shape be non-zero. 627 // by the clip shape be non-zero.
629 dst = result; 628 dst = result;
630 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement, 629 GR_STATIC_CONST_SAME_STENCIL(kStencilInElement,
(...skipping 26 matching lines...) Expand all
657 // Draw to the exterior pixels (those with a zero stencil value) . 656 // Draw to the exterior pixels (those with a zero stencil value) .
658 drawState->setAlpha(invert ? 0xff : 0x00); 657 drawState->setAlpha(invert ? 0xff : 0x00);
659 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement, 658 GR_STATIC_CONST_SAME_STENCIL(kDrawOutsideElement,
660 kZero_StencilOp, 659 kZero_StencilOp,
661 kZero_StencilOp, 660 kZero_StencilOp,
662 kEqual_StencilFunc, 661 kEqual_StencilFunc,
663 0xffff, 662 0xffff,
664 0x0000, 663 0x0000,
665 0xffff); 664 0xffff);
666 drawState->setStencil(kDrawOutsideElement); 665 drawState->setStencil(kDrawOutsideElement);
667 fGpu->drawSimpleRect(clipSpaceIBounds); 666 fClipTarget->drawSimpleRect(clipSpaceIBounds);
668 drawState->disableStencil(); 667 drawState->disableStencil();
669 } 668 }
670 } else { 669 } else {
671 // all the remaining ops can just be directly draw into the accumula tion buffer 670 // all the remaining ops can just be directly draw into the accumula tion buffer
672 drawState->setAlpha(0xff); 671 drawState->setAlpha(0xff);
673 setup_boolean_blendcoeffs(drawState, op); 672 setup_boolean_blendcoeffs(drawState, op);
674 this->drawElement(result, element); 673 this->drawElement(result, element);
675 } 674 }
676 } 675 }
677 676
678 fCurrClipMaskType = kAlpha_ClipMaskType; 677 fCurrClipMaskType = kAlpha_ClipMaskType;
679 return result; 678 return result;
680 } 679 }
681 680
682 //////////////////////////////////////////////////////////////////////////////// 681 ////////////////////////////////////////////////////////////////////////////////
683 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device 682 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
684 // (as opposed to canvas) coordinates 683 // (as opposed to canvas) coordinates
685 bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID, 684 bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID,
686 GrReducedClip::InitialState initia lState, 685 GrReducedClip::InitialState initia lState,
687 const GrReducedClip::ElementList& elements, 686 const GrReducedClip::ElementList& elements,
688 const SkIRect& clipSpaceIBounds, 687 const SkIRect& clipSpaceIBounds,
689 const SkIPoint& clipSpaceToStencil Offset) { 688 const SkIPoint& clipSpaceToStencil Offset) {
690 689
691 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); 690 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
692 691
693 GrDrawState* drawState = fGpu->drawState(); 692 GrDrawState* drawState = fClipTarget->drawState();
694 SkASSERT(drawState->isClipState()); 693 SkASSERT(drawState->isClipState());
695 694
696 GrRenderTarget* rt = drawState->getRenderTarget(); 695 GrRenderTarget* rt = drawState->getRenderTarget();
697 SkASSERT(rt); 696 SkASSERT(rt);
698 697
699 // TODO: dynamically attach a SB when needed. 698 // TODO: dynamically attach a SB when needed.
700 GrStencilBuffer* stencilBuffer = rt->getStencilBuffer(); 699 GrStencilBuffer* stencilBuffer = rt->getStencilBuffer();
701 if (NULL == stencilBuffer) { 700 if (NULL == stencilBuffer) {
702 return false; 701 return false;
703 } 702 }
704 703
705 if (stencilBuffer->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpace ToStencilOffset)) { 704 if (stencilBuffer->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpace ToStencilOffset)) {
706 stencilBuffer->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToS tencilOffset); 705 stencilBuffer->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToS tencilOffset);
707 706
708 // Set the matrix so that rendered clip elements are transformed from cl ip to stencil space. 707 // Set the matrix so that rendered clip elements are transformed from cl ip to stencil space.
709 SkVector translate = { 708 SkVector translate = {
710 SkIntToScalar(clipSpaceToStencilOffset.fX), 709 SkIntToScalar(clipSpaceToStencilOffset.fX),
711 SkIntToScalar(clipSpaceToStencilOffset.fY) 710 SkIntToScalar(clipSpaceToStencilOffset.fY)
712 }; 711 };
713 SkMatrix matrix; 712 SkMatrix matrix;
714 matrix.setTranslate(translate); 713 matrix.setTranslate(translate);
715 GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ ASRInit, &matrix); 714 GrDrawTarget::AutoGeometryAndStatePush agasp(fClipTarget, GrDrawTarget:: kReset_ASRInit, &matrix);
716 drawState = fGpu->drawState(); 715 drawState = fClipTarget->drawState();
717 716
718 drawState->setRenderTarget(rt); 717 drawState->setRenderTarget(rt);
719 718
720 // We set the current clip to the bounds so that our recursive draws are scissored to them. 719 // We set the current clip to the bounds so that our recursive draws are scissored to them.
721 SkIRect stencilSpaceIBounds(clipSpaceIBounds); 720 SkIRect stencilSpaceIBounds(clipSpaceIBounds);
722 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); 721 stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
723 GrDrawTarget::AutoClipRestore acr(fGpu, stencilSpaceIBounds); 722 GrDrawTarget::AutoClipRestore acr(fClipTarget, stencilSpaceIBounds);
724 drawState->enableState(GrDrawState::kClip_StateBit); 723 drawState->enableState(GrDrawState::kClip_StateBit);
725 724
726 #if !VISUALIZE_COMPLEX_CLIP 725 #if !VISUALIZE_COMPLEX_CLIP
727 drawState->enableState(GrDrawState::kNoColorWrites_StateBit); 726 drawState->enableState(GrDrawState::kNoColorWrites_StateBit);
728 #endif 727 #endif
729 728
730 int clipBit = stencilBuffer->bits(); 729 int clipBit = stencilBuffer->bits();
731 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers"); 730 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers");
732 clipBit = (1 << (clipBit-1)); 731 clipBit = (1 << (clipBit-1));
733 732
734 fGpu->clearStencilClip(stencilSpaceIBounds, 733 fClipTarget->clearStencilClip(stencilSpaceIBounds,
735 GrReducedClip::kAllIn_InitialState == initialStat e, 734 GrReducedClip::kAllIn_InitialState == initialStat e,
736 rt); 735 rt);
737 736
738 // walk through each clip element and perform its set op 737 // walk through each clip element and perform its set op
739 // with the existing clip. 738 // with the existing clip.
740 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) { 739 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) {
741 const Element* element = iter.get(); 740 const Element* element = iter.get();
742 bool fillInverted = false; 741 bool fillInverted = false;
743 // enabled at bottom of loop 742 // enabled at bottom of loop
744 drawState->disableState(GrGpu::kModifyStencilClip_StateBit); 743 drawState->disableState(kModifyStencilClip_StateBit);
745 // if the target is MSAA then we want MSAA enabled when the clip is soft 744 // if the target is MSAA then we want MSAA enabled when the clip is soft
746 if (rt->isMultisampled()) { 745 if (rt->isMultisampled()) {
747 drawState->setState(GrDrawState::kHWAntialias_StateBit, element- >isAA()); 746 drawState->setState(GrDrawState::kHWAntialias_StateBit, element- >isAA());
748 } 747 }
749 748
750 // This will be used to determine whether the clip shape can be rend ered into the 749 // This will be used to determine whether the clip shape can be rend ered into the
751 // stencil with arbitrary stencil settings. 750 // stencil with arbitrary stencil settings.
752 GrPathRenderer::StencilSupport stencilSupport; 751 GrPathRenderer::StencilSupport stencilSupport;
753 752
754 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 753 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
755 754
756 SkRegion::Op op = element->getOp(); 755 SkRegion::Op op = element->getOp();
757 756
758 GrPathRenderer* pr = NULL; 757 GrPathRenderer* pr = NULL;
759 SkPath clipPath; 758 SkPath clipPath;
760 if (Element::kRect_Type == element->getType()) { 759 if (Element::kRect_Type == element->getType()) {
761 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; 760 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
762 fillInverted = false; 761 fillInverted = false;
763 } else { 762 } else {
764 element->asPath(&clipPath); 763 element->asPath(&clipPath);
765 fillInverted = clipPath.isInverseFillType(); 764 fillInverted = clipPath.isInverseFillType();
766 if (fillInverted) { 765 if (fillInverted) {
767 clipPath.toggleInverseFillType(); 766 clipPath.toggleInverseFillType();
768 } 767 }
769 pr = this->getContext()->getPathRenderer(clipPath, 768 pr = this->getContext()->getPathRenderer(clipPath,
770 stroke, 769 stroke,
771 fGpu, 770 fClipTarget,
772 false, 771 false,
773 GrPathRendererChain::kS tencilOnly_DrawType, 772 GrPathRendererChain::kS tencilOnly_DrawType,
774 &stencilSupport); 773 &stencilSupport);
775 if (NULL == pr) { 774 if (NULL == pr) {
776 return false; 775 return false;
777 } 776 }
778 } 777 }
779 778
780 int passes; 779 int passes;
781 GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClip Passes]; 780 GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClip Passes];
(...skipping 16 matching lines...) Expand all
798 GR_STATIC_CONST_SAME_STENCIL(gDrawToStencil, 797 GR_STATIC_CONST_SAME_STENCIL(gDrawToStencil,
799 kIncClamp_StencilOp, 798 kIncClamp_StencilOp,
800 kIncClamp_StencilOp, 799 kIncClamp_StencilOp,
801 kAlways_StencilFunc, 800 kAlways_StencilFunc,
802 0xffff, 801 0xffff,
803 0x0000, 802 0x0000,
804 0xffff); 803 0xffff);
805 SET_RANDOM_COLOR 804 SET_RANDOM_COLOR
806 if (Element::kRect_Type == element->getType()) { 805 if (Element::kRect_Type == element->getType()) {
807 *drawState->stencil() = gDrawToStencil; 806 *drawState->stencil() = gDrawToStencil;
808 fGpu->drawSimpleRect(element->getRect()); 807 fClipTarget->drawSimpleRect(element->getRect());
809 } else { 808 } else {
810 if (!clipPath.isEmpty()) { 809 if (!clipPath.isEmpty()) {
811 if (canRenderDirectToStencil) { 810 if (canRenderDirectToStencil) {
812 *drawState->stencil() = gDrawToStencil; 811 *drawState->stencil() = gDrawToStencil;
813 pr->drawPath(clipPath, stroke, fGpu, false); 812 pr->drawPath(clipPath, stroke, fClipTarget, false);
814 } else { 813 } else {
815 pr->stencilPath(clipPath, stroke, fGpu); 814 pr->stencilPath(clipPath, stroke, fClipTarget);
816 } 815 }
817 } 816 }
818 } 817 }
819 } 818 }
820 819
821 // now we modify the clip bit by rendering either the clip 820 // now we modify the clip bit by rendering either the clip
822 // element directly or a bounding rect of the entire clip. 821 // element directly or a bounding rect of the entire clip.
823 drawState->enableState(GrGpu::kModifyStencilClip_StateBit); 822 drawState->enableState(kModifyStencilClip_StateBit);
824 for (int p = 0; p < passes; ++p) { 823 for (int p = 0; p < passes; ++p) {
825 *drawState->stencil() = stencilSettings[p]; 824 *drawState->stencil() = stencilSettings[p];
826 if (canDrawDirectToClip) { 825 if (canDrawDirectToClip) {
827 if (Element::kRect_Type == element->getType()) { 826 if (Element::kRect_Type == element->getType()) {
828 SET_RANDOM_COLOR 827 SET_RANDOM_COLOR
829 fGpu->drawSimpleRect(element->getRect()); 828 fClipTarget->drawSimpleRect(element->getRect());
830 } else { 829 } else {
831 SET_RANDOM_COLOR 830 SET_RANDOM_COLOR
832 pr->drawPath(clipPath, stroke, fGpu, false); 831 pr->drawPath(clipPath, stroke, fClipTarget, false);
833 } 832 }
834 } else { 833 } else {
835 SET_RANDOM_COLOR 834 SET_RANDOM_COLOR
836 // The view matrix is setup to do clip space -> stencil spac e translation, so 835 // The view matrix is setup to do clip space -> stencil spac e translation, so
837 // draw rect in clip space. 836 // draw rect in clip space.
838 fGpu->drawSimpleRect(SkRect::Make(clipSpaceIBounds)); 837 fClipTarget->drawSimpleRect(SkRect::Make(clipSpaceIBounds));
839 } 838 }
840 } 839 }
841 } 840 }
842 } 841 }
843 // set this last because recursive draws may overwrite it back to kNone. 842 // set this last because recursive draws may overwrite it back to kNone.
844 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); 843 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
845 fCurrClipMaskType = kStencil_ClipMaskType; 844 fCurrClipMaskType = kStencil_ClipMaskType;
846 return true; 845 return true;
847 } 846 }
848 847
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings); 897 return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
899 } 898 }
900 } 899 }
901 900
902 void GrClipMaskManager::setDrawStateStencil(GrDrawState::AutoRestoreStencil* ars ) { 901 void GrClipMaskManager::setDrawStateStencil(GrDrawState::AutoRestoreStencil* ars ) {
903 // We make two copies of the StencilSettings here (except in the early 902 // We make two copies of the StencilSettings here (except in the early
904 // exit scenario. One copy from draw state to the stack var. Then another 903 // exit scenario. One copy from draw state to the stack var. Then another
905 // from the stack var to the gpu. We could make this class hold a ptr to 904 // from the stack var to the gpu. We could make this class hold a ptr to
906 // GrGpu's fStencilSettings and eliminate the stack copy here. 905 // GrGpu's fStencilSettings and eliminate the stack copy here.
907 906
908 const GrDrawState& drawState = fGpu->getDrawState(); 907 const GrDrawState& drawState = fClipTarget->getDrawState();
909 908
910 // use stencil for clipping if clipping is enabled and the clip 909 // use stencil for clipping if clipping is enabled and the clip
911 // has been written into the stencil. 910 // has been written into the stencil.
912 GrClipMaskManager::StencilClipMode clipMode; 911 GrClipMaskManager::StencilClipMode clipMode;
913 if (this->isClipInStencil() && drawState.isClipState()) { 912 if (this->isClipInStencil() && drawState.isClipState()) {
914 clipMode = GrClipMaskManager::kRespectClip_StencilClipMode; 913 clipMode = GrClipMaskManager::kRespectClip_StencilClipMode;
915 // We can't be modifying the clip and respecting it at the same time. 914 // We can't be modifying the clip and respecting it at the same time.
916 SkASSERT(!drawState.isStateFlagEnabled( 915 SkASSERT(!drawState.isStateFlagEnabled(kModifyStencilClip_StateBit));
917 GrGpu::kModifyStencilClip_StateBit)); 916 } else if (drawState.isStateFlagEnabled(kModifyStencilClip_StateBit)) {
918 } else if (drawState.isStateFlagEnabled(
919 GrGpu::kModifyStencilClip_StateBit)) {
920 clipMode = GrClipMaskManager::kModifyClip_StencilClipMode; 917 clipMode = GrClipMaskManager::kModifyClip_StencilClipMode;
921 } else { 918 } else {
922 clipMode = GrClipMaskManager::kIgnoreClip_StencilClipMode; 919 clipMode = GrClipMaskManager::kIgnoreClip_StencilClipMode;
923 } 920 }
924 921
925 GrStencilSettings settings; 922 GrStencilSettings settings;
926 // The GrGpu client may not be using the stencil buffer but we may need to 923 // The GrGpu client may not be using the stencil buffer but we may need to
927 // enable it in order to respect a stencil clip. 924 // enable it in order to respect a stencil clip.
928 if (drawState.getStencil().isDisabled()) { 925 if (drawState.getStencil().isDisabled()) {
929 if (GrClipMaskManager::kRespectClip_StencilClipMode == clipMode) { 926 if (GrClipMaskManager::kRespectClip_StencilClipMode == clipMode) {
930 settings = basic_apply_stencil_clip_settings(); 927 settings = basic_apply_stencil_clip_settings();
931 } else { 928 } else {
932 return; 929 return;
933 } 930 }
934 } else { 931 } else {
935 settings = drawState.getStencil(); 932 settings = drawState.getStencil();
936 } 933 }
937 934
938 // TODO: dynamically attach a stencil buffer 935 // TODO: dynamically attach a stencil buffer
939 int stencilBits = 0; 936 int stencilBits = 0;
940 GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuff er(); 937 GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuff er();
941 if (stencilBuffer) { 938 if (stencilBuffer) {
942 stencilBits = stencilBuffer->bits(); 939 stencilBits = stencilBuffer->bits();
943 } 940 }
944 941
945 SkASSERT(fGpu->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp()); 942 SkASSERT(fClipTarget->caps()->stencilWrapOpsSupport() || !settings.usesWrapO p());
946 SkASSERT(fGpu->caps()->twoSidedStencilSupport() || !settings.isTwoSided()); 943 SkASSERT(fClipTarget->caps()->twoSidedStencilSupport() || !settings.isTwoSid ed());
947 this->adjustStencilParams(&settings, clipMode, stencilBits); 944 this->adjustStencilParams(&settings, clipMode, stencilBits);
948 ars->set(fGpu->drawState()); 945 ars->set(fClipTarget->drawState());
949 fGpu->drawState()->setStencil(settings); 946 fClipTarget->drawState()->setStencil(settings);
950 } 947 }
951 948
952 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, 949 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings,
953 StencilClipMode mode, 950 StencilClipMode mode,
954 int stencilBitCnt) { 951 int stencilBitCnt) {
955 SkASSERT(stencilBitCnt > 0); 952 SkASSERT(stencilBitCnt > 0);
956 953
957 if (kModifyClip_StencilClipMode == mode) { 954 if (kModifyClip_StencilClipMode == mode) {
958 // We assume that this clip manager itself is drawing to the GrGpu and 955 // We assume that this clip manager itself is drawing to the GrGpu and
959 // has already setup the correct values. 956 // has already setup the correct values.
960 return; 957 return;
961 } 958 }
962 959
963 unsigned int clipBit = (1 << (stencilBitCnt - 1)); 960 unsigned int clipBit = (1 << (stencilBitCnt - 1));
964 unsigned int userBits = clipBit - 1; 961 unsigned int userBits = clipBit - 1;
965 962
966 GrStencilSettings::Face face = GrStencilSettings::kFront_Face; 963 GrStencilSettings::Face face = GrStencilSettings::kFront_Face;
967 bool twoSided = fGpu->caps()->twoSidedStencilSupport(); 964 bool twoSided = fClipTarget->caps()->twoSidedStencilSupport();
968 965
969 bool finished = false; 966 bool finished = false;
970 while (!finished) { 967 while (!finished) {
971 GrStencilFunc func = settings->func(face); 968 GrStencilFunc func = settings->func(face);
972 uint16_t writeMask = settings->writeMask(face); 969 uint16_t writeMask = settings->writeMask(face);
973 uint16_t funcMask = settings->funcMask(face); 970 uint16_t funcMask = settings->funcMask(face);
974 uint16_t funcRef = settings->funcRef(face); 971 uint16_t funcRef = settings->funcRef(face);
975 972
976 SkASSERT((unsigned) func < kStencilFuncCount); 973 SkASSERT((unsigned) func < kStencilFuncCount);
977 974
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
1102 1099
1103 fCurrClipMaskType = kAlpha_ClipMaskType; 1100 fCurrClipMaskType = kAlpha_ClipMaskType;
1104 return result; 1101 return result;
1105 } 1102 }
1106 1103
1107 //////////////////////////////////////////////////////////////////////////////// 1104 ////////////////////////////////////////////////////////////////////////////////
1108 void GrClipMaskManager::purgeResources() { 1105 void GrClipMaskManager::purgeResources() {
1109 fAACache.purgeResources(); 1106 fAACache.purgeResources();
1110 } 1107 }
1111 1108
1112 void GrClipMaskManager::setGpu(GrGpu* gpu) { 1109 void GrClipMaskManager::setClipTarget(GrClipTarget* clipTarget) {
1113 fGpu = gpu; 1110 fClipTarget = clipTarget;
1114 fAACache.setContext(gpu->getContext()); 1111 fAACache.setContext(clipTarget->getContext());
1115 } 1112 }
1116 1113
1117 void GrClipMaskManager::adjustPathStencilParams(GrStencilSettings* settings) { 1114 void GrClipMaskManager::adjustPathStencilParams(GrStencilSettings* settings) {
1118 const GrDrawState& drawState = fGpu->getDrawState(); 1115 const GrDrawState& drawState = fClipTarget->getDrawState();
1119 GrClipMaskManager::StencilClipMode clipMode; 1116 GrClipMaskManager::StencilClipMode clipMode;
1120 if (this->isClipInStencil() && drawState.isClipState()) { 1117 if (this->isClipInStencil() && drawState.isClipState()) {
1121 clipMode = GrClipMaskManager::kRespectClip_StencilClipMode; 1118 clipMode = GrClipMaskManager::kRespectClip_StencilClipMode;
1122 // We can't be modifying the clip and respecting it at the same time. 1119 // We can't be modifying the clip and respecting it at the same time.
1123 SkASSERT(!drawState.isStateFlagEnabled( 1120 SkASSERT(!drawState.isStateFlagEnabled(kModifyStencilClip_StateBit));
1124 GrGpu::kModifyStencilClip_StateBit)); 1121 } else if (drawState.isStateFlagEnabled(kModifyStencilClip_StateBit)) {
1125 } else if (drawState.isStateFlagEnabled(
1126 GrGpu::kModifyStencilClip_StateBit)) {
1127 clipMode = GrClipMaskManager::kModifyClip_StencilClipMode; 1122 clipMode = GrClipMaskManager::kModifyClip_StencilClipMode;
1128 } else { 1123 } else {
1129 clipMode = GrClipMaskManager::kIgnoreClip_StencilClipMode; 1124 clipMode = GrClipMaskManager::kIgnoreClip_StencilClipMode;
1130 } 1125 }
1131 1126
1132 // TODO: dynamically attach a stencil buffer 1127 // TODO: dynamically attach a stencil buffer
1133 int stencilBits = 0; 1128 int stencilBits = 0;
1134 GrStencilBuffer* stencilBuffer = 1129 GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuff er();
1135 drawState.getRenderTarget()->getStencilBuffer();
1136 if (stencilBuffer) { 1130 if (stencilBuffer) {
1137 stencilBits = stencilBuffer->bits(); 1131 stencilBits = stencilBuffer->bits();
1138 this->adjustStencilParams(settings, clipMode, stencilBits); 1132 this->adjustStencilParams(settings, clipMode, stencilBits);
1139 } 1133 }
1140 } 1134 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698