aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/gpu/GrClipMaskManager.cpp36
-rw-r--r--src/gpu/GrClipMaskManager.h6
-rw-r--r--src/gpu/GrDrawState.h30
-rw-r--r--src/gpu/GrGpu.cpp18
-rw-r--r--src/gpu/GrGpu.h18
-rw-r--r--src/gpu/gl/GrGpuGL.cpp16
-rw-r--r--src/gpu/gl/GrGpuGL.h2
-rw-r--r--src/gpu/gl/GrGpuGL_program.cpp2
8 files changed, 75 insertions, 53 deletions
diff --git a/src/gpu/GrClipMaskManager.cpp b/src/gpu/GrClipMaskManager.cpp
index 349d51e311..0738108ab8 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 c98648b128..8a4b45a82e 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 3043fd76d5..71c44d4867 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 65100489f4..d8ffe6745d 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,
+ GrDrawState::AutoRestoreStencil* ars,
const SkRect* devBounds) {
- if (!fClipMaskManager.setupClipping(this->getClip(), are, devBounds)) {
+ if (!fClipMaskManager.setupClipping(this->getClip(), are, ars, devBounds)) {
return false;
}
@@ -344,8 +346,9 @@ void GrGpu::geometrySourceWillPop(const GeometrySrcState& restoredState) {
void GrGpu::onDraw(const DrawInfo& info) {
this->handleDirtyContext();
GrDrawState::AutoRestoreEffects are;
+ GrDrawState::AutoRestoreStencil asr;
if (!this->setupClipAndFlushState(PrimTypeToDrawType(info.primitiveType()),
- info.getDstCopy(), &are, info.getDevBounds())) {
+ info.getDstCopy(), &are, &asr, info.getDevBounds())) {
return;
}
this->onGpuDraw(info);
@@ -355,7 +358,8 @@ void GrGpu::onStencilPath(const GrPath* path, SkPath::FillType fill) {
this->handleDirtyContext();
GrDrawState::AutoRestoreEffects are;
- if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, &are, NULL)) {
+ GrDrawState::AutoRestoreStencil asr;
+ if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, &are, &asr, NULL)) {
return;
}
@@ -370,7 +374,8 @@ void GrGpu::onDrawPath(const GrPath* path, SkPath::FillType fill,
drawState()->setDefaultVertexAttribs();
GrDrawState::AutoRestoreEffects are;
- if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, &are, NULL)) {
+ GrDrawState::AutoRestoreStencil asr;
+ if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, &are, &asr, NULL)) {
return;
}
@@ -386,7 +391,8 @@ void GrGpu::onDrawPaths(const GrPathRange* pathRange,
drawState()->setDefaultVertexAttribs();
GrDrawState::AutoRestoreEffects are;
- if (!this->setupClipAndFlushState(kDrawPaths_DrawType, dstCopy, &are, NULL)) {
+ GrDrawState::AutoRestoreStencil asr;
+ if (!this->setupClipAndFlushState(kDrawPaths_DrawType, dstCopy, &are, &asr, NULL)) {
return;
}
diff --git a/src/gpu/GrGpu.h b/src/gpu/GrGpu.h
index e4669a25c5..5ce2528924 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,8 @@ protected:
// prepares clip flushes gpu state before a draw
bool setupClipAndFlushState(DrawType,
const GrDeviceCoordTexture* dstCopy,
- GrDrawState::AutoRestoreEffects* are,
+ GrDrawState::AutoRestoreEffects*,
+ GrDrawState::AutoRestoreStencil*,
const SkRect* devBounds);
// Functions used to map clip-respecting stencil tests into normal
@@ -404,9 +393,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 c83a668ea3..75c9b3af30 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 24ab4ec14d..f18962cd37 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 6a09ebf64e..ecfd81381e 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<GrGLRenderTarget*>(optState->getRenderTarget());
- this->flushStencil(type);
+ this->flushStencil(optState->getStencil(), type);
this->flushScissor(glRT->getViewport(), glRT->origin());
this->flushAAState(*optState.get(), type);