fHWBounds.fViewportRect.invalidate();
- fHWDrawState.stencil()->invalidate();
- fHWStencilClip = false;
+ fHWStencilSettings.invalidate();
+ fHWStencilClipMode = kInvalid_StencilClipMode;
// TODO: I believe this should actually go in GrGpu::onResetContext
// rather than here
GL_CALL(StencilMask(0xffffffff));
GL_CALL(ClearStencil(0));
GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
- fHWDrawState.stencil()->invalidate();
+ fHWStencilSettings.invalidate();
+ fHWStencilClipMode = kInvalid_StencilClipMode;
}
void GrGpuGL::clearStencilClip(const GrIRect& rect, bool insideClip) {
GL_CALL(StencilMask(clipStencilMask));
GL_CALL(ClearStencil(value));
GL_CALL(Clear(GR_GL_STENCIL_BUFFER_BIT));
- fHWDrawState.stencil()->invalidate();
+ fHWStencilSettings.invalidate();
+ fHWStencilClipMode = kInvalid_StencilClipMode;
}
void GrGpuGL::onForceRenderTargetFlush() {
// use stencil for clipping if clipping is enabled and the clip
// has been written into the stencil.
- bool stencilClip = fClipMaskManager.isClipInStencil() && drawState.isClipState();
- bool drawClipToStencil =
- drawState.isStateFlagEnabled(kModifyStencilClip_StateBit);
- bool stencilChange = (fHWDrawState.getStencil() != *settings) ||
- (fHWStencilClip != stencilClip) ||
- (fHWDrawState.isStateFlagEnabled(kModifyStencilClip_StateBit) !=
- drawClipToStencil);
+ StencilClipMode clipMode;
+ if (fClipMaskManager.isClipInStencil() &&
+ drawState.isClipState()) {
+ clipMode = kUseClip_StencilClipMode;
+ // We can't be modifying the clip and respecting it at the same time.
+ GrAssert(!drawState.isStateFlagEnabled(kModifyStencilClip_StateBit));
+ } else if (drawState.isStateFlagEnabled(kModifyStencilClip_StateBit)) {
+ clipMode = kModifyClip_StencilClipMode;
+ } else {
+ clipMode = kIgnoreClip_StencilClipMode;
+ }
+ bool stencilChange = (fHWStencilSettings != *settings) ||
+ (fHWStencilClipMode != clipMode);
if (stencilChange) {
- // we can't simultaneously perform stencil-clipping and
- // modify the stencil clip
- GrAssert(!stencilClip || !drawClipToStencil);
-
if (settings->isDisabled()) {
- if (stencilClip) {
+ if (kUseClip_StencilClipMode == clipMode) {
settings = GetClipStencilSettings();
}
}
unsigned int frontWriteMask = settings->frontWriteMask();
GrGLenum frontFunc;
- if (drawClipToStencil) {
+ if (kModifyClip_StencilClipMode == clipMode) {
GrAssert(settings->frontFunc() < kBasicStencilFuncCount);
frontFunc = grToGLStencilFunc[settings->frontFunc()];
} else {
- frontFunc = grToGLStencilFunc[ConvertStencilFunc(
- stencilClip, settings->frontFunc())];
+ bool useClip = kUseClip_StencilClipMode == clipMode;
+ frontFunc = grToGLStencilFunc[ConvertStencilFunc(useClip,
+ settings->frontFunc())];
ConvertStencilFuncAndMask(settings->frontFunc(),
- stencilClip,
+ useClip,
clipStencilMask,
userStencilMask,
&frontRef,
unsigned int backWriteMask = settings->backWriteMask();
- if (drawClipToStencil) {
+ if (kModifyClip_StencilClipMode == clipMode) {
GrAssert(settings->backFunc() < kBasicStencilFuncCount);
backFunc = grToGLStencilFunc[settings->backFunc()];
} else {
- backFunc = grToGLStencilFunc[ConvertStencilFunc(
- stencilClip, settings->backFunc())];
+ bool useClip = kUseClip_StencilClipMode == clipMode;
+ backFunc = grToGLStencilFunc[ConvertStencilFunc(useClip,
+ settings->backFunc())];
ConvertStencilFuncAndMask(settings->backFunc(),
- stencilClip,
+ useClip,
clipStencilMask,
userStencilMask,
&backRef,
grToGLStencilOp[settings->frontPassOp()]));
}
}
- *fHWDrawState.stencil() = *settings;
- fHWStencilClip = stencilClip;
+ fHWStencilSettings = *settings;
+ fHWStencilClipMode = clipMode;
}
}
} fUnpremulConversion;
GrDrawState fHWDrawState;
- bool fHWStencilClip;
// As flush of GL state proceeds it updates fHDrawState
// to reflect the new state. Later parts of the state flush
}
} fHWAAState;
+ // The high bit of the stencil buffer is used for clipping. This enum is
+ // used to track whether the clip bit of the stencil buffer is being used,
+ // manipulated, or neither.
+ enum StencilClipMode {
+ // Draw to the clip bit of the stencil buffer
+ kModifyClip_StencilClipMode,
+ // Clip against the existing representation of the clip in the high bit
+ // of the stencil buffer.
+ kUseClip_StencilClipMode,
+ // Neither writing to nor clipping against the clip bit.
+ kIgnoreClip_StencilClipMode,
+ // Unknown state of HW
+ kInvalid_StencilClipMode,
+ };
+ StencilClipMode fHWStencilClipMode;
+ GrStencilSettings fHWStencilSettings;
+
GrDrawState::DrawFace fHWDrawFace;
TriState fHWWriteToColor;
TriState fHWDitherEnabled;