void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) { if (!dirtyBits.any()) { return; } for (auto dirtyBit : dirtyBits) { switch (dirtyBit) { case gl::State::DIRTY_BIT_BLEND_ENABLED: if (state.getBlendState().blend != mCurBlendState.blend) { mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED); // BlendColor and funcs and equations has to be set if blend is enabled mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); // The color mask may have to be updated if the blend state changes if (mUsingZeroColorMaskWorkaround) { mDirtyBits.set(DIRTY_BIT_COLOR_MASK); } } break; case gl::State::DIRTY_BIT_BLEND_FUNCS: { const gl::BlendState &blendState = state.getBlendState(); if (blendState.sourceBlendRGB != mCurBlendState.sourceBlendRGB || blendState.destBlendRGB != mCurBlendState.destBlendRGB || blendState.sourceBlendAlpha != mCurBlendState.sourceBlendAlpha || blendState.destBlendAlpha != mCurBlendState.destBlendAlpha) { mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); // BlendColor depends on the values of blend funcs mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); // The color mask may have to be updated if the blend funcs change if (mUsingZeroColorMaskWorkaround) { mDirtyBits.set(DIRTY_BIT_COLOR_MASK); } } break; } case gl::State::DIRTY_BIT_BLEND_EQUATIONS: { const gl::BlendState &blendState = state.getBlendState(); if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB || blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha) { mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); // The color mask may have to be updated if the blend funcs change if (mUsingZeroColorMaskWorkaround) { mDirtyBits.set(DIRTY_BIT_COLOR_MASK); } } break; } case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED: if (state.getBlendState().sampleAlphaToCoverage != mCurBlendState.sampleAlphaToCoverage) { mDirtyBits.set(DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE); } break; case gl::State::DIRTY_BIT_COLOR_MASK: { const gl::BlendState &blendState = state.getBlendState(); if (blendState.colorMaskRed != mCurBlendState.colorMaskRed || blendState.colorMaskGreen != mCurBlendState.colorMaskGreen || blendState.colorMaskBlue != mCurBlendState.colorMaskBlue || blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha) { mDirtyBits.set(DIRTY_BIT_COLOR_MASK); // The color mask can cause the blend state to get out of sync when using the // zero color mask workaround if (mUsingZeroColorMaskWorkaround) { mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED); mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); } } break; } case gl::State::DIRTY_BIT_DITHER_ENABLED: if (state.getBlendState().dither != mCurBlendState.dither) { mDirtyBits.set(DIRTY_BIT_DITHER); } break; case gl::State::DIRTY_BIT_BLEND_COLOR: if (state.getBlendColor() != mCurBlendColor) { mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); } break; case gl::State::DIRTY_BIT_CULL_FACE_ENABLED: if (state.getRasterizerState().cullFace != mCurRasterState.cullFace) { mDirtyBits.set(DIRTY_BIT_CULL_MODE); } break; case gl::State::DIRTY_BIT_CULL_FACE: if (state.getRasterizerState().cullMode != mCurRasterState.cullMode) { mDirtyBits.set(DIRTY_BIT_CULL_MODE); } break; case gl::State::DIRTY_BIT_FRONT_FACE: if (state.getRasterizerState().frontFace != mCurRasterState.frontFace) { mDirtyBits.set(DIRTY_BIT_CULL_MODE); // Viewport state depends on rasterizer.frontface mDirtyBits.set(DIRTY_BIT_VIEWPORT); } break; case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED: if (state.getRasterizerState().polygonOffsetFill != mCurRasterState.polygonOffsetFill) { mDirtyBits.set(DIRTY_BIT_DEPTH_BIAS); } break; case gl::State::DIRTY_BIT_POLYGON_OFFSET: { const gl::RasterizerState &rasterizerState = state.getRasterizerState(); if (rasterizerState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor || rasterizerState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits) { mDirtyBits.set(DIRTY_BIT_DEPTH_BIAS); } break; } case gl::State::DIRTY_BIT_DEPTH_MASK: if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask) { mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_MASK); } break; case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED: if (state.getDepthStencilState().depthTest != mCurDepthStencilState.depthTest) { mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC); } break; case gl::State::DIRTY_BIT_DEPTH_FUNC: if (state.getDepthStencilState().depthFunc != mCurDepthStencilState.depthFunc) { mDirtyBits.set(DIRTY_BIT_STENCIL_DEPTH_FUNC); } break; case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED: if (state.getDepthStencilState().stencilTest != mCurDepthStencilState.stencilTest) { mDirtyBits.set(DIRTY_BIT_STENCIL_TEST_ENABLED); // If we enable the stencil test, all of these must be set mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT); mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK); mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT); mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK); } break; case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT: { const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); if (depthStencilState.stencilFunc != mCurDepthStencilState.stencilFunc || depthStencilState.stencilMask != mCurDepthStencilState.stencilMask || state.getStencilRef() != mCurStencilRef) { mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_FRONT); } break; } case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK: { const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); if (depthStencilState.stencilBackFunc != mCurDepthStencilState.stencilBackFunc || depthStencilState.stencilBackMask != mCurDepthStencilState.stencilBackMask || state.getStencilBackRef() != mCurStencilBackRef) { mDirtyBits.set(DIRTY_BIT_STENCIL_FUNCS_BACK); } break; } case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT: if (state.getDepthStencilState().stencilWritemask != mCurDepthStencilState.stencilWritemask) { mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_FRONT); } break; case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK: if (state.getDepthStencilState().stencilBackWritemask != mCurDepthStencilState.stencilBackWritemask) { mDirtyBits.set(DIRTY_BIT_STENCIL_WRITEMASK_BACK); } break; case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT: { const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); if (depthStencilState.stencilFail != mCurDepthStencilState.stencilFail || depthStencilState.stencilPassDepthFail != mCurDepthStencilState.stencilPassDepthFail || depthStencilState.stencilPassDepthPass != mCurDepthStencilState.stencilPassDepthPass) { mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_FRONT); } break; } case gl::State::DIRTY_BIT_STENCIL_OPS_BACK: { const gl::DepthStencilState &depthStencilState = state.getDepthStencilState(); if (depthStencilState.stencilBackFail != mCurDepthStencilState.stencilBackFail || depthStencilState.stencilBackPassDepthFail != mCurDepthStencilState.stencilBackPassDepthFail || depthStencilState.stencilBackPassDepthPass != mCurDepthStencilState.stencilBackPassDepthPass) { mDirtyBits.set(DIRTY_BIT_STENCIL_OPS_BACK); } break; } case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: if (state.isScissorTestEnabled() != mCurScissorEnabled) { mDirtyBits.set(DIRTY_BIT_SCISSOR_ENABLED); // If scissor is enabled, we have to set the scissor rect mDirtyBits.set(DIRTY_BIT_SCISSOR_RECT); } break; case gl::State::DIRTY_BIT_SCISSOR: if (state.getScissor() != mCurScissorRect) { mDirtyBits.set(DIRTY_BIT_SCISSOR_RECT); } break; case gl::State::DIRTY_BIT_DEPTH_RANGE: if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar) { mDirtyBits.set(DIRTY_BIT_VIEWPORT); } break; case gl::State::DIRTY_BIT_VIEWPORT: if (state.getViewport() != mCurViewport) { mDirtyBits.set(DIRTY_BIT_VIEWPORT); } break; default: break; } } }
void StateManager11::syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits) { if (!dirtyBits.any()) { return; } for (auto dirtyBit : angle::IterateBitSet(dirtyBits)) { switch (dirtyBit) { case gl::State::DIRTY_BIT_BLEND_EQUATIONS: { const gl::BlendState &blendState = state.getBlendState(); if (blendState.blendEquationRGB != mCurBlendState.blendEquationRGB || blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha) { mBlendStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_BLEND_FUNCS: { const gl::BlendState &blendState = state.getBlendState(); if (blendState.sourceBlendRGB != mCurBlendState.sourceBlendRGB || blendState.destBlendRGB != mCurBlendState.destBlendRGB || blendState.sourceBlendAlpha != mCurBlendState.sourceBlendAlpha || blendState.destBlendAlpha != mCurBlendState.destBlendAlpha) { mBlendStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_BLEND_ENABLED: if (state.getBlendState().blend != mCurBlendState.blend) { mBlendStateIsDirty = true; } break; case gl::State::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED: if (state.getBlendState().sampleAlphaToCoverage != mCurBlendState.sampleAlphaToCoverage) { mBlendStateIsDirty = true; } break; case gl::State::DIRTY_BIT_DITHER_ENABLED: if (state.getBlendState().dither != mCurBlendState.dither) { mBlendStateIsDirty = true; } break; case gl::State::DIRTY_BIT_COLOR_MASK: { const gl::BlendState &blendState = state.getBlendState(); if (blendState.colorMaskRed != mCurBlendState.colorMaskRed || blendState.colorMaskGreen != mCurBlendState.colorMaskGreen || blendState.colorMaskBlue != mCurBlendState.colorMaskBlue || blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha) { mBlendStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_BLEND_COLOR: if (state.getBlendColor() != mCurBlendColor) { mBlendStateIsDirty = true; } break; case gl::State::DIRTY_BIT_DEPTH_MASK: if (state.getDepthStencilState().depthMask != mCurDepthStencilState.depthMask) { mDepthStencilStateIsDirty = true; } break; case gl::State::DIRTY_BIT_DEPTH_TEST_ENABLED: if (state.getDepthStencilState().depthTest != mCurDepthStencilState.depthTest) { mDepthStencilStateIsDirty = true; } break; case gl::State::DIRTY_BIT_DEPTH_FUNC: if (state.getDepthStencilState().depthFunc != mCurDepthStencilState.depthFunc) { mDepthStencilStateIsDirty = true; } break; case gl::State::DIRTY_BIT_STENCIL_TEST_ENABLED: if (state.getDepthStencilState().stencilTest != mCurDepthStencilState.stencilTest) { mDepthStencilStateIsDirty = true; } break; case gl::State::DIRTY_BIT_STENCIL_FUNCS_FRONT: { const gl::DepthStencilState &depthStencil = state.getDepthStencilState(); if (depthStencil.stencilFunc != mCurDepthStencilState.stencilFunc || depthStencil.stencilMask != mCurDepthStencilState.stencilMask || state.getStencilRef() != mCurStencilRef) { mDepthStencilStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_STENCIL_FUNCS_BACK: { const gl::DepthStencilState &depthStencil = state.getDepthStencilState(); if (depthStencil.stencilBackFunc != mCurDepthStencilState.stencilBackFunc || depthStencil.stencilBackMask != mCurDepthStencilState.stencilBackMask || state.getStencilBackRef() != mCurStencilBackRef) { mDepthStencilStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_FRONT: if (state.getDepthStencilState().stencilWritemask != mCurDepthStencilState.stencilWritemask) { mDepthStencilStateIsDirty = true; } break; case gl::State::DIRTY_BIT_STENCIL_WRITEMASK_BACK: if (state.getDepthStencilState().stencilBackWritemask != mCurDepthStencilState.stencilBackWritemask) { mDepthStencilStateIsDirty = true; } break; case gl::State::DIRTY_BIT_STENCIL_OPS_FRONT: { const gl::DepthStencilState &depthStencil = state.getDepthStencilState(); if (depthStencil.stencilFail != mCurDepthStencilState.stencilFail || depthStencil.stencilPassDepthFail != mCurDepthStencilState.stencilPassDepthFail || depthStencil.stencilPassDepthPass != mCurDepthStencilState.stencilPassDepthPass) { mDepthStencilStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_STENCIL_OPS_BACK: { const gl::DepthStencilState &depthStencil = state.getDepthStencilState(); if (depthStencil.stencilBackFail != mCurDepthStencilState.stencilBackFail || depthStencil.stencilBackPassDepthFail != mCurDepthStencilState.stencilBackPassDepthFail || depthStencil.stencilBackPassDepthPass != mCurDepthStencilState.stencilBackPassDepthPass) { mDepthStencilStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_CULL_FACE_ENABLED: if (state.getRasterizerState().cullFace != mCurRasterState.cullFace) { mRasterizerStateIsDirty = true; } break; case gl::State::DIRTY_BIT_CULL_FACE: if (state.getRasterizerState().cullMode != mCurRasterState.cullMode) { mRasterizerStateIsDirty = true; } break; case gl::State::DIRTY_BIT_FRONT_FACE: if (state.getRasterizerState().frontFace != mCurRasterState.frontFace) { mRasterizerStateIsDirty = true; } break; case gl::State::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED: if (state.getRasterizerState().polygonOffsetFill != mCurRasterState.polygonOffsetFill) { mRasterizerStateIsDirty = true; } break; case gl::State::DIRTY_BIT_POLYGON_OFFSET: { const gl::RasterizerState &rasterState = state.getRasterizerState(); if (rasterState.polygonOffsetFactor != mCurRasterState.polygonOffsetFactor || rasterState.polygonOffsetUnits != mCurRasterState.polygonOffsetUnits) { mRasterizerStateIsDirty = true; } break; } case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED: if (state.getRasterizerState().rasterizerDiscard != mCurRasterState.rasterizerDiscard) { mRasterizerStateIsDirty = true; } break; case gl::State::DIRTY_BIT_SCISSOR: if (state.getScissor() != mCurScissorRect) { mScissorStateIsDirty = true; } break; case gl::State::DIRTY_BIT_SCISSOR_TEST_ENABLED: if (state.isScissorTestEnabled() != mCurScissorEnabled) { mScissorStateIsDirty = true; // Rasterizer state update needs mCurScissorsEnabled and updates when it changes mRasterizerStateIsDirty = true; } break; case gl::State::DIRTY_BIT_DEPTH_RANGE: if (state.getNearPlane() != mCurNear || state.getFarPlane() != mCurFar) { mViewportStateIsDirty = true; } break; case gl::State::DIRTY_BIT_VIEWPORT: if (state.getViewport() != mCurViewport) { mViewportStateIsDirty = true; } break; case gl::State::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING: mRenderTargetIsDirty = true; break; default: if (dirtyBit >= gl::State::DIRTY_BIT_CURRENT_VALUE_0 && dirtyBit < gl::State::DIRTY_BIT_CURRENT_VALUE_MAX) { size_t attribIndex = static_cast<size_t>(dirtyBit - gl::State::DIRTY_BIT_CURRENT_VALUE_0); mDirtyCurrentValueAttribs.set(attribIndex); } break; } } }