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

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

Issue 1969693003: Revert of Separate user and raw stencil settings (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 7 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/GrDrawContext.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 "GrCaps.h" 9 #include "GrCaps.h"
10 #include "GrDrawingManager.h" 10 #include "GrDrawingManager.h"
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 const SkRect& rect) { 55 const SkRect& rect) {
56 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, v iewMatrix, rect, 56 SkAutoTUnref<GrDrawBatch> batch(GrRectBatchFactory::CreateNonAAFill(color, v iewMatrix, rect,
57 nullptr, nullptr)); 57 nullptr, nullptr));
58 drawTarget->drawBatch(pipelineBuilder, batch); 58 drawTarget->drawBatch(pipelineBuilder, batch);
59 } 59 }
60 60
61 // Does the path in 'element' require SW rendering? If so, return true (and, 61 // Does the path in 'element' require SW rendering? If so, return true (and,
62 // optionally, set 'prOut' to NULL. If not, return false (and, optionally, set 62 // optionally, set 'prOut' to NULL. If not, return false (and, optionally, set
63 // 'prOut' to the non-SW path renderer that will do the job). 63 // 'prOut' to the non-SW path renderer that will do the job).
64 bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context, 64 bool GrClipMaskManager::PathNeedsSWRenderer(GrContext* context,
65 bool hasUserStencilSettings, 65 bool isStencilDisabled,
66 const GrRenderTarget* rt, 66 const GrRenderTarget* rt,
67 const SkMatrix& viewMatrix, 67 const SkMatrix& viewMatrix,
68 const Element* element, 68 const Element* element,
69 GrPathRenderer** prOut, 69 GrPathRenderer** prOut,
70 bool needsStencil) { 70 bool needsStencil) {
71 if (Element::kRect_Type == element->getType()) { 71 if (Element::kRect_Type == element->getType()) {
72 // rects can always be drawn directly w/o using the software path 72 // rects can always be drawn directly w/o using the software path
73 // TODO: skip rrects once we're drawing them directly. 73 // TODO: skip rrects once we're drawing them directly.
74 if (prOut) { 74 if (prOut) {
75 *prOut = nullptr; 75 *prOut = nullptr;
(...skipping 21 matching lines...) Expand all
97 ? GrPathRendererChain::kColorAntiAlias_DrawType 97 ? GrPathRendererChain::kColorAntiAlias_DrawType
98 : GrPathRendererChain::kColor_DrawType; 98 : GrPathRendererChain::kColor_DrawType;
99 } 99 }
100 100
101 GrPathRenderer::CanDrawPathArgs canDrawArgs; 101 GrPathRenderer::CanDrawPathArgs canDrawArgs;
102 canDrawArgs.fShaderCaps = context->caps()->shaderCaps(); 102 canDrawArgs.fShaderCaps = context->caps()->shaderCaps();
103 canDrawArgs.fViewMatrix = &viewMatrix; 103 canDrawArgs.fViewMatrix = &viewMatrix;
104 canDrawArgs.fPath = &path; 104 canDrawArgs.fPath = &path;
105 canDrawArgs.fStyle = &GrStyle::SimpleFill(); 105 canDrawArgs.fStyle = &GrStyle::SimpleFill();
106 canDrawArgs.fAntiAlias = element->isAA(); 106 canDrawArgs.fAntiAlias = element->isAA();
107 canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings; 107 canDrawArgs.fIsStencilDisabled = isStencilDisabled;
108 canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled(); 108 canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampled();
109 109
110 // the 'false' parameter disallows use of the SW path renderer 110 // the 'false' parameter disallows use of the SW path renderer
111 GrPathRenderer* pr = context->drawingManager()->getPathRenderer(canDrawA rgs, false, type); 111 GrPathRenderer* pr = context->drawingManager()->getPathRenderer(canDrawA rgs, false, type);
112 if (prOut) { 112 if (prOut) {
113 *prOut = pr; 113 *prOut = pr;
114 } 114 }
115 return SkToBool(!pr); 115 return SkToBool(!pr);
116 } 116 }
117 } 117 }
118 118
119 // Determines whether it is possible to draw the element to both the stencil buf fer and the 119 // Determines whether it is possible to draw the element to both the stencil buf fer and the
120 // alpha mask simultaneously. If so and the element is a path a compatible path renderer is 120 // alpha mask simultaneously. If so and the element is a path a compatible path renderer is
121 // also returned. 121 // also returned.
122 GrPathRenderer* GrClipMaskManager::GetPathRenderer(GrContext* context, 122 GrPathRenderer* GrClipMaskManager::GetPathRenderer(GrContext* context,
123 GrTexture* texture, 123 GrTexture* texture,
124 const SkMatrix& viewMatrix, 124 const SkMatrix& viewMatrix,
125 const SkClipStack::Element* e lement) { 125 const SkClipStack::Element* e lement) {
126 GrPathRenderer* pr; 126 GrPathRenderer* pr;
127 constexpr bool kNeedsStencil = true; 127 static const bool kNeedsStencil = true;
128 constexpr bool kHasUserStencilSettings = false; 128 static const bool kStencilIsDisabled = true;
129 PathNeedsSWRenderer(context, 129 PathNeedsSWRenderer(context,
130 kHasUserStencilSettings, 130 kStencilIsDisabled,
131 texture->asRenderTarget(), 131 texture->asRenderTarget(),
132 viewMatrix, 132 viewMatrix,
133 element, 133 element,
134 &pr, 134 &pr,
135 kNeedsStencil); 135 kNeedsStencil);
136 return pr; 136 return pr;
137 } 137 }
138 138
139 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget, bool debugClipBat chToBounds) 139 GrClipMaskManager::GrClipMaskManager(GrDrawTarget* drawTarget, bool debugClipBat chToBounds)
140 : fDrawTarget(drawTarget) 140 : fDrawTarget(drawTarget)
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY); 172 const SkMatrix translate = SkMatrix::MakeTrans(clipToMaskOffset.fX, clipToMa skOffset.fY);
173 173
174 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { 174 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
175 const Element* element = iter.get(); 175 const Element* element = iter.get();
176 176
177 SkRegion::Op op = element->getOp(); 177 SkRegion::Op op = element->getOp();
178 bool invert = element->isInverseFilled(); 178 bool invert = element->isInverseFilled();
179 bool needsStencil = invert || 179 bool needsStencil = invert ||
180 SkRegion::kIntersect_Op == op || SkRegion::kReverseD ifference_Op == op; 180 SkRegion::kIntersect_Op == op || SkRegion::kReverseD ifference_Op == op;
181 181
182 if (PathNeedsSWRenderer(context, pipelineBuilder.hasUserStencilSettings( ), 182 if (PathNeedsSWRenderer(context, pipelineBuilder.getStencil().isDisabled (),
183 rt, translate, element, nullptr, needsStencil)) { 183 rt, translate, element, nullptr, needsStencil)) {
184 return true; 184 return true;
185 } 185 }
186 } 186 }
187 return false; 187 return false;
188 } 188 }
189 189
190 bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis t& elements, 190 bool GrClipMaskManager::getAnalyticClipProcessor(const GrReducedClip::ElementLis t& elements,
191 bool abortIfAA, 191 bool abortIfAA,
192 SkVector& clipToRTOffset, 192 SkVector& clipToRTOffset,
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
310 *out = GrClip(intersect); 310 *out = GrClip(intersect);
311 } else { 311 } else {
312 *out = clip; 312 *out = clip;
313 } 313 }
314 break; 314 break;
315 } 315 }
316 } 316 }
317 } 317 }
318 318
319 bool GrClipMaskManager::setupScissorClip(const GrPipelineBuilder& pipelineBuilde r, 319 bool GrClipMaskManager::setupScissorClip(const GrPipelineBuilder& pipelineBuilde r,
320 GrPipelineBuilder::AutoRestoreStencil* ars,
320 const SkIRect& clipScissor, 321 const SkIRect& clipScissor,
321 const SkRect* devBounds, 322 const SkRect* devBounds,
322 GrAppliedClip* out) { 323 GrAppliedClip* out) {
323 SkASSERT(kModifyClip_StencilClipMode != fClipMode); // TODO: Remove fClipMod e. 324 if (kRespectClip_StencilClipMode == fClipMode) {
324 fClipMode = kIgnoreClip_StencilClipMode; 325 fClipMode = kIgnoreClip_StencilClipMode;
326 }
325 327
326 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); 328 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
327 329
328 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); 330 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
329 SkIRect devBoundsScissor; 331 SkIRect devBoundsScissor;
330 const SkIRect* scissor = &clipScissor; 332 const SkIRect* scissor = &clipScissor;
331 bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds; 333 bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds;
332 if (doDevBoundsClip) { 334 if (doDevBoundsClip) {
333 devBounds->roundOut(&devBoundsScissor); 335 devBounds->roundOut(&devBoundsScissor);
334 if (devBoundsScissor.intersect(clipScissor)) { 336 if (devBoundsScissor.intersect(clipScissor)) {
335 scissor = &devBoundsScissor; 337 scissor = &devBoundsScissor;
336 } 338 }
337 } 339 }
338 340
339 if (scissor->contains(clipSpaceRTIBounds)) { 341 if (scissor->contains(clipSpaceRTIBounds)) {
340 // This counts as wide open 342 // This counts as wide open
343 this->setPipelineBuilderStencil(pipelineBuilder, ars);
341 return true; 344 return true;
342 } 345 }
343 346
344 if (clipSpaceRTIBounds.intersect(*scissor)) { 347 if (clipSpaceRTIBounds.intersect(*scissor)) {
345 out->fScissorState.set(clipSpaceRTIBounds); 348 out->fScissorState.set(clipSpaceRTIBounds);
349 this->setPipelineBuilderStencil(pipelineBuilder, ars);
346 return true; 350 return true;
347 } 351 }
348 return false; 352 return false;
349 } 353 }
350 354
351 //////////////////////////////////////////////////////////////////////////////// 355 ////////////////////////////////////////////////////////////////////////////////
352 // sort out what kind of clip mask needs to be created: alpha, stencil, 356 // sort out what kind of clip mask needs to be created: alpha, stencil,
353 // scissor, or entirely software 357 // scissor, or entirely software
354 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, 358 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
359 GrPipelineBuilder::AutoRestoreStencil* ars ,
355 const SkRect* devBounds, 360 const SkRect* devBounds,
356 GrAppliedClip* out) { 361 GrAppliedClip* out) {
357 if (kRespectClip_StencilClipMode == fClipMode) { 362 if (kRespectClip_StencilClipMode == fClipMode) {
358 fClipMode = kIgnoreClip_StencilClipMode; 363 fClipMode = kIgnoreClip_StencilClipMode;
359 } 364 }
360 365
361 GrReducedClip::ElementList elements; 366 GrReducedClip::ElementList elements;
362 int32_t genID = 0; 367 int32_t genID = 0;
363 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat e; 368 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat e;
364 SkIRect clipSpaceIBounds; 369 SkIRect clipSpaceIBounds;
365 bool requiresAA = false; 370 bool requiresAA = false;
366 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); 371 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
367 372
368 // GrDrawTarget should have filtered this for us 373 // GrDrawTarget should have filtered this for us
369 SkASSERT(rt); 374 SkASSERT(rt);
370 375
371 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); 376 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
372 GrClip devBoundsClip; 377 GrClip devBoundsClip;
373 bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds; 378 bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds;
374 if (doDevBoundsClip) { 379 if (doDevBoundsClip) {
375 add_rect_to_clip(pipelineBuilder.clip(), *devBounds, &devBoundsClip); 380 add_rect_to_clip(pipelineBuilder.clip(), *devBounds, &devBoundsClip);
376 } 381 }
377 const GrClip& clip = doDevBoundsClip ? devBoundsClip : pipelineBuilder.clip( ); 382 const GrClip& clip = doDevBoundsClip ? devBoundsClip : pipelineBuilder.clip( );
378 383
379 if (clip.isWideOpen(clipSpaceRTIBounds)) { 384 if (clip.isWideOpen(clipSpaceRTIBounds)) {
385 this->setPipelineBuilderStencil(pipelineBuilder, ars);
380 return true; 386 return true;
381 } 387 }
382 388
383 // The clip mask manager always draws with a single IRect so we special case that logic here 389 // The clip mask manager always draws with a single IRect so we special case that logic here
384 // Image filters just use a rect, so we also special case that logic 390 // Image filters just use a rect, so we also special case that logic
385 switch (clip.clipType()) { 391 switch (clip.clipType()) {
386 case GrClip::kWideOpen_ClipType: 392 case GrClip::kWideOpen_ClipType:
387 SkFAIL("Should have caught this with clip.isWideOpen()"); 393 SkFAIL("Should have caught this with clip.isWideOpen()");
388 return true; 394 return true;
389 case GrClip::kIRect_ClipType: { 395 case GrClip::kIRect_ClipType: {
390 SkIRect scissor = clip.irect(); 396 SkIRect scissor = clip.irect();
391 if (scissor.intersect(clipSpaceRTIBounds)) { 397 if (scissor.intersect(clipSpaceRTIBounds)) {
392 out->fScissorState.set(scissor); 398 out->fScissorState.set(scissor);
393 out->fHasStencilClip = kIgnoreClip_StencilClipMode != fClipMode; 399 this->setPipelineBuilderStencil(pipelineBuilder, ars);
394 return true; 400 return true;
395 } 401 }
396 return false; 402 return false;
397 } 403 }
398 case GrClip::kClipStack_ClipType: { 404 case GrClip::kClipStack_ClipType: {
399 clipSpaceRTIBounds.offset(clip.origin()); 405 clipSpaceRTIBounds.offset(clip.origin());
400 SkIRect clipSpaceReduceQueryBounds; 406 SkIRect clipSpaceReduceQueryBounds;
401 #define DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION 0 407 #define DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION 0
402 if (devBounds && !DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION) { 408 if (devBounds && !DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION) {
403 SkIRect devIBounds = devBounds->roundOut(); 409 SkIRect devIBounds = devBounds->roundOut();
404 devIBounds.offset(clip.origin()); 410 devIBounds.offset(clip.origin());
405 if (!clipSpaceReduceQueryBounds.intersect(clipSpaceRTIBounds, de vIBounds)) { 411 if (!clipSpaceReduceQueryBounds.intersect(clipSpaceRTIBounds, de vIBounds)) {
406 return false; 412 return false;
407 } 413 }
408 } else { 414 } else {
409 clipSpaceReduceQueryBounds = clipSpaceRTIBounds; 415 clipSpaceReduceQueryBounds = clipSpaceRTIBounds;
410 } 416 }
411 GrReducedClip::ReduceClipStack(*clip.clipStack(), 417 GrReducedClip::ReduceClipStack(*clip.clipStack(),
412 clipSpaceReduceQueryBounds, 418 clipSpaceReduceQueryBounds,
413 &elements, 419 &elements,
414 &genID, 420 &genID,
415 &initialState, 421 &initialState,
416 &clipSpaceIBounds, 422 &clipSpaceIBounds,
417 &requiresAA); 423 &requiresAA);
418 if (elements.isEmpty()) { 424 if (elements.isEmpty()) {
419 if (GrReducedClip::kAllIn_InitialState == initialState) { 425 if (GrReducedClip::kAllIn_InitialState == initialState) {
420 if (clipSpaceIBounds == clipSpaceRTIBounds) { 426 if (clipSpaceIBounds == clipSpaceRTIBounds) {
427 this->setPipelineBuilderStencil(pipelineBuilder, ars);
421 return true; 428 return true;
422 } 429 }
423 } else { 430 } else {
424 return false; 431 return false;
425 } 432 }
426 } 433 }
427 } break; 434 } break;
428 } 435 }
429 436
430 SkASSERT(kIgnoreClip_StencilClipMode == fClipMode); // TODO: Remove fClipMod e.
431
432 // An element count of 4 was chosen because of the common pattern in Blink o f: 437 // An element count of 4 was chosen because of the common pattern in Blink o f:
433 // isect RR 438 // isect RR
434 // diff RR 439 // diff RR
435 // isect convex_poly 440 // isect convex_poly
436 // isect convex_poly 441 // isect convex_poly
437 // when drawing rounded div borders. This could probably be tuned based on a 442 // when drawing rounded div borders. This could probably be tuned based on a
438 // configuration's relative costs of switching RTs to generate a mask vs 443 // configuration's relative costs of switching RTs to generate a mask vs
439 // longer shaders. 444 // longer shaders.
440 if (elements.count() <= kMaxAnalyticElements) { 445 if (elements.count() <= kMaxAnalyticElements) {
441 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX), 446 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX),
442 SkIntToScalar(-clip.origin().fY) }; 447 SkIntToScalar(-clip.origin().fY) };
443 // When there are multiple samples we want to do per-sample clipping, no t compute a 448 // When there are multiple samples we want to do per-sample clipping, no t compute a
444 // fractional pixel coverage. 449 // fractional pixel coverage.
445 bool disallowAnalyticAA = rt->isStencilBufferMultisampled(); 450 bool disallowAnalyticAA = rt->isStencilBufferMultisampled();
446 if (disallowAnalyticAA && !rt->numColorSamples()) { 451 if (disallowAnalyticAA && !rt->numColorSamples()) {
447 // With a single color sample, any coverage info is lost from color once it hits the 452 // With a single color sample, any coverage info is lost from color once it hits the
448 // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe 453 // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe
449 // is multisampled. 454 // is multisampled.
450 disallowAnalyticAA = pipelineBuilder.isHWAntialias() || 455 disallowAnalyticAA = pipelineBuilder.isHWAntialias() ||
451 pipelineBuilder.hasUserStencilSettings(); 456 !pipelineBuilder.getStencil().isDisabled();
452 } 457 }
453 const GrFragmentProcessor* clipFP = nullptr; 458 const GrFragmentProcessor* clipFP = nullptr;
454 if (elements.isEmpty() || 459 if (elements.isEmpty() ||
455 (requiresAA && 460 (requiresAA &&
456 this->getAnalyticClipProcessor(elements, disallowAnalyticAA, clipTo RTOffset, devBounds, 461 this->getAnalyticClipProcessor(elements, disallowAnalyticAA, clipTo RTOffset, devBounds,
457 &clipFP))) { 462 &clipFP))) {
458 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 463 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
459 scissorSpaceIBounds.offset(-clip.origin()); 464 scissorSpaceIBounds.offset(-clip.origin());
460 if (nullptr == devBounds || 465 if (nullptr == devBounds ||
461 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { 466 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
462 out->fScissorState.set(scissorSpaceIBounds); 467 out->fScissorState.set(scissorSpaceIBounds);
463 } 468 }
469 this->setPipelineBuilderStencil(pipelineBuilder, ars);
464 out->fClipCoverageFP.reset(clipFP); 470 out->fClipCoverageFP.reset(clipFP);
465 return true; 471 return true;
466 } 472 }
467 } 473 }
468 474
469 // If the stencil buffer is multisampled we can use it to do everything. 475 // If the stencil buffer is multisampled we can use it to do everything.
470 if (!rt->isStencilBufferMultisampled() && requiresAA) { 476 if (!rt->isStencilBufferMultisampled() && requiresAA) {
471 SkAutoTUnref<GrTexture> result; 477 SkAutoTUnref<GrTexture> result;
472 478
473 // The top-left of the mask corresponds to the top-left corner of the bo unds. 479 // The top-left of the mask corresponds to the top-left corner of the bo unds.
(...skipping 21 matching lines...) Expand all
495 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug 501 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug
496 SkASSERT(result); 502 SkASSERT(result);
497 } 503 }
498 504
499 if (result) { 505 if (result) {
500 // The mask's top left coord should be pinned to the rounded-out top left corner of 506 // The mask's top left coord should be pinned to the rounded-out top left corner of
501 // clipSpace bounds. We determine the mask's position WRT to the ren der target here. 507 // clipSpace bounds. We determine the mask's position WRT to the ren der target here.
502 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; 508 SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
503 rtSpaceMaskBounds.offset(-clip.origin()); 509 rtSpaceMaskBounds.offset(-clip.origin());
504 out->fClipCoverageFP.reset(create_fp_for_mask(result, rtSpaceMaskBou nds)); 510 out->fClipCoverageFP.reset(create_fp_for_mask(result, rtSpaceMaskBou nds));
511 this->setPipelineBuilderStencil(pipelineBuilder, ars);
505 return true; 512 return true;
506 } 513 }
507 // if alpha clip mask creation fails fall through to the non-AA code pat hs 514 // if alpha clip mask creation fails fall through to the non-AA code pat hs
508 } 515 }
509 516
510 // use the stencil clip if we can't represent the clip as a rectangle. 517 // use the stencil clip if we can't represent the clip as a rectangle.
511 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin(); 518 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin();
512 this->createStencilClipMask(rt, 519 this->createStencilClipMask(rt,
513 genID, 520 genID,
514 initialState, 521 initialState,
515 elements, 522 elements,
516 clipSpaceIBounds, 523 clipSpaceIBounds,
517 clipSpaceToStencilSpaceOffset); 524 clipSpaceToStencilSpaceOffset);
518 525
519 // This must occur after createStencilClipMask. That function may change the scissor. Also, it 526 // This must occur after createStencilClipMask. That function may change the scissor. Also, it
520 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must 527 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must
521 // use both stencil and scissor test to the bounds for the final draw. 528 // use both stencil and scissor test to the bounds for the final draw.
522 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 529 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
523 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); 530 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
524 out->fScissorState.set(scissorSpaceIBounds); 531 out->fScissorState.set(scissorSpaceIBounds);
525 SkASSERT(kRespectClip_StencilClipMode == fClipMode); // TODO: Remove fClipMo de. 532 this->setPipelineBuilderStencil(pipelineBuilder, ars);
526 out->fHasStencilClip = true;
527 return true; 533 return true;
528 } 534 }
529 535
530 static bool stencil_element(GrDrawContext* dc, 536 static bool stencil_element(GrDrawContext* dc,
531 const SkIRect* scissorRect, 537 const SkIRect* scissorRect,
532 const GrUserStencilSettings* ss, 538 const GrStencilSettings& ss,
533 const SkMatrix& viewMatrix, 539 const SkMatrix& viewMatrix,
534 const SkClipStack::Element* element) { 540 const SkClipStack::Element* element) {
535 541
536 // TODO: Draw rrects directly here. 542 // TODO: Draw rrects directly here.
537 switch (element->getType()) { 543 switch (element->getType()) {
538 case Element::kEmpty_Type: 544 case Element::kEmpty_Type:
539 SkDEBUGFAIL("Should never get here with an empty element."); 545 SkDEBUGFAIL("Should never get here with an empty element.");
540 break; 546 break;
541 case Element::kRect_Type: 547 case Element::kRect_Type:
542 return dc->drawContextPriv().drawAndStencilRect(scissorRect, ss, 548 return dc->drawContextPriv().drawAndStencilRect(scissorRect, ss,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 if (Element::kRect_Type != element->getType() && !pr) { 674 if (Element::kRect_Type != element->getType() && !pr) {
669 // UseSWOnlyPath should now filter out all cases where gpu-side mask merging would 675 // UseSWOnlyPath should now filter out all cases where gpu-side mask merging would
670 // be performed (i.e., pr would be NULL for a non-rect path). 676 // be performed (i.e., pr would be NULL for a non-rect path).
671 // See https://bug.skia.org/4519 for rationale and details. 677 // See https://bug.skia.org/4519 for rationale and details.
672 SkASSERT(0); 678 SkASSERT(0);
673 } 679 }
674 #endif 680 #endif
675 681
676 // draw directly into the result with the stencil set to make the pi xels affected 682 // draw directly into the result with the stencil set to make the pi xels affected
677 // by the clip shape be non-zero. 683 // by the clip shape be non-zero.
678 static constexpr GrUserStencilSettings kStencilInElement( 684 static constexpr GrStencilSettings kStencilInElement(
679 GrUserStencilSettings::StaticInit< 685 kReplace_StencilOp,
680 0xffff, 686 kReplace_StencilOp,
681 GrUserStencilTest::kAlways, 687 kAlways_StencilFunc,
682 0xffff, 688 0xffff,
683 GrUserStencilOp::kReplace, 689 0xffff,
684 GrUserStencilOp::kReplace, 690 0xffff);
685 0xffff>() 691 if (!stencil_element(dc.get(), &maskSpaceIBounds, kStencilInElement,
686 );
687 if (!stencil_element(dc.get(), &maskSpaceIBounds, &kStencilInElement ,
688 translate, element)) { 692 translate, element)) {
689 texture->resourcePriv().removeUniqueKey(); 693 texture->resourcePriv().removeUniqueKey();
690 return nullptr; 694 return nullptr;
691 } 695 }
692 696
693 // Draw to the exterior pixels (those with a zero stencil value). 697 // Draw to the exterior pixels (those with a zero stencil value).
694 static constexpr GrUserStencilSettings kDrawOutsideElement( 698 static constexpr GrStencilSettings kDrawOutsideElement(
695 GrUserStencilSettings::StaticInit< 699 kZero_StencilOp,
696 0x0000, 700 kZero_StencilOp,
697 GrUserStencilTest::kEqual, 701 kEqual_StencilFunc,
698 0xffff, 702 0xffff,
699 GrUserStencilOp::kZero, 703 0x0000,
700 GrUserStencilOp::kZero, 704 0xffff);
701 0xffff>() 705 if (!dc->drawContextPriv().drawAndStencilRect(&maskSpaceIBounds, kDr awOutsideElement,
702 );
703 if (!dc->drawContextPriv().drawAndStencilRect(&maskSpaceIBounds, &kD rawOutsideElement,
704 op, !invert, false, 706 op, !invert, false,
705 translate, 707 translate,
706 SkRect::Make(clipSpace IBounds))) { 708 SkRect::Make(clipSpace IBounds))) {
707 texture->resourcePriv().removeUniqueKey(); 709 texture->resourcePriv().removeUniqueKey();
708 return nullptr; 710 return nullptr;
709 } 711 }
710 } else { 712 } else {
711 // all the remaining ops can just be directly draw into the accumula tion buffer 713 // all the remaining ops can just be directly draw into the accumula tion buffer
712 GrPaint paint; 714 GrPaint paint;
713 paint.setAntiAlias(element->isAA()); 715 paint.setAntiAlias(element->isAA());
(...skipping 30 matching lines...) Expand all
744 SkIntToScalar(clipSpaceToStencilOffset.fY) 746 SkIntToScalar(clipSpaceToStencilOffset.fY)
745 }; 747 };
746 SkMatrix viewMatrix; 748 SkMatrix viewMatrix;
747 viewMatrix.setTranslate(translate); 749 viewMatrix.setTranslate(translate);
748 750
749 // We set the current clip to the bounds so that our recursive draws are scissored to them. 751 // We set the current clip to the bounds so that our recursive draws are scissored to them.
750 SkIRect stencilSpaceIBounds(clipSpaceIBounds); 752 SkIRect stencilSpaceIBounds(clipSpaceIBounds);
751 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); 753 stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
752 GrClip clip(stencilSpaceIBounds); 754 GrClip clip(stencilSpaceIBounds);
753 755
756 int clipBit = stencilAttachment->bits();
757 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers");
758 clipBit = (1 << (clipBit-1));
759
754 fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds, 760 fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds,
755 GrReducedClip::kAllIn_InitialState == initialState, rt); 761 GrReducedClip::kAllIn_InitialState == initialState, rt);
756 762
757 // walk through each clip element and perform its set op 763 // walk through each clip element and perform its set op
758 // with the existing clip. 764 // with the existing clip.
759 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) { 765 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) {
760 const Element* element = iter.get(); 766 const Element* element = iter.get();
761 767
762 GrPipelineBuilder pipelineBuilder; 768 GrPipelineBuilder pipelineBuilder;
763 pipelineBuilder.setClip(clip); 769 pipelineBuilder.setClip(clip);
(...skipping 21 matching lines...) Expand all
785 if (Element::kRect_Type == element->getType()) { 791 if (Element::kRect_Type == element->getType()) {
786 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; 792 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
787 fillInverted = false; 793 fillInverted = false;
788 } else { 794 } else {
789 element->asPath(&clipPath); 795 element->asPath(&clipPath);
790 fillInverted = clipPath.isInverseFillType(); 796 fillInverted = clipPath.isInverseFillType();
791 if (fillInverted) { 797 if (fillInverted) {
792 clipPath.toggleInverseFillType(); 798 clipPath.toggleInverseFillType();
793 } 799 }
794 800
795 SkASSERT(!pipelineBuilder.hasUserStencilSettings()); 801 SkASSERT(pipelineBuilder.getStencil().isDisabled());
796 802
797 GrPathRenderer::CanDrawPathArgs canDrawArgs; 803 GrPathRenderer::CanDrawPathArgs canDrawArgs;
798 canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps (); 804 canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps ();
799 canDrawArgs.fViewMatrix = &viewMatrix; 805 canDrawArgs.fViewMatrix = &viewMatrix;
800 canDrawArgs.fPath = &clipPath; 806 canDrawArgs.fPath = &clipPath;
801 canDrawArgs.fStyle = &GrStyle::SimpleFill(); 807 canDrawArgs.fStyle = &GrStyle::SimpleFill();
802 canDrawArgs.fAntiAlias = false; 808 canDrawArgs.fAntiAlias = false;
803 canDrawArgs.fHasUserStencilSettings = pipelineBuilder.hasUserSte ncilSettings(); 809 canDrawArgs.fIsStencilDisabled = pipelineBuilder.getStencil().is Disabled();
804 canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampl ed(); 810 canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampl ed();
805 811
806 pr = this->getContext()->drawingManager()->getPathRenderer(canDr awArgs, false, 812 pr = this->getContext()->drawingManager()->getPathRenderer(canDr awArgs, false,
807 GrPat hRendererChain::kStencilOnly_DrawType, 813 GrPat hRendererChain::kStencilOnly_DrawType,
808 &sten cilSupport); 814 &sten cilSupport);
809 if (nullptr == pr) { 815 if (nullptr == pr) {
810 return false; 816 return false;
811 } 817 }
812 } 818 }
813 819
820 int passes;
821 GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClip Passes];
822
814 bool canRenderDirectToStencil = 823 bool canRenderDirectToStencil =
815 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport; 824 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport;
816 bool drawDirectToClip; // Given the renderer, the element, 825 bool canDrawDirectToClip; // Given the renderer, the element,
817 // fill rule, and set operation should 826 // fill rule, and set operation can
818 // we render the element directly to 827 // we render the element directly to
819 // stencil bit used for clipping. 828 // stencil bit used for clipping.
820 GrUserStencilSettings const* const* stencilPasses = 829 canDrawDirectToClip = GrStencilSettings::GetClipPasses(op,
821 GrStencilSettings::GetClipPasses(op, canRenderDirectToStencil, f illInverted, 830 canRenderDire ctToStencil,
822 &drawDirectToClip); 831 clipBit,
832 fillInverted,
833 &passes,
834 stencilSettin gs);
823 835
824 // draw the element to the client stencil bits if necessary 836 // draw the element to the client stencil bits if necessary
825 if (!drawDirectToClip) { 837 if (!canDrawDirectToClip) {
826 static constexpr GrUserStencilSettings kDrawToStencil( 838 static constexpr GrStencilSettings kDrawToStencil(
827 GrUserStencilSettings::StaticInit< 839 kIncClamp_StencilOp,
828 0x0000, 840 kIncClamp_StencilOp,
829 GrUserStencilTest::kAlways, 841 kAlways_StencilFunc,
830 0xffff, 842 0xffff,
831 GrUserStencilOp::kIncMaybeClamp, 843 0x0000,
832 GrUserStencilOp::kIncMaybeClamp, 844 0xffff);
833 0xffff>()
834 );
835 if (Element::kRect_Type == element->getType()) { 845 if (Element::kRect_Type == element->getType()) {
836 pipelineBuilder.setUserStencil(&kDrawToStencil); 846 *pipelineBuilder.stencil() = kDrawToStencil;
837 847
838 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE , viewMatrix, 848 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE , viewMatrix,
839 element->getRect()); 849 element->getRect());
840 } else { 850 } else {
841 if (!clipPath.isEmpty()) { 851 if (!clipPath.isEmpty()) {
842 if (canRenderDirectToStencil) { 852 if (canRenderDirectToStencil) {
843 pipelineBuilder.setUserStencil(&kDrawToStencil); 853 *pipelineBuilder.stencil() = kDrawToStencil;
844 854
845 GrPathRenderer::DrawPathArgs args; 855 GrPathRenderer::DrawPathArgs args;
846 args.fTarget = fDrawTarget; 856 args.fTarget = fDrawTarget;
847 args.fResourceProvider = this->getContext()->resourc eProvider(); 857 args.fResourceProvider = this->getContext()->resourc eProvider();
848 args.fPipelineBuilder = &pipelineBuilder; 858 args.fPipelineBuilder = &pipelineBuilder;
849 args.fColor = GrColor_WHITE; 859 args.fColor = GrColor_WHITE;
850 args.fViewMatrix = &viewMatrix; 860 args.fViewMatrix = &viewMatrix;
851 args.fPath = &clipPath; 861 args.fPath = &clipPath;
852 args.fStyle = &GrStyle::SimpleFill(); 862 args.fStyle = &GrStyle::SimpleFill();
853 args.fAntiAlias = false; 863 args.fAntiAlias = false;
854 args.fGammaCorrect = false; 864 args.fGammaCorrect = false;
855 pr->drawPath(args); 865 pr->drawPath(args);
856 } else { 866 } else {
857 GrPathRenderer::StencilPathArgs args; 867 GrPathRenderer::StencilPathArgs args;
858 args.fTarget = fDrawTarget; 868 args.fTarget = fDrawTarget;
859 args.fResourceProvider = this->getContext()->resourc eProvider(); 869 args.fResourceProvider = this->getContext()->resourc eProvider();
860 args.fPipelineBuilder = &pipelineBuilder; 870 args.fPipelineBuilder = &pipelineBuilder;
861 args.fViewMatrix = &viewMatrix; 871 args.fViewMatrix = &viewMatrix;
862 args.fPath = &clipPath; 872 args.fPath = &clipPath;
863 pr->stencilPath(args); 873 pr->stencilPath(args);
864 } 874 }
865 } 875 }
866 } 876 }
867 } 877 }
868 878
869 // now we modify the clip bit by rendering either the clip 879 // now we modify the clip bit by rendering either the clip
870 // element directly or a bounding rect of the entire clip. 880 // element directly or a bounding rect of the entire clip.
871 fClipMode = kModifyClip_StencilClipMode; 881 fClipMode = kModifyClip_StencilClipMode;
872 for (GrUserStencilSettings const* const* pass = stencilPasses; *pass ; ++pass) { 882 for (int p = 0; p < passes; ++p) {
873 pipelineBuilder.setUserStencil(*pass); 883 *pipelineBuilder.stencil() = stencilSettings[p];
874 884
875 if (drawDirectToClip) { 885 if (canDrawDirectToClip) {
876 if (Element::kRect_Type == element->getType()) { 886 if (Element::kRect_Type == element->getType()) {
877 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_W HITE, viewMatrix, 887 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_W HITE, viewMatrix,
878 element->getRect()); 888 element->getRect());
879 } else { 889 } else {
880 GrPathRenderer::DrawPathArgs args; 890 GrPathRenderer::DrawPathArgs args;
881 args.fTarget = fDrawTarget; 891 args.fTarget = fDrawTarget;
882 args.fResourceProvider = this->getContext()->resourcePro vider(); 892 args.fResourceProvider = this->getContext()->resourcePro vider();
883 args.fPipelineBuilder = &pipelineBuilder; 893 args.fPipelineBuilder = &pipelineBuilder;
884 args.fColor = GrColor_WHITE; 894 args.fColor = GrColor_WHITE;
885 args.fViewMatrix = &viewMatrix; 895 args.fViewMatrix = &viewMatrix;
886 args.fPath = &clipPath; 896 args.fPath = &clipPath;
887 args.fStyle = &GrStyle::SimpleFill(); 897 args.fStyle = &GrStyle::SimpleFill();
888 args.fAntiAlias = false; 898 args.fAntiAlias = false;
889 args.fGammaCorrect = false; 899 args.fGammaCorrect = false;
890 pr->drawPath(args); 900 pr->drawPath(args);
891 } 901 }
892 } else { 902 } else {
893 // The view matrix is setup to do clip space -> stencil spac e translation, so 903 // The view matrix is setup to do clip space -> stencil spac e translation, so
894 // draw rect in clip space. 904 // draw rect in clip space.
895 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE , viewMatrix, 905 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE , viewMatrix,
896 SkRect::Make(clipSpaceIBounds)); 906 SkRect::Make(clipSpaceIBounds));
897 } 907 }
898 } 908 }
899 } 909 }
900 } 910 }
901 fClipMode = kRespectClip_StencilClipMode; 911 fClipMode = kRespectClip_StencilClipMode;
902 return true; 912 return true;
903 } 913 }
904 914
915 // mapping of clip-respecting stencil funcs to normal stencil funcs
916 // mapping depends on whether stencil-clipping is in effect.
917 static const GrStencilFunc
918 gSpecialToBasicStencilFunc[2][kClipStencilFuncCnt] = {
919 {// Stencil-Clipping is DISABLED, we are effectively always inside the clip
920 // In the Clip Funcs
921 kAlways_StencilFunc, // kAlwaysIfInClip_StencilFunc
922 kEqual_StencilFunc, // kEqualIfInClip_StencilFunc
923 kLess_StencilFunc, // kLessIfInClip_StencilFunc
924 kLEqual_StencilFunc, // kLEqualIfInClip_StencilFunc
925 // Special in the clip func that forces user's ref to be 0.
926 kNotEqual_StencilFunc, // kNonZeroIfInClip_StencilFunc
927 // make ref 0 and do normal nequal.
928 },
929 {// Stencil-Clipping is ENABLED
930 // In the Clip Funcs
931 kEqual_StencilFunc, // kAlwaysIfInClip_StencilFunc
932 // eq stencil clip bit, mask
933 // out user bits.
934
935 kEqual_StencilFunc, // kEqualIfInClip_StencilFunc
936 // add stencil bit to mask and ref
937
938 kLess_StencilFunc, // kLessIfInClip_StencilFunc
939 kLEqual_StencilFunc, // kLEqualIfInClip_StencilFunc
940 // for both of these we can add
941 // the clip bit to the mask and
942 // ref and compare as normal
943 // Special in the clip func that forces user's ref to be 0.
944 kLess_StencilFunc, // kNonZeroIfInClip_StencilFunc
945 // make ref have only the clip bit set
946 // and make comparison be less
947 // 10..0 < 1..user_bits..
948 }
949 };
950
951 void GrClipMaskManager::setPipelineBuilderStencil(const GrPipelineBuilder& pipel ineBuilder,
952 GrPipelineBuilder::AutoRestore Stencil* ars) {
953 // We make two copies of the StencilSettings here (except in the early
954 // exit scenario. One copy from draw state to the stack var. Then another
955 // from the stack var to the gpu. We could make this class hold a ptr to
956 // GrGpu's fStencilSettings and eliminate the stack copy here.
957
958 // use stencil for clipping if clipping is enabled and the clip
959 // has been written into the stencil.
960 GrStencilSettings settings;
961
962 // The GrGpu client may not be using the stencil buffer but we may need to
963 // enable it in order to respect a stencil clip.
964 if (pipelineBuilder.getStencil().isDisabled()) {
965 if (GrClipMaskManager::kRespectClip_StencilClipMode == fClipMode) {
966 static constexpr GrStencilSettings kBasicApplyClipSettings(
967 kKeep_StencilOp,
968 kKeep_StencilOp,
969 kAlwaysIfInClip_StencilFunc,
970 0x0000,
971 0x0000,
972 0x0000);
973 settings = kBasicApplyClipSettings;
974 } else {
975 return;
976 }
977 } else {
978 settings = pipelineBuilder.getStencil();
979 }
980
981 int stencilBits = 0;
982 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
983 GrStencilAttachment* stencilAttachment = this->resourceProvider()->attachSte ncilAttachment(rt);
984 if (stencilAttachment) {
985 stencilBits = stencilAttachment->bits();
986 }
987
988 SkASSERT(this->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp());
989 SkASSERT(this->caps()->twoSidedStencilSupport() || !settings.isTwoSided());
990 this->adjustStencilParams(&settings, fClipMode, stencilBits);
991 ars->set(&pipelineBuilder);
992 ars->setStencil(settings);
993 }
994
995 void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings,
996 StencilClipMode mode,
997 int stencilBitCnt) {
998 SkASSERT(stencilBitCnt > 0);
999
1000 if (kModifyClip_StencilClipMode == mode) {
1001 // We assume that this clip manager itself is drawing to the GrGpu and
1002 // has already setup the correct values.
1003 return;
1004 }
1005
1006 unsigned int clipBit = (1 << (stencilBitCnt - 1));
1007 unsigned int userBits = clipBit - 1;
1008
1009 GrStencilSettings::Face face = GrStencilSettings::kFront_Face;
1010 bool twoSided = this->caps()->twoSidedStencilSupport();
1011
1012 bool finished = false;
1013 while (!finished) {
1014 GrStencilFunc func = settings->func(face);
1015 uint16_t writeMask = settings->writeMask(face);
1016 uint16_t funcMask = settings->funcMask(face);
1017 uint16_t funcRef = settings->funcRef(face);
1018
1019 SkASSERT((unsigned) func < kStencilFuncCnt);
1020
1021 writeMask &= userBits;
1022
1023 if (func >= kBasicStencilFuncCnt) {
1024 int respectClip = kRespectClip_StencilClipMode == mode;
1025 if (respectClip) {
1026 switch (func) {
1027 case kAlwaysIfInClip_StencilFunc:
1028 funcMask = clipBit;
1029 funcRef = clipBit;
1030 break;
1031 case kEqualIfInClip_StencilFunc:
1032 case kLessIfInClip_StencilFunc:
1033 case kLEqualIfInClip_StencilFunc:
1034 funcMask = (funcMask & userBits) | clipBit;
1035 funcRef = (funcRef & userBits) | clipBit;
1036 break;
1037 case kNonZeroIfInClip_StencilFunc:
1038 funcMask = (funcMask & userBits) | clipBit;
1039 funcRef = clipBit;
1040 break;
1041 default:
1042 SkFAIL("Unknown stencil func");
1043 }
1044 } else {
1045 funcMask &= userBits;
1046 funcRef &= userBits;
1047 }
1048 const GrStencilFunc* table =
1049 gSpecialToBasicStencilFunc[respectClip];
1050 func = table[func - kBasicStencilFuncCnt];
1051 SkASSERT(func >= 0 && func < kBasicStencilFuncCnt);
1052 } else {
1053 funcMask &= userBits;
1054 funcRef &= userBits;
1055 }
1056
1057 settings->setFunc(face, func);
1058 settings->setWriteMask(face, writeMask);
1059 settings->setFuncMask(face, funcMask);
1060 settings->setFuncRef(face, funcRef);
1061
1062 if (GrStencilSettings::kFront_Face == face) {
1063 face = GrStencilSettings::kBack_Face;
1064 finished = !twoSided;
1065 } else {
1066 finished = true;
1067 }
1068 }
1069 if (!twoSided) {
1070 settings->copyFrontSettingsToBack();
1071 }
1072 }
1073
905 //////////////////////////////////////////////////////////////////////////////// 1074 ////////////////////////////////////////////////////////////////////////////////
906 GrTexture* GrClipMaskManager::CreateSoftwareClipMask(GrContext* context, 1075 GrTexture* GrClipMaskManager::CreateSoftwareClipMask(GrContext* context,
907 int32_t elementsGenID, 1076 int32_t elementsGenID,
908 GrReducedClip::InitialState initialState, 1077 GrReducedClip::InitialState initialState,
909 const GrReducedClip::Elemen tList& elements, 1078 const GrReducedClip::Elemen tList& elements,
910 const SkVector& clipToMaskO ffset, 1079 const SkVector& clipToMaskO ffset,
911 const SkIRect& clipSpaceIBo unds) { 1080 const SkIRect& clipSpaceIBo unds) {
912 GrUniqueKey key; 1081 GrUniqueKey key;
913 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); 1082 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key);
914 GrResourceProvider* resourceProvider = context->resourceProvider(); 1083 GrResourceProvider* resourceProvider = context->resourceProvider();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
972 GrTexture* result = context->resourceProvider()->createApproxTexture(desc, 0 ); 1141 GrTexture* result = context->resourceProvider()->createApproxTexture(desc, 0 );
973 if (!result) { 1142 if (!result) {
974 return nullptr; 1143 return nullptr;
975 } 1144 }
976 result->resourcePriv().setUniqueKey(key); 1145 result->resourcePriv().setUniqueKey(key);
977 1146
978 helper.toTexture(result); 1147 helper.toTexture(result);
979 1148
980 return result; 1149 return result;
981 } 1150 }
1151
1152 ////////////////////////////////////////////////////////////////////////////////
1153
1154 void GrClipMaskManager::adjustPathStencilParams(const GrStencilAttachment* stenc ilAttachment,
1155 GrStencilSettings* settings) {
1156 if (stencilAttachment) {
1157 int stencilBits = stencilAttachment->bits();
1158 this->adjustStencilParams(settings, fClipMode, stencilBits);
1159 }
1160 }
OLDNEW
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrDrawContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698