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

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
« 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 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 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.fIsStencilDisabled = isStencilDisabled; 107 canDrawArgs.fHasUserStencilSettings = hasUserStencilSettings;
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 static const bool kNeedsStencil = true; 127 constexpr bool kNeedsStencil = true;
128 static const bool kStencilIsDisabled = true; 128 constexpr bool kHasUserStencilSettings = false;
129 PathNeedsSWRenderer(context, 129 PathNeedsSWRenderer(context,
130 kStencilIsDisabled, 130 kHasUserStencilSettings,
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.getStencil().isDisabled (), 182 if (PathNeedsSWRenderer(context, pipelineBuilder.hasUserStencilSettings( ),
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,
321 const SkIRect& clipScissor, 320 const SkIRect& clipScissor,
322 const SkRect* devBounds, 321 const SkRect* devBounds,
323 GrAppliedClip* out) { 322 GrAppliedClip* out) {
324 if (kRespectClip_StencilClipMode == fClipMode) { 323 SkASSERT(kModifyClip_StencilClipMode != fClipMode); // TODO: Remove fClipMod e.
325 fClipMode = kIgnoreClip_StencilClipMode; 324 fClipMode = kIgnoreClip_StencilClipMode;
326 }
327 325
328 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); 326 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
329 327
330 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); 328 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
331 SkIRect devBoundsScissor; 329 SkIRect devBoundsScissor;
332 const SkIRect* scissor = &clipScissor; 330 const SkIRect* scissor = &clipScissor;
333 bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds; 331 bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds;
334 if (doDevBoundsClip) { 332 if (doDevBoundsClip) {
335 devBounds->roundOut(&devBoundsScissor); 333 devBounds->roundOut(&devBoundsScissor);
336 if (devBoundsScissor.intersect(clipScissor)) { 334 if (devBoundsScissor.intersect(clipScissor)) {
337 scissor = &devBoundsScissor; 335 scissor = &devBoundsScissor;
338 } 336 }
339 } 337 }
340 338
341 if (scissor->contains(clipSpaceRTIBounds)) { 339 if (scissor->contains(clipSpaceRTIBounds)) {
342 // This counts as wide open 340 // This counts as wide open
343 this->setPipelineBuilderStencil(pipelineBuilder, ars);
344 return true; 341 return true;
345 } 342 }
346 343
347 if (clipSpaceRTIBounds.intersect(*scissor)) { 344 if (clipSpaceRTIBounds.intersect(*scissor)) {
348 out->fScissorState.set(clipSpaceRTIBounds); 345 out->fScissorState.set(clipSpaceRTIBounds);
349 this->setPipelineBuilderStencil(pipelineBuilder, ars);
350 return true; 346 return true;
351 } 347 }
352 return false; 348 return false;
353 } 349 }
354 350
355 //////////////////////////////////////////////////////////////////////////////// 351 ////////////////////////////////////////////////////////////////////////////////
356 // sort out what kind of clip mask needs to be created: alpha, stencil, 352 // sort out what kind of clip mask needs to be created: alpha, stencil,
357 // scissor, or entirely software 353 // scissor, or entirely software
358 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder, 354 bool GrClipMaskManager::setupClipping(const GrPipelineBuilder& pipelineBuilder,
359 GrPipelineBuilder::AutoRestoreStencil* ars ,
360 const SkRect* devBounds, 355 const SkRect* devBounds,
361 GrAppliedClip* out) { 356 GrAppliedClip* out) {
362 if (kRespectClip_StencilClipMode == fClipMode) { 357 if (kRespectClip_StencilClipMode == fClipMode) {
363 fClipMode = kIgnoreClip_StencilClipMode; 358 fClipMode = kIgnoreClip_StencilClipMode;
364 } 359 }
365 360
366 GrReducedClip::ElementList elements; 361 GrReducedClip::ElementList elements;
367 int32_t genID = 0; 362 int32_t genID = 0;
368 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat e; 363 GrReducedClip::InitialState initialState = GrReducedClip::kAllIn_InitialStat e;
369 SkIRect clipSpaceIBounds; 364 SkIRect clipSpaceIBounds;
370 bool requiresAA = false; 365 bool requiresAA = false;
371 GrRenderTarget* rt = pipelineBuilder.getRenderTarget(); 366 GrRenderTarget* rt = pipelineBuilder.getRenderTarget();
372 367
373 // GrDrawTarget should have filtered this for us 368 // GrDrawTarget should have filtered this for us
374 SkASSERT(rt); 369 SkASSERT(rt);
375 370
376 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); 371 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
377 GrClip devBoundsClip; 372 GrClip devBoundsClip;
378 bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds; 373 bool doDevBoundsClip = fDebugClipBatchToBounds && devBounds;
379 if (doDevBoundsClip) { 374 if (doDevBoundsClip) {
380 add_rect_to_clip(pipelineBuilder.clip(), *devBounds, &devBoundsClip); 375 add_rect_to_clip(pipelineBuilder.clip(), *devBounds, &devBoundsClip);
381 } 376 }
382 const GrClip& clip = doDevBoundsClip ? devBoundsClip : pipelineBuilder.clip( ); 377 const GrClip& clip = doDevBoundsClip ? devBoundsClip : pipelineBuilder.clip( );
383 378
384 if (clip.isWideOpen(clipSpaceRTIBounds)) { 379 if (clip.isWideOpen(clipSpaceRTIBounds)) {
385 this->setPipelineBuilderStencil(pipelineBuilder, ars);
386 return true; 380 return true;
387 } 381 }
388 382
389 // The clip mask manager always draws with a single IRect so we special case that logic here 383 // The clip mask manager always draws with a single IRect so we special case that logic here
390 // Image filters just use a rect, so we also special case that logic 384 // Image filters just use a rect, so we also special case that logic
391 switch (clip.clipType()) { 385 switch (clip.clipType()) {
392 case GrClip::kWideOpen_ClipType: 386 case GrClip::kWideOpen_ClipType:
393 SkFAIL("Should have caught this with clip.isWideOpen()"); 387 SkFAIL("Should have caught this with clip.isWideOpen()");
394 return true; 388 return true;
395 case GrClip::kIRect_ClipType: { 389 case GrClip::kIRect_ClipType: {
396 SkIRect scissor = clip.irect(); 390 SkIRect scissor = clip.irect();
397 if (scissor.intersect(clipSpaceRTIBounds)) { 391 if (scissor.intersect(clipSpaceRTIBounds)) {
398 out->fScissorState.set(scissor); 392 out->fScissorState.set(scissor);
399 this->setPipelineBuilderStencil(pipelineBuilder, ars); 393 out->fHasStencilClip = kIgnoreClip_StencilClipMode != fClipMode;
400 return true; 394 return true;
401 } 395 }
402 return false; 396 return false;
403 } 397 }
404 case GrClip::kClipStack_ClipType: { 398 case GrClip::kClipStack_ClipType: {
405 clipSpaceRTIBounds.offset(clip.origin()); 399 clipSpaceRTIBounds.offset(clip.origin());
406 SkIRect clipSpaceReduceQueryBounds; 400 SkIRect clipSpaceReduceQueryBounds;
407 #define DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION 0 401 #define DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION 0
408 if (devBounds && !DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION) { 402 if (devBounds && !DISABLE_DEV_BOUNDS_FOR_CLIP_REDUCTION) {
409 SkIRect devIBounds = devBounds->roundOut(); 403 SkIRect devIBounds = devBounds->roundOut();
410 devIBounds.offset(clip.origin()); 404 devIBounds.offset(clip.origin());
411 if (!clipSpaceReduceQueryBounds.intersect(clipSpaceRTIBounds, de vIBounds)) { 405 if (!clipSpaceReduceQueryBounds.intersect(clipSpaceRTIBounds, de vIBounds)) {
412 return false; 406 return false;
413 } 407 }
414 } else { 408 } else {
415 clipSpaceReduceQueryBounds = clipSpaceRTIBounds; 409 clipSpaceReduceQueryBounds = clipSpaceRTIBounds;
416 } 410 }
417 GrReducedClip::ReduceClipStack(*clip.clipStack(), 411 GrReducedClip::ReduceClipStack(*clip.clipStack(),
418 clipSpaceReduceQueryBounds, 412 clipSpaceReduceQueryBounds,
419 &elements, 413 &elements,
420 &genID, 414 &genID,
421 &initialState, 415 &initialState,
422 &clipSpaceIBounds, 416 &clipSpaceIBounds,
423 &requiresAA); 417 &requiresAA);
424 if (elements.isEmpty()) { 418 if (elements.isEmpty()) {
425 if (GrReducedClip::kAllIn_InitialState == initialState) { 419 if (GrReducedClip::kAllIn_InitialState == initialState) {
426 if (clipSpaceIBounds == clipSpaceRTIBounds) { 420 if (clipSpaceIBounds == clipSpaceRTIBounds) {
427 this->setPipelineBuilderStencil(pipelineBuilder, ars);
428 return true; 421 return true;
429 } 422 }
430 } else { 423 } else {
431 return false; 424 return false;
432 } 425 }
433 } 426 }
434 } break; 427 } break;
435 } 428 }
436 429
430 SkASSERT(kIgnoreClip_StencilClipMode == fClipMode); // TODO: Remove fClipMod e.
431
437 // An element count of 4 was chosen because of the common pattern in Blink o f: 432 // An element count of 4 was chosen because of the common pattern in Blink o f:
438 // isect RR 433 // isect RR
439 // diff RR 434 // diff RR
440 // isect convex_poly 435 // isect convex_poly
441 // isect convex_poly 436 // isect convex_poly
442 // when drawing rounded div borders. This could probably be tuned based on a 437 // when drawing rounded div borders. This could probably be tuned based on a
443 // configuration's relative costs of switching RTs to generate a mask vs 438 // configuration's relative costs of switching RTs to generate a mask vs
444 // longer shaders. 439 // longer shaders.
445 if (elements.count() <= kMaxAnalyticElements) { 440 if (elements.count() <= kMaxAnalyticElements) {
446 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX), 441 SkVector clipToRTOffset = { SkIntToScalar(-clip.origin().fX),
447 SkIntToScalar(-clip.origin().fY) }; 442 SkIntToScalar(-clip.origin().fY) };
448 // When there are multiple samples we want to do per-sample clipping, no t compute a 443 // When there are multiple samples we want to do per-sample clipping, no t compute a
449 // fractional pixel coverage. 444 // fractional pixel coverage.
450 bool disallowAnalyticAA = rt->isStencilBufferMultisampled(); 445 bool disallowAnalyticAA = rt->isStencilBufferMultisampled();
451 if (disallowAnalyticAA && !rt->numColorSamples()) { 446 if (disallowAnalyticAA && !rt->numColorSamples()) {
452 // With a single color sample, any coverage info is lost from color once it hits the 447 // With a single color sample, any coverage info is lost from color once it hits the
453 // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe 448 // color buffer anyway, so we may as well use coverage AA if nothing else in the pipe
454 // is multisampled. 449 // is multisampled.
455 disallowAnalyticAA = pipelineBuilder.isHWAntialias() || 450 disallowAnalyticAA = pipelineBuilder.isHWAntialias() ||
456 !pipelineBuilder.getStencil().isDisabled(); 451 pipelineBuilder.hasUserStencilSettings();
457 } 452 }
458 const GrFragmentProcessor* clipFP = nullptr; 453 const GrFragmentProcessor* clipFP = nullptr;
459 if (elements.isEmpty() || 454 if (elements.isEmpty() ||
460 (requiresAA && 455 (requiresAA &&
461 this->getAnalyticClipProcessor(elements, disallowAnalyticAA, clipTo RTOffset, devBounds, 456 this->getAnalyticClipProcessor(elements, disallowAnalyticAA, clipTo RTOffset, devBounds,
462 &clipFP))) { 457 &clipFP))) {
463 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 458 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
464 scissorSpaceIBounds.offset(-clip.origin()); 459 scissorSpaceIBounds.offset(-clip.origin());
465 if (nullptr == devBounds || 460 if (nullptr == devBounds ||
466 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) { 461 !SkRect::Make(scissorSpaceIBounds).contains(*devBounds)) {
467 out->fScissorState.set(scissorSpaceIBounds); 462 out->fScissorState.set(scissorSpaceIBounds);
468 } 463 }
469 this->setPipelineBuilderStencil(pipelineBuilder, ars);
470 out->fClipCoverageFP.reset(clipFP); 464 out->fClipCoverageFP.reset(clipFP);
471 return true; 465 return true;
472 } 466 }
473 } 467 }
474 468
475 // If the stencil buffer is multisampled we can use it to do everything. 469 // If the stencil buffer is multisampled we can use it to do everything.
476 if (!rt->isStencilBufferMultisampled() && requiresAA) { 470 if (!rt->isStencilBufferMultisampled() && requiresAA) {
477 SkAutoTUnref<GrTexture> result; 471 SkAutoTUnref<GrTexture> result;
478 472
479 // The top-left of the mask corresponds to the top-left corner of the bo unds. 473 // The top-left of the mask corresponds to the top-left corner of the bo unds.
(...skipping 21 matching lines...) Expand all
501 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug 495 // If createAlphaClipMask fails it means UseSWOnlyPath has a bug
502 SkASSERT(result); 496 SkASSERT(result);
503 } 497 }
504 498
505 if (result) { 499 if (result) {
506 // The mask's top left coord should be pinned to the rounded-out top left corner of 500 // The mask's top left coord should be pinned to the rounded-out top left corner of
507 // clipSpace bounds. We determine the mask's position WRT to the ren der target here. 501 // clipSpace bounds. We determine the mask's position WRT to the ren der target here.
508 SkIRect rtSpaceMaskBounds = clipSpaceIBounds; 502 SkIRect rtSpaceMaskBounds = clipSpaceIBounds;
509 rtSpaceMaskBounds.offset(-clip.origin()); 503 rtSpaceMaskBounds.offset(-clip.origin());
510 out->fClipCoverageFP.reset(create_fp_for_mask(result, rtSpaceMaskBou nds)); 504 out->fClipCoverageFP.reset(create_fp_for_mask(result, rtSpaceMaskBou nds));
511 this->setPipelineBuilderStencil(pipelineBuilder, ars);
512 return true; 505 return true;
513 } 506 }
514 // if alpha clip mask creation fails fall through to the non-AA code pat hs 507 // if alpha clip mask creation fails fall through to the non-AA code pat hs
515 } 508 }
516 509
517 // use the stencil clip if we can't represent the clip as a rectangle. 510 // use the stencil clip if we can't represent the clip as a rectangle.
518 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin(); 511 SkIPoint clipSpaceToStencilSpaceOffset = -clip.origin();
519 this->createStencilClipMask(rt, 512 this->createStencilClipMask(rt,
520 genID, 513 genID,
521 initialState, 514 initialState,
522 elements, 515 elements,
523 clipSpaceIBounds, 516 clipSpaceIBounds,
524 clipSpaceToStencilSpaceOffset); 517 clipSpaceToStencilSpaceOffset);
525 518
526 // This must occur after createStencilClipMask. That function may change the scissor. Also, it 519 // This must occur after createStencilClipMask. That function may change the scissor. Also, it
527 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must 520 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must
528 // use both stencil and scissor test to the bounds for the final draw. 521 // use both stencil and scissor test to the bounds for the final draw.
529 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 522 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
530 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); 523 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
531 out->fScissorState.set(scissorSpaceIBounds); 524 out->fScissorState.set(scissorSpaceIBounds);
532 this->setPipelineBuilderStencil(pipelineBuilder, ars); 525 SkASSERT(kRespectClip_StencilClipMode == fClipMode); // TODO: Remove fClipMo de.
526 out->fHasStencilClip = true;
533 return true; 527 return true;
534 } 528 }
535 529
536 static bool stencil_element(GrDrawContext* dc, 530 static bool stencil_element(GrDrawContext* dc,
537 const SkIRect* scissorRect, 531 const SkIRect* scissorRect,
538 const GrStencilSettings& ss, 532 const GrUserStencilSettings* ss,
539 const SkMatrix& viewMatrix, 533 const SkMatrix& viewMatrix,
540 const SkClipStack::Element* element) { 534 const SkClipStack::Element* element) {
541 535
542 // TODO: Draw rrects directly here. 536 // TODO: Draw rrects directly here.
543 switch (element->getType()) { 537 switch (element->getType()) {
544 case Element::kEmpty_Type: 538 case Element::kEmpty_Type:
545 SkDEBUGFAIL("Should never get here with an empty element."); 539 SkDEBUGFAIL("Should never get here with an empty element.");
546 break; 540 break;
547 case Element::kRect_Type: 541 case Element::kRect_Type:
548 return dc->drawContextPriv().drawAndStencilRect(scissorRect, ss, 542 return dc->drawContextPriv().drawAndStencilRect(scissorRect, ss,
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 if (Element::kRect_Type != element->getType() && !pr) { 668 if (Element::kRect_Type != element->getType() && !pr) {
675 // UseSWOnlyPath should now filter out all cases where gpu-side mask merging would 669 // UseSWOnlyPath should now filter out all cases where gpu-side mask merging would
676 // be performed (i.e., pr would be NULL for a non-rect path). 670 // be performed (i.e., pr would be NULL for a non-rect path).
677 // See https://bug.skia.org/4519 for rationale and details. 671 // See https://bug.skia.org/4519 for rationale and details.
678 SkASSERT(0); 672 SkASSERT(0);
679 } 673 }
680 #endif 674 #endif
681 675
682 // draw directly into the result with the stencil set to make the pi xels affected 676 // draw directly into the result with the stencil set to make the pi xels affected
683 // by the clip shape be non-zero. 677 // by the clip shape be non-zero.
684 static constexpr GrStencilSettings kStencilInElement( 678 static constexpr GrUserStencilSettings kStencilInElement(
685 kReplace_StencilOp, 679 GrUserStencilSettings::StaticInit<
686 kReplace_StencilOp, 680 0xffff,
687 kAlways_StencilFunc, 681 GrUserStencilTest::kAlways,
688 0xffff, 682 0xffff,
689 0xffff, 683 GrUserStencilOp::kReplace,
690 0xffff); 684 GrUserStencilOp::kReplace,
691 if (!stencil_element(dc.get(), &maskSpaceIBounds, kStencilInElement, 685 0xffff>()
686 );
687 if (!stencil_element(dc.get(), &maskSpaceIBounds, &kStencilInElement ,
692 translate, element)) { 688 translate, element)) {
693 texture->resourcePriv().removeUniqueKey(); 689 texture->resourcePriv().removeUniqueKey();
694 return nullptr; 690 return nullptr;
695 } 691 }
696 692
697 // Draw to the exterior pixels (those with a zero stencil value). 693 // Draw to the exterior pixels (those with a zero stencil value).
698 static constexpr GrStencilSettings kDrawOutsideElement( 694 static constexpr GrUserStencilSettings kDrawOutsideElement(
699 kZero_StencilOp, 695 GrUserStencilSettings::StaticInit<
700 kZero_StencilOp, 696 0x0000,
701 kEqual_StencilFunc, 697 GrUserStencilTest::kEqual,
702 0xffff, 698 0xffff,
703 0x0000, 699 GrUserStencilOp::kZero,
704 0xffff); 700 GrUserStencilOp::kZero,
705 if (!dc->drawContextPriv().drawAndStencilRect(&maskSpaceIBounds, kDr awOutsideElement, 701 0xffff>()
702 );
703 if (!dc->drawContextPriv().drawAndStencilRect(&maskSpaceIBounds, &kD rawOutsideElement,
706 op, !invert, false, 704 op, !invert, false,
707 translate, 705 translate,
708 SkRect::Make(clipSpace IBounds))) { 706 SkRect::Make(clipSpace IBounds))) {
709 texture->resourcePriv().removeUniqueKey(); 707 texture->resourcePriv().removeUniqueKey();
710 return nullptr; 708 return nullptr;
711 } 709 }
712 } else { 710 } else {
713 // all the remaining ops can just be directly draw into the accumula tion buffer 711 // all the remaining ops can just be directly draw into the accumula tion buffer
714 GrPaint paint; 712 GrPaint paint;
715 paint.setAntiAlias(element->isAA()); 713 paint.setAntiAlias(element->isAA());
(...skipping 30 matching lines...) Expand all
746 SkIntToScalar(clipSpaceToStencilOffset.fY) 744 SkIntToScalar(clipSpaceToStencilOffset.fY)
747 }; 745 };
748 SkMatrix viewMatrix; 746 SkMatrix viewMatrix;
749 viewMatrix.setTranslate(translate); 747 viewMatrix.setTranslate(translate);
750 748
751 // We set the current clip to the bounds so that our recursive draws are scissored to them. 749 // We set the current clip to the bounds so that our recursive draws are scissored to them.
752 SkIRect stencilSpaceIBounds(clipSpaceIBounds); 750 SkIRect stencilSpaceIBounds(clipSpaceIBounds);
753 stencilSpaceIBounds.offset(clipSpaceToStencilOffset); 751 stencilSpaceIBounds.offset(clipSpaceToStencilOffset);
754 GrClip clip(stencilSpaceIBounds); 752 GrClip clip(stencilSpaceIBounds);
755 753
756 int clipBit = stencilAttachment->bits();
757 SkASSERT((clipBit <= 16) && "Ganesh only handles 16b or smaller stencil buffers");
758 clipBit = (1 << (clipBit-1));
759
760 fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds, 754 fDrawTarget->cmmAccess().clearStencilClip(stencilSpaceIBounds,
761 GrReducedClip::kAllIn_InitialState == initialState, rt); 755 GrReducedClip::kAllIn_InitialState == initialState, rt);
762 756
763 // walk through each clip element and perform its set op 757 // walk through each clip element and perform its set op
764 // with the existing clip. 758 // with the existing clip.
765 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) { 759 for (GrReducedClip::ElementList::Iter iter(elements.headIter()); iter.ge t(); iter.next()) {
766 const Element* element = iter.get(); 760 const Element* element = iter.get();
767 761
768 GrPipelineBuilder pipelineBuilder; 762 GrPipelineBuilder pipelineBuilder;
769 pipelineBuilder.setClip(clip); 763 pipelineBuilder.setClip(clip);
(...skipping 21 matching lines...) Expand all
791 if (Element::kRect_Type == element->getType()) { 785 if (Element::kRect_Type == element->getType()) {
792 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; 786 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
793 fillInverted = false; 787 fillInverted = false;
794 } else { 788 } else {
795 element->asPath(&clipPath); 789 element->asPath(&clipPath);
796 fillInverted = clipPath.isInverseFillType(); 790 fillInverted = clipPath.isInverseFillType();
797 if (fillInverted) { 791 if (fillInverted) {
798 clipPath.toggleInverseFillType(); 792 clipPath.toggleInverseFillType();
799 } 793 }
800 794
801 SkASSERT(pipelineBuilder.getStencil().isDisabled()); 795 SkASSERT(!pipelineBuilder.hasUserStencilSettings());
802 796
803 GrPathRenderer::CanDrawPathArgs canDrawArgs; 797 GrPathRenderer::CanDrawPathArgs canDrawArgs;
804 canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps (); 798 canDrawArgs.fShaderCaps = this->getContext()->caps()->shaderCaps ();
805 canDrawArgs.fViewMatrix = &viewMatrix; 799 canDrawArgs.fViewMatrix = &viewMatrix;
806 canDrawArgs.fPath = &clipPath; 800 canDrawArgs.fPath = &clipPath;
807 canDrawArgs.fStyle = &GrStyle::SimpleFill(); 801 canDrawArgs.fStyle = &GrStyle::SimpleFill();
808 canDrawArgs.fAntiAlias = false; 802 canDrawArgs.fAntiAlias = false;
809 canDrawArgs.fIsStencilDisabled = pipelineBuilder.getStencil().is Disabled(); 803 canDrawArgs.fHasUserStencilSettings = pipelineBuilder.hasUserSte ncilSettings();
810 canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampl ed(); 804 canDrawArgs.fIsStencilBufferMSAA = rt->isStencilBufferMultisampl ed();
811 805
812 pr = this->getContext()->drawingManager()->getPathRenderer(canDr awArgs, false, 806 pr = this->getContext()->drawingManager()->getPathRenderer(canDr awArgs, false,
813 GrPat hRendererChain::kStencilOnly_DrawType, 807 GrPat hRendererChain::kStencilOnly_DrawType,
814 &sten cilSupport); 808 &sten cilSupport);
815 if (nullptr == pr) { 809 if (nullptr == pr) {
816 return false; 810 return false;
817 } 811 }
818 } 812 }
819 813
820 int passes;
821 GrStencilSettings stencilSettings[GrStencilSettings::kMaxStencilClip Passes];
822
823 bool canRenderDirectToStencil = 814 bool canRenderDirectToStencil =
824 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport; 815 GrPathRenderer::kNoRestriction_StencilSupport == stencilSupport;
825 bool canDrawDirectToClip; // Given the renderer, the element, 816 bool drawDirectToClip; // Given the renderer, the element,
826 // fill rule, and set operation can 817 // fill rule, and set operation should
827 // we render the element directly to 818 // we render the element directly to
828 // stencil bit used for clipping. 819 // stencil bit used for clipping.
829 canDrawDirectToClip = GrStencilSettings::GetClipPasses(op, 820 GrUserStencilSettings const* const* stencilPasses =
830 canRenderDire ctToStencil, 821 GrStencilSettings::GetClipPasses(op, canRenderDirectToStencil, f illInverted,
831 clipBit, 822 &drawDirectToClip);
832 fillInverted,
833 &passes,
834 stencilSettin gs);
835 823
836 // draw the element to the client stencil bits if necessary 824 // draw the element to the client stencil bits if necessary
837 if (!canDrawDirectToClip) { 825 if (!drawDirectToClip) {
838 static constexpr GrStencilSettings kDrawToStencil( 826 static constexpr GrUserStencilSettings kDrawToStencil(
839 kIncClamp_StencilOp, 827 GrUserStencilSettings::StaticInit<
840 kIncClamp_StencilOp, 828 0x0000,
841 kAlways_StencilFunc, 829 GrUserStencilTest::kAlways,
842 0xffff, 830 0xffff,
843 0x0000, 831 GrUserStencilOp::kIncMaybeClamp,
844 0xffff); 832 GrUserStencilOp::kIncMaybeClamp,
833 0xffff>()
834 );
845 if (Element::kRect_Type == element->getType()) { 835 if (Element::kRect_Type == element->getType()) {
846 *pipelineBuilder.stencil() = kDrawToStencil; 836 pipelineBuilder.setUserStencil(&kDrawToStencil);
847 837
848 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE , viewMatrix, 838 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE , viewMatrix,
849 element->getRect()); 839 element->getRect());
850 } else { 840 } else {
851 if (!clipPath.isEmpty()) { 841 if (!clipPath.isEmpty()) {
852 if (canRenderDirectToStencil) { 842 if (canRenderDirectToStencil) {
853 *pipelineBuilder.stencil() = kDrawToStencil; 843 pipelineBuilder.setUserStencil(&kDrawToStencil);
854 844
855 GrPathRenderer::DrawPathArgs args; 845 GrPathRenderer::DrawPathArgs args;
856 args.fTarget = fDrawTarget; 846 args.fTarget = fDrawTarget;
857 args.fResourceProvider = this->getContext()->resourc eProvider(); 847 args.fResourceProvider = this->getContext()->resourc eProvider();
858 args.fPipelineBuilder = &pipelineBuilder; 848 args.fPipelineBuilder = &pipelineBuilder;
859 args.fColor = GrColor_WHITE; 849 args.fColor = GrColor_WHITE;
860 args.fViewMatrix = &viewMatrix; 850 args.fViewMatrix = &viewMatrix;
861 args.fPath = &clipPath; 851 args.fPath = &clipPath;
862 args.fStyle = &GrStyle::SimpleFill(); 852 args.fStyle = &GrStyle::SimpleFill();
863 args.fAntiAlias = false; 853 args.fAntiAlias = false;
864 args.fGammaCorrect = false; 854 args.fGammaCorrect = false;
865 pr->drawPath(args); 855 pr->drawPath(args);
866 } else { 856 } else {
867 GrPathRenderer::StencilPathArgs args; 857 GrPathRenderer::StencilPathArgs args;
868 args.fTarget = fDrawTarget; 858 args.fTarget = fDrawTarget;
869 args.fResourceProvider = this->getContext()->resourc eProvider(); 859 args.fResourceProvider = this->getContext()->resourc eProvider();
870 args.fPipelineBuilder = &pipelineBuilder; 860 args.fPipelineBuilder = &pipelineBuilder;
871 args.fViewMatrix = &viewMatrix; 861 args.fViewMatrix = &viewMatrix;
872 args.fPath = &clipPath; 862 args.fPath = &clipPath;
873 pr->stencilPath(args); 863 pr->stencilPath(args);
874 } 864 }
875 } 865 }
876 } 866 }
877 } 867 }
878 868
879 // now we modify the clip bit by rendering either the clip 869 // now we modify the clip bit by rendering either the clip
880 // element directly or a bounding rect of the entire clip. 870 // element directly or a bounding rect of the entire clip.
881 fClipMode = kModifyClip_StencilClipMode; 871 fClipMode = kModifyClip_StencilClipMode;
882 for (int p = 0; p < passes; ++p) { 872 for (GrUserStencilSettings const* const* pass = stencilPasses; *pass ; ++pass) {
883 *pipelineBuilder.stencil() = stencilSettings[p]; 873 pipelineBuilder.setUserStencil(*pass);
884 874
885 if (canDrawDirectToClip) { 875 if (drawDirectToClip) {
886 if (Element::kRect_Type == element->getType()) { 876 if (Element::kRect_Type == element->getType()) {
887 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_W HITE, viewMatrix, 877 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_W HITE, viewMatrix,
888 element->getRect()); 878 element->getRect());
889 } else { 879 } else {
890 GrPathRenderer::DrawPathArgs args; 880 GrPathRenderer::DrawPathArgs args;
891 args.fTarget = fDrawTarget; 881 args.fTarget = fDrawTarget;
892 args.fResourceProvider = this->getContext()->resourcePro vider(); 882 args.fResourceProvider = this->getContext()->resourcePro vider();
893 args.fPipelineBuilder = &pipelineBuilder; 883 args.fPipelineBuilder = &pipelineBuilder;
894 args.fColor = GrColor_WHITE; 884 args.fColor = GrColor_WHITE;
895 args.fViewMatrix = &viewMatrix; 885 args.fViewMatrix = &viewMatrix;
896 args.fPath = &clipPath; 886 args.fPath = &clipPath;
897 args.fStyle = &GrStyle::SimpleFill(); 887 args.fStyle = &GrStyle::SimpleFill();
898 args.fAntiAlias = false; 888 args.fAntiAlias = false;
899 args.fGammaCorrect = false; 889 args.fGammaCorrect = false;
900 pr->drawPath(args); 890 pr->drawPath(args);
901 } 891 }
902 } else { 892 } else {
903 // The view matrix is setup to do clip space -> stencil spac e translation, so 893 // The view matrix is setup to do clip space -> stencil spac e translation, so
904 // draw rect in clip space. 894 // draw rect in clip space.
905 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE , viewMatrix, 895 draw_non_aa_rect(fDrawTarget, pipelineBuilder, GrColor_WHITE , viewMatrix,
906 SkRect::Make(clipSpaceIBounds)); 896 SkRect::Make(clipSpaceIBounds));
907 } 897 }
908 } 898 }
909 } 899 }
910 } 900 }
911 fClipMode = kRespectClip_StencilClipMode; 901 fClipMode = kRespectClip_StencilClipMode;
912 return true; 902 return true;
913 } 903 }
914 904
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
1074 //////////////////////////////////////////////////////////////////////////////// 905 ////////////////////////////////////////////////////////////////////////////////
1075 GrTexture* GrClipMaskManager::CreateSoftwareClipMask(GrContext* context, 906 GrTexture* GrClipMaskManager::CreateSoftwareClipMask(GrContext* context,
1076 int32_t elementsGenID, 907 int32_t elementsGenID,
1077 GrReducedClip::InitialState initialState, 908 GrReducedClip::InitialState initialState,
1078 const GrReducedClip::Elemen tList& elements, 909 const GrReducedClip::Elemen tList& elements,
1079 const SkVector& clipToMaskO ffset, 910 const SkVector& clipToMaskO ffset,
1080 const SkIRect& clipSpaceIBo unds) { 911 const SkIRect& clipSpaceIBo unds) {
1081 GrUniqueKey key; 912 GrUniqueKey key;
1082 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key); 913 GetClipMaskKey(elementsGenID, clipSpaceIBounds, &key);
1083 GrResourceProvider* resourceProvider = context->resourceProvider(); 914 GrResourceProvider* resourceProvider = context->resourceProvider();
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 GrTexture* result = context->resourceProvider()->createApproxTexture(desc, 0 ); 972 GrTexture* result = context->resourceProvider()->createApproxTexture(desc, 0 );
1142 if (!result) { 973 if (!result) {
1143 return nullptr; 974 return nullptr;
1144 } 975 }
1145 result->resourcePriv().setUniqueKey(key); 976 result->resourcePriv().setUniqueKey(key);
1146 977
1147 helper.toTexture(result); 978 helper.toTexture(result);
1148 979
1149 return result; 980 return result;
1150 } 981 }
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