From a58fe35fdae3481cf43062f7032820c320c3d163 Mon Sep 17 00:00:00 2001 From: joshualitt Date: Mon, 27 Oct 2014 08:39:00 -0700 Subject: [PATCH] Clip mask manager sets stencil on draw type BUG=skia: Committed: https://skia.googlesource.com/skia/+/7afb5aa201e4b59397cbd8480e121d7501a227e7 Review URL: https://codereview.chromium.org/676983003 --- src/gpu/GrClipMaskManager.cpp | 36 +++++++++++++++++------------------- src/gpu/GrClipMaskManager.h | 6 ++++-- src/gpu/GrDrawState.h | 30 ++++++++++++++++++++++++++++++ src/gpu/GrGpu.cpp | 6 ++++-- src/gpu/GrGpu.h | 17 +---------------- src/gpu/gl/GrGpuGL.cpp | 16 ++++++++-------- src/gpu/gl/GrGpuGL.h | 2 +- src/gpu/gl/GrGpuGL_program.cpp | 2 +- 8 files changed, 66 insertions(+), 49 deletions(-) diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp index 349d51e..0738108 100644 --- a/src/gpu/GrClipMaskManager.cpp +++ b/src/gpu/GrClipMaskManager.cpp @@ -17,12 +17,12 @@ #include "GrRenderTarget.h" #include "GrStencilBuffer.h" #include "GrSWMaskHelper.h" -#include "effects/GrTextureDomain.h" -#include "effects/GrConvexPolyEffect.h" -#include "effects/GrRRectEffect.h" #include "SkRasterClip.h" #include "SkStrokeRec.h" #include "SkTLazy.h" +#include "effects/GrTextureDomain.h" +#include "effects/GrConvexPolyEffect.h" +#include "effects/GrRRectEffect.h" #define GR_AA_CLIP 1 @@ -212,6 +212,7 @@ bool GrClipMaskManager::installClipEffects(const GrReducedClip::ElementList& ele // scissor, or entirely software bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, GrDrawState::AutoRestoreEffects* are, + GrDrawState::AutoRestoreStencil* asr, const SkRect* devBounds) { fCurrClipMaskType = kNone_ClipMaskType; @@ -228,7 +229,6 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, SkASSERT(rt); bool ignoreClip = !drawState->isClipState() || clipDataIn->fClipStack->isWideOpen(); - if (!ignoreClip) { SkIRect clipSpaceRTIBounds = SkIRect::MakeWH(rt->width(), rt->height()); clipSpaceRTIBounds.offset(clipDataIn->fOrigin); @@ -250,7 +250,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, if (ignoreClip) { fGpu->disableScissor(); - this->setGpuStencil(); + this->setDrawStateStencil(asr); return true; } @@ -275,7 +275,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, } else { fGpu->disableScissor(); } - this->setGpuStencil(); + this->setDrawStateStencil(asr); return true; } } @@ -307,7 +307,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, are->set(fGpu->drawState()); setup_drawstate_aaclip(fGpu, result, rtSpaceMaskBounds); fGpu->disableScissor(); - this->setGpuStencil(); + this->setDrawStateStencil(asr); return true; } // if alpha clip mask creation fails fall through to the non-AA code paths @@ -335,7 +335,7 @@ bool GrClipMaskManager::setupClipping(const GrClipData* clipDataIn, SkIRect scissorSpaceIBounds(clipSpaceIBounds); scissorSpaceIBounds.offset(clipSpaceToStencilSpaceOffset); fGpu->enableScissor(scissorSpaceIBounds); - this->setGpuStencil(); + this->setDrawStateStencil(asr); return true; } @@ -400,11 +400,11 @@ bool GrClipMaskManager::drawElement(GrTexture* target, // TODO: Do rects directly to the accumulator using a aa-rect GrProcessor that covers // the entire mask bounds and writes 0 outside the rect. if (element->isAA()) { - getContext()->getAARectRenderer()->fillAARect(fGpu, - fGpu, - element->getRect(), - SkMatrix::I(), - element->getRect()); + this->getContext()->getAARectRenderer()->fillAARect(fGpu, + fGpu, + element->getRect(), + SkMatrix::I(), + element->getRect()); } else { fGpu->drawSimpleRect(element->getRect()); } @@ -707,7 +707,6 @@ bool GrClipMaskManager::createStencilClipMask(int32_t elementsGenID, } if (stencilBuffer->mustRenderClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset)) { - stencilBuffer->setLastClip(elementsGenID, clipSpaceIBounds, clipSpaceToStencilOffset); // Set the matrix so that rendered clip elements are transformed from clip to stencil space. @@ -903,7 +902,7 @@ const GrStencilSettings& basic_apply_stencil_clip_settings() { } } -void GrClipMaskManager::setGpuStencil() { +void GrClipMaskManager::setDrawStateStencil(GrDrawState::AutoRestoreStencil* ars) { // We make two copies of the StencilSettings here (except in the early // exit scenario. One copy from draw state to the stack var. Then another // from the stack var to the gpu. We could make this class hold a ptr to @@ -933,7 +932,6 @@ void GrClipMaskManager::setGpuStencil() { if (GrClipMaskManager::kRespectClip_StencilClipMode == clipMode) { settings = basic_apply_stencil_clip_settings(); } else { - fGpu->disableStencil(); return; } } else { @@ -942,8 +940,7 @@ void GrClipMaskManager::setGpuStencil() { // TODO: dynamically attach a stencil buffer int stencilBits = 0; - GrStencilBuffer* stencilBuffer = - drawState.getRenderTarget()->getStencilBuffer(); + GrStencilBuffer* stencilBuffer = drawState.getRenderTarget()->getStencilBuffer(); if (stencilBuffer) { stencilBits = stencilBuffer->bits(); } @@ -951,7 +948,8 @@ void GrClipMaskManager::setGpuStencil() { SkASSERT(fGpu->caps()->stencilWrapOpsSupport() || !settings.usesWrapOp()); SkASSERT(fGpu->caps()->twoSidedStencilSupport() || !settings.isTwoSided()); this->adjustStencilParams(&settings, clipMode, stencilBits); - fGpu->setStencilSettings(settings); + ars->set(fGpu->drawState()); + fGpu->drawState()->setStencil(settings); } void GrClipMaskManager::adjustStencilParams(GrStencilSettings* settings, diff --git a/src/gpu/GrClipMaskManager.h b/src/gpu/GrClipMaskManager.h index c98648b..8a4b45a 100644 --- a/src/gpu/GrClipMaskManager.h +++ b/src/gpu/GrClipMaskManager.h @@ -50,7 +50,9 @@ public: * the manager when it must install additional effects to implement the * clip. devBounds is optional but can help optimize clipping. */ - bool setupClipping(const GrClipData* clipDataIn, GrDrawState::AutoRestoreEffects*, + bool setupClipping(const GrClipData* clipDataIn, + GrDrawState::AutoRestoreEffects*, + GrDrawState::AutoRestoreStencil*, const SkRect* devBounds); /** @@ -173,7 +175,7 @@ private: * updates the GrGpu with stencil settings that account stencil-based * clipping. */ - void setGpuStencil(); + void setDrawStateStencil(GrDrawState::AutoRestoreStencil* asr); /** * Adjusts the stencil settings to account for interaction with stencil diff --git a/src/gpu/GrDrawState.h b/src/gpu/GrDrawState.h index 3043fd7..71c44d4 100644 --- a/src/gpu/GrDrawState.h +++ b/src/gpu/GrDrawState.h @@ -346,6 +346,36 @@ public: int fCoverageEffectCnt; }; + /** + * AutoRestoreStencil + * + * This simple struct saves and restores the stencil settings + */ + class AutoRestoreStencil : public ::SkNoncopyable { + public: + AutoRestoreStencil() : fDrawState(NULL) {} + + AutoRestoreStencil(GrDrawState* ds) : fDrawState(NULL) { this->set(ds); } + + ~AutoRestoreStencil() { this->set(NULL); } + + void set(GrDrawState* ds) { + if (fDrawState) { + fDrawState->setStencil(fStencilSettings); + } + fDrawState = ds; + if (ds) { + fStencilSettings = ds->getStencil(); + } + } + + bool isSet() const { return SkToBool(fDrawState); } + + private: + GrDrawState* fDrawState; + GrStencilSettings fStencilSettings; + }; + /// @} /////////////////////////////////////////////////////////////////////////// diff --git a/src/gpu/GrGpu.cpp b/src/gpu/GrGpu.cpp index 6510048..221aaec 100644 --- a/src/gpu/GrGpu.cpp +++ b/src/gpu/GrGpu.cpp @@ -298,10 +298,12 @@ const GrIndexBuffer* GrGpu::getQuadIndexBuffer() const { //////////////////////////////////////////////////////////////////////////////// -bool GrGpu::setupClipAndFlushState(DrawType type, const GrDeviceCoordTexture* dstCopy, +bool GrGpu::setupClipAndFlushState(DrawType type, + const GrDeviceCoordTexture* dstCopy, GrDrawState::AutoRestoreEffects* are, const SkRect* devBounds) { - if (!fClipMaskManager.setupClipping(this->getClip(), are, devBounds)) { + GrDrawState::AutoRestoreStencil asr; + if (!fClipMaskManager.setupClipping(this->getClip(), are, &asr, devBounds)) { return false; } diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h index e4669a2..cb14696 100644 --- a/src/gpu/GrGpu.h +++ b/src/gpu/GrGpu.h @@ -306,18 +306,6 @@ public: } void disableScissor() { fScissorState.fEnabled = false; } - /** - * Like the scissor methods above this is called by setupClipping and - * should be flushed by the GrGpu subclass in flushGraphicsState. These - * stencil settings should be used in place of those on the GrDrawState. - * They have been adjusted to account for any interactions between the - * GrDrawState's stencil settings and stencil clipping. - */ - void setStencilSettings(const GrStencilSettings& settings) { - fStencilSettings = settings; - } - void disableStencil() { fStencilSettings.setDisabled(); } - // GrGpu subclass sets clip bit in the stencil buffer. The subclass is // free to clear the remaining bits to zero if masked clears are more // expensive than clearing all bits. @@ -369,7 +357,7 @@ protected: // prepares clip flushes gpu state before a draw bool setupClipAndFlushState(DrawType, const GrDeviceCoordTexture* dstCopy, - GrDrawState::AutoRestoreEffects* are, + GrDrawState::AutoRestoreEffects*, const SkRect* devBounds); // Functions used to map clip-respecting stencil tests into normal @@ -404,9 +392,6 @@ protected: SkIRect fRect; } fScissorState; - // The final stencil settings to use as determined by the clip manager. - GrStencilSettings fStencilSettings; - // Helpers for setting up geometry state void finalizeReservedVertices(); void finalizeReservedIndices(); diff --git a/src/gpu/gl/GrGpuGL.cpp b/src/gpu/gl/GrGpuGL.cpp index c83a668..75c9b3a 100644 --- a/src/gpu/gl/GrGpuGL.cpp +++ b/src/gpu/gl/GrGpuGL.cpp @@ -1904,9 +1904,9 @@ void set_gl_stencil(const GrGLInterface* gl, } } -void GrGpuGL::flushStencil(DrawType type) { - if (kStencilPath_DrawType != type && fHWStencilSettings != fStencilSettings) { - if (fStencilSettings.isDisabled()) { +void GrGpuGL::flushStencil(const GrStencilSettings& stencilSettings, DrawType type) { + if (kStencilPath_DrawType != type && fHWStencilSettings != stencilSettings) { + if (stencilSettings.isDisabled()) { if (kNo_TriState != fHWStencilTestEnabled) { GL_CALL(Disable(GR_GL_STENCIL_TEST)); fHWStencilTestEnabled = kNo_TriState; @@ -1917,24 +1917,24 @@ void GrGpuGL::flushStencil(DrawType type) { fHWStencilTestEnabled = kYes_TriState; } } - if (!fStencilSettings.isDisabled()) { + if (!stencilSettings.isDisabled()) { if (this->caps()->twoSidedStencilSupport()) { set_gl_stencil(this->glInterface(), - fStencilSettings, + stencilSettings, GR_GL_FRONT, GrStencilSettings::kFront_Face); set_gl_stencil(this->glInterface(), - fStencilSettings, + stencilSettings, GR_GL_BACK, GrStencilSettings::kBack_Face); } else { set_gl_stencil(this->glInterface(), - fStencilSettings, + stencilSettings, GR_GL_FRONT_AND_BACK, GrStencilSettings::kFront_Face); } } - fHWStencilSettings = fStencilSettings; + fHWStencilSettings = stencilSettings; } } diff --git a/src/gpu/gl/GrGpuGL.h b/src/gpu/gl/GrGpuGL.h index 24ab4ec..f18962c 100644 --- a/src/gpu/gl/GrGpuGL.h +++ b/src/gpu/gl/GrGpuGL.h @@ -235,7 +235,7 @@ private: // NULL means whole target. Can be an empty rect. void flushRenderTarget(GrGLRenderTarget*, const SkIRect* bounds); - void flushStencil(DrawType); + void flushStencil(const GrStencilSettings&, DrawType); void flushAAState(const GrOptDrawState&, DrawType); bool configToGLFormats(GrPixelConfig config, diff --git a/src/gpu/gl/GrGpuGL_program.cpp b/src/gpu/gl/GrGpuGL_program.cpp index 6a09ebf..ecfd813 100644 --- a/src/gpu/gl/GrGpuGL_program.cpp +++ b/src/gpu/gl/GrGpuGL_program.cpp @@ -258,7 +258,7 @@ bool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstC } GrGLRenderTarget* glRT = static_cast(optState->getRenderTarget()); - this->flushStencil(type); + this->flushStencil(optState->getStencil(), type); this->flushScissor(glRT->getViewport(), glRT->origin()); this->flushAAState(*optState.get(), type); -- 2.7.4