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

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

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

Powered by Google App Engine
This is Rietveld 408576698