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

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

Issue 48593003: Avoid re-rendering stencil clip for every draw with reducable clip stack (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: gcc-4.2 mac os 10.6 fix Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrReducedClip.h » ('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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 } 106 }
107 107
108 //////////////////////////////////////////////////////////////////////////////// 108 ////////////////////////////////////////////////////////////////////////////////
109 // sort out what kind of clip mask needs to be created: alpha, stencil, 109 // sort out what kind of clip mask needs to be created: alpha, stencil,
110 // scissor, or entirely software 110 // scissor, or entirely software
111 bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, 111 bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn,
112 GrDrawState::AutoRestoreEffects* are) { 112 GrDrawState::AutoRestoreEffects* are) {
113 fCurrClipMaskType = kNone_ClipMaskType; 113 fCurrClipMaskType = kNone_ClipMaskType;
114 114
115 ElementList elements(16); 115 ElementList elements(16);
116 int32_t genID;
116 InitialState initialState; 117 InitialState initialState;
117 SkIRect clipSpaceIBounds; 118 SkIRect clipSpaceIBounds;
118 bool requiresAA; 119 bool requiresAA;
119 bool isRect = false; 120 bool isRect = false;
120 121
121 GrDrawState* drawState = fGpu->drawState(); 122 GrDrawState* drawState = fGpu->drawState();
122 123
123 const GrRenderTarget* rt = drawState->getRenderTarget(); 124 const GrRenderTarget* rt = drawState->getRenderTarget();
124 // GrDrawTarget should have filtered this for us 125 // GrDrawTarget should have filtered this for us
125 SkASSERT(NULL != rt); 126 SkASSERT(NULL != rt);
126 127
127 bool ignoreClip = !drawState->isClipState() || clipDataIn->fClipStack->isWid eOpen(); 128 bool ignoreClip = !drawState->isClipState() || clipDataIn->fClipStack->isWid eOpen();
128 129
129 if (!ignoreClip) { 130 if (!ignoreClip) {
130 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); 131 SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height());
131 clipSpaceRTIBounds.offset(clipDataIn->fOrigin); 132 clipSpaceRTIBounds.offset(clipDataIn->fOrigin);
132 ReduceClipStack(*clipDataIn->fClipStack, 133 ReduceClipStack(*clipDataIn->fClipStack,
133 clipSpaceRTIBounds, 134 clipSpaceRTIBounds,
134 &elements, 135 &elements,
136 &genID,
135 &initialState, 137 &initialState,
136 &clipSpaceIBounds, 138 &clipSpaceIBounds,
137 &requiresAA); 139 &requiresAA);
138 if (elements.isEmpty()) { 140 if (elements.isEmpty()) {
139 if (kAllIn_InitialState == initialState) { 141 if (kAllIn_InitialState == initialState) {
140 ignoreClip = clipSpaceIBounds == clipSpaceRTIBounds; 142 ignoreClip = clipSpaceIBounds == clipSpaceRTIBounds;
141 isRect = true; 143 isRect = true;
142 } else { 144 } else {
143 return false; 145 return false;
144 } 146 }
145 } 147 }
146 } 148 }
147 149
148 if (ignoreClip) { 150 if (ignoreClip) {
149 fGpu->disableScissor(); 151 fGpu->disableScissor();
150 this->setGpuStencil(); 152 this->setGpuStencil();
151 return true; 153 return true;
152 } 154 }
153 155
154 #if GR_AA_CLIP 156 #if GR_AA_CLIP
155 // TODO: catch isRect && requiresAA and use clip planes if available rather than a mask. 157 // TODO: catch isRect && requiresAA and use clip planes if available rather than a mask.
156 158
157 // If MSAA is enabled we can do everything in the stencil buffer. 159 // If MSAA is enabled we can do everything in the stencil buffer.
158 if (0 == rt->numSamples() && requiresAA) { 160 if (0 == rt->numSamples() && requiresAA) {
159 int32_t genID = clipDataIn->fClipStack->getTopmostGenID();
160 GrTexture* result = NULL; 161 GrTexture* result = NULL;
161 162
162 if (this->useSWOnlyPath(elements)) { 163 if (this->useSWOnlyPath(elements)) {
163 // The clip geometry is complex enough that it will be more efficien t to create it 164 // The clip geometry is complex enough that it will be more efficien t to create it
164 // entirely in software 165 // entirely in software
165 result = this->createSoftwareClipMask(genID, 166 result = this->createSoftwareClipMask(genID,
166 initialState, 167 initialState,
167 elements, 168 elements,
168 clipSpaceIBounds); 169 clipSpaceIBounds);
169 } else { 170 } else {
(...skipping 30 matching lines...) Expand all
200 if (isRect) { 201 if (isRect) {
201 SkIRect clipRect = clipSpaceIBounds; 202 SkIRect clipRect = clipSpaceIBounds;
202 clipRect.offset(-clipDataIn->fOrigin); 203 clipRect.offset(-clipDataIn->fOrigin);
203 fGpu->enableScissor(clipRect); 204 fGpu->enableScissor(clipRect);
204 this->setGpuStencil(); 205 this->setGpuStencil();
205 return true; 206 return true;
206 } 207 }
207 208
208 // use the stencil clip if we can't represent the clip as a rectangle. 209 // use the stencil clip if we can't represent the clip as a rectangle.
209 SkIPoint clipSpaceToStencilSpaceOffset = -clipDataIn->fOrigin; 210 SkIPoint clipSpaceToStencilSpaceOffset = -clipDataIn->fOrigin;
210 this->createStencilClipMask(initialState, 211 this->createStencilClipMask(genID,
212 initialState,
211 elements, 213 elements,
212 clipSpaceIBounds, 214 clipSpaceIBounds,
213 clipSpaceToStencilSpaceOffset); 215 clipSpaceToStencilSpaceOffset);
214 216
215 // This must occur after createStencilClipMask. That function may change the scissor. Also, it 217 // This must occur after createStencilClipMask. That function may change the scissor. Also, it
216 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must 218 // only guarantees that the stencil mask is correct within the bounds it was passed, so we must
217 // use both stencil and scissor test to the bounds for the final draw. 219 // use both stencil and scissor test to the bounds for the final draw.
218 SkIRect scissorSpaceIBounds(clipSpaceIBounds); 220 SkIRect scissorSpaceIBounds(clipSpaceIBounds);
219 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); 221 scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset);
220 fGpu->enableScissor(scissorSpaceIBounds); 222 fGpu->enableScissor(scissorSpaceIBounds);
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 desc.fHeight = height; 385 desc.fHeight = height;
384 desc.fConfig = kAlpha_8_GrPixelConfig; 386 desc.fConfig = kAlpha_8_GrPixelConfig;
385 387
386 temp->set(this->getContext(), desc); 388 temp->set(this->getContext(), desc);
387 } 389 }
388 390
389 //////////////////////////////////////////////////////////////////////////////// 391 ////////////////////////////////////////////////////////////////////////////////
390 // Handles caching & allocation (if needed) of a clip alpha-mask texture for bot h the sw-upload 392 // Handles caching & allocation (if needed) of a clip alpha-mask texture for bot h the sw-upload
391 // or gpu-rendered cases. Returns true if there is no more work to be done (i.e. , we got a cache 393 // or gpu-rendered cases. Returns true if there is no more work to be done (i.e. , we got a cache
392 // hit) 394 // hit)
393 bool GrClipMaskManager::getMaskTexture(int32_t clipStackGenID, 395 bool GrClipMaskManager::getMaskTexture(int32_t elementsGenID,
394 const SkIRect& clipSpaceIBounds, 396 const SkIRect& clipSpaceIBounds,
395 GrTexture** result, 397 GrTexture** result,
396 bool willUpload) { 398 bool willUpload) {
397 bool cached = fAACache.canReuse(clipStackGenID, clipSpaceIBounds); 399 bool cached = fAACache.canReuse(elementsGenID, clipSpaceIBounds);
398 if (!cached) { 400 if (!cached) {
399 401
400 // There isn't a suitable entry in the cache so we create a new texture to store the mask. 402 // There isn't a suitable entry in the cache so we create a new texture to store the mask.
401 // Since we are setting up the cache we know the last lookup was a miss. Free up the 403 // Since we are setting up the cache we know the last lookup was a miss. Free up the
402 // currently cached mask so it can be reused. 404 // currently cached mask so it can be reused.
403 fAACache.reset(); 405 fAACache.reset();
404 406
405 GrTextureDesc desc; 407 GrTextureDesc desc;
406 desc.fFlags = willUpload ? kNone_GrTextureFlags : kRenderTarget_GrTextur eFlagBit; 408 desc.fFlags = willUpload ? kNone_GrTextureFlags : kRenderTarget_GrTextur eFlagBit;
407 desc.fWidth = clipSpaceIBounds.width(); 409 desc.fWidth = clipSpaceIBounds.width();
408 desc.fHeight = clipSpaceIBounds.height(); 410 desc.fHeight = clipSpaceIBounds.height();
409 desc.fConfig = kRGBA_8888_GrPixelConfig; 411 desc.fConfig = kRGBA_8888_GrPixelConfig;
410 if (willUpload || this->getContext()->isConfigRenderable(kAlpha_8_GrPixe lConfig, false)) { 412 if (willUpload || this->getContext()->isConfigRenderable(kAlpha_8_GrPixe lConfig, false)) {
411 // We would always like A8 but it isn't supported on all platforms 413 // We would always like A8 but it isn't supported on all platforms
412 desc.fConfig = kAlpha_8_GrPixelConfig; 414 desc.fConfig = kAlpha_8_GrPixelConfig;
413 } 415 }
414 416
415 fAACache.acquireMask(clipStackGenID, desc, clipSpaceIBounds); 417 fAACache.acquireMask(elementsGenID, desc, clipSpaceIBounds);
416 } 418 }
417 419
418 *result = fAACache.getLastMask(); 420 *result = fAACache.getLastMask();
419 return cached; 421 return cached;
420 } 422 }
421 423
422 //////////////////////////////////////////////////////////////////////////////// 424 ////////////////////////////////////////////////////////////////////////////////
423 // Create a 8-bit clip mask in alpha 425 // Create a 8-bit clip mask in alpha
424 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t clipStackGenID, 426 GrTexture* GrClipMaskManager::createAlphaClipMask(int32_t elementsGenID,
425 InitialState initialState, 427 InitialState initialState,
426 const ElementList& elements, 428 const ElementList& elements,
427 const SkIRect& clipSpaceIBound s) { 429 const SkIRect& clipSpaceIBound s) {
428 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); 430 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
429 431
430 GrTexture* result; 432 GrTexture* result;
431 if (this->getMaskTexture(clipStackGenID, clipSpaceIBounds, &result, false)) { 433 if (this->getMaskTexture(elementsGenID, clipSpaceIBounds, &result, false)) {
432 fCurrClipMaskType = kAlpha_ClipMaskType; 434 fCurrClipMaskType = kAlpha_ClipMaskType;
433 return result; 435 return result;
434 } 436 }
435 437
436 if (NULL == result) { 438 if (NULL == result) {
437 fAACache.reset(); 439 fAACache.reset();
438 return NULL; 440 return NULL;
439 } 441 }
440 442
441 // The top-left of the mask corresponds to the top-left corner of the bounds . 443 // The top-left of the mask corresponds to the top-left corner of the bounds .
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 } 564 }
563 } 565 }
564 566
565 fCurrClipMaskType = kAlpha_ClipMaskType; 567 fCurrClipMaskType = kAlpha_ClipMaskType;
566 return result; 568 return result;
567 } 569 }
568 570
569 //////////////////////////////////////////////////////////////////////////////// 571 ////////////////////////////////////////////////////////////////////////////////
570 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device 572 // Create a 1-bit clip mask in the stencil buffer. 'devClipBounds' are in device
571 // (as opposed to canvas) coordinates 573 // (as opposed to canvas) coordinates
572 bool GrClipMaskManager::createStencilClipMask(InitialState initialState, 574 bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID,
575 InitialState initialState,
573 const ElementList& elements, 576 const ElementList& elements,
574 const SkIRect& clipSpaceIBounds, 577 const SkIRect& clipSpaceIBounds,
575 const SkIPoint& clipSpaceToStencil Offset) { 578 const SkIPoint& clipSpaceToStencil Offset) {
576 579
577 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); 580 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
578 581
579 GrDrawState* drawState = fGpu->drawState(); 582 GrDrawState* drawState = fGpu->drawState();
580 SkASSERT(drawState->isClipState()); 583 SkASSERT(drawState->isClipState());
581 584
582 GrRenderTarget* rt = drawState->getRenderTarget(); 585 GrRenderTarget* rt = drawState->getRenderTarget();
583 SkASSERT(NULL != rt); 586 SkASSERT(NULL != rt);
584 587
585 // TODO: dynamically attach a SB when needed. 588 // TODO: dynamically attach a SB when needed.
586 GrStencilBuffer* stencilBuffer = rt->getStencilBuffer(); 589 GrStencilBuffer* stencilBuffer = rt->getStencilBuffer();
587 if (NULL == stencilBuffer) { 590 if (NULL == stencilBuffer) {
588 return false; 591 return false;
589 } 592 }
590 int32_t genID = elements.tail()->getGenID();
591 593
592 if (stencilBuffer->mustRenderClip(genID, clipSpaceIBounds, clipSpaceToStenci lOffset)) { 594 if (stencilBuffer->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpace ToStencilOffset)) {
593 595
594 stencilBuffer->setLastClip(genID, clipSpaceIBounds, clipSpaceToStencilOf fset); 596 stencilBuffer->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToS tencilOffset);
595 597
596 // Set the matrix so that rendered clip elements are transformed from cl ip to stencil space. 598 // Set the matrix so that rendered clip elements are transformed from cl ip to stencil space.
597 SkVector translate = { 599 SkVector translate = {
598 SkIntToScalar(clipSpaceToStencilOffset.fX), 600 SkIntToScalar(clipSpaceToStencilOffset.fX),
599 SkIntToScalar(clipSpaceToStencilOffset.fY) 601 SkIntToScalar(clipSpaceToStencilOffset.fY)
600 }; 602 };
601 SkMatrix matrix; 603 SkMatrix matrix;
602 matrix.setTranslate(translate); 604 matrix.setTranslate(translate);
603 GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ ASRInit, &matrix); 605 GrDrawTarget::AutoGeometryAndStatePush agasp(fGpu, GrDrawTarget::kReset_ ASRInit, &matrix);
604 drawState = fGpu->drawState(); 606 drawState = fGpu->drawState();
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 } else { 916 } else {
915 finished = true; 917 finished = true;
916 } 918 }
917 } 919 }
918 if (!twoSided) { 920 if (!twoSided) {
919 settings->copyFrontSettingsToBack(); 921 settings->copyFrontSettingsToBack();
920 } 922 }
921 } 923 }
922 924
923 //////////////////////////////////////////////////////////////////////////////// 925 ////////////////////////////////////////////////////////////////////////////////
924 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t clipStackGenID, 926 GrTexture* GrClipMaskManager::createSoftwareClipMask(int32_t elementsGenID,
925 GrReducedClip::InitialState initialState, 927 GrReducedClip::InitialState initialState,
926 const GrReducedClip::Elemen tList& elements, 928 const GrReducedClip::Elemen tList& elements,
927 const SkIRect& clipSpaceIBo unds) { 929 const SkIRect& clipSpaceIBo unds) {
928 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType); 930 SkASSERT(kNone_ClipMaskType == fCurrClipMaskType);
929 931
930 GrTexture* result; 932 GrTexture* result;
931 if (this->getMaskTexture(clipStackGenID, clipSpaceIBounds, &result, true)) { 933 if (this->getMaskTexture(elementsGenID, clipSpaceIBounds, &result, true)) {
932 return result; 934 return result;
933 } 935 }
934 936
935 if (NULL == result) { 937 if (NULL == result) {
936 fAACache.reset(); 938 fAACache.reset();
937 return NULL; 939 return NULL;
938 } 940 }
939 941
940 // The mask texture may be larger than necessary. We round out the clip spac e bounds and pin 942 // The mask texture may be larger than necessary. We round out the clip spac e bounds and pin
941 // the top left corner of the resulting rect to the top left of the texture. 943 // the top left corner of the resulting rect to the top left of the texture.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 1035
1034 // TODO: dynamically attach a stencil buffer 1036 // TODO: dynamically attach a stencil buffer
1035 int stencilBits = 0; 1037 int stencilBits = 0;
1036 GrStencilBuffer* stencilBuffer = 1038 GrStencilBuffer* stencilBuffer =
1037 drawState.getRenderTarget()->getStencilBuffer(); 1039 drawState.getRenderTarget()->getStencilBuffer();
1038 if (NULL != stencilBuffer) { 1040 if (NULL != stencilBuffer) {
1039 stencilBits = stencilBuffer->bits(); 1041 stencilBits = stencilBuffer->bits();
1040 this->adjustStencilParams(settings, clipMode, stencilBits); 1042 this->adjustStencilParams(settings, clipMode, stencilBits);
1041 } 1043 }
1042 } 1044 }
OLDNEW
« no previous file with comments | « src/gpu/GrClipMaskManager.h ('k') | src/gpu/GrReducedClip.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698