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

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

Issue 163683002: Store SkRRects in SkClipStack (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: fix unhandled enum value warning in unit test Created 6 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « src/core/SkClipStack.cpp ('k') | src/gpu/GrReducedClip.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 /* 2 /*
3 * Copyright 2012 Google Inc. 3 * Copyright 2012 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "GrClipMaskManager.h" 9 #include "GrClipMaskManager.h"
10 #include "GrAAConvexPathRenderer.h" 10 #include "GrAAConvexPathRenderer.h"
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 bool GrClipMaskManager::useSWOnlyPath(const ElementList& elements) { 87 bool GrClipMaskManager::useSWOnlyPath(const ElementList& elements) {
88 88
89 // TODO: generalize this function so that when 89 // TODO: generalize this function so that when
90 // a clip gets complex enough it can just be done in SW regardless 90 // a clip gets complex enough it can just be done in SW regardless
91 // of whether it would invoke the GrSoftwarePathRenderer. 91 // of whether it would invoke the GrSoftwarePathRenderer.
92 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 92 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
93 93
94 for (ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) { 94 for (ElementList::Iter iter(elements.headIter()); iter.get(); iter.next()) {
95 const Element* element = iter.get(); 95 const Element* element = iter.get();
96 // rects can always be drawn directly w/o using the software path 96 // rects can always be drawn directly w/o using the software path
97 // so only paths need to be checked 97 // Skip rrects once we're drawing them directly.
98 if (Element::kPath_Type == element->getType() && 98 if (Element::kRect_Type != element->getType()) {
99 path_needs_SW_renderer(this->getContext(), fGpu, 99 SkPath path;
100 element->getPath(), 100 element->asPath(&path);
101 stroke, 101 if (path_needs_SW_renderer(this->getContext(), fGpu, path, stroke, e lement->isAA())) {
102 element->isAA())) { 102 return true;
103 return true; 103 }
104 } 104 }
105 } 105 }
106 return false; 106 return false;
107 } 107 }
108 108
109 //////////////////////////////////////////////////////////////////////////////// 109 ////////////////////////////////////////////////////////////////////////////////
110 // sort out what kind of clip mask needs to be created: alpha, stencil, 110 // sort out what kind of clip mask needs to be created: alpha, stencil,
111 // scissor, or entirely software 111 // scissor, or entirely software
112 bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, 112 bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
113 GrDrawState::AutoRestoreEffects* are, 113 GrDrawState::AutoRestoreEffects* are,
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
162 if (NULL != devBounds) { 162 if (NULL != devBounds) {
163 SkRect boundsInClipSpace = *devBounds; 163 SkRect boundsInClipSpace = *devBounds;
164 boundsInClipSpace.offset(SkIntToScalar(clipDataIn->fOrigin.fX), 164 boundsInClipSpace.offset(SkIntToScalar(clipDataIn->fOrigin.fX),
165 SkIntToScalar(clipDataIn->fOrigin.fY)); 165 SkIntToScalar(clipDataIn->fOrigin.fY));
166 if (elements.tail()->contains(boundsInClipSpace)) { 166 if (elements.tail()->contains(boundsInClipSpace)) {
167 fGpu->disableScissor(); 167 fGpu->disableScissor();
168 this->setGpuStencil(); 168 this->setGpuStencil();
169 return true; 169 return true;
170 } 170 }
171 } 171 }
172 Element::Type type = elements.tail()->getType();
173 bool isAA = GR_AA_CLIP && elements.tail()->isAA();
172 SkAutoTUnref<GrEffectRef> effect; 174 SkAutoTUnref<GrEffectRef> effect;
173 if (SkClipStack::Element::kPath_Type == elements.tail()->getType()) { 175 if (SkClipStack::Element::kPath_Type == type) {
174 const SkPath& path = elements.tail()->getPath(); 176 const SkPath& path = elements.tail()->getPath();
175 bool isAA = GR_AA_CLIP && elements.tail()->isAA();
176 if (rt->isMultisampled()) { 177 if (rt->isMultisampled()) {
177 // A coverage effect for AA clipping won't play nicely with MSAA . 178 // A coverage effect for AA clipping won't play nicely with MSAA .
178 if (!isAA) { 179 if (!isAA) {
179 SkVector offset = { SkIntToScalar(-clipDataIn->fOrigin.fX), 180 SkVector offset = { SkIntToScalar(-clipDataIn->fOrigin.fX),
180 SkIntToScalar(-clipDataIn->fOrigin.fY) } ; 181 SkIntToScalar(-clipDataIn->fOrigin.fY) } ;
181 effect.reset(GrConvexPolyEffect::Create(GrConvexPolyEffect:: kFillNoAA_EdgeType, 182 effect.reset(GrConvexPolyEffect::Create(GrConvexPolyEffect:: kFillNoAA_EdgeType,
182 path, &offset)); 183 path, &offset));
183 } 184 }
184 } else { 185 } else {
185 SkVector offset = { SkIntToScalar(-clipDataIn->fOrigin.fX), 186 SkVector offset = { SkIntToScalar(-clipDataIn->fOrigin.fX),
186 SkIntToScalar(-clipDataIn->fOrigin.fY) }; 187 SkIntToScalar(-clipDataIn->fOrigin.fY) };
187 GrConvexPolyEffect::EdgeType type = isAA ? GrConvexPolyEffect::k FillAA_EdgeType : 188 GrConvexPolyEffect::EdgeType type = isAA ? GrConvexPolyEffect::k FillAA_EdgeType :
188 GrConvexPolyEffect::k FillNoAA_EdgeType; 189 GrConvexPolyEffect::k FillNoAA_EdgeType;
189 effect.reset(GrConvexPolyEffect::Create(type, path, &offset)); 190 effect.reset(GrConvexPolyEffect::Create(type, path, &offset));
190 } 191 }
191 } else if (GR_AA_CLIP && elements.tail()->isAA() && !rt->isMultisampled( )) { 192 } else if (isAA && SkClipStack::Element::kRect_Type == type && !rt->isMu ltisampled()) {
192 // We only handle AA/non-MSAA rects here. Coverage effect AA isn't M SAA friendly and 193 // We only handle AA/non-MSAA rects here. Coverage effect AA isn't M SAA friendly and
193 // non-AA rect clips are handled by the scissor. 194 // non-AA rect clips are handled by the scissor.
194 SkASSERT(SkClipStack::Element::kRect_Type == elements.tail()->getTyp e());
195 SkRect rect = elements.tail()->getRect(); 195 SkRect rect = elements.tail()->getRect();
196 SkVector offset = { SkIntToScalar(-clipDataIn->fOrigin.fX), 196 SkVector offset = { SkIntToScalar(-clipDataIn->fOrigin.fX),
197 SkIntToScalar(-clipDataIn->fOrigin.fY) }; 197 SkIntToScalar(-clipDataIn->fOrigin.fY) };
198 rect.offset(offset); 198 rect.offset(offset);
199 effect.reset(GrConvexPolyEffect::CreateForAAFillRect(rect)); 199 effect.reset(GrConvexPolyEffect::CreateForAAFillRect(rect));
200 // This should never fail. 200 // This should never fail.
201 SkASSERT(effect); 201 SkASSERT(effect);
202 } 202 }
203 if (effect) { 203 if (effect) {
204 are->set(fGpu->drawState()); 204 are->set(fGpu->drawState());
205 fGpu->drawState()->addCoverageEffect(effect); 205 fGpu->drawState()->addCoverageEffect(effect);
206 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 206 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
207 scissorSpaceIBounds.offset(-clipDataIn->fOrigin); 207 scissorSpaceIBounds.offset(-clipDataIn->fOrigin);
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 } 325 }
326 326
327 //////////////////////////////////////////////////////////////////////////////// 327 ////////////////////////////////////////////////////////////////////////////////
328 bool GrClipMaskManager::drawElement(GrTexture* target, 328 bool GrClipMaskManager::drawElement(GrTexture* target,
329 const SkClipStack::Element* element, 329 const SkClipStack::Element* element,
330 GrPathRenderer* pr) { 330 GrPathRenderer* pr) {
331 GrDrawState* drawState = fGpu->drawState(); 331 GrDrawState* drawState = fGpu->drawState();
332 332
333 drawState->setRenderTarget(target->asRenderTarget()); 333 drawState->setRenderTarget(target->asRenderTarget());
334 334
335 // TODO: Draw rrects directly here.
335 switch (element->getType()) { 336 switch (element->getType()) {
337 case Element::kEmpty_Type:
338 SkDEBUGFAIL("Should never get here with an empty element.");
339 break;
336 case Element::kRect_Type: 340 case Element::kRect_Type:
337 // TODO: Do rects directly to the accumulator using a aa-rect GrEffe ct that covers the 341 // TODO: Do rects directly to the accumulator using a aa-rect GrEffe ct that covers the
338 // entire mask bounds and writes 0 outside the rect. 342 // entire mask bounds and writes 0 outside the rect.
339 if (element->isAA()) { 343 if (element->isAA()) {
340 getContext()->getAARectRenderer()->fillAARect(fGpu, 344 getContext()->getAARectRenderer()->fillAARect(fGpu,
341 fGpu, 345 fGpu,
342 element->getRect() , 346 element->getRect() ,
343 SkMatrix::I(), 347 SkMatrix::I(),
344 element->getRect() , 348 element->getRect() ,
345 false); 349 false);
346 } else { 350 } else {
347 fGpu->drawSimpleRect(element->getRect(), NULL); 351 fGpu->drawSimpleRect(element->getRect(), NULL);
348 } 352 }
349 return true; 353 return true;
350 case Element::kPath_Type: { 354 default: {
351 SkTCopyOnFirstWrite<SkPath> path(element->getPath()); 355 SkPath path;
352 if (path->isInverseFillType()) { 356 element->asPath(&path);
353 path.writable()->toggleInverseFillType(); 357 if (path.isInverseFillType()) {
358 path.toggleInverseFillType();
354 } 359 }
355 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 360 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
356 if (NULL == pr) { 361 if (NULL == pr) {
357 GrPathRendererChain::DrawType type; 362 GrPathRendererChain::DrawType type;
358 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr awType : 363 type = element->isAA() ? GrPathRendererChain::kColorAntiAlias_Dr awType :
359 GrPathRendererChain::kColor_DrawType; 364 GrPathRendererChain::kColor_DrawType;
360 pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, fa lse, type); 365 pr = this->getContext()->getPathRenderer(path, stroke, fGpu, fal se, type);
361 } 366 }
362 if (NULL == pr) { 367 if (NULL == pr) {
363 return false; 368 return false;
364 } 369 }
365 pr->drawPath(element->getPath(), stroke, fGpu, element->isAA()); 370 pr->drawPath(path, stroke, fGpu, element->isAA());
366 break; 371 break;
367 } 372 }
368 default:
369 // something is wrong if we're trying to draw an empty element.
370 GrCrash("Unexpected element type");
371 return false;
372 } 373 }
373 return true; 374 return true;
374 } 375 }
375 376
376 bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target, 377 bool GrClipMaskManager::canStencilAndDrawElement(GrTexture* target,
377 const SkClipStack::Element* ele ment, 378 const SkClipStack::Element* ele ment,
378 GrPathRenderer** pr) { 379 GrPathRenderer** pr) {
379 GrDrawState* drawState = fGpu->drawState(); 380 GrDrawState* drawState = fGpu->drawState();
380 drawState->setRenderTarget(target->asRenderTarget()); 381 drawState->setRenderTarget(target->asRenderTarget());
381 382
382 switch (element->getType()) { 383 if (Element::kRect_Type == element->getType()) {
383 case Element::kRect_Type: 384 return true;
384 return true; 385 } else {
385 case Element::kPath_Type: { 386 // We shouldn't get here with an empty clip element.
386 SkTCopyOnFirstWrite<SkPath> path(element->getPath()); 387 SkASSERT(Element::kEmpty_Type != element->getType());
387 if (path->isInverseFillType()) { 388 SkPath path;
388 path.writable()->toggleInverseFillType(); 389 element->asPath(&path);
389 } 390 if (path.isInverseFillType()) {
390 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 391 path.toggleInverseFillType();
391 GrPathRendererChain::DrawType type = element->isAA() ?
392 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
393 GrPathRendererChain::kStencilAndColor_DrawType;
394 *pr = this->getContext()->getPathRenderer(*path, stroke, fGpu, false , type);
395 return NULL != *pr;
396 } 392 }
397 default: 393 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
398 // something is wrong if we're trying to draw an empty element. 394 GrPathRendererChain::DrawType type = element->isAA() ?
399 GrCrash("Unexpected element type"); 395 GrPathRendererChain::kStencilAndColorAntiAlias_DrawType :
400 return false; 396 GrPathRendererChain::kStencilAndColor_DrawType;
397 *pr = this->getContext()->getPathRenderer(path, stroke, fGpu, false, typ e);
398 return NULL != *pr;
401 } 399 }
402 } 400 }
403 401
404 void GrClipMaskManager::mergeMask(GrTexture* dstMask, 402 void GrClipMaskManager::mergeMask(GrTexture* dstMask,
405 GrTexture* srcMask, 403 GrTexture* srcMask,
406 SkRegion::Op op, 404 SkRegion::Op op,
407 const SkIRect& dstBound, 405 const SkIRect& dstBound,
408 const SkIRect& srcBound) { 406 const SkIRect& srcBound) {
409 GrDrawState::AutoViewMatrixRestore avmr; 407 GrDrawState::AutoViewMatrixRestore avmr;
410 GrDrawState* drawState = fGpu->drawState(); 408 GrDrawState* drawState = fGpu->drawState();
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
693 691
694 // This will be used to determine whether the clip shape can be rend ered into the 692 // This will be used to determine whether the clip shape can be rend ered into the
695 // stencil with arbitrary stencil settings. 693 // stencil with arbitrary stencil settings.
696 GrPathRenderer::StencilSupport stencilSupport; 694 GrPathRenderer::StencilSupport stencilSupport;
697 695
698 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle); 696 SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
699 697
700 SkRegion::Op op = element->getOp(); 698 SkRegion::Op op = element->getOp();
701 699
702 GrPathRenderer* pr = NULL; 700 GrPathRenderer* pr = NULL;
703 SkTCopyOnFirstWrite<SkPath> clipPath; 701 SkPath clipPath;
704 if (Element::kRect_Type == element->getType()) { 702 if (Element::kRect_Type == element->getType()) {
705 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport; 703 stencilSupport = GrPathRenderer::kNoRestriction_StencilSupport;
706 fillInverted = false; 704 fillInverted = false;
707 } else { 705 } else {
708 SkASSERT(Element::kPath_Type == element->getType()); 706 element->asPath(&clipPath);
709 clipPath.init(element->getPath()); 707 fillInverted = clipPath.isInverseFillType();
710 fillInverted = clipPath->isInverseFillType();
711 if (fillInverted) { 708 if (fillInverted) {
712 clipPath.writable()->toggleInverseFillType(); 709 clipPath.toggleInverseFillType();
713 } 710 }
714 pr = this->getContext()->getPathRenderer(*clipPath, 711 pr = this->getContext()->getPathRenderer(clipPath,
715 stroke, 712 stroke,
716 fGpu, 713 fGpu,
717 false, 714 false,
718 GrPathRendererChain::kS tencilOnly_DrawType, 715 GrPathRendererChain::kS tencilOnly_DrawType,
719 &stencilSupport); 716 &stencilSupport);
720 if (NULL == pr) { 717 if (NULL == pr) {
721 return false; 718 return false;
722 } 719 }
723 } 720 }
724 721
(...skipping 20 matching lines...) Expand all
745 kIncClamp_StencilOp, 742 kIncClamp_StencilOp,
746 kAlways_StencilFunc, 743 kAlways_StencilFunc,
747 0xffff, 744 0xffff,
748 0x0000, 745 0x0000,
749 0xffff); 746 0xffff);
750 SET_RANDOM_COLOR 747 SET_RANDOM_COLOR
751 if (Element::kRect_Type == element->getType()) { 748 if (Element::kRect_Type == element->getType()) {
752 *drawState->stencil() = gDrawToStencil; 749 *drawState->stencil() = gDrawToStencil;
753 fGpu->drawSimpleRect(element->getRect(), NULL); 750 fGpu->drawSimpleRect(element->getRect(), NULL);
754 } else { 751 } else {
755 SkASSERT(Element::kPath_Type == element->getType()); 752 if (!clipPath.isEmpty()) {
756 if (!clipPath->isEmpty()) {
757 if (canRenderDirectToStencil) { 753 if (canRenderDirectToStencil) {
758 *drawState->stencil() = gDrawToStencil; 754 *drawState->stencil() = gDrawToStencil;
759 pr->drawPath(*clipPath, stroke, fGpu, false); 755 pr->drawPath(clipPath, stroke, fGpu, false);
760 } else { 756 } else {
761 pr->stencilPath(*clipPath, stroke, fGpu); 757 pr->stencilPath(clipPath, stroke, fGpu);
762 } 758 }
763 } 759 }
764 } 760 }
765 } 761 }
766 762
767 // now we modify the clip bit by rendering either the clip 763 // now we modify the clip bit by rendering either the clip
768 // element directly or a bounding rect of the entire clip. 764 // element directly or a bounding rect of the entire clip.
769 drawState->enableState(GrGpu::kModifyStencilClip_StateBit); 765 drawState->enableState(GrGpu::kModifyStencilClip_StateBit);
770 for (int p = 0; p < passes; ++p) { 766 for (int p = 0; p < passes; ++p) {
771 *drawState->stencil() = stencilSettings[p]; 767 *drawState->stencil() = stencilSettings[p];
772 if (canDrawDirectToClip) { 768 if (canDrawDirectToClip) {
773 if (Element::kRect_Type == element->getType()) { 769 if (Element::kRect_Type == element->getType()) {
774 SET_RANDOM_COLOR 770 SET_RANDOM_COLOR
775 fGpu->drawSimpleRect(element->getRect(), NULL); 771 fGpu->drawSimpleRect(element->getRect(), NULL);
776 } else { 772 } else {
777 SkASSERT(Element::kPath_Type == element->getType());
778 SET_RANDOM_COLOR 773 SET_RANDOM_COLOR
779 pr->drawPath(*clipPath, stroke, fGpu, false); 774 pr->drawPath(clipPath, stroke, fGpu, false);
780 } 775 }
781 } else { 776 } else {
782 SET_RANDOM_COLOR 777 SET_RANDOM_COLOR
783 // The view matrix is setup to do clip space -> stencil spac e translation, so 778 // The view matrix is setup to do clip space -> stencil spac e translation, so
784 // draw rect in clip space. 779 // draw rect in clip space.
785 fGpu->drawSimpleRect(SkRect::Make(clipSpaceIBounds), NULL); 780 fGpu->drawSimpleRect(SkRect::Make(clipSpaceIBounds), NULL);
786 } 781 }
787 } 782 }
788 } 783 }
789 } 784 }
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1091 1086
1092 // TODO: dynamically attach a stencil buffer 1087 // TODO: dynamically attach a stencil buffer
1093 int stencilBits = 0; 1088 int stencilBits = 0;
1094 GrStencilBuffer* stencilBuffer = 1089 GrStencilBuffer* stencilBuffer =
1095 drawState.getRenderTarget()->getStencilBuffer(); 1090 drawState.getRenderTarget()->getStencilBuffer();
1096 if (NULL != stencilBuffer) { 1091 if (NULL != stencilBuffer) {
1097 stencilBits = stencilBuffer->bits(); 1092 stencilBits = stencilBuffer->bits();
1098 this->adjustStencilParams(settings, clipMode, stencilBits); 1093 this->adjustStencilParams(settings, clipMode, stencilBits);
1099 } 1094 }
1100 } 1095 }
OLDNEW
« no previous file with comments | « src/core/SkClipStack.cpp ('k') | src/gpu/GrReducedClip.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698