xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/gl/StateManagerGL.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker 
7*8975f5c5SAndroid Build Coastguard Worker // StateManagerGL.h: Defines a class for caching applied OpenGL state
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/StateManagerGL.h"
10*8975f5c5SAndroid Build Coastguard Worker 
11*8975f5c5SAndroid Build Coastguard Worker #include <string.h>
12*8975f5c5SAndroid Build Coastguard Worker #include <algorithm>
13*8975f5c5SAndroid Build Coastguard Worker #include <limits>
14*8975f5c5SAndroid Build Coastguard Worker 
15*8975f5c5SAndroid Build Coastguard Worker #include "anglebase/numerics/safe_conversions.h"
16*8975f5c5SAndroid Build Coastguard Worker #include "common/bitset_utils.h"
17*8975f5c5SAndroid Build Coastguard Worker #include "common/mathutil.h"
18*8975f5c5SAndroid Build Coastguard Worker #include "common/matrix_utils.h"
19*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Context.h"
20*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Framebuffer.h"
21*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/Query.h"
22*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/TransformFeedback.h"
23*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/VertexArray.h"
24*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/histogram_macros.h"
25*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/BufferGL.h"
26*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/FramebufferGL.h"
27*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/FunctionsGL.h"
28*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/ProgramGL.h"
29*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/QueryGL.h"
30*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/SamplerGL.h"
31*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/TextureGL.h"
32*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/TransformFeedbackGL.h"
33*8975f5c5SAndroid Build Coastguard Worker #include "libANGLE/renderer/gl/VertexArrayGL.h"
34*8975f5c5SAndroid Build Coastguard Worker #include "platform/PlatformMethods.h"
35*8975f5c5SAndroid Build Coastguard Worker 
36*8975f5c5SAndroid Build Coastguard Worker namespace rx
37*8975f5c5SAndroid Build Coastguard Worker {
38*8975f5c5SAndroid Build Coastguard Worker 
39*8975f5c5SAndroid Build Coastguard Worker namespace
40*8975f5c5SAndroid Build Coastguard Worker {
41*8975f5c5SAndroid Build Coastguard Worker 
ValidateStateHelper(const FunctionsGL * functions,const GLuint localValue,const GLenum pname,const char * localName,const char * driverName)42*8975f5c5SAndroid Build Coastguard Worker static void ValidateStateHelper(const FunctionsGL *functions,
43*8975f5c5SAndroid Build Coastguard Worker                                 const GLuint localValue,
44*8975f5c5SAndroid Build Coastguard Worker                                 const GLenum pname,
45*8975f5c5SAndroid Build Coastguard Worker                                 const char *localName,
46*8975f5c5SAndroid Build Coastguard Worker                                 const char *driverName)
47*8975f5c5SAndroid Build Coastguard Worker {
48*8975f5c5SAndroid Build Coastguard Worker     GLint queryValue;
49*8975f5c5SAndroid Build Coastguard Worker     functions->getIntegerv(pname, &queryValue);
50*8975f5c5SAndroid Build Coastguard Worker     if (localValue != static_cast<GLuint>(queryValue))
51*8975f5c5SAndroid Build Coastguard Worker     {
52*8975f5c5SAndroid Build Coastguard Worker         WARN() << localName << " (" << localValue << ") != " << driverName << " (" << queryValue
53*8975f5c5SAndroid Build Coastguard Worker                << ")";
54*8975f5c5SAndroid Build Coastguard Worker         // Re-add ASSERT: http://anglebug.com/42262547
55*8975f5c5SAndroid Build Coastguard Worker         // ASSERT(false);
56*8975f5c5SAndroid Build Coastguard Worker     }
57*8975f5c5SAndroid Build Coastguard Worker }
58*8975f5c5SAndroid Build Coastguard Worker 
59*8975f5c5SAndroid Build Coastguard Worker }  // anonymous namespace
60*8975f5c5SAndroid Build Coastguard Worker 
VertexArrayStateGL(size_t maxAttribs,size_t maxBindings)61*8975f5c5SAndroid Build Coastguard Worker VertexArrayStateGL::VertexArrayStateGL(size_t maxAttribs, size_t maxBindings)
62*8975f5c5SAndroid Build Coastguard Worker     : attributes(std::min<size_t>(maxAttribs, gl::MAX_VERTEX_ATTRIBS)),
63*8975f5c5SAndroid Build Coastguard Worker       bindings(std::min<size_t>(maxBindings, gl::MAX_VERTEX_ATTRIBS))
64*8975f5c5SAndroid Build Coastguard Worker {
65*8975f5c5SAndroid Build Coastguard Worker     // Set the cached vertex attribute array and vertex attribute binding array size
66*8975f5c5SAndroid Build Coastguard Worker     for (GLuint i = 0; i < attributes.size(); i++)
67*8975f5c5SAndroid Build Coastguard Worker     {
68*8975f5c5SAndroid Build Coastguard Worker         attributes[i].bindingIndex = i;
69*8975f5c5SAndroid Build Coastguard Worker     }
70*8975f5c5SAndroid Build Coastguard Worker }
71*8975f5c5SAndroid Build Coastguard Worker 
IndexedBufferBinding()72*8975f5c5SAndroid Build Coastguard Worker StateManagerGL::IndexedBufferBinding::IndexedBufferBinding() : offset(0), size(0), buffer(0) {}
73*8975f5c5SAndroid Build Coastguard Worker 
StateManagerGL(const FunctionsGL * functions,const gl::Caps & rendererCaps,const gl::Extensions & extensions,const angle::FeaturesGL & features)74*8975f5c5SAndroid Build Coastguard Worker StateManagerGL::StateManagerGL(const FunctionsGL *functions,
75*8975f5c5SAndroid Build Coastguard Worker                                const gl::Caps &rendererCaps,
76*8975f5c5SAndroid Build Coastguard Worker                                const gl::Extensions &extensions,
77*8975f5c5SAndroid Build Coastguard Worker                                const angle::FeaturesGL &features)
78*8975f5c5SAndroid Build Coastguard Worker     : mFunctions(functions),
79*8975f5c5SAndroid Build Coastguard Worker       mFeatures(features),
80*8975f5c5SAndroid Build Coastguard Worker       mProgram(0),
81*8975f5c5SAndroid Build Coastguard Worker       mSupportsVertexArrayObjects(nativegl::SupportsVertexArrayObjects(functions)),
82*8975f5c5SAndroid Build Coastguard Worker       mVAO(0),
83*8975f5c5SAndroid Build Coastguard Worker       mVertexAttribCurrentValues(rendererCaps.maxVertexAttributes),
84*8975f5c5SAndroid Build Coastguard Worker       mDefaultVAOState(rendererCaps.maxVertexAttributes, rendererCaps.maxVertexAttribBindings),
85*8975f5c5SAndroid Build Coastguard Worker       mVAOState(&mDefaultVAOState),
86*8975f5c5SAndroid Build Coastguard Worker       mBuffers(),
87*8975f5c5SAndroid Build Coastguard Worker       mIndexedBuffers(),
88*8975f5c5SAndroid Build Coastguard Worker       mTextureUnitIndex(0),
89*8975f5c5SAndroid Build Coastguard Worker       mTextures{},
90*8975f5c5SAndroid Build Coastguard Worker       mSamplers{},
91*8975f5c5SAndroid Build Coastguard Worker       mImages(rendererCaps.maxImageUnits, ImageUnitBinding()),
92*8975f5c5SAndroid Build Coastguard Worker       mTransformFeedback(0),
93*8975f5c5SAndroid Build Coastguard Worker       mCurrentTransformFeedback(nullptr),
94*8975f5c5SAndroid Build Coastguard Worker       mQueries(),
95*8975f5c5SAndroid Build Coastguard Worker       mPrevDrawContext({0}),
96*8975f5c5SAndroid Build Coastguard Worker       mUnpackAlignment(4),
97*8975f5c5SAndroid Build Coastguard Worker       mUnpackRowLength(0),
98*8975f5c5SAndroid Build Coastguard Worker       mUnpackSkipRows(0),
99*8975f5c5SAndroid Build Coastguard Worker       mUnpackSkipPixels(0),
100*8975f5c5SAndroid Build Coastguard Worker       mUnpackImageHeight(0),
101*8975f5c5SAndroid Build Coastguard Worker       mUnpackSkipImages(0),
102*8975f5c5SAndroid Build Coastguard Worker       mPackAlignment(4),
103*8975f5c5SAndroid Build Coastguard Worker       mPackRowLength(0),
104*8975f5c5SAndroid Build Coastguard Worker       mPackSkipRows(0),
105*8975f5c5SAndroid Build Coastguard Worker       mPackSkipPixels(0),
106*8975f5c5SAndroid Build Coastguard Worker       mFramebuffers(angle::FramebufferBindingSingletonMax, 0),
107*8975f5c5SAndroid Build Coastguard Worker       mRenderbuffer(0),
108*8975f5c5SAndroid Build Coastguard Worker       mPlaceholderFbo(0),
109*8975f5c5SAndroid Build Coastguard Worker       mPlaceholderRbo(0),
110*8975f5c5SAndroid Build Coastguard Worker       mScissorTestEnabled(false),
111*8975f5c5SAndroid Build Coastguard Worker       mScissor(0, 0, 0, 0),
112*8975f5c5SAndroid Build Coastguard Worker       mViewport(0, 0, 0, 0),
113*8975f5c5SAndroid Build Coastguard Worker       mNear(0.0f),
114*8975f5c5SAndroid Build Coastguard Worker       mFar(1.0f),
115*8975f5c5SAndroid Build Coastguard Worker       mClipOrigin(gl::ClipOrigin::LowerLeft),
116*8975f5c5SAndroid Build Coastguard Worker       mClipDepthMode(gl::ClipDepthMode::NegativeOneToOne),
117*8975f5c5SAndroid Build Coastguard Worker       mBlendColor(0, 0, 0, 0),
118*8975f5c5SAndroid Build Coastguard Worker       mBlendStateExt(rendererCaps.maxDrawBuffers),
119*8975f5c5SAndroid Build Coastguard Worker       mBlendAdvancedCoherent(extensions.blendEquationAdvancedCoherentKHR),
120*8975f5c5SAndroid Build Coastguard Worker       mIndependentBlendStates(extensions.drawBuffersIndexedAny()),
121*8975f5c5SAndroid Build Coastguard Worker       mSampleAlphaToCoverageEnabled(false),
122*8975f5c5SAndroid Build Coastguard Worker       mSampleCoverageEnabled(false),
123*8975f5c5SAndroid Build Coastguard Worker       mSampleCoverageValue(1.0f),
124*8975f5c5SAndroid Build Coastguard Worker       mSampleCoverageInvert(false),
125*8975f5c5SAndroid Build Coastguard Worker       mSampleMaskEnabled(false),
126*8975f5c5SAndroid Build Coastguard Worker       mDepthTestEnabled(false),
127*8975f5c5SAndroid Build Coastguard Worker       mDepthFunc(GL_LESS),
128*8975f5c5SAndroid Build Coastguard Worker       mDepthMask(true),
129*8975f5c5SAndroid Build Coastguard Worker       mStencilTestEnabled(false),
130*8975f5c5SAndroid Build Coastguard Worker       mStencilFrontFunc(GL_ALWAYS),
131*8975f5c5SAndroid Build Coastguard Worker       mStencilFrontRef(0),
132*8975f5c5SAndroid Build Coastguard Worker       mStencilFrontValueMask(static_cast<GLuint>(-1)),
133*8975f5c5SAndroid Build Coastguard Worker       mStencilFrontStencilFailOp(GL_KEEP),
134*8975f5c5SAndroid Build Coastguard Worker       mStencilFrontStencilPassDepthFailOp(GL_KEEP),
135*8975f5c5SAndroid Build Coastguard Worker       mStencilFrontStencilPassDepthPassOp(GL_KEEP),
136*8975f5c5SAndroid Build Coastguard Worker       mStencilFrontWritemask(static_cast<GLuint>(-1)),
137*8975f5c5SAndroid Build Coastguard Worker       mStencilBackFunc(GL_ALWAYS),
138*8975f5c5SAndroid Build Coastguard Worker       mStencilBackRef(0),
139*8975f5c5SAndroid Build Coastguard Worker       mStencilBackValueMask(static_cast<GLuint>(-1)),
140*8975f5c5SAndroid Build Coastguard Worker       mStencilBackStencilFailOp(GL_KEEP),
141*8975f5c5SAndroid Build Coastguard Worker       mStencilBackStencilPassDepthFailOp(GL_KEEP),
142*8975f5c5SAndroid Build Coastguard Worker       mStencilBackStencilPassDepthPassOp(GL_KEEP),
143*8975f5c5SAndroid Build Coastguard Worker       mStencilBackWritemask(static_cast<GLuint>(-1)),
144*8975f5c5SAndroid Build Coastguard Worker       mCullFaceEnabled(false),
145*8975f5c5SAndroid Build Coastguard Worker       mCullFace(gl::CullFaceMode::Back),
146*8975f5c5SAndroid Build Coastguard Worker       mFrontFace(GL_CCW),
147*8975f5c5SAndroid Build Coastguard Worker       mPolygonMode(gl::PolygonMode::Fill),
148*8975f5c5SAndroid Build Coastguard Worker       mPolygonOffsetPointEnabled(false),
149*8975f5c5SAndroid Build Coastguard Worker       mPolygonOffsetLineEnabled(false),
150*8975f5c5SAndroid Build Coastguard Worker       mPolygonOffsetFillEnabled(false),
151*8975f5c5SAndroid Build Coastguard Worker       mPolygonOffsetFactor(0.0f),
152*8975f5c5SAndroid Build Coastguard Worker       mPolygonOffsetUnits(0.0f),
153*8975f5c5SAndroid Build Coastguard Worker       mPolygonOffsetClamp(0.0f),
154*8975f5c5SAndroid Build Coastguard Worker       mDepthClampEnabled(false),
155*8975f5c5SAndroid Build Coastguard Worker       mRasterizerDiscardEnabled(false),
156*8975f5c5SAndroid Build Coastguard Worker       mLineWidth(1.0f),
157*8975f5c5SAndroid Build Coastguard Worker       mPrimitiveRestartEnabled(false),
158*8975f5c5SAndroid Build Coastguard Worker       mPrimitiveRestartIndex(0),
159*8975f5c5SAndroid Build Coastguard Worker       mClearColor(0.0f, 0.0f, 0.0f, 0.0f),
160*8975f5c5SAndroid Build Coastguard Worker       mClearDepth(1.0f),
161*8975f5c5SAndroid Build Coastguard Worker       mClearStencil(0),
162*8975f5c5SAndroid Build Coastguard Worker       mFramebufferSRGBAvailable(extensions.sRGBWriteControlEXT),
163*8975f5c5SAndroid Build Coastguard Worker       mFramebufferSRGBEnabled(false),
164*8975f5c5SAndroid Build Coastguard Worker       mHasSeparateFramebufferBindings(mFunctions->isAtLeastGL(gl::Version(3, 0)) ||
165*8975f5c5SAndroid Build Coastguard Worker                                       mFunctions->isAtLeastGLES(gl::Version(3, 0))),
166*8975f5c5SAndroid Build Coastguard Worker       mDitherEnabled(true),
167*8975f5c5SAndroid Build Coastguard Worker       mTextureCubemapSeamlessEnabled(false),
168*8975f5c5SAndroid Build Coastguard Worker       mMultisamplingEnabled(true),
169*8975f5c5SAndroid Build Coastguard Worker       mSampleAlphaToOneEnabled(false),
170*8975f5c5SAndroid Build Coastguard Worker       mCoverageModulation(GL_NONE),
171*8975f5c5SAndroid Build Coastguard Worker       mIsMultiviewEnabled(extensions.multiviewOVR || extensions.multiview2OVR),
172*8975f5c5SAndroid Build Coastguard Worker       mProvokingVertex(GL_LAST_VERTEX_CONVENTION),
173*8975f5c5SAndroid Build Coastguard Worker       mMaxClipDistances(rendererCaps.maxClipDistances),
174*8975f5c5SAndroid Build Coastguard Worker       mLogicOpEnabled(false),
175*8975f5c5SAndroid Build Coastguard Worker       mLogicOp(gl::LogicalOperation::Copy)
176*8975f5c5SAndroid Build Coastguard Worker {
177*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mFunctions);
178*8975f5c5SAndroid Build Coastguard Worker     ASSERT(rendererCaps.maxViews >= 1u);
179*8975f5c5SAndroid Build Coastguard Worker 
180*8975f5c5SAndroid Build Coastguard Worker     mIndexedBuffers[gl::BufferBinding::Uniform].resize(rendererCaps.maxUniformBufferBindings);
181*8975f5c5SAndroid Build Coastguard Worker     mIndexedBuffers[gl::BufferBinding::AtomicCounter].resize(
182*8975f5c5SAndroid Build Coastguard Worker         rendererCaps.maxAtomicCounterBufferBindings);
183*8975f5c5SAndroid Build Coastguard Worker     mIndexedBuffers[gl::BufferBinding::ShaderStorage].resize(
184*8975f5c5SAndroid Build Coastguard Worker         rendererCaps.maxShaderStorageBufferBindings);
185*8975f5c5SAndroid Build Coastguard Worker 
186*8975f5c5SAndroid Build Coastguard Worker     mSampleMaskValues.fill(~GLbitfield(0));
187*8975f5c5SAndroid Build Coastguard Worker 
188*8975f5c5SAndroid Build Coastguard Worker     mQueries.fill(nullptr);
189*8975f5c5SAndroid Build Coastguard Worker     mTemporaryPausedQueries.fill(nullptr);
190*8975f5c5SAndroid Build Coastguard Worker 
191*8975f5c5SAndroid Build Coastguard Worker     // Initialize point sprite state for desktop GL
192*8975f5c5SAndroid Build Coastguard Worker     if (mFunctions->standard == STANDARD_GL_DESKTOP)
193*8975f5c5SAndroid Build Coastguard Worker     {
194*8975f5c5SAndroid Build Coastguard Worker         mFunctions->enable(GL_PROGRAM_POINT_SIZE);
195*8975f5c5SAndroid Build Coastguard Worker 
196*8975f5c5SAndroid Build Coastguard Worker         // GL_POINT_SPRITE was deprecated in the core profile. Point rasterization is always
197*8975f5c5SAndroid Build Coastguard Worker         // performed
198*8975f5c5SAndroid Build Coastguard Worker         // as though POINT_SPRITE were enabled.
199*8975f5c5SAndroid Build Coastguard Worker         if ((mFunctions->profile & GL_CONTEXT_CORE_PROFILE_BIT) == 0)
200*8975f5c5SAndroid Build Coastguard Worker         {
201*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_POINT_SPRITE);
202*8975f5c5SAndroid Build Coastguard Worker         }
203*8975f5c5SAndroid Build Coastguard Worker     }
204*8975f5c5SAndroid Build Coastguard Worker 
205*8975f5c5SAndroid Build Coastguard Worker     if (features.emulatePrimitiveRestartFixedIndex.enabled)
206*8975f5c5SAndroid Build Coastguard Worker     {
207*8975f5c5SAndroid Build Coastguard Worker         // There is no consistent default value for primitive restart index. Set it to UINT -1.
208*8975f5c5SAndroid Build Coastguard Worker         constexpr GLuint primitiveRestartIndex = gl::GetPrimitiveRestartIndexFromType<GLuint>();
209*8975f5c5SAndroid Build Coastguard Worker         mFunctions->primitiveRestartIndex(primitiveRestartIndex);
210*8975f5c5SAndroid Build Coastguard Worker         mPrimitiveRestartIndex = primitiveRestartIndex;
211*8975f5c5SAndroid Build Coastguard Worker     }
212*8975f5c5SAndroid Build Coastguard Worker 
213*8975f5c5SAndroid Build Coastguard Worker     // It's possible we've enabled the emulated VAO feature for testing but we're on a core profile.
214*8975f5c5SAndroid Build Coastguard Worker     // Use a generated VAO as the default VAO so we can still test.
215*8975f5c5SAndroid Build Coastguard Worker     if ((features.syncAllVertexArraysToDefault.enabled ||
216*8975f5c5SAndroid Build Coastguard Worker          features.syncDefaultVertexArraysToDefault.enabled) &&
217*8975f5c5SAndroid Build Coastguard Worker         !nativegl::CanUseDefaultVertexArrayObject(mFunctions))
218*8975f5c5SAndroid Build Coastguard Worker     {
219*8975f5c5SAndroid Build Coastguard Worker         ASSERT(nativegl::SupportsVertexArrayObjects(mFunctions));
220*8975f5c5SAndroid Build Coastguard Worker         mFunctions->genVertexArrays(1, &mDefaultVAO);
221*8975f5c5SAndroid Build Coastguard Worker         mFunctions->bindVertexArray(mDefaultVAO);
222*8975f5c5SAndroid Build Coastguard Worker         mVAO = mDefaultVAO;
223*8975f5c5SAndroid Build Coastguard Worker     }
224*8975f5c5SAndroid Build Coastguard Worker 
225*8975f5c5SAndroid Build Coastguard Worker     // By default, desktop GL clamps values read from normalized
226*8975f5c5SAndroid Build Coastguard Worker     // color buffers to [0, 1], which does not match expected ES
227*8975f5c5SAndroid Build Coastguard Worker     // behavior for signed normalized color buffers.
228*8975f5c5SAndroid Build Coastguard Worker     if (mFunctions->clampColor)
229*8975f5c5SAndroid Build Coastguard Worker     {
230*8975f5c5SAndroid Build Coastguard Worker         mFunctions->clampColor(GL_CLAMP_READ_COLOR, GL_FALSE);
231*8975f5c5SAndroid Build Coastguard Worker     }
232*8975f5c5SAndroid Build Coastguard Worker }
233*8975f5c5SAndroid Build Coastguard Worker 
~StateManagerGL()234*8975f5c5SAndroid Build Coastguard Worker StateManagerGL::~StateManagerGL()
235*8975f5c5SAndroid Build Coastguard Worker {
236*8975f5c5SAndroid Build Coastguard Worker     if (mPlaceholderFbo != 0)
237*8975f5c5SAndroid Build Coastguard Worker     {
238*8975f5c5SAndroid Build Coastguard Worker         deleteFramebuffer(mPlaceholderFbo);
239*8975f5c5SAndroid Build Coastguard Worker     }
240*8975f5c5SAndroid Build Coastguard Worker     if (mPlaceholderRbo != 0)
241*8975f5c5SAndroid Build Coastguard Worker     {
242*8975f5c5SAndroid Build Coastguard Worker         deleteRenderbuffer(mPlaceholderRbo);
243*8975f5c5SAndroid Build Coastguard Worker     }
244*8975f5c5SAndroid Build Coastguard Worker     if (mDefaultVAO != 0)
245*8975f5c5SAndroid Build Coastguard Worker     {
246*8975f5c5SAndroid Build Coastguard Worker         mFunctions->deleteVertexArrays(1, &mDefaultVAO);
247*8975f5c5SAndroid Build Coastguard Worker     }
248*8975f5c5SAndroid Build Coastguard Worker }
249*8975f5c5SAndroid Build Coastguard Worker 
deleteProgram(GLuint program)250*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::deleteProgram(GLuint program)
251*8975f5c5SAndroid Build Coastguard Worker {
252*8975f5c5SAndroid Build Coastguard Worker     if (program != 0)
253*8975f5c5SAndroid Build Coastguard Worker     {
254*8975f5c5SAndroid Build Coastguard Worker         if (mProgram == program)
255*8975f5c5SAndroid Build Coastguard Worker         {
256*8975f5c5SAndroid Build Coastguard Worker             useProgram(0);
257*8975f5c5SAndroid Build Coastguard Worker         }
258*8975f5c5SAndroid Build Coastguard Worker 
259*8975f5c5SAndroid Build Coastguard Worker         mFunctions->deleteProgram(program);
260*8975f5c5SAndroid Build Coastguard Worker     }
261*8975f5c5SAndroid Build Coastguard Worker }
262*8975f5c5SAndroid Build Coastguard Worker 
deleteVertexArray(GLuint vao)263*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::deleteVertexArray(GLuint vao)
264*8975f5c5SAndroid Build Coastguard Worker {
265*8975f5c5SAndroid Build Coastguard Worker     if (vao != 0)
266*8975f5c5SAndroid Build Coastguard Worker     {
267*8975f5c5SAndroid Build Coastguard Worker         if (mVAO == vao)
268*8975f5c5SAndroid Build Coastguard Worker         {
269*8975f5c5SAndroid Build Coastguard Worker             bindVertexArray(0, &mDefaultVAOState);
270*8975f5c5SAndroid Build Coastguard Worker         }
271*8975f5c5SAndroid Build Coastguard Worker         mFunctions->deleteVertexArrays(1, &vao);
272*8975f5c5SAndroid Build Coastguard Worker     }
273*8975f5c5SAndroid Build Coastguard Worker }
274*8975f5c5SAndroid Build Coastguard Worker 
deleteTexture(GLuint texture)275*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::deleteTexture(GLuint texture)
276*8975f5c5SAndroid Build Coastguard Worker {
277*8975f5c5SAndroid Build Coastguard Worker     if (texture != 0)
278*8975f5c5SAndroid Build Coastguard Worker     {
279*8975f5c5SAndroid Build Coastguard Worker         for (gl::TextureType type : angle::AllEnums<gl::TextureType>())
280*8975f5c5SAndroid Build Coastguard Worker         {
281*8975f5c5SAndroid Build Coastguard Worker             const auto &textureVector = mTextures[type];
282*8975f5c5SAndroid Build Coastguard Worker             for (size_t textureUnitIndex = 0; textureUnitIndex < textureVector.size();
283*8975f5c5SAndroid Build Coastguard Worker                  textureUnitIndex++)
284*8975f5c5SAndroid Build Coastguard Worker             {
285*8975f5c5SAndroid Build Coastguard Worker                 if (textureVector[textureUnitIndex] == texture)
286*8975f5c5SAndroid Build Coastguard Worker                 {
287*8975f5c5SAndroid Build Coastguard Worker                     activeTexture(textureUnitIndex);
288*8975f5c5SAndroid Build Coastguard Worker                     bindTexture(type, 0);
289*8975f5c5SAndroid Build Coastguard Worker                 }
290*8975f5c5SAndroid Build Coastguard Worker             }
291*8975f5c5SAndroid Build Coastguard Worker         }
292*8975f5c5SAndroid Build Coastguard Worker 
293*8975f5c5SAndroid Build Coastguard Worker         for (size_t imageUnitIndex = 0; imageUnitIndex < mImages.size(); imageUnitIndex++)
294*8975f5c5SAndroid Build Coastguard Worker         {
295*8975f5c5SAndroid Build Coastguard Worker             if (mImages[imageUnitIndex].texture == texture)
296*8975f5c5SAndroid Build Coastguard Worker             {
297*8975f5c5SAndroid Build Coastguard Worker                 bindImageTexture(imageUnitIndex, 0, 0, false, 0, GL_READ_ONLY, GL_R32UI);
298*8975f5c5SAndroid Build Coastguard Worker             }
299*8975f5c5SAndroid Build Coastguard Worker         }
300*8975f5c5SAndroid Build Coastguard Worker 
301*8975f5c5SAndroid Build Coastguard Worker         mFunctions->deleteTextures(1, &texture);
302*8975f5c5SAndroid Build Coastguard Worker     }
303*8975f5c5SAndroid Build Coastguard Worker }
304*8975f5c5SAndroid Build Coastguard Worker 
deleteSampler(GLuint sampler)305*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::deleteSampler(GLuint sampler)
306*8975f5c5SAndroid Build Coastguard Worker {
307*8975f5c5SAndroid Build Coastguard Worker     if (sampler != 0)
308*8975f5c5SAndroid Build Coastguard Worker     {
309*8975f5c5SAndroid Build Coastguard Worker         for (size_t unit = 0; unit < mSamplers.size(); unit++)
310*8975f5c5SAndroid Build Coastguard Worker         {
311*8975f5c5SAndroid Build Coastguard Worker             if (mSamplers[unit] == sampler)
312*8975f5c5SAndroid Build Coastguard Worker             {
313*8975f5c5SAndroid Build Coastguard Worker                 bindSampler(unit, 0);
314*8975f5c5SAndroid Build Coastguard Worker             }
315*8975f5c5SAndroid Build Coastguard Worker         }
316*8975f5c5SAndroid Build Coastguard Worker 
317*8975f5c5SAndroid Build Coastguard Worker         mFunctions->deleteSamplers(1, &sampler);
318*8975f5c5SAndroid Build Coastguard Worker     }
319*8975f5c5SAndroid Build Coastguard Worker }
320*8975f5c5SAndroid Build Coastguard Worker 
deleteBuffer(GLuint buffer)321*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::deleteBuffer(GLuint buffer)
322*8975f5c5SAndroid Build Coastguard Worker {
323*8975f5c5SAndroid Build Coastguard Worker     if (buffer == 0)
324*8975f5c5SAndroid Build Coastguard Worker     {
325*8975f5c5SAndroid Build Coastguard Worker         return;
326*8975f5c5SAndroid Build Coastguard Worker     }
327*8975f5c5SAndroid Build Coastguard Worker 
328*8975f5c5SAndroid Build Coastguard Worker     for (auto target : angle::AllEnums<gl::BufferBinding>())
329*8975f5c5SAndroid Build Coastguard Worker     {
330*8975f5c5SAndroid Build Coastguard Worker         if (mBuffers[target] == buffer)
331*8975f5c5SAndroid Build Coastguard Worker         {
332*8975f5c5SAndroid Build Coastguard Worker             bindBuffer(target, 0);
333*8975f5c5SAndroid Build Coastguard Worker         }
334*8975f5c5SAndroid Build Coastguard Worker 
335*8975f5c5SAndroid Build Coastguard Worker         auto &indexedTarget = mIndexedBuffers[target];
336*8975f5c5SAndroid Build Coastguard Worker         for (size_t bindIndex = 0; bindIndex < indexedTarget.size(); ++bindIndex)
337*8975f5c5SAndroid Build Coastguard Worker         {
338*8975f5c5SAndroid Build Coastguard Worker             if (indexedTarget[bindIndex].buffer == buffer)
339*8975f5c5SAndroid Build Coastguard Worker             {
340*8975f5c5SAndroid Build Coastguard Worker                 bindBufferBase(target, bindIndex, 0);
341*8975f5c5SAndroid Build Coastguard Worker             }
342*8975f5c5SAndroid Build Coastguard Worker         }
343*8975f5c5SAndroid Build Coastguard Worker     }
344*8975f5c5SAndroid Build Coastguard Worker 
345*8975f5c5SAndroid Build Coastguard Worker     if (mVAOState)
346*8975f5c5SAndroid Build Coastguard Worker     {
347*8975f5c5SAndroid Build Coastguard Worker         if (mVAOState->elementArrayBuffer == buffer)
348*8975f5c5SAndroid Build Coastguard Worker         {
349*8975f5c5SAndroid Build Coastguard Worker             mVAOState->elementArrayBuffer = 0;
350*8975f5c5SAndroid Build Coastguard Worker         }
351*8975f5c5SAndroid Build Coastguard Worker 
352*8975f5c5SAndroid Build Coastguard Worker         for (VertexBindingGL &binding : mVAOState->bindings)
353*8975f5c5SAndroid Build Coastguard Worker         {
354*8975f5c5SAndroid Build Coastguard Worker             if (binding.buffer == buffer)
355*8975f5c5SAndroid Build Coastguard Worker             {
356*8975f5c5SAndroid Build Coastguard Worker                 binding.buffer = 0;
357*8975f5c5SAndroid Build Coastguard Worker             }
358*8975f5c5SAndroid Build Coastguard Worker         }
359*8975f5c5SAndroid Build Coastguard Worker     }
360*8975f5c5SAndroid Build Coastguard Worker 
361*8975f5c5SAndroid Build Coastguard Worker     mFunctions->deleteBuffers(1, &buffer);
362*8975f5c5SAndroid Build Coastguard Worker }
363*8975f5c5SAndroid Build Coastguard Worker 
deleteFramebuffer(GLuint fbo)364*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::deleteFramebuffer(GLuint fbo)
365*8975f5c5SAndroid Build Coastguard Worker {
366*8975f5c5SAndroid Build Coastguard Worker     if (fbo != 0)
367*8975f5c5SAndroid Build Coastguard Worker     {
368*8975f5c5SAndroid Build Coastguard Worker         if (mHasSeparateFramebufferBindings)
369*8975f5c5SAndroid Build Coastguard Worker         {
370*8975f5c5SAndroid Build Coastguard Worker             for (size_t binding = 0; binding < mFramebuffers.size(); ++binding)
371*8975f5c5SAndroid Build Coastguard Worker             {
372*8975f5c5SAndroid Build Coastguard Worker                 if (mFramebuffers[binding] == fbo)
373*8975f5c5SAndroid Build Coastguard Worker                 {
374*8975f5c5SAndroid Build Coastguard Worker                     GLenum enumValue = angle::FramebufferBindingToEnum(
375*8975f5c5SAndroid Build Coastguard Worker                         static_cast<angle::FramebufferBinding>(binding));
376*8975f5c5SAndroid Build Coastguard Worker                     bindFramebuffer(enumValue, 0);
377*8975f5c5SAndroid Build Coastguard Worker                 }
378*8975f5c5SAndroid Build Coastguard Worker             }
379*8975f5c5SAndroid Build Coastguard Worker         }
380*8975f5c5SAndroid Build Coastguard Worker         else
381*8975f5c5SAndroid Build Coastguard Worker         {
382*8975f5c5SAndroid Build Coastguard Worker             ASSERT(mFramebuffers[angle::FramebufferBindingRead] ==
383*8975f5c5SAndroid Build Coastguard Worker                    mFramebuffers[angle::FramebufferBindingDraw]);
384*8975f5c5SAndroid Build Coastguard Worker             if (mFramebuffers[angle::FramebufferBindingRead] == fbo)
385*8975f5c5SAndroid Build Coastguard Worker             {
386*8975f5c5SAndroid Build Coastguard Worker                 bindFramebuffer(GL_FRAMEBUFFER, 0);
387*8975f5c5SAndroid Build Coastguard Worker             }
388*8975f5c5SAndroid Build Coastguard Worker         }
389*8975f5c5SAndroid Build Coastguard Worker         mFunctions->deleteFramebuffers(1, &fbo);
390*8975f5c5SAndroid Build Coastguard Worker     }
391*8975f5c5SAndroid Build Coastguard Worker }
392*8975f5c5SAndroid Build Coastguard Worker 
deleteRenderbuffer(GLuint rbo)393*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::deleteRenderbuffer(GLuint rbo)
394*8975f5c5SAndroid Build Coastguard Worker {
395*8975f5c5SAndroid Build Coastguard Worker     if (rbo != 0)
396*8975f5c5SAndroid Build Coastguard Worker     {
397*8975f5c5SAndroid Build Coastguard Worker         if (mRenderbuffer == rbo)
398*8975f5c5SAndroid Build Coastguard Worker         {
399*8975f5c5SAndroid Build Coastguard Worker             bindRenderbuffer(GL_RENDERBUFFER, 0);
400*8975f5c5SAndroid Build Coastguard Worker         }
401*8975f5c5SAndroid Build Coastguard Worker 
402*8975f5c5SAndroid Build Coastguard Worker         mFunctions->deleteRenderbuffers(1, &rbo);
403*8975f5c5SAndroid Build Coastguard Worker     }
404*8975f5c5SAndroid Build Coastguard Worker }
405*8975f5c5SAndroid Build Coastguard Worker 
deleteTransformFeedback(GLuint transformFeedback)406*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::deleteTransformFeedback(GLuint transformFeedback)
407*8975f5c5SAndroid Build Coastguard Worker {
408*8975f5c5SAndroid Build Coastguard Worker     if (transformFeedback != 0)
409*8975f5c5SAndroid Build Coastguard Worker     {
410*8975f5c5SAndroid Build Coastguard Worker         if (mTransformFeedback == transformFeedback)
411*8975f5c5SAndroid Build Coastguard Worker         {
412*8975f5c5SAndroid Build Coastguard Worker             bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
413*8975f5c5SAndroid Build Coastguard Worker         }
414*8975f5c5SAndroid Build Coastguard Worker 
415*8975f5c5SAndroid Build Coastguard Worker         if (mCurrentTransformFeedback != nullptr &&
416*8975f5c5SAndroid Build Coastguard Worker             mCurrentTransformFeedback->getTransformFeedbackID() == transformFeedback)
417*8975f5c5SAndroid Build Coastguard Worker         {
418*8975f5c5SAndroid Build Coastguard Worker             mCurrentTransformFeedback = nullptr;
419*8975f5c5SAndroid Build Coastguard Worker         }
420*8975f5c5SAndroid Build Coastguard Worker 
421*8975f5c5SAndroid Build Coastguard Worker         mFunctions->deleteTransformFeedbacks(1, &transformFeedback);
422*8975f5c5SAndroid Build Coastguard Worker     }
423*8975f5c5SAndroid Build Coastguard Worker }
424*8975f5c5SAndroid Build Coastguard Worker 
useProgram(GLuint program)425*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::useProgram(GLuint program)
426*8975f5c5SAndroid Build Coastguard Worker {
427*8975f5c5SAndroid Build Coastguard Worker     if (mProgram != program)
428*8975f5c5SAndroid Build Coastguard Worker     {
429*8975f5c5SAndroid Build Coastguard Worker         forceUseProgram(program);
430*8975f5c5SAndroid Build Coastguard Worker     }
431*8975f5c5SAndroid Build Coastguard Worker }
432*8975f5c5SAndroid Build Coastguard Worker 
forceUseProgram(GLuint program)433*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::forceUseProgram(GLuint program)
434*8975f5c5SAndroid Build Coastguard Worker {
435*8975f5c5SAndroid Build Coastguard Worker     mProgram = program;
436*8975f5c5SAndroid Build Coastguard Worker     mFunctions->useProgram(mProgram);
437*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_PROGRAM_BINDING);
438*8975f5c5SAndroid Build Coastguard Worker }
439*8975f5c5SAndroid Build Coastguard Worker 
bindVertexArray(GLuint vao,VertexArrayStateGL * vaoState)440*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::bindVertexArray(GLuint vao, VertexArrayStateGL *vaoState)
441*8975f5c5SAndroid Build Coastguard Worker {
442*8975f5c5SAndroid Build Coastguard Worker     if (mVAO != vao)
443*8975f5c5SAndroid Build Coastguard Worker     {
444*8975f5c5SAndroid Build Coastguard Worker         ASSERT(!mFeatures.syncAllVertexArraysToDefault.enabled);
445*8975f5c5SAndroid Build Coastguard Worker         forceBindVertexArray(vao, vaoState);
446*8975f5c5SAndroid Build Coastguard Worker     }
447*8975f5c5SAndroid Build Coastguard Worker }
448*8975f5c5SAndroid Build Coastguard Worker 
forceBindVertexArray(GLuint vao,VertexArrayStateGL * vaoState)449*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::forceBindVertexArray(GLuint vao, VertexArrayStateGL *vaoState)
450*8975f5c5SAndroid Build Coastguard Worker {
451*8975f5c5SAndroid Build Coastguard Worker     mVAO                                      = vao;
452*8975f5c5SAndroid Build Coastguard Worker     mVAOState                                 = vaoState;
453*8975f5c5SAndroid Build Coastguard Worker     mBuffers[gl::BufferBinding::ElementArray] = vaoState ? vaoState->elementArrayBuffer : 0;
454*8975f5c5SAndroid Build Coastguard Worker 
455*8975f5c5SAndroid Build Coastguard Worker     mFunctions->bindVertexArray(vao);
456*8975f5c5SAndroid Build Coastguard Worker 
457*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_VERTEX_ARRAY_BINDING);
458*8975f5c5SAndroid Build Coastguard Worker }
459*8975f5c5SAndroid Build Coastguard Worker 
bindBuffer(gl::BufferBinding target,GLuint buffer)460*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::bindBuffer(gl::BufferBinding target, GLuint buffer)
461*8975f5c5SAndroid Build Coastguard Worker {
462*8975f5c5SAndroid Build Coastguard Worker     // GL drivers differ in whether the transform feedback bind point is modified when
463*8975f5c5SAndroid Build Coastguard Worker     // glBindTransformFeedback is called. To avoid these behavior differences we shouldn't try to
464*8975f5c5SAndroid Build Coastguard Worker     // use it.
465*8975f5c5SAndroid Build Coastguard Worker     ASSERT(target != gl::BufferBinding::TransformFeedback);
466*8975f5c5SAndroid Build Coastguard Worker     if (mBuffers[target] != buffer)
467*8975f5c5SAndroid Build Coastguard Worker     {
468*8975f5c5SAndroid Build Coastguard Worker         mBuffers[target] = buffer;
469*8975f5c5SAndroid Build Coastguard Worker         mFunctions->bindBuffer(gl::ToGLenum(target), buffer);
470*8975f5c5SAndroid Build Coastguard Worker     }
471*8975f5c5SAndroid Build Coastguard Worker }
472*8975f5c5SAndroid Build Coastguard Worker 
bindBufferBase(gl::BufferBinding target,size_t index,GLuint buffer)473*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::bindBufferBase(gl::BufferBinding target, size_t index, GLuint buffer)
474*8975f5c5SAndroid Build Coastguard Worker {
475*8975f5c5SAndroid Build Coastguard Worker     // Transform feedback buffer bindings are tracked in TransformFeedbackGL
476*8975f5c5SAndroid Build Coastguard Worker     ASSERT(target != gl::BufferBinding::TransformFeedback);
477*8975f5c5SAndroid Build Coastguard Worker 
478*8975f5c5SAndroid Build Coastguard Worker     ASSERT(index < mIndexedBuffers[target].size());
479*8975f5c5SAndroid Build Coastguard Worker     auto &binding = mIndexedBuffers[target][index];
480*8975f5c5SAndroid Build Coastguard Worker     if (binding.buffer != buffer || binding.offset != static_cast<size_t>(-1) ||
481*8975f5c5SAndroid Build Coastguard Worker         binding.size != static_cast<size_t>(-1))
482*8975f5c5SAndroid Build Coastguard Worker     {
483*8975f5c5SAndroid Build Coastguard Worker         binding.buffer   = buffer;
484*8975f5c5SAndroid Build Coastguard Worker         binding.offset   = static_cast<size_t>(-1);
485*8975f5c5SAndroid Build Coastguard Worker         binding.size     = static_cast<size_t>(-1);
486*8975f5c5SAndroid Build Coastguard Worker         mBuffers[target] = buffer;
487*8975f5c5SAndroid Build Coastguard Worker         mFunctions->bindBufferBase(gl::ToGLenum(target), static_cast<GLuint>(index), buffer);
488*8975f5c5SAndroid Build Coastguard Worker     }
489*8975f5c5SAndroid Build Coastguard Worker }
490*8975f5c5SAndroid Build Coastguard Worker 
bindBufferRange(gl::BufferBinding target,size_t index,GLuint buffer,size_t offset,size_t size)491*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::bindBufferRange(gl::BufferBinding target,
492*8975f5c5SAndroid Build Coastguard Worker                                      size_t index,
493*8975f5c5SAndroid Build Coastguard Worker                                      GLuint buffer,
494*8975f5c5SAndroid Build Coastguard Worker                                      size_t offset,
495*8975f5c5SAndroid Build Coastguard Worker                                      size_t size)
496*8975f5c5SAndroid Build Coastguard Worker {
497*8975f5c5SAndroid Build Coastguard Worker     // Transform feedback buffer bindings are tracked in TransformFeedbackGL
498*8975f5c5SAndroid Build Coastguard Worker     ASSERT(target != gl::BufferBinding::TransformFeedback);
499*8975f5c5SAndroid Build Coastguard Worker 
500*8975f5c5SAndroid Build Coastguard Worker     auto &binding = mIndexedBuffers[target][index];
501*8975f5c5SAndroid Build Coastguard Worker     if (binding.buffer != buffer || binding.offset != offset || binding.size != size)
502*8975f5c5SAndroid Build Coastguard Worker     {
503*8975f5c5SAndroid Build Coastguard Worker         binding.buffer   = buffer;
504*8975f5c5SAndroid Build Coastguard Worker         binding.offset   = offset;
505*8975f5c5SAndroid Build Coastguard Worker         binding.size     = size;
506*8975f5c5SAndroid Build Coastguard Worker         mBuffers[target] = buffer;
507*8975f5c5SAndroid Build Coastguard Worker         mFunctions->bindBufferRange(gl::ToGLenum(target), static_cast<GLuint>(index), buffer,
508*8975f5c5SAndroid Build Coastguard Worker                                     offset, size);
509*8975f5c5SAndroid Build Coastguard Worker     }
510*8975f5c5SAndroid Build Coastguard Worker }
511*8975f5c5SAndroid Build Coastguard Worker 
activeTexture(size_t unit)512*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::activeTexture(size_t unit)
513*8975f5c5SAndroid Build Coastguard Worker {
514*8975f5c5SAndroid Build Coastguard Worker     if (mTextureUnitIndex != unit)
515*8975f5c5SAndroid Build Coastguard Worker     {
516*8975f5c5SAndroid Build Coastguard Worker         mTextureUnitIndex = unit;
517*8975f5c5SAndroid Build Coastguard Worker         mFunctions->activeTexture(GL_TEXTURE0 + static_cast<GLenum>(mTextureUnitIndex));
518*8975f5c5SAndroid Build Coastguard Worker     }
519*8975f5c5SAndroid Build Coastguard Worker }
520*8975f5c5SAndroid Build Coastguard Worker 
bindTexture(gl::TextureType type,GLuint texture)521*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::bindTexture(gl::TextureType type, GLuint texture)
522*8975f5c5SAndroid Build Coastguard Worker {
523*8975f5c5SAndroid Build Coastguard Worker     gl::TextureType nativeType = nativegl::GetNativeTextureType(type);
524*8975f5c5SAndroid Build Coastguard Worker     if (mTextures[nativeType][mTextureUnitIndex] != texture)
525*8975f5c5SAndroid Build Coastguard Worker     {
526*8975f5c5SAndroid Build Coastguard Worker         mTextures[nativeType][mTextureUnitIndex] = texture;
527*8975f5c5SAndroid Build Coastguard Worker         mFunctions->bindTexture(nativegl::GetTextureBindingTarget(type), texture);
528*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_TEXTURE_BINDINGS);
529*8975f5c5SAndroid Build Coastguard Worker     }
530*8975f5c5SAndroid Build Coastguard Worker }
531*8975f5c5SAndroid Build Coastguard Worker 
invalidateTexture(gl::TextureType type)532*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::invalidateTexture(gl::TextureType type)
533*8975f5c5SAndroid Build Coastguard Worker {
534*8975f5c5SAndroid Build Coastguard Worker     // Assume the tracked texture binding is incorrect, query the real bound texture from GL.
535*8975f5c5SAndroid Build Coastguard Worker     GLint boundTexture = 0;
536*8975f5c5SAndroid Build Coastguard Worker     mFunctions->getIntegerv(nativegl::GetTextureBindingQuery(type), &boundTexture);
537*8975f5c5SAndroid Build Coastguard Worker     mTextures[type][mTextureUnitIndex] = static_cast<GLuint>(boundTexture);
538*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_TEXTURE_BINDINGS);
539*8975f5c5SAndroid Build Coastguard Worker }
540*8975f5c5SAndroid Build Coastguard Worker 
bindSampler(size_t unit,GLuint sampler)541*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::bindSampler(size_t unit, GLuint sampler)
542*8975f5c5SAndroid Build Coastguard Worker {
543*8975f5c5SAndroid Build Coastguard Worker     if (mSamplers[unit] != sampler)
544*8975f5c5SAndroid Build Coastguard Worker     {
545*8975f5c5SAndroid Build Coastguard Worker         mSamplers[unit] = sampler;
546*8975f5c5SAndroid Build Coastguard Worker         mFunctions->bindSampler(static_cast<GLuint>(unit), sampler);
547*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SAMPLER_BINDINGS);
548*8975f5c5SAndroid Build Coastguard Worker     }
549*8975f5c5SAndroid Build Coastguard Worker }
550*8975f5c5SAndroid Build Coastguard Worker 
bindImageTexture(size_t unit,GLuint texture,GLint level,GLboolean layered,GLint layer,GLenum access,GLenum format)551*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::bindImageTexture(size_t unit,
552*8975f5c5SAndroid Build Coastguard Worker                                       GLuint texture,
553*8975f5c5SAndroid Build Coastguard Worker                                       GLint level,
554*8975f5c5SAndroid Build Coastguard Worker                                       GLboolean layered,
555*8975f5c5SAndroid Build Coastguard Worker                                       GLint layer,
556*8975f5c5SAndroid Build Coastguard Worker                                       GLenum access,
557*8975f5c5SAndroid Build Coastguard Worker                                       GLenum format)
558*8975f5c5SAndroid Build Coastguard Worker {
559*8975f5c5SAndroid Build Coastguard Worker     auto &binding = mImages[unit];
560*8975f5c5SAndroid Build Coastguard Worker     if (binding.texture != texture || binding.level != level || binding.layered != layered ||
561*8975f5c5SAndroid Build Coastguard Worker         binding.layer != layer || binding.access != access || binding.format != format)
562*8975f5c5SAndroid Build Coastguard Worker     {
563*8975f5c5SAndroid Build Coastguard Worker         binding.texture = texture;
564*8975f5c5SAndroid Build Coastguard Worker         binding.level   = level;
565*8975f5c5SAndroid Build Coastguard Worker         binding.layered = layered;
566*8975f5c5SAndroid Build Coastguard Worker         binding.layer   = layer;
567*8975f5c5SAndroid Build Coastguard Worker         binding.access  = access;
568*8975f5c5SAndroid Build Coastguard Worker         binding.format  = format;
569*8975f5c5SAndroid Build Coastguard Worker         mFunctions->bindImageTexture(angle::base::checked_cast<GLuint>(unit), texture, level,
570*8975f5c5SAndroid Build Coastguard Worker                                      layered, layer, access, format);
571*8975f5c5SAndroid Build Coastguard Worker     }
572*8975f5c5SAndroid Build Coastguard Worker }
573*8975f5c5SAndroid Build Coastguard Worker 
setPixelUnpackState(const gl::Context * context,const gl::PixelUnpackState & unpack)574*8975f5c5SAndroid Build Coastguard Worker angle::Result StateManagerGL::setPixelUnpackState(const gl::Context *context,
575*8975f5c5SAndroid Build Coastguard Worker                                                   const gl::PixelUnpackState &unpack)
576*8975f5c5SAndroid Build Coastguard Worker {
577*8975f5c5SAndroid Build Coastguard Worker     if (mUnpackAlignment != unpack.alignment)
578*8975f5c5SAndroid Build Coastguard Worker     {
579*8975f5c5SAndroid Build Coastguard Worker         mUnpackAlignment = unpack.alignment;
580*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_UNPACK_ALIGNMENT, mUnpackAlignment));
581*8975f5c5SAndroid Build Coastguard Worker 
582*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_UNPACK_STATE);
583*8975f5c5SAndroid Build Coastguard Worker     }
584*8975f5c5SAndroid Build Coastguard Worker 
585*8975f5c5SAndroid Build Coastguard Worker     if (mUnpackRowLength != unpack.rowLength)
586*8975f5c5SAndroid Build Coastguard Worker     {
587*8975f5c5SAndroid Build Coastguard Worker         mUnpackRowLength = unpack.rowLength;
588*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_UNPACK_ROW_LENGTH, mUnpackRowLength));
589*8975f5c5SAndroid Build Coastguard Worker 
590*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_UNPACK_STATE);
591*8975f5c5SAndroid Build Coastguard Worker     }
592*8975f5c5SAndroid Build Coastguard Worker 
593*8975f5c5SAndroid Build Coastguard Worker     if (mUnpackSkipRows != unpack.skipRows)
594*8975f5c5SAndroid Build Coastguard Worker     {
595*8975f5c5SAndroid Build Coastguard Worker         mUnpackSkipRows = unpack.skipRows;
596*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_UNPACK_SKIP_ROWS, mUnpackSkipRows));
597*8975f5c5SAndroid Build Coastguard Worker 
598*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_UNPACK_STATE);
599*8975f5c5SAndroid Build Coastguard Worker     }
600*8975f5c5SAndroid Build Coastguard Worker 
601*8975f5c5SAndroid Build Coastguard Worker     if (mUnpackSkipPixels != unpack.skipPixels)
602*8975f5c5SAndroid Build Coastguard Worker     {
603*8975f5c5SAndroid Build Coastguard Worker         mUnpackSkipPixels = unpack.skipPixels;
604*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_UNPACK_SKIP_PIXELS, mUnpackSkipPixels));
605*8975f5c5SAndroid Build Coastguard Worker 
606*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_UNPACK_STATE);
607*8975f5c5SAndroid Build Coastguard Worker     }
608*8975f5c5SAndroid Build Coastguard Worker 
609*8975f5c5SAndroid Build Coastguard Worker     if (mUnpackImageHeight != unpack.imageHeight)
610*8975f5c5SAndroid Build Coastguard Worker     {
611*8975f5c5SAndroid Build Coastguard Worker         mUnpackImageHeight = unpack.imageHeight;
612*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_UNPACK_IMAGE_HEIGHT, mUnpackImageHeight));
613*8975f5c5SAndroid Build Coastguard Worker 
614*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_UNPACK_STATE);
615*8975f5c5SAndroid Build Coastguard Worker     }
616*8975f5c5SAndroid Build Coastguard Worker 
617*8975f5c5SAndroid Build Coastguard Worker     if (mUnpackSkipImages != unpack.skipImages)
618*8975f5c5SAndroid Build Coastguard Worker     {
619*8975f5c5SAndroid Build Coastguard Worker         mUnpackSkipImages = unpack.skipImages;
620*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_UNPACK_SKIP_IMAGES, mUnpackSkipImages));
621*8975f5c5SAndroid Build Coastguard Worker 
622*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_UNPACK_STATE);
623*8975f5c5SAndroid Build Coastguard Worker     }
624*8975f5c5SAndroid Build Coastguard Worker 
625*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
626*8975f5c5SAndroid Build Coastguard Worker }
627*8975f5c5SAndroid Build Coastguard Worker 
setPixelUnpackBuffer(const gl::Context * context,const gl::Buffer * pixelBuffer)628*8975f5c5SAndroid Build Coastguard Worker angle::Result StateManagerGL::setPixelUnpackBuffer(const gl::Context *context,
629*8975f5c5SAndroid Build Coastguard Worker                                                    const gl::Buffer *pixelBuffer)
630*8975f5c5SAndroid Build Coastguard Worker {
631*8975f5c5SAndroid Build Coastguard Worker     GLuint bufferID = 0;
632*8975f5c5SAndroid Build Coastguard Worker     if (pixelBuffer != nullptr)
633*8975f5c5SAndroid Build Coastguard Worker     {
634*8975f5c5SAndroid Build Coastguard Worker         bufferID = GetImplAs<BufferGL>(pixelBuffer)->getBufferID();
635*8975f5c5SAndroid Build Coastguard Worker     }
636*8975f5c5SAndroid Build Coastguard Worker     bindBuffer(gl::BufferBinding::PixelUnpack, bufferID);
637*8975f5c5SAndroid Build Coastguard Worker 
638*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
639*8975f5c5SAndroid Build Coastguard Worker }
640*8975f5c5SAndroid Build Coastguard Worker 
setPixelPackState(const gl::Context * context,const gl::PixelPackState & pack)641*8975f5c5SAndroid Build Coastguard Worker angle::Result StateManagerGL::setPixelPackState(const gl::Context *context,
642*8975f5c5SAndroid Build Coastguard Worker                                                 const gl::PixelPackState &pack)
643*8975f5c5SAndroid Build Coastguard Worker {
644*8975f5c5SAndroid Build Coastguard Worker     if (mPackAlignment != pack.alignment)
645*8975f5c5SAndroid Build Coastguard Worker     {
646*8975f5c5SAndroid Build Coastguard Worker         mPackAlignment = pack.alignment;
647*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_PACK_ALIGNMENT, mPackAlignment));
648*8975f5c5SAndroid Build Coastguard Worker 
649*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_PACK_STATE);
650*8975f5c5SAndroid Build Coastguard Worker     }
651*8975f5c5SAndroid Build Coastguard Worker 
652*8975f5c5SAndroid Build Coastguard Worker     if (mPackRowLength != pack.rowLength)
653*8975f5c5SAndroid Build Coastguard Worker     {
654*8975f5c5SAndroid Build Coastguard Worker         mPackRowLength = pack.rowLength;
655*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_PACK_ROW_LENGTH, mPackRowLength));
656*8975f5c5SAndroid Build Coastguard Worker 
657*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_PACK_STATE);
658*8975f5c5SAndroid Build Coastguard Worker     }
659*8975f5c5SAndroid Build Coastguard Worker 
660*8975f5c5SAndroid Build Coastguard Worker     if (mPackSkipRows != pack.skipRows)
661*8975f5c5SAndroid Build Coastguard Worker     {
662*8975f5c5SAndroid Build Coastguard Worker         mPackSkipRows = pack.skipRows;
663*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_PACK_SKIP_ROWS, mPackSkipRows));
664*8975f5c5SAndroid Build Coastguard Worker 
665*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_PACK_STATE);
666*8975f5c5SAndroid Build Coastguard Worker     }
667*8975f5c5SAndroid Build Coastguard Worker 
668*8975f5c5SAndroid Build Coastguard Worker     if (mPackSkipPixels != pack.skipPixels)
669*8975f5c5SAndroid Build Coastguard Worker     {
670*8975f5c5SAndroid Build Coastguard Worker         mPackSkipPixels = pack.skipPixels;
671*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_TRY(context, mFunctions->pixelStorei(GL_PACK_SKIP_PIXELS, mPackSkipPixels));
672*8975f5c5SAndroid Build Coastguard Worker 
673*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_PACK_STATE);
674*8975f5c5SAndroid Build Coastguard Worker     }
675*8975f5c5SAndroid Build Coastguard Worker 
676*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
677*8975f5c5SAndroid Build Coastguard Worker }
678*8975f5c5SAndroid Build Coastguard Worker 
setPixelPackBuffer(const gl::Context * context,const gl::Buffer * pixelBuffer)679*8975f5c5SAndroid Build Coastguard Worker angle::Result StateManagerGL::setPixelPackBuffer(const gl::Context *context,
680*8975f5c5SAndroid Build Coastguard Worker                                                  const gl::Buffer *pixelBuffer)
681*8975f5c5SAndroid Build Coastguard Worker {
682*8975f5c5SAndroid Build Coastguard Worker     GLuint bufferID = 0;
683*8975f5c5SAndroid Build Coastguard Worker     if (pixelBuffer != nullptr)
684*8975f5c5SAndroid Build Coastguard Worker     {
685*8975f5c5SAndroid Build Coastguard Worker         bufferID = GetImplAs<BufferGL>(pixelBuffer)->getBufferID();
686*8975f5c5SAndroid Build Coastguard Worker     }
687*8975f5c5SAndroid Build Coastguard Worker     bindBuffer(gl::BufferBinding::PixelPack, bufferID);
688*8975f5c5SAndroid Build Coastguard Worker 
689*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
690*8975f5c5SAndroid Build Coastguard Worker }
691*8975f5c5SAndroid Build Coastguard Worker 
bindFramebuffer(GLenum type,GLuint framebuffer)692*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::bindFramebuffer(GLenum type, GLuint framebuffer)
693*8975f5c5SAndroid Build Coastguard Worker {
694*8975f5c5SAndroid Build Coastguard Worker     bool framebufferChanged = false;
695*8975f5c5SAndroid Build Coastguard Worker     switch (type)
696*8975f5c5SAndroid Build Coastguard Worker     {
697*8975f5c5SAndroid Build Coastguard Worker         case GL_FRAMEBUFFER:
698*8975f5c5SAndroid Build Coastguard Worker             if (mFramebuffers[angle::FramebufferBindingRead] != framebuffer ||
699*8975f5c5SAndroid Build Coastguard Worker                 mFramebuffers[angle::FramebufferBindingDraw] != framebuffer)
700*8975f5c5SAndroid Build Coastguard Worker             {
701*8975f5c5SAndroid Build Coastguard Worker                 mFramebuffers[angle::FramebufferBindingRead] = framebuffer;
702*8975f5c5SAndroid Build Coastguard Worker                 mFramebuffers[angle::FramebufferBindingDraw] = framebuffer;
703*8975f5c5SAndroid Build Coastguard Worker                 mFunctions->bindFramebuffer(GL_FRAMEBUFFER, framebuffer);
704*8975f5c5SAndroid Build Coastguard Worker 
705*8975f5c5SAndroid Build Coastguard Worker                 mLocalDirtyBits.set(gl::state::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
706*8975f5c5SAndroid Build Coastguard Worker                 mLocalDirtyBits.set(gl::state::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
707*8975f5c5SAndroid Build Coastguard Worker 
708*8975f5c5SAndroid Build Coastguard Worker                 framebufferChanged = true;
709*8975f5c5SAndroid Build Coastguard Worker             }
710*8975f5c5SAndroid Build Coastguard Worker             break;
711*8975f5c5SAndroid Build Coastguard Worker 
712*8975f5c5SAndroid Build Coastguard Worker         case GL_READ_FRAMEBUFFER:
713*8975f5c5SAndroid Build Coastguard Worker             ASSERT(mHasSeparateFramebufferBindings);
714*8975f5c5SAndroid Build Coastguard Worker             if (mFramebuffers[angle::FramebufferBindingRead] != framebuffer)
715*8975f5c5SAndroid Build Coastguard Worker             {
716*8975f5c5SAndroid Build Coastguard Worker                 mFramebuffers[angle::FramebufferBindingRead] = framebuffer;
717*8975f5c5SAndroid Build Coastguard Worker                 mFunctions->bindFramebuffer(GL_READ_FRAMEBUFFER, framebuffer);
718*8975f5c5SAndroid Build Coastguard Worker 
719*8975f5c5SAndroid Build Coastguard Worker                 mLocalDirtyBits.set(gl::state::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
720*8975f5c5SAndroid Build Coastguard Worker 
721*8975f5c5SAndroid Build Coastguard Worker                 framebufferChanged = true;
722*8975f5c5SAndroid Build Coastguard Worker             }
723*8975f5c5SAndroid Build Coastguard Worker             break;
724*8975f5c5SAndroid Build Coastguard Worker 
725*8975f5c5SAndroid Build Coastguard Worker         case GL_DRAW_FRAMEBUFFER:
726*8975f5c5SAndroid Build Coastguard Worker             ASSERT(mHasSeparateFramebufferBindings);
727*8975f5c5SAndroid Build Coastguard Worker             if (mFramebuffers[angle::FramebufferBindingDraw] != framebuffer)
728*8975f5c5SAndroid Build Coastguard Worker             {
729*8975f5c5SAndroid Build Coastguard Worker                 mFramebuffers[angle::FramebufferBindingDraw] = framebuffer;
730*8975f5c5SAndroid Build Coastguard Worker                 mFunctions->bindFramebuffer(GL_DRAW_FRAMEBUFFER, framebuffer);
731*8975f5c5SAndroid Build Coastguard Worker 
732*8975f5c5SAndroid Build Coastguard Worker                 mLocalDirtyBits.set(gl::state::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
733*8975f5c5SAndroid Build Coastguard Worker 
734*8975f5c5SAndroid Build Coastguard Worker                 framebufferChanged = true;
735*8975f5c5SAndroid Build Coastguard Worker             }
736*8975f5c5SAndroid Build Coastguard Worker             break;
737*8975f5c5SAndroid Build Coastguard Worker 
738*8975f5c5SAndroid Build Coastguard Worker         default:
739*8975f5c5SAndroid Build Coastguard Worker             UNREACHABLE();
740*8975f5c5SAndroid Build Coastguard Worker             break;
741*8975f5c5SAndroid Build Coastguard Worker     }
742*8975f5c5SAndroid Build Coastguard Worker 
743*8975f5c5SAndroid Build Coastguard Worker     if (framebufferChanged && mFeatures.flushOnFramebufferChange.enabled)
744*8975f5c5SAndroid Build Coastguard Worker     {
745*8975f5c5SAndroid Build Coastguard Worker         mFunctions->flush();
746*8975f5c5SAndroid Build Coastguard Worker     }
747*8975f5c5SAndroid Build Coastguard Worker }
748*8975f5c5SAndroid Build Coastguard Worker 
bindRenderbuffer(GLenum type,GLuint renderbuffer)749*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::bindRenderbuffer(GLenum type, GLuint renderbuffer)
750*8975f5c5SAndroid Build Coastguard Worker {
751*8975f5c5SAndroid Build Coastguard Worker     ASSERT(type == GL_RENDERBUFFER);
752*8975f5c5SAndroid Build Coastguard Worker     if (mRenderbuffer != renderbuffer)
753*8975f5c5SAndroid Build Coastguard Worker     {
754*8975f5c5SAndroid Build Coastguard Worker         mRenderbuffer = renderbuffer;
755*8975f5c5SAndroid Build Coastguard Worker         mFunctions->bindRenderbuffer(type, mRenderbuffer);
756*8975f5c5SAndroid Build Coastguard Worker     }
757*8975f5c5SAndroid Build Coastguard Worker }
758*8975f5c5SAndroid Build Coastguard Worker 
bindTransformFeedback(GLenum type,GLuint transformFeedback)759*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::bindTransformFeedback(GLenum type, GLuint transformFeedback)
760*8975f5c5SAndroid Build Coastguard Worker {
761*8975f5c5SAndroid Build Coastguard Worker     ASSERT(type == GL_TRANSFORM_FEEDBACK);
762*8975f5c5SAndroid Build Coastguard Worker     if (mTransformFeedback != transformFeedback)
763*8975f5c5SAndroid Build Coastguard Worker     {
764*8975f5c5SAndroid Build Coastguard Worker         // Pause the current transform feedback if one is active.
765*8975f5c5SAndroid Build Coastguard Worker         // To handle virtualized contexts, StateManagerGL needs to be able to bind a new transform
766*8975f5c5SAndroid Build Coastguard Worker         // feedback at any time, even if there is one active.
767*8975f5c5SAndroid Build Coastguard Worker         if (mCurrentTransformFeedback != nullptr &&
768*8975f5c5SAndroid Build Coastguard Worker             mCurrentTransformFeedback->getTransformFeedbackID() != transformFeedback)
769*8975f5c5SAndroid Build Coastguard Worker         {
770*8975f5c5SAndroid Build Coastguard Worker             mCurrentTransformFeedback->syncPausedState(true);
771*8975f5c5SAndroid Build Coastguard Worker             mCurrentTransformFeedback = nullptr;
772*8975f5c5SAndroid Build Coastguard Worker         }
773*8975f5c5SAndroid Build Coastguard Worker 
774*8975f5c5SAndroid Build Coastguard Worker         mTransformFeedback = transformFeedback;
775*8975f5c5SAndroid Build Coastguard Worker         mFunctions->bindTransformFeedback(type, mTransformFeedback);
776*8975f5c5SAndroid Build Coastguard Worker         onTransformFeedbackStateChange();
777*8975f5c5SAndroid Build Coastguard Worker     }
778*8975f5c5SAndroid Build Coastguard Worker }
779*8975f5c5SAndroid Build Coastguard Worker 
onTransformFeedbackStateChange()780*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::onTransformFeedbackStateChange()
781*8975f5c5SAndroid Build Coastguard Worker {
782*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING);
783*8975f5c5SAndroid Build Coastguard Worker }
784*8975f5c5SAndroid Build Coastguard Worker 
beginQuery(gl::QueryType type,QueryGL * queryObject,GLuint queryId)785*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::beginQuery(gl::QueryType type, QueryGL *queryObject, GLuint queryId)
786*8975f5c5SAndroid Build Coastguard Worker {
787*8975f5c5SAndroid Build Coastguard Worker     // Make sure this is a valid query type and there is no current active query of this type
788*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mQueries[type] == nullptr);
789*8975f5c5SAndroid Build Coastguard Worker     ASSERT(queryId != 0);
790*8975f5c5SAndroid Build Coastguard Worker 
791*8975f5c5SAndroid Build Coastguard Worker     GLuint oldFramebufferBindingDraw = mFramebuffers[angle::FramebufferBindingDraw];
792*8975f5c5SAndroid Build Coastguard Worker     if (mFeatures.bindCompleteFramebufferForTimerQueries.enabled &&
793*8975f5c5SAndroid Build Coastguard Worker         (mFramebuffers[angle::FramebufferBindingDraw] == 0 ||
794*8975f5c5SAndroid Build Coastguard Worker          mFunctions->checkFramebufferStatus(GL_DRAW_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) &&
795*8975f5c5SAndroid Build Coastguard Worker         (type == gl::QueryType::TimeElapsed || type == gl::QueryType::Timestamp))
796*8975f5c5SAndroid Build Coastguard Worker     {
797*8975f5c5SAndroid Build Coastguard Worker         if (!mPlaceholderFbo)
798*8975f5c5SAndroid Build Coastguard Worker         {
799*8975f5c5SAndroid Build Coastguard Worker             mFunctions->genFramebuffers(1, &mPlaceholderFbo);
800*8975f5c5SAndroid Build Coastguard Worker         }
801*8975f5c5SAndroid Build Coastguard Worker         bindFramebuffer(GL_DRAW_FRAMEBUFFER, mPlaceholderFbo);
802*8975f5c5SAndroid Build Coastguard Worker 
803*8975f5c5SAndroid Build Coastguard Worker         if (!mPlaceholderRbo)
804*8975f5c5SAndroid Build Coastguard Worker         {
805*8975f5c5SAndroid Build Coastguard Worker             GLuint oldRenderBufferBinding = mRenderbuffer;
806*8975f5c5SAndroid Build Coastguard Worker             mFunctions->genRenderbuffers(1, &mPlaceholderRbo);
807*8975f5c5SAndroid Build Coastguard Worker             bindRenderbuffer(GL_RENDERBUFFER, mPlaceholderRbo);
808*8975f5c5SAndroid Build Coastguard Worker             mFunctions->renderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, 2, 2);
809*8975f5c5SAndroid Build Coastguard Worker             mFunctions->framebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
810*8975f5c5SAndroid Build Coastguard Worker                                                 GL_RENDERBUFFER, mPlaceholderRbo);
811*8975f5c5SAndroid Build Coastguard Worker             bindRenderbuffer(GL_RENDERBUFFER, oldRenderBufferBinding);
812*8975f5c5SAndroid Build Coastguard Worker 
813*8975f5c5SAndroid Build Coastguard Worker             // This ensures renderbuffer attachment is not lazy.
814*8975f5c5SAndroid Build Coastguard Worker             mFunctions->checkFramebufferStatus(GL_DRAW_FRAMEBUFFER);
815*8975f5c5SAndroid Build Coastguard Worker         }
816*8975f5c5SAndroid Build Coastguard Worker     }
817*8975f5c5SAndroid Build Coastguard Worker 
818*8975f5c5SAndroid Build Coastguard Worker     mQueries[type] = queryObject;
819*8975f5c5SAndroid Build Coastguard Worker     mFunctions->beginQuery(ToGLenum(type), queryId);
820*8975f5c5SAndroid Build Coastguard Worker 
821*8975f5c5SAndroid Build Coastguard Worker     if (oldFramebufferBindingDraw != mPlaceholderFbo)
822*8975f5c5SAndroid Build Coastguard Worker     {
823*8975f5c5SAndroid Build Coastguard Worker         bindFramebuffer(GL_DRAW_FRAMEBUFFER, oldFramebufferBindingDraw);
824*8975f5c5SAndroid Build Coastguard Worker     }
825*8975f5c5SAndroid Build Coastguard Worker }
826*8975f5c5SAndroid Build Coastguard Worker 
endQuery(gl::QueryType type,QueryGL * queryObject,GLuint queryId)827*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::endQuery(gl::QueryType type, QueryGL *queryObject, GLuint queryId)
828*8975f5c5SAndroid Build Coastguard Worker {
829*8975f5c5SAndroid Build Coastguard Worker     ASSERT(queryObject != nullptr);
830*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mQueries[type] == queryObject);
831*8975f5c5SAndroid Build Coastguard Worker     mQueries[type] = nullptr;
832*8975f5c5SAndroid Build Coastguard Worker     mFunctions->endQuery(ToGLenum(type));
833*8975f5c5SAndroid Build Coastguard Worker }
834*8975f5c5SAndroid Build Coastguard Worker 
updateDrawIndirectBufferBinding(const gl::Context * context)835*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::updateDrawIndirectBufferBinding(const gl::Context *context)
836*8975f5c5SAndroid Build Coastguard Worker {
837*8975f5c5SAndroid Build Coastguard Worker     gl::Buffer *drawIndirectBuffer =
838*8975f5c5SAndroid Build Coastguard Worker         context->getState().getTargetBuffer(gl::BufferBinding::DrawIndirect);
839*8975f5c5SAndroid Build Coastguard Worker     if (drawIndirectBuffer != nullptr)
840*8975f5c5SAndroid Build Coastguard Worker     {
841*8975f5c5SAndroid Build Coastguard Worker         const BufferGL *bufferGL = GetImplAs<BufferGL>(drawIndirectBuffer);
842*8975f5c5SAndroid Build Coastguard Worker         bindBuffer(gl::BufferBinding::DrawIndirect, bufferGL->getBufferID());
843*8975f5c5SAndroid Build Coastguard Worker     }
844*8975f5c5SAndroid Build Coastguard Worker }
845*8975f5c5SAndroid Build Coastguard Worker 
updateDispatchIndirectBufferBinding(const gl::Context * context)846*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::updateDispatchIndirectBufferBinding(const gl::Context *context)
847*8975f5c5SAndroid Build Coastguard Worker {
848*8975f5c5SAndroid Build Coastguard Worker     gl::Buffer *dispatchIndirectBuffer =
849*8975f5c5SAndroid Build Coastguard Worker         context->getState().getTargetBuffer(gl::BufferBinding::DispatchIndirect);
850*8975f5c5SAndroid Build Coastguard Worker     if (dispatchIndirectBuffer != nullptr)
851*8975f5c5SAndroid Build Coastguard Worker     {
852*8975f5c5SAndroid Build Coastguard Worker         const BufferGL *bufferGL = GetImplAs<BufferGL>(dispatchIndirectBuffer);
853*8975f5c5SAndroid Build Coastguard Worker         bindBuffer(gl::BufferBinding::DispatchIndirect, bufferGL->getBufferID());
854*8975f5c5SAndroid Build Coastguard Worker     }
855*8975f5c5SAndroid Build Coastguard Worker }
856*8975f5c5SAndroid Build Coastguard Worker 
pauseTransformFeedback()857*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::pauseTransformFeedback()
858*8975f5c5SAndroid Build Coastguard Worker {
859*8975f5c5SAndroid Build Coastguard Worker     if (mCurrentTransformFeedback != nullptr)
860*8975f5c5SAndroid Build Coastguard Worker     {
861*8975f5c5SAndroid Build Coastguard Worker         mCurrentTransformFeedback->syncPausedState(true);
862*8975f5c5SAndroid Build Coastguard Worker         onTransformFeedbackStateChange();
863*8975f5c5SAndroid Build Coastguard Worker     }
864*8975f5c5SAndroid Build Coastguard Worker }
865*8975f5c5SAndroid Build Coastguard Worker 
pauseAllQueries(const gl::Context * context)866*8975f5c5SAndroid Build Coastguard Worker angle::Result StateManagerGL::pauseAllQueries(const gl::Context *context)
867*8975f5c5SAndroid Build Coastguard Worker {
868*8975f5c5SAndroid Build Coastguard Worker     for (gl::QueryType type : angle::AllEnums<gl::QueryType>())
869*8975f5c5SAndroid Build Coastguard Worker     {
870*8975f5c5SAndroid Build Coastguard Worker         QueryGL *previousQuery = mQueries[type];
871*8975f5c5SAndroid Build Coastguard Worker 
872*8975f5c5SAndroid Build Coastguard Worker         if (previousQuery != nullptr)
873*8975f5c5SAndroid Build Coastguard Worker         {
874*8975f5c5SAndroid Build Coastguard Worker             ANGLE_TRY(previousQuery->pause(context));
875*8975f5c5SAndroid Build Coastguard Worker             mTemporaryPausedQueries[type] = previousQuery;
876*8975f5c5SAndroid Build Coastguard Worker             mQueries[type]                = nullptr;
877*8975f5c5SAndroid Build Coastguard Worker         }
878*8975f5c5SAndroid Build Coastguard Worker     }
879*8975f5c5SAndroid Build Coastguard Worker 
880*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
881*8975f5c5SAndroid Build Coastguard Worker }
882*8975f5c5SAndroid Build Coastguard Worker 
pauseQuery(const gl::Context * context,gl::QueryType type)883*8975f5c5SAndroid Build Coastguard Worker angle::Result StateManagerGL::pauseQuery(const gl::Context *context, gl::QueryType type)
884*8975f5c5SAndroid Build Coastguard Worker {
885*8975f5c5SAndroid Build Coastguard Worker     QueryGL *previousQuery = mQueries[type];
886*8975f5c5SAndroid Build Coastguard Worker 
887*8975f5c5SAndroid Build Coastguard Worker     if (previousQuery)
888*8975f5c5SAndroid Build Coastguard Worker     {
889*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(previousQuery->pause(context));
890*8975f5c5SAndroid Build Coastguard Worker         mTemporaryPausedQueries[type] = previousQuery;
891*8975f5c5SAndroid Build Coastguard Worker         mQueries[type]                = nullptr;
892*8975f5c5SAndroid Build Coastguard Worker     }
893*8975f5c5SAndroid Build Coastguard Worker 
894*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
895*8975f5c5SAndroid Build Coastguard Worker }
896*8975f5c5SAndroid Build Coastguard Worker 
resumeAllQueries(const gl::Context * context)897*8975f5c5SAndroid Build Coastguard Worker angle::Result StateManagerGL::resumeAllQueries(const gl::Context *context)
898*8975f5c5SAndroid Build Coastguard Worker {
899*8975f5c5SAndroid Build Coastguard Worker     for (gl::QueryType type : angle::AllEnums<gl::QueryType>())
900*8975f5c5SAndroid Build Coastguard Worker     {
901*8975f5c5SAndroid Build Coastguard Worker         QueryGL *pausedQuery = mTemporaryPausedQueries[type];
902*8975f5c5SAndroid Build Coastguard Worker 
903*8975f5c5SAndroid Build Coastguard Worker         if (pausedQuery != nullptr)
904*8975f5c5SAndroid Build Coastguard Worker         {
905*8975f5c5SAndroid Build Coastguard Worker             ASSERT(mQueries[type] == nullptr);
906*8975f5c5SAndroid Build Coastguard Worker             ANGLE_TRY(pausedQuery->resume(context));
907*8975f5c5SAndroid Build Coastguard Worker             mTemporaryPausedQueries[type] = nullptr;
908*8975f5c5SAndroid Build Coastguard Worker         }
909*8975f5c5SAndroid Build Coastguard Worker     }
910*8975f5c5SAndroid Build Coastguard Worker 
911*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
912*8975f5c5SAndroid Build Coastguard Worker }
913*8975f5c5SAndroid Build Coastguard Worker 
resumeQuery(const gl::Context * context,gl::QueryType type)914*8975f5c5SAndroid Build Coastguard Worker angle::Result StateManagerGL::resumeQuery(const gl::Context *context, gl::QueryType type)
915*8975f5c5SAndroid Build Coastguard Worker {
916*8975f5c5SAndroid Build Coastguard Worker     QueryGL *pausedQuery = mTemporaryPausedQueries[type];
917*8975f5c5SAndroid Build Coastguard Worker 
918*8975f5c5SAndroid Build Coastguard Worker     if (pausedQuery != nullptr)
919*8975f5c5SAndroid Build Coastguard Worker     {
920*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(pausedQuery->resume(context));
921*8975f5c5SAndroid Build Coastguard Worker         mTemporaryPausedQueries[type] = nullptr;
922*8975f5c5SAndroid Build Coastguard Worker     }
923*8975f5c5SAndroid Build Coastguard Worker 
924*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
925*8975f5c5SAndroid Build Coastguard Worker }
926*8975f5c5SAndroid Build Coastguard Worker 
onMakeCurrent(const gl::Context * context)927*8975f5c5SAndroid Build Coastguard Worker angle::Result StateManagerGL::onMakeCurrent(const gl::Context *context)
928*8975f5c5SAndroid Build Coastguard Worker {
929*8975f5c5SAndroid Build Coastguard Worker     const gl::State &glState = context->getState();
930*8975f5c5SAndroid Build Coastguard Worker 
931*8975f5c5SAndroid Build Coastguard Worker #if defined(ANGLE_ENABLE_ASSERTS)
932*8975f5c5SAndroid Build Coastguard Worker     // Temporarily pausing queries during context switch is not supported
933*8975f5c5SAndroid Build Coastguard Worker     for (QueryGL *pausedQuery : mTemporaryPausedQueries)
934*8975f5c5SAndroid Build Coastguard Worker     {
935*8975f5c5SAndroid Build Coastguard Worker         ASSERT(pausedQuery == nullptr);
936*8975f5c5SAndroid Build Coastguard Worker     }
937*8975f5c5SAndroid Build Coastguard Worker #endif
938*8975f5c5SAndroid Build Coastguard Worker 
939*8975f5c5SAndroid Build Coastguard Worker     // If the context has changed, pause the previous context's queries
940*8975f5c5SAndroid Build Coastguard Worker     auto contextID = context->getState().getContextID();
941*8975f5c5SAndroid Build Coastguard Worker     if (contextID != mPrevDrawContext)
942*8975f5c5SAndroid Build Coastguard Worker     {
943*8975f5c5SAndroid Build Coastguard Worker         for (gl::QueryType type : angle::AllEnums<gl::QueryType>())
944*8975f5c5SAndroid Build Coastguard Worker         {
945*8975f5c5SAndroid Build Coastguard Worker             QueryGL *currentQuery = mQueries[type];
946*8975f5c5SAndroid Build Coastguard Worker             // Pause any old query object
947*8975f5c5SAndroid Build Coastguard Worker             if (currentQuery != nullptr)
948*8975f5c5SAndroid Build Coastguard Worker             {
949*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_TRY(currentQuery->pause(context));
950*8975f5c5SAndroid Build Coastguard Worker                 mQueries[type] = nullptr;
951*8975f5c5SAndroid Build Coastguard Worker             }
952*8975f5c5SAndroid Build Coastguard Worker 
953*8975f5c5SAndroid Build Coastguard Worker             // Check if this new context needs to resume a query
954*8975f5c5SAndroid Build Coastguard Worker             gl::Query *newQuery = glState.getActiveQuery(type);
955*8975f5c5SAndroid Build Coastguard Worker             if (newQuery != nullptr)
956*8975f5c5SAndroid Build Coastguard Worker             {
957*8975f5c5SAndroid Build Coastguard Worker                 QueryGL *queryGL = GetImplAs<QueryGL>(newQuery);
958*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_TRY(queryGL->resume(context));
959*8975f5c5SAndroid Build Coastguard Worker             }
960*8975f5c5SAndroid Build Coastguard Worker         }
961*8975f5c5SAndroid Build Coastguard Worker     }
962*8975f5c5SAndroid Build Coastguard Worker     onTransformFeedbackStateChange();
963*8975f5c5SAndroid Build Coastguard Worker     mPrevDrawContext = contextID;
964*8975f5c5SAndroid Build Coastguard Worker 
965*8975f5c5SAndroid Build Coastguard Worker     // Seamless cubemaps are required for ES3 and higher contexts. It should be the cheapest to set
966*8975f5c5SAndroid Build Coastguard Worker     // this state here since MakeCurrent is expected to be called less frequently than draw calls.
967*8975f5c5SAndroid Build Coastguard Worker     setTextureCubemapSeamlessEnabled(context->getClientMajorVersion() >= 3);
968*8975f5c5SAndroid Build Coastguard Worker 
969*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
970*8975f5c5SAndroid Build Coastguard Worker }
971*8975f5c5SAndroid Build Coastguard Worker 
updateProgramTextureBindings(const gl::Context * context)972*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::updateProgramTextureBindings(const gl::Context *context)
973*8975f5c5SAndroid Build Coastguard Worker {
974*8975f5c5SAndroid Build Coastguard Worker     const gl::State &glState                = context->getState();
975*8975f5c5SAndroid Build Coastguard Worker     const gl::ProgramExecutable *executable = glState.getProgramExecutable();
976*8975f5c5SAndroid Build Coastguard Worker 
977*8975f5c5SAndroid Build Coastguard Worker     // It is possible there is no active program during a path operation.
978*8975f5c5SAndroid Build Coastguard Worker     if (!executable)
979*8975f5c5SAndroid Build Coastguard Worker         return;
980*8975f5c5SAndroid Build Coastguard Worker 
981*8975f5c5SAndroid Build Coastguard Worker     const gl::ActiveTexturesCache &textures        = glState.getActiveTexturesCache();
982*8975f5c5SAndroid Build Coastguard Worker     const gl::ActiveTextureMask &activeTextures    = executable->getActiveSamplersMask();
983*8975f5c5SAndroid Build Coastguard Worker     const gl::ActiveTextureTypeArray &textureTypes = executable->getActiveSamplerTypes();
984*8975f5c5SAndroid Build Coastguard Worker 
985*8975f5c5SAndroid Build Coastguard Worker     for (size_t textureUnitIndex : activeTextures)
986*8975f5c5SAndroid Build Coastguard Worker     {
987*8975f5c5SAndroid Build Coastguard Worker         gl::TextureType textureType = textureTypes[textureUnitIndex];
988*8975f5c5SAndroid Build Coastguard Worker         gl::Texture *texture        = textures[textureUnitIndex];
989*8975f5c5SAndroid Build Coastguard Worker 
990*8975f5c5SAndroid Build Coastguard Worker         // A nullptr texture indicates incomplete.
991*8975f5c5SAndroid Build Coastguard Worker         if (texture != nullptr)
992*8975f5c5SAndroid Build Coastguard Worker         {
993*8975f5c5SAndroid Build Coastguard Worker             const TextureGL *textureGL = GetImplAs<TextureGL>(texture);
994*8975f5c5SAndroid Build Coastguard Worker             // The DIRTY_BIT_BOUND_AS_ATTACHMENT may get inserted when texture is attached to
995*8975f5c5SAndroid Build Coastguard Worker             // FBO and if texture is already bound, Texture::syncState will not get called and dirty
996*8975f5c5SAndroid Build Coastguard Worker             // bit not gets cleared. But this bit is not used by GL backend at all, so it is
997*8975f5c5SAndroid Build Coastguard Worker             // harmless even though we expect texture is clean when reaching here. The bit will
998*8975f5c5SAndroid Build Coastguard Worker             // still get cleared next time syncState been called.
999*8975f5c5SAndroid Build Coastguard Worker             ASSERT(!texture->hasAnyDirtyBitExcludingBoundAsAttachmentBit());
1000*8975f5c5SAndroid Build Coastguard Worker             ASSERT(!textureGL->hasAnyDirtyBit());
1001*8975f5c5SAndroid Build Coastguard Worker 
1002*8975f5c5SAndroid Build Coastguard Worker             activeTexture(textureUnitIndex);
1003*8975f5c5SAndroid Build Coastguard Worker             bindTexture(textureType, textureGL->getTextureID());
1004*8975f5c5SAndroid Build Coastguard Worker         }
1005*8975f5c5SAndroid Build Coastguard Worker         else
1006*8975f5c5SAndroid Build Coastguard Worker         {
1007*8975f5c5SAndroid Build Coastguard Worker             activeTexture(textureUnitIndex);
1008*8975f5c5SAndroid Build Coastguard Worker             bindTexture(textureType, 0);
1009*8975f5c5SAndroid Build Coastguard Worker         }
1010*8975f5c5SAndroid Build Coastguard Worker     }
1011*8975f5c5SAndroid Build Coastguard Worker }
1012*8975f5c5SAndroid Build Coastguard Worker 
updateProgramStorageBufferBindings(const gl::Context * context)1013*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::updateProgramStorageBufferBindings(const gl::Context *context)
1014*8975f5c5SAndroid Build Coastguard Worker {
1015*8975f5c5SAndroid Build Coastguard Worker     const gl::State &glState                = context->getState();
1016*8975f5c5SAndroid Build Coastguard Worker     const gl::ProgramExecutable *executable = glState.getProgramExecutable();
1017*8975f5c5SAndroid Build Coastguard Worker 
1018*8975f5c5SAndroid Build Coastguard Worker     for (size_t blockIndex = 0; blockIndex < executable->getShaderStorageBlocks().size();
1019*8975f5c5SAndroid Build Coastguard Worker          blockIndex++)
1020*8975f5c5SAndroid Build Coastguard Worker     {
1021*8975f5c5SAndroid Build Coastguard Worker         GLuint binding = executable->getShaderStorageBlockBinding(static_cast<GLuint>(blockIndex));
1022*8975f5c5SAndroid Build Coastguard Worker         const auto &shaderStorageBuffer = glState.getIndexedShaderStorageBuffer(binding);
1023*8975f5c5SAndroid Build Coastguard Worker 
1024*8975f5c5SAndroid Build Coastguard Worker         if (shaderStorageBuffer.get() != nullptr)
1025*8975f5c5SAndroid Build Coastguard Worker         {
1026*8975f5c5SAndroid Build Coastguard Worker             BufferGL *bufferGL = GetImplAs<BufferGL>(shaderStorageBuffer.get());
1027*8975f5c5SAndroid Build Coastguard Worker 
1028*8975f5c5SAndroid Build Coastguard Worker             if (shaderStorageBuffer.getSize() == 0)
1029*8975f5c5SAndroid Build Coastguard Worker             {
1030*8975f5c5SAndroid Build Coastguard Worker                 bindBufferBase(gl::BufferBinding::ShaderStorage, binding, bufferGL->getBufferID());
1031*8975f5c5SAndroid Build Coastguard Worker             }
1032*8975f5c5SAndroid Build Coastguard Worker             else
1033*8975f5c5SAndroid Build Coastguard Worker             {
1034*8975f5c5SAndroid Build Coastguard Worker                 bindBufferRange(gl::BufferBinding::ShaderStorage, binding, bufferGL->getBufferID(),
1035*8975f5c5SAndroid Build Coastguard Worker                                 shaderStorageBuffer.getOffset(), shaderStorageBuffer.getSize());
1036*8975f5c5SAndroid Build Coastguard Worker             }
1037*8975f5c5SAndroid Build Coastguard Worker         }
1038*8975f5c5SAndroid Build Coastguard Worker     }
1039*8975f5c5SAndroid Build Coastguard Worker }
1040*8975f5c5SAndroid Build Coastguard Worker 
updateProgramUniformBufferBindings(const gl::Context * context)1041*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::updateProgramUniformBufferBindings(const gl::Context *context)
1042*8975f5c5SAndroid Build Coastguard Worker {
1043*8975f5c5SAndroid Build Coastguard Worker     // Sync the current program executable state
1044*8975f5c5SAndroid Build Coastguard Worker     const gl::State &glState                = context->getState();
1045*8975f5c5SAndroid Build Coastguard Worker     const gl::ProgramExecutable *executable = glState.getProgramExecutable();
1046*8975f5c5SAndroid Build Coastguard Worker     ProgramExecutableGL *executableGL       = GetImplAs<ProgramExecutableGL>(executable);
1047*8975f5c5SAndroid Build Coastguard Worker 
1048*8975f5c5SAndroid Build Coastguard Worker     // If any calls to glUniformBlockBinding have been made, make them effective.  Note that if PPOs
1049*8975f5c5SAndroid Build Coastguard Worker     // are ever supported in this backend, this needs to look at the Program's attached to PPOs
1050*8975f5c5SAndroid Build Coastguard Worker     // instead of the PPOs own executable.  This is because glUniformBlockBinding operates on
1051*8975f5c5SAndroid Build Coastguard Worker     // programs directly.
1052*8975f5c5SAndroid Build Coastguard Worker     executableGL->syncUniformBlockBindings();
1053*8975f5c5SAndroid Build Coastguard Worker 
1054*8975f5c5SAndroid Build Coastguard Worker     for (size_t uniformBlockIndex = 0; uniformBlockIndex < executable->getUniformBlocks().size();
1055*8975f5c5SAndroid Build Coastguard Worker          uniformBlockIndex++)
1056*8975f5c5SAndroid Build Coastguard Worker     {
1057*8975f5c5SAndroid Build Coastguard Worker         GLuint binding = executable->getUniformBlockBinding(static_cast<GLuint>(uniformBlockIndex));
1058*8975f5c5SAndroid Build Coastguard Worker         const auto &uniformBuffer = glState.getIndexedUniformBuffer(binding);
1059*8975f5c5SAndroid Build Coastguard Worker 
1060*8975f5c5SAndroid Build Coastguard Worker         if (uniformBuffer.get() != nullptr)
1061*8975f5c5SAndroid Build Coastguard Worker         {
1062*8975f5c5SAndroid Build Coastguard Worker             BufferGL *bufferGL = GetImplAs<BufferGL>(uniformBuffer.get());
1063*8975f5c5SAndroid Build Coastguard Worker 
1064*8975f5c5SAndroid Build Coastguard Worker             if (uniformBuffer.getSize() == 0)
1065*8975f5c5SAndroid Build Coastguard Worker             {
1066*8975f5c5SAndroid Build Coastguard Worker                 bindBufferBase(gl::BufferBinding::Uniform, binding, bufferGL->getBufferID());
1067*8975f5c5SAndroid Build Coastguard Worker             }
1068*8975f5c5SAndroid Build Coastguard Worker             else
1069*8975f5c5SAndroid Build Coastguard Worker             {
1070*8975f5c5SAndroid Build Coastguard Worker                 bindBufferRange(gl::BufferBinding::Uniform, binding, bufferGL->getBufferID(),
1071*8975f5c5SAndroid Build Coastguard Worker                                 uniformBuffer.getOffset(), uniformBuffer.getSize());
1072*8975f5c5SAndroid Build Coastguard Worker             }
1073*8975f5c5SAndroid Build Coastguard Worker         }
1074*8975f5c5SAndroid Build Coastguard Worker     }
1075*8975f5c5SAndroid Build Coastguard Worker }
1076*8975f5c5SAndroid Build Coastguard Worker 
updateProgramAtomicCounterBufferBindings(const gl::Context * context)1077*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::updateProgramAtomicCounterBufferBindings(const gl::Context *context)
1078*8975f5c5SAndroid Build Coastguard Worker {
1079*8975f5c5SAndroid Build Coastguard Worker     const gl::State &glState                = context->getState();
1080*8975f5c5SAndroid Build Coastguard Worker     const gl::ProgramExecutable *executable = glState.getProgramExecutable();
1081*8975f5c5SAndroid Build Coastguard Worker 
1082*8975f5c5SAndroid Build Coastguard Worker     const std::vector<gl::AtomicCounterBuffer> &atomicCounterBuffers =
1083*8975f5c5SAndroid Build Coastguard Worker         executable->getAtomicCounterBuffers();
1084*8975f5c5SAndroid Build Coastguard Worker     for (size_t index = 0; index < atomicCounterBuffers.size(); ++index)
1085*8975f5c5SAndroid Build Coastguard Worker     {
1086*8975f5c5SAndroid Build Coastguard Worker         const GLuint binding = executable->getAtomicCounterBufferBinding(index);
1087*8975f5c5SAndroid Build Coastguard Worker         const auto &buffer   = glState.getIndexedAtomicCounterBuffer(binding);
1088*8975f5c5SAndroid Build Coastguard Worker 
1089*8975f5c5SAndroid Build Coastguard Worker         if (buffer.get() != nullptr)
1090*8975f5c5SAndroid Build Coastguard Worker         {
1091*8975f5c5SAndroid Build Coastguard Worker             BufferGL *bufferGL = GetImplAs<BufferGL>(buffer.get());
1092*8975f5c5SAndroid Build Coastguard Worker 
1093*8975f5c5SAndroid Build Coastguard Worker             if (buffer.getSize() == 0)
1094*8975f5c5SAndroid Build Coastguard Worker             {
1095*8975f5c5SAndroid Build Coastguard Worker                 bindBufferBase(gl::BufferBinding::AtomicCounter, binding, bufferGL->getBufferID());
1096*8975f5c5SAndroid Build Coastguard Worker             }
1097*8975f5c5SAndroid Build Coastguard Worker             else
1098*8975f5c5SAndroid Build Coastguard Worker             {
1099*8975f5c5SAndroid Build Coastguard Worker                 bindBufferRange(gl::BufferBinding::AtomicCounter, binding, bufferGL->getBufferID(),
1100*8975f5c5SAndroid Build Coastguard Worker                                 buffer.getOffset(), buffer.getSize());
1101*8975f5c5SAndroid Build Coastguard Worker             }
1102*8975f5c5SAndroid Build Coastguard Worker         }
1103*8975f5c5SAndroid Build Coastguard Worker     }
1104*8975f5c5SAndroid Build Coastguard Worker }
1105*8975f5c5SAndroid Build Coastguard Worker 
updateProgramImageBindings(const gl::Context * context)1106*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::updateProgramImageBindings(const gl::Context *context)
1107*8975f5c5SAndroid Build Coastguard Worker {
1108*8975f5c5SAndroid Build Coastguard Worker     const gl::State &glState                = context->getState();
1109*8975f5c5SAndroid Build Coastguard Worker     const gl::ProgramExecutable *executable = glState.getProgramExecutable();
1110*8975f5c5SAndroid Build Coastguard Worker 
1111*8975f5c5SAndroid Build Coastguard Worker     // It is possible there is no active program during a path operation.
1112*8975f5c5SAndroid Build Coastguard Worker     if (!executable)
1113*8975f5c5SAndroid Build Coastguard Worker         return;
1114*8975f5c5SAndroid Build Coastguard Worker 
1115*8975f5c5SAndroid Build Coastguard Worker     ASSERT(context->getClientVersion() >= gl::ES_3_1 ||
1116*8975f5c5SAndroid Build Coastguard Worker            context->getExtensions().shaderPixelLocalStorageANGLE ||
1117*8975f5c5SAndroid Build Coastguard Worker            executable->getImageBindings().empty());
1118*8975f5c5SAndroid Build Coastguard Worker     for (size_t imageUnitIndex : executable->getActiveImagesMask())
1119*8975f5c5SAndroid Build Coastguard Worker     {
1120*8975f5c5SAndroid Build Coastguard Worker         const gl::ImageUnit &imageUnit = glState.getImageUnit(imageUnitIndex);
1121*8975f5c5SAndroid Build Coastguard Worker         const TextureGL *textureGL     = SafeGetImplAs<TextureGL>(imageUnit.texture.get());
1122*8975f5c5SAndroid Build Coastguard Worker         if (textureGL)
1123*8975f5c5SAndroid Build Coastguard Worker         {
1124*8975f5c5SAndroid Build Coastguard Worker             // Do not set layer parameters for non-layered texture types to avoid driver bugs.
1125*8975f5c5SAndroid Build Coastguard Worker             const bool layered = IsLayeredTextureType(textureGL->getType());
1126*8975f5c5SAndroid Build Coastguard Worker             bindImageTexture(imageUnitIndex, textureGL->getTextureID(), imageUnit.level,
1127*8975f5c5SAndroid Build Coastguard Worker                              layered && imageUnit.layered, layered ? imageUnit.layer : 0,
1128*8975f5c5SAndroid Build Coastguard Worker                              imageUnit.access, imageUnit.format);
1129*8975f5c5SAndroid Build Coastguard Worker         }
1130*8975f5c5SAndroid Build Coastguard Worker         else
1131*8975f5c5SAndroid Build Coastguard Worker         {
1132*8975f5c5SAndroid Build Coastguard Worker             bindImageTexture(imageUnitIndex, 0, imageUnit.level, imageUnit.layered, imageUnit.layer,
1133*8975f5c5SAndroid Build Coastguard Worker                              imageUnit.access, imageUnit.format);
1134*8975f5c5SAndroid Build Coastguard Worker         }
1135*8975f5c5SAndroid Build Coastguard Worker     }
1136*8975f5c5SAndroid Build Coastguard Worker }
1137*8975f5c5SAndroid Build Coastguard Worker 
setAttributeCurrentData(size_t index,const gl::VertexAttribCurrentValueData & data)1138*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setAttributeCurrentData(size_t index,
1139*8975f5c5SAndroid Build Coastguard Worker                                              const gl::VertexAttribCurrentValueData &data)
1140*8975f5c5SAndroid Build Coastguard Worker {
1141*8975f5c5SAndroid Build Coastguard Worker     if (mVertexAttribCurrentValues[index] != data)
1142*8975f5c5SAndroid Build Coastguard Worker     {
1143*8975f5c5SAndroid Build Coastguard Worker         mVertexAttribCurrentValues[index] = data;
1144*8975f5c5SAndroid Build Coastguard Worker         switch (mVertexAttribCurrentValues[index].Type)
1145*8975f5c5SAndroid Build Coastguard Worker         {
1146*8975f5c5SAndroid Build Coastguard Worker             case gl::VertexAttribType::Float:
1147*8975f5c5SAndroid Build Coastguard Worker                 mFunctions->vertexAttrib4fv(static_cast<GLuint>(index),
1148*8975f5c5SAndroid Build Coastguard Worker                                             mVertexAttribCurrentValues[index].Values.FloatValues);
1149*8975f5c5SAndroid Build Coastguard Worker                 break;
1150*8975f5c5SAndroid Build Coastguard Worker             case gl::VertexAttribType::Int:
1151*8975f5c5SAndroid Build Coastguard Worker                 mFunctions->vertexAttribI4iv(static_cast<GLuint>(index),
1152*8975f5c5SAndroid Build Coastguard Worker                                              mVertexAttribCurrentValues[index].Values.IntValues);
1153*8975f5c5SAndroid Build Coastguard Worker                 break;
1154*8975f5c5SAndroid Build Coastguard Worker             case gl::VertexAttribType::UnsignedInt:
1155*8975f5c5SAndroid Build Coastguard Worker                 mFunctions->vertexAttribI4uiv(
1156*8975f5c5SAndroid Build Coastguard Worker                     static_cast<GLuint>(index),
1157*8975f5c5SAndroid Build Coastguard Worker                     mVertexAttribCurrentValues[index].Values.UnsignedIntValues);
1158*8975f5c5SAndroid Build Coastguard Worker                 break;
1159*8975f5c5SAndroid Build Coastguard Worker             default:
1160*8975f5c5SAndroid Build Coastguard Worker                 UNREACHABLE();
1161*8975f5c5SAndroid Build Coastguard Worker         }
1162*8975f5c5SAndroid Build Coastguard Worker 
1163*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_CURRENT_VALUES);
1164*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyCurrentValues.set(index);
1165*8975f5c5SAndroid Build Coastguard Worker     }
1166*8975f5c5SAndroid Build Coastguard Worker }
1167*8975f5c5SAndroid Build Coastguard Worker 
setScissorTestEnabled(bool enabled)1168*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setScissorTestEnabled(bool enabled)
1169*8975f5c5SAndroid Build Coastguard Worker {
1170*8975f5c5SAndroid Build Coastguard Worker     if (mScissorTestEnabled != enabled)
1171*8975f5c5SAndroid Build Coastguard Worker     {
1172*8975f5c5SAndroid Build Coastguard Worker         mScissorTestEnabled = enabled;
1173*8975f5c5SAndroid Build Coastguard Worker         if (mScissorTestEnabled)
1174*8975f5c5SAndroid Build Coastguard Worker         {
1175*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_SCISSOR_TEST);
1176*8975f5c5SAndroid Build Coastguard Worker         }
1177*8975f5c5SAndroid Build Coastguard Worker         else
1178*8975f5c5SAndroid Build Coastguard Worker         {
1179*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_SCISSOR_TEST);
1180*8975f5c5SAndroid Build Coastguard Worker         }
1181*8975f5c5SAndroid Build Coastguard Worker 
1182*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SCISSOR_TEST_ENABLED);
1183*8975f5c5SAndroid Build Coastguard Worker     }
1184*8975f5c5SAndroid Build Coastguard Worker }
1185*8975f5c5SAndroid Build Coastguard Worker 
setScissor(const gl::Rectangle & scissor)1186*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setScissor(const gl::Rectangle &scissor)
1187*8975f5c5SAndroid Build Coastguard Worker {
1188*8975f5c5SAndroid Build Coastguard Worker     if (scissor != mScissor)
1189*8975f5c5SAndroid Build Coastguard Worker     {
1190*8975f5c5SAndroid Build Coastguard Worker         mScissor = scissor;
1191*8975f5c5SAndroid Build Coastguard Worker         mFunctions->scissor(mScissor.x, mScissor.y, mScissor.width, mScissor.height);
1192*8975f5c5SAndroid Build Coastguard Worker 
1193*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SCISSOR);
1194*8975f5c5SAndroid Build Coastguard Worker     }
1195*8975f5c5SAndroid Build Coastguard Worker }
1196*8975f5c5SAndroid Build Coastguard Worker 
setViewport(const gl::Rectangle & viewport)1197*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setViewport(const gl::Rectangle &viewport)
1198*8975f5c5SAndroid Build Coastguard Worker {
1199*8975f5c5SAndroid Build Coastguard Worker     if (viewport != mViewport)
1200*8975f5c5SAndroid Build Coastguard Worker     {
1201*8975f5c5SAndroid Build Coastguard Worker         mViewport = viewport;
1202*8975f5c5SAndroid Build Coastguard Worker         mFunctions->viewport(mViewport.x, mViewport.y, mViewport.width, mViewport.height);
1203*8975f5c5SAndroid Build Coastguard Worker 
1204*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_VIEWPORT);
1205*8975f5c5SAndroid Build Coastguard Worker     }
1206*8975f5c5SAndroid Build Coastguard Worker }
1207*8975f5c5SAndroid Build Coastguard Worker 
setDepthRange(float near,float far)1208*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setDepthRange(float near, float far)
1209*8975f5c5SAndroid Build Coastguard Worker {
1210*8975f5c5SAndroid Build Coastguard Worker     mNear = near;
1211*8975f5c5SAndroid Build Coastguard Worker     mFar  = far;
1212*8975f5c5SAndroid Build Coastguard Worker 
1213*8975f5c5SAndroid Build Coastguard Worker     // The glDepthRangef function isn't available until OpenGL 4.1.  Prefer it when it is
1214*8975f5c5SAndroid Build Coastguard Worker     // available because OpenGL ES only works in floats.
1215*8975f5c5SAndroid Build Coastguard Worker     if (mFunctions->depthRangef)
1216*8975f5c5SAndroid Build Coastguard Worker     {
1217*8975f5c5SAndroid Build Coastguard Worker         mFunctions->depthRangef(mNear, mFar);
1218*8975f5c5SAndroid Build Coastguard Worker     }
1219*8975f5c5SAndroid Build Coastguard Worker     else
1220*8975f5c5SAndroid Build Coastguard Worker     {
1221*8975f5c5SAndroid Build Coastguard Worker         ASSERT(mFunctions->depthRange);
1222*8975f5c5SAndroid Build Coastguard Worker         mFunctions->depthRange(mNear, mFar);
1223*8975f5c5SAndroid Build Coastguard Worker     }
1224*8975f5c5SAndroid Build Coastguard Worker 
1225*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_DEPTH_RANGE);
1226*8975f5c5SAndroid Build Coastguard Worker }
1227*8975f5c5SAndroid Build Coastguard Worker 
setClipControl(gl::ClipOrigin origin,gl::ClipDepthMode depth)1228*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setClipControl(gl::ClipOrigin origin, gl::ClipDepthMode depth)
1229*8975f5c5SAndroid Build Coastguard Worker {
1230*8975f5c5SAndroid Build Coastguard Worker     if (mClipOrigin == origin && mClipDepthMode == depth)
1231*8975f5c5SAndroid Build Coastguard Worker     {
1232*8975f5c5SAndroid Build Coastguard Worker         return;
1233*8975f5c5SAndroid Build Coastguard Worker     }
1234*8975f5c5SAndroid Build Coastguard Worker 
1235*8975f5c5SAndroid Build Coastguard Worker     mClipOrigin    = origin;
1236*8975f5c5SAndroid Build Coastguard Worker     mClipDepthMode = depth;
1237*8975f5c5SAndroid Build Coastguard Worker 
1238*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mFunctions->clipControl);
1239*8975f5c5SAndroid Build Coastguard Worker     mFunctions->clipControl(ToGLenum(mClipOrigin), ToGLenum(mClipDepthMode));
1240*8975f5c5SAndroid Build Coastguard Worker 
1241*8975f5c5SAndroid Build Coastguard Worker     if (mFeatures.resyncDepthRangeOnClipControl.enabled)
1242*8975f5c5SAndroid Build Coastguard Worker     {
1243*8975f5c5SAndroid Build Coastguard Worker         // Change and restore depth range to trigger internal transformation
1244*8975f5c5SAndroid Build Coastguard Worker         // state resync. This is needed to apply clip control on some drivers.
1245*8975f5c5SAndroid Build Coastguard Worker         const float near = mNear;
1246*8975f5c5SAndroid Build Coastguard Worker         setDepthRange(near == 0.0f ? 1.0f : 0.0f, mFar);
1247*8975f5c5SAndroid Build Coastguard Worker         setDepthRange(near, mFar);
1248*8975f5c5SAndroid Build Coastguard Worker     }
1249*8975f5c5SAndroid Build Coastguard Worker 
1250*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
1251*8975f5c5SAndroid Build Coastguard Worker     mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_CLIP_CONTROL);
1252*8975f5c5SAndroid Build Coastguard Worker }
1253*8975f5c5SAndroid Build Coastguard Worker 
setClipControlWithEmulatedClipOrigin(const gl::ProgramExecutable * executable,GLenum frontFace,gl::ClipOrigin origin,gl::ClipDepthMode depth)1254*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setClipControlWithEmulatedClipOrigin(const gl::ProgramExecutable *executable,
1255*8975f5c5SAndroid Build Coastguard Worker                                                           GLenum frontFace,
1256*8975f5c5SAndroid Build Coastguard Worker                                                           gl::ClipOrigin origin,
1257*8975f5c5SAndroid Build Coastguard Worker                                                           gl::ClipDepthMode depth)
1258*8975f5c5SAndroid Build Coastguard Worker {
1259*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mFeatures.emulateClipOrigin.enabled);
1260*8975f5c5SAndroid Build Coastguard Worker     if (executable)
1261*8975f5c5SAndroid Build Coastguard Worker     {
1262*8975f5c5SAndroid Build Coastguard Worker         updateEmulatedClipOriginUniform(executable, origin);
1263*8975f5c5SAndroid Build Coastguard Worker     }
1264*8975f5c5SAndroid Build Coastguard Worker     static_assert((GL_CW ^ GL_CCW) == static_cast<GLenum>(gl::ClipOrigin::UpperLeft));
1265*8975f5c5SAndroid Build Coastguard Worker     setFrontFace(frontFace ^ static_cast<GLenum>(origin));
1266*8975f5c5SAndroid Build Coastguard Worker     setClipControl(gl::ClipOrigin::LowerLeft, depth);
1267*8975f5c5SAndroid Build Coastguard Worker }
1268*8975f5c5SAndroid Build Coastguard Worker 
setBlendEnabled(bool enabled)1269*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setBlendEnabled(bool enabled)
1270*8975f5c5SAndroid Build Coastguard Worker {
1271*8975f5c5SAndroid Build Coastguard Worker     const gl::DrawBufferMask mask =
1272*8975f5c5SAndroid Build Coastguard Worker         enabled ? mBlendStateExt.getAllEnabledMask() : gl::DrawBufferMask::Zero();
1273*8975f5c5SAndroid Build Coastguard Worker     if (mBlendStateExt.getEnabledMask() == mask)
1274*8975f5c5SAndroid Build Coastguard Worker     {
1275*8975f5c5SAndroid Build Coastguard Worker         return;
1276*8975f5c5SAndroid Build Coastguard Worker     }
1277*8975f5c5SAndroid Build Coastguard Worker 
1278*8975f5c5SAndroid Build Coastguard Worker     if (enabled)
1279*8975f5c5SAndroid Build Coastguard Worker     {
1280*8975f5c5SAndroid Build Coastguard Worker         mFunctions->enable(GL_BLEND);
1281*8975f5c5SAndroid Build Coastguard Worker     }
1282*8975f5c5SAndroid Build Coastguard Worker     else
1283*8975f5c5SAndroid Build Coastguard Worker     {
1284*8975f5c5SAndroid Build Coastguard Worker         mFunctions->disable(GL_BLEND);
1285*8975f5c5SAndroid Build Coastguard Worker     }
1286*8975f5c5SAndroid Build Coastguard Worker 
1287*8975f5c5SAndroid Build Coastguard Worker     mBlendStateExt.setEnabled(enabled);
1288*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_BLEND_ENABLED);
1289*8975f5c5SAndroid Build Coastguard Worker }
1290*8975f5c5SAndroid Build Coastguard Worker 
setBlendEnabledIndexed(const gl::DrawBufferMask enabledMask)1291*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setBlendEnabledIndexed(const gl::DrawBufferMask enabledMask)
1292*8975f5c5SAndroid Build Coastguard Worker {
1293*8975f5c5SAndroid Build Coastguard Worker     if (mBlendStateExt.getEnabledMask() == enabledMask)
1294*8975f5c5SAndroid Build Coastguard Worker     {
1295*8975f5c5SAndroid Build Coastguard Worker         return;
1296*8975f5c5SAndroid Build Coastguard Worker     }
1297*8975f5c5SAndroid Build Coastguard Worker 
1298*8975f5c5SAndroid Build Coastguard Worker     // Get DrawBufferMask of buffers with different blend enable state
1299*8975f5c5SAndroid Build Coastguard Worker     gl::DrawBufferMask diffMask = mBlendStateExt.getEnabledMask() ^ enabledMask;
1300*8975f5c5SAndroid Build Coastguard Worker     const size_t diffCount      = diffMask.count();
1301*8975f5c5SAndroid Build Coastguard Worker 
1302*8975f5c5SAndroid Build Coastguard Worker     // Check if enabling or disabling blending for all buffers reduces the number of subsequent
1303*8975f5c5SAndroid Build Coastguard Worker     // indexed commands. Implicitly handles the case when the new blend enable state is the same for
1304*8975f5c5SAndroid Build Coastguard Worker     // all buffers.
1305*8975f5c5SAndroid Build Coastguard Worker     if (diffCount > 1)
1306*8975f5c5SAndroid Build Coastguard Worker     {
1307*8975f5c5SAndroid Build Coastguard Worker         // The number of indexed blend enable commands in case a mass disable is used.
1308*8975f5c5SAndroid Build Coastguard Worker         const size_t enabledCount = enabledMask.count();
1309*8975f5c5SAndroid Build Coastguard Worker 
1310*8975f5c5SAndroid Build Coastguard Worker         // The mask and the number of indexed blend disable commands in case a mass enable is used.
1311*8975f5c5SAndroid Build Coastguard Worker         const gl::DrawBufferMask disabledMask = enabledMask ^ mBlendStateExt.getAllEnabledMask();
1312*8975f5c5SAndroid Build Coastguard Worker         const size_t disabledCount            = disabledMask.count();
1313*8975f5c5SAndroid Build Coastguard Worker 
1314*8975f5c5SAndroid Build Coastguard Worker         if (enabledCount < diffCount && enabledCount <= disabledCount)
1315*8975f5c5SAndroid Build Coastguard Worker         {
1316*8975f5c5SAndroid Build Coastguard Worker             diffMask = enabledMask;
1317*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_BLEND);
1318*8975f5c5SAndroid Build Coastguard Worker         }
1319*8975f5c5SAndroid Build Coastguard Worker         else if (disabledCount < diffCount && disabledCount <= enabledCount)
1320*8975f5c5SAndroid Build Coastguard Worker         {
1321*8975f5c5SAndroid Build Coastguard Worker             diffMask = disabledMask;
1322*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_BLEND);
1323*8975f5c5SAndroid Build Coastguard Worker         }
1324*8975f5c5SAndroid Build Coastguard Worker     }
1325*8975f5c5SAndroid Build Coastguard Worker 
1326*8975f5c5SAndroid Build Coastguard Worker     for (size_t drawBufferIndex : diffMask)
1327*8975f5c5SAndroid Build Coastguard Worker     {
1328*8975f5c5SAndroid Build Coastguard Worker         if (enabledMask.test(drawBufferIndex))
1329*8975f5c5SAndroid Build Coastguard Worker         {
1330*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enablei(GL_BLEND, static_cast<GLuint>(drawBufferIndex));
1331*8975f5c5SAndroid Build Coastguard Worker         }
1332*8975f5c5SAndroid Build Coastguard Worker         else
1333*8975f5c5SAndroid Build Coastguard Worker         {
1334*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disablei(GL_BLEND, static_cast<GLuint>(drawBufferIndex));
1335*8975f5c5SAndroid Build Coastguard Worker         }
1336*8975f5c5SAndroid Build Coastguard Worker     }
1337*8975f5c5SAndroid Build Coastguard Worker 
1338*8975f5c5SAndroid Build Coastguard Worker     mBlendStateExt.setEnabledMask(enabledMask);
1339*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_BLEND_ENABLED);
1340*8975f5c5SAndroid Build Coastguard Worker }
1341*8975f5c5SAndroid Build Coastguard Worker 
setBlendColor(const gl::ColorF & blendColor)1342*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setBlendColor(const gl::ColorF &blendColor)
1343*8975f5c5SAndroid Build Coastguard Worker {
1344*8975f5c5SAndroid Build Coastguard Worker     if (mBlendColor != blendColor)
1345*8975f5c5SAndroid Build Coastguard Worker     {
1346*8975f5c5SAndroid Build Coastguard Worker         mBlendColor = blendColor;
1347*8975f5c5SAndroid Build Coastguard Worker         mFunctions->blendColor(mBlendColor.red, mBlendColor.green, mBlendColor.blue,
1348*8975f5c5SAndroid Build Coastguard Worker                                mBlendColor.alpha);
1349*8975f5c5SAndroid Build Coastguard Worker 
1350*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_BLEND_COLOR);
1351*8975f5c5SAndroid Build Coastguard Worker     }
1352*8975f5c5SAndroid Build Coastguard Worker }
1353*8975f5c5SAndroid Build Coastguard Worker 
setBlendAdvancedCoherent(bool enabled)1354*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setBlendAdvancedCoherent(bool enabled)
1355*8975f5c5SAndroid Build Coastguard Worker {
1356*8975f5c5SAndroid Build Coastguard Worker     if (mBlendAdvancedCoherent != enabled)
1357*8975f5c5SAndroid Build Coastguard Worker     {
1358*8975f5c5SAndroid Build Coastguard Worker         mBlendAdvancedCoherent = enabled;
1359*8975f5c5SAndroid Build Coastguard Worker 
1360*8975f5c5SAndroid Build Coastguard Worker         if (mBlendAdvancedCoherent)
1361*8975f5c5SAndroid Build Coastguard Worker         {
1362*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_BLEND_ADVANCED_COHERENT_KHR);
1363*8975f5c5SAndroid Build Coastguard Worker         }
1364*8975f5c5SAndroid Build Coastguard Worker         else
1365*8975f5c5SAndroid Build Coastguard Worker         {
1366*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_BLEND_ADVANCED_COHERENT_KHR);
1367*8975f5c5SAndroid Build Coastguard Worker         }
1368*8975f5c5SAndroid Build Coastguard Worker 
1369*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
1370*8975f5c5SAndroid Build Coastguard Worker         mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_BLEND_ADVANCED_COHERENT);
1371*8975f5c5SAndroid Build Coastguard Worker     }
1372*8975f5c5SAndroid Build Coastguard Worker }
1373*8975f5c5SAndroid Build Coastguard Worker 
setBlendFuncs(const gl::BlendStateExt & blendStateExt)1374*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setBlendFuncs(const gl::BlendStateExt &blendStateExt)
1375*8975f5c5SAndroid Build Coastguard Worker {
1376*8975f5c5SAndroid Build Coastguard Worker     if (mBlendStateExt.getSrcColorBits() == blendStateExt.getSrcColorBits() &&
1377*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.getDstColorBits() == blendStateExt.getDstColorBits() &&
1378*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.getSrcAlphaBits() == blendStateExt.getSrcAlphaBits() &&
1379*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.getDstAlphaBits() == blendStateExt.getDstAlphaBits())
1380*8975f5c5SAndroid Build Coastguard Worker     {
1381*8975f5c5SAndroid Build Coastguard Worker         return;
1382*8975f5c5SAndroid Build Coastguard Worker     }
1383*8975f5c5SAndroid Build Coastguard Worker 
1384*8975f5c5SAndroid Build Coastguard Worker     if (!mIndependentBlendStates)
1385*8975f5c5SAndroid Build Coastguard Worker     {
1386*8975f5c5SAndroid Build Coastguard Worker         mFunctions->blendFuncSeparate(ToGLenum(blendStateExt.getSrcColorIndexed(0)),
1387*8975f5c5SAndroid Build Coastguard Worker                                       ToGLenum(blendStateExt.getDstColorIndexed(0)),
1388*8975f5c5SAndroid Build Coastguard Worker                                       ToGLenum(blendStateExt.getSrcAlphaIndexed(0)),
1389*8975f5c5SAndroid Build Coastguard Worker                                       ToGLenum(blendStateExt.getDstAlphaIndexed(0)));
1390*8975f5c5SAndroid Build Coastguard Worker     }
1391*8975f5c5SAndroid Build Coastguard Worker     else
1392*8975f5c5SAndroid Build Coastguard Worker     {
1393*8975f5c5SAndroid Build Coastguard Worker         // Get DrawBufferMask of buffers with different blend factors
1394*8975f5c5SAndroid Build Coastguard Worker         gl::DrawBufferMask diffMask = mBlendStateExt.compareFactors(blendStateExt);
1395*8975f5c5SAndroid Build Coastguard Worker         size_t diffCount            = diffMask.count();
1396*8975f5c5SAndroid Build Coastguard Worker 
1397*8975f5c5SAndroid Build Coastguard Worker         // Check if setting all buffers to the same value reduces the number of subsequent indexed
1398*8975f5c5SAndroid Build Coastguard Worker         // commands. Implicitly handles the case when the new blend function state is the same for
1399*8975f5c5SAndroid Build Coastguard Worker         // all buffers.
1400*8975f5c5SAndroid Build Coastguard Worker         if (diffCount > 1)
1401*8975f5c5SAndroid Build Coastguard Worker         {
1402*8975f5c5SAndroid Build Coastguard Worker             bool found                                            = false;
1403*8975f5c5SAndroid Build Coastguard Worker             gl::BlendStateExt::FactorStorage::Type commonSrcColor = 0;
1404*8975f5c5SAndroid Build Coastguard Worker             gl::BlendStateExt::FactorStorage::Type commonDstColor = 0;
1405*8975f5c5SAndroid Build Coastguard Worker             gl::BlendStateExt::FactorStorage::Type commonSrcAlpha = 0;
1406*8975f5c5SAndroid Build Coastguard Worker             gl::BlendStateExt::FactorStorage::Type commonDstAlpha = 0;
1407*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < mBlendStateExt.getDrawBufferCount() - 1; i++)
1408*8975f5c5SAndroid Build Coastguard Worker             {
1409*8975f5c5SAndroid Build Coastguard Worker                 const gl::BlendStateExt::FactorStorage::Type tempCommonSrcColor =
1410*8975f5c5SAndroid Build Coastguard Worker                     blendStateExt.expandSrcColorIndexed(i);
1411*8975f5c5SAndroid Build Coastguard Worker                 const gl::BlendStateExt::FactorStorage::Type tempCommonDstColor =
1412*8975f5c5SAndroid Build Coastguard Worker                     blendStateExt.expandDstColorIndexed(i);
1413*8975f5c5SAndroid Build Coastguard Worker                 const gl::BlendStateExt::FactorStorage::Type tempCommonSrcAlpha =
1414*8975f5c5SAndroid Build Coastguard Worker                     blendStateExt.expandSrcAlphaIndexed(i);
1415*8975f5c5SAndroid Build Coastguard Worker                 const gl::BlendStateExt::FactorStorage::Type tempCommonDstAlpha =
1416*8975f5c5SAndroid Build Coastguard Worker                     blendStateExt.expandDstAlphaIndexed(i);
1417*8975f5c5SAndroid Build Coastguard Worker 
1418*8975f5c5SAndroid Build Coastguard Worker                 const gl::DrawBufferMask tempDiffMask = blendStateExt.compareFactors(
1419*8975f5c5SAndroid Build Coastguard Worker                     tempCommonSrcColor, tempCommonDstColor, tempCommonSrcAlpha, tempCommonDstAlpha);
1420*8975f5c5SAndroid Build Coastguard Worker 
1421*8975f5c5SAndroid Build Coastguard Worker                 const size_t tempDiffCount = tempDiffMask.count();
1422*8975f5c5SAndroid Build Coastguard Worker                 if (tempDiffCount < diffCount)
1423*8975f5c5SAndroid Build Coastguard Worker                 {
1424*8975f5c5SAndroid Build Coastguard Worker                     found          = true;
1425*8975f5c5SAndroid Build Coastguard Worker                     diffMask       = tempDiffMask;
1426*8975f5c5SAndroid Build Coastguard Worker                     diffCount      = tempDiffCount;
1427*8975f5c5SAndroid Build Coastguard Worker                     commonSrcColor = tempCommonSrcColor;
1428*8975f5c5SAndroid Build Coastguard Worker                     commonDstColor = tempCommonDstColor;
1429*8975f5c5SAndroid Build Coastguard Worker                     commonSrcAlpha = tempCommonSrcAlpha;
1430*8975f5c5SAndroid Build Coastguard Worker                     commonDstAlpha = tempCommonDstAlpha;
1431*8975f5c5SAndroid Build Coastguard Worker                     if (tempDiffCount == 0)
1432*8975f5c5SAndroid Build Coastguard Worker                     {
1433*8975f5c5SAndroid Build Coastguard Worker                         break;  // the blend factors are the same for all buffers
1434*8975f5c5SAndroid Build Coastguard Worker                     }
1435*8975f5c5SAndroid Build Coastguard Worker                 }
1436*8975f5c5SAndroid Build Coastguard Worker             }
1437*8975f5c5SAndroid Build Coastguard Worker             if (found)
1438*8975f5c5SAndroid Build Coastguard Worker             {
1439*8975f5c5SAndroid Build Coastguard Worker                 mFunctions->blendFuncSeparate(
1440*8975f5c5SAndroid Build Coastguard Worker                     ToGLenum(gl::BlendStateExt::FactorStorage::GetValueIndexed(0, commonSrcColor)),
1441*8975f5c5SAndroid Build Coastguard Worker                     ToGLenum(gl::BlendStateExt::FactorStorage::GetValueIndexed(0, commonDstColor)),
1442*8975f5c5SAndroid Build Coastguard Worker                     ToGLenum(gl::BlendStateExt::FactorStorage::GetValueIndexed(0, commonSrcAlpha)),
1443*8975f5c5SAndroid Build Coastguard Worker                     ToGLenum(gl::BlendStateExt::FactorStorage::GetValueIndexed(0, commonDstAlpha)));
1444*8975f5c5SAndroid Build Coastguard Worker             }
1445*8975f5c5SAndroid Build Coastguard Worker         }
1446*8975f5c5SAndroid Build Coastguard Worker 
1447*8975f5c5SAndroid Build Coastguard Worker         for (size_t drawBufferIndex : diffMask)
1448*8975f5c5SAndroid Build Coastguard Worker         {
1449*8975f5c5SAndroid Build Coastguard Worker             mFunctions->blendFuncSeparatei(
1450*8975f5c5SAndroid Build Coastguard Worker                 static_cast<GLuint>(drawBufferIndex),
1451*8975f5c5SAndroid Build Coastguard Worker                 ToGLenum(blendStateExt.getSrcColorIndexed(drawBufferIndex)),
1452*8975f5c5SAndroid Build Coastguard Worker                 ToGLenum(blendStateExt.getDstColorIndexed(drawBufferIndex)),
1453*8975f5c5SAndroid Build Coastguard Worker                 ToGLenum(blendStateExt.getSrcAlphaIndexed(drawBufferIndex)),
1454*8975f5c5SAndroid Build Coastguard Worker                 ToGLenum(blendStateExt.getDstAlphaIndexed(drawBufferIndex)));
1455*8975f5c5SAndroid Build Coastguard Worker         }
1456*8975f5c5SAndroid Build Coastguard Worker     }
1457*8975f5c5SAndroid Build Coastguard Worker     mBlendStateExt.setSrcColorBits(blendStateExt.getSrcColorBits());
1458*8975f5c5SAndroid Build Coastguard Worker     mBlendStateExt.setDstColorBits(blendStateExt.getDstColorBits());
1459*8975f5c5SAndroid Build Coastguard Worker     mBlendStateExt.setSrcAlphaBits(blendStateExt.getSrcAlphaBits());
1460*8975f5c5SAndroid Build Coastguard Worker     mBlendStateExt.setDstAlphaBits(blendStateExt.getDstAlphaBits());
1461*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_BLEND_FUNCS);
1462*8975f5c5SAndroid Build Coastguard Worker }
1463*8975f5c5SAndroid Build Coastguard Worker 
setBlendEquations(const gl::BlendStateExt & blendStateExt)1464*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setBlendEquations(const gl::BlendStateExt &blendStateExt)
1465*8975f5c5SAndroid Build Coastguard Worker {
1466*8975f5c5SAndroid Build Coastguard Worker     if (mBlendStateExt.getEquationColorBits() == blendStateExt.getEquationColorBits() &&
1467*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.getEquationAlphaBits() == blendStateExt.getEquationAlphaBits())
1468*8975f5c5SAndroid Build Coastguard Worker     {
1469*8975f5c5SAndroid Build Coastguard Worker         return;
1470*8975f5c5SAndroid Build Coastguard Worker     }
1471*8975f5c5SAndroid Build Coastguard Worker 
1472*8975f5c5SAndroid Build Coastguard Worker     if (!mIndependentBlendStates)
1473*8975f5c5SAndroid Build Coastguard Worker     {
1474*8975f5c5SAndroid Build Coastguard Worker         mFunctions->blendEquationSeparate(ToGLenum(blendStateExt.getEquationColorIndexed(0)),
1475*8975f5c5SAndroid Build Coastguard Worker                                           ToGLenum(blendStateExt.getEquationAlphaIndexed(0)));
1476*8975f5c5SAndroid Build Coastguard Worker     }
1477*8975f5c5SAndroid Build Coastguard Worker     else
1478*8975f5c5SAndroid Build Coastguard Worker     {
1479*8975f5c5SAndroid Build Coastguard Worker         // Get DrawBufferMask of buffers with different blend equations
1480*8975f5c5SAndroid Build Coastguard Worker         gl::DrawBufferMask diffMask = mBlendStateExt.compareEquations(blendStateExt);
1481*8975f5c5SAndroid Build Coastguard Worker         size_t diffCount            = diffMask.count();
1482*8975f5c5SAndroid Build Coastguard Worker 
1483*8975f5c5SAndroid Build Coastguard Worker         // Check if setting all buffers to the same value reduces the number of subsequent indexed
1484*8975f5c5SAndroid Build Coastguard Worker         // commands. Implicitly handles the case when the new blend equation state is the same for
1485*8975f5c5SAndroid Build Coastguard Worker         // all buffers.
1486*8975f5c5SAndroid Build Coastguard Worker         if (diffCount > 1)
1487*8975f5c5SAndroid Build Coastguard Worker         {
1488*8975f5c5SAndroid Build Coastguard Worker             bool found                                                   = false;
1489*8975f5c5SAndroid Build Coastguard Worker             gl::BlendStateExt::EquationStorage::Type commonEquationColor = 0;
1490*8975f5c5SAndroid Build Coastguard Worker             gl::BlendStateExt::EquationStorage::Type commonEquationAlpha = 0;
1491*8975f5c5SAndroid Build Coastguard Worker             for (size_t i = 0; i < mBlendStateExt.getDrawBufferCount() - 1; i++)
1492*8975f5c5SAndroid Build Coastguard Worker             {
1493*8975f5c5SAndroid Build Coastguard Worker                 const gl::BlendStateExt::EquationStorage::Type tempCommonEquationColor =
1494*8975f5c5SAndroid Build Coastguard Worker                     blendStateExt.expandEquationColorIndexed(i);
1495*8975f5c5SAndroid Build Coastguard Worker                 const gl::BlendStateExt::EquationStorage::Type tempCommonEquationAlpha =
1496*8975f5c5SAndroid Build Coastguard Worker                     blendStateExt.expandEquationAlphaIndexed(i);
1497*8975f5c5SAndroid Build Coastguard Worker 
1498*8975f5c5SAndroid Build Coastguard Worker                 const gl::DrawBufferMask tempDiffMask = blendStateExt.compareEquations(
1499*8975f5c5SAndroid Build Coastguard Worker                     tempCommonEquationColor, tempCommonEquationAlpha);
1500*8975f5c5SAndroid Build Coastguard Worker 
1501*8975f5c5SAndroid Build Coastguard Worker                 const size_t tempDiffCount = tempDiffMask.count();
1502*8975f5c5SAndroid Build Coastguard Worker                 if (tempDiffCount < diffCount)
1503*8975f5c5SAndroid Build Coastguard Worker                 {
1504*8975f5c5SAndroid Build Coastguard Worker                     found               = true;
1505*8975f5c5SAndroid Build Coastguard Worker                     diffMask            = tempDiffMask;
1506*8975f5c5SAndroid Build Coastguard Worker                     diffCount           = tempDiffCount;
1507*8975f5c5SAndroid Build Coastguard Worker                     commonEquationColor = tempCommonEquationColor;
1508*8975f5c5SAndroid Build Coastguard Worker                     commonEquationAlpha = tempCommonEquationAlpha;
1509*8975f5c5SAndroid Build Coastguard Worker                     if (tempDiffCount == 0)
1510*8975f5c5SAndroid Build Coastguard Worker                     {
1511*8975f5c5SAndroid Build Coastguard Worker                         break;  // the new blend equations are the same for all buffers
1512*8975f5c5SAndroid Build Coastguard Worker                     }
1513*8975f5c5SAndroid Build Coastguard Worker                 }
1514*8975f5c5SAndroid Build Coastguard Worker             }
1515*8975f5c5SAndroid Build Coastguard Worker             if (found)
1516*8975f5c5SAndroid Build Coastguard Worker             {
1517*8975f5c5SAndroid Build Coastguard Worker                 if (commonEquationColor == commonEquationAlpha)
1518*8975f5c5SAndroid Build Coastguard Worker                 {
1519*8975f5c5SAndroid Build Coastguard Worker                     mFunctions->blendEquation(
1520*8975f5c5SAndroid Build Coastguard Worker                         ToGLenum(gl::BlendStateExt::EquationStorage::GetValueIndexed(
1521*8975f5c5SAndroid Build Coastguard Worker                             0, commonEquationColor)));
1522*8975f5c5SAndroid Build Coastguard Worker                 }
1523*8975f5c5SAndroid Build Coastguard Worker                 else
1524*8975f5c5SAndroid Build Coastguard Worker                 {
1525*8975f5c5SAndroid Build Coastguard Worker                     mFunctions->blendEquationSeparate(
1526*8975f5c5SAndroid Build Coastguard Worker                         ToGLenum(gl::BlendStateExt::EquationStorage::GetValueIndexed(
1527*8975f5c5SAndroid Build Coastguard Worker                             0, commonEquationColor)),
1528*8975f5c5SAndroid Build Coastguard Worker                         ToGLenum(gl::BlendStateExt::EquationStorage::GetValueIndexed(
1529*8975f5c5SAndroid Build Coastguard Worker                             0, commonEquationAlpha)));
1530*8975f5c5SAndroid Build Coastguard Worker                 }
1531*8975f5c5SAndroid Build Coastguard Worker             }
1532*8975f5c5SAndroid Build Coastguard Worker         }
1533*8975f5c5SAndroid Build Coastguard Worker 
1534*8975f5c5SAndroid Build Coastguard Worker         for (size_t drawBufferIndex : diffMask)
1535*8975f5c5SAndroid Build Coastguard Worker         {
1536*8975f5c5SAndroid Build Coastguard Worker             gl::BlendEquationType equationColor =
1537*8975f5c5SAndroid Build Coastguard Worker                 blendStateExt.getEquationColorIndexed(drawBufferIndex);
1538*8975f5c5SAndroid Build Coastguard Worker             gl::BlendEquationType equationAlpha =
1539*8975f5c5SAndroid Build Coastguard Worker                 blendStateExt.getEquationAlphaIndexed(drawBufferIndex);
1540*8975f5c5SAndroid Build Coastguard Worker             if (equationColor == equationAlpha)
1541*8975f5c5SAndroid Build Coastguard Worker             {
1542*8975f5c5SAndroid Build Coastguard Worker                 mFunctions->blendEquationi(static_cast<GLuint>(drawBufferIndex),
1543*8975f5c5SAndroid Build Coastguard Worker                                            ToGLenum(equationColor));
1544*8975f5c5SAndroid Build Coastguard Worker             }
1545*8975f5c5SAndroid Build Coastguard Worker             else
1546*8975f5c5SAndroid Build Coastguard Worker             {
1547*8975f5c5SAndroid Build Coastguard Worker                 mFunctions->blendEquationSeparatei(static_cast<GLuint>(drawBufferIndex),
1548*8975f5c5SAndroid Build Coastguard Worker                                                    ToGLenum(equationColor),
1549*8975f5c5SAndroid Build Coastguard Worker                                                    ToGLenum(equationAlpha));
1550*8975f5c5SAndroid Build Coastguard Worker             }
1551*8975f5c5SAndroid Build Coastguard Worker         }
1552*8975f5c5SAndroid Build Coastguard Worker     }
1553*8975f5c5SAndroid Build Coastguard Worker     mBlendStateExt.setEquationColorBits(blendStateExt.getEquationColorBits());
1554*8975f5c5SAndroid Build Coastguard Worker     mBlendStateExt.setEquationAlphaBits(blendStateExt.getEquationAlphaBits());
1555*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_COLOR_MASK);
1556*8975f5c5SAndroid Build Coastguard Worker }
1557*8975f5c5SAndroid Build Coastguard Worker 
setColorMask(bool red,bool green,bool blue,bool alpha)1558*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setColorMask(bool red, bool green, bool blue, bool alpha)
1559*8975f5c5SAndroid Build Coastguard Worker {
1560*8975f5c5SAndroid Build Coastguard Worker     const gl::BlendStateExt::ColorMaskStorage::Type mask =
1561*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.expandColorMaskValue(red, green, blue, alpha);
1562*8975f5c5SAndroid Build Coastguard Worker     if (mBlendStateExt.getColorMaskBits() != mask)
1563*8975f5c5SAndroid Build Coastguard Worker     {
1564*8975f5c5SAndroid Build Coastguard Worker         mFunctions->colorMask(red, green, blue, alpha);
1565*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.setColorMaskBits(mask);
1566*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_COLOR_MASK);
1567*8975f5c5SAndroid Build Coastguard Worker     }
1568*8975f5c5SAndroid Build Coastguard Worker }
1569*8975f5c5SAndroid Build Coastguard Worker 
setSampleAlphaToCoverageEnabled(bool enabled)1570*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setSampleAlphaToCoverageEnabled(bool enabled)
1571*8975f5c5SAndroid Build Coastguard Worker {
1572*8975f5c5SAndroid Build Coastguard Worker     if (mSampleAlphaToCoverageEnabled != enabled)
1573*8975f5c5SAndroid Build Coastguard Worker     {
1574*8975f5c5SAndroid Build Coastguard Worker         mSampleAlphaToCoverageEnabled = enabled;
1575*8975f5c5SAndroid Build Coastguard Worker         if (mSampleAlphaToCoverageEnabled)
1576*8975f5c5SAndroid Build Coastguard Worker         {
1577*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_SAMPLE_ALPHA_TO_COVERAGE);
1578*8975f5c5SAndroid Build Coastguard Worker         }
1579*8975f5c5SAndroid Build Coastguard Worker         else
1580*8975f5c5SAndroid Build Coastguard Worker         {
1581*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_SAMPLE_ALPHA_TO_COVERAGE);
1582*8975f5c5SAndroid Build Coastguard Worker         }
1583*8975f5c5SAndroid Build Coastguard Worker 
1584*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED);
1585*8975f5c5SAndroid Build Coastguard Worker     }
1586*8975f5c5SAndroid Build Coastguard Worker }
1587*8975f5c5SAndroid Build Coastguard Worker 
setSampleCoverageEnabled(bool enabled)1588*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setSampleCoverageEnabled(bool enabled)
1589*8975f5c5SAndroid Build Coastguard Worker {
1590*8975f5c5SAndroid Build Coastguard Worker     if (mSampleCoverageEnabled != enabled)
1591*8975f5c5SAndroid Build Coastguard Worker     {
1592*8975f5c5SAndroid Build Coastguard Worker         mSampleCoverageEnabled = enabled;
1593*8975f5c5SAndroid Build Coastguard Worker         if (mSampleCoverageEnabled)
1594*8975f5c5SAndroid Build Coastguard Worker         {
1595*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_SAMPLE_COVERAGE);
1596*8975f5c5SAndroid Build Coastguard Worker         }
1597*8975f5c5SAndroid Build Coastguard Worker         else
1598*8975f5c5SAndroid Build Coastguard Worker         {
1599*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_SAMPLE_COVERAGE);
1600*8975f5c5SAndroid Build Coastguard Worker         }
1601*8975f5c5SAndroid Build Coastguard Worker 
1602*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
1603*8975f5c5SAndroid Build Coastguard Worker     }
1604*8975f5c5SAndroid Build Coastguard Worker }
1605*8975f5c5SAndroid Build Coastguard Worker 
setSampleCoverage(float value,bool invert)1606*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setSampleCoverage(float value, bool invert)
1607*8975f5c5SAndroid Build Coastguard Worker {
1608*8975f5c5SAndroid Build Coastguard Worker     if (mSampleCoverageValue != value || mSampleCoverageInvert != invert)
1609*8975f5c5SAndroid Build Coastguard Worker     {
1610*8975f5c5SAndroid Build Coastguard Worker         mSampleCoverageValue  = value;
1611*8975f5c5SAndroid Build Coastguard Worker         mSampleCoverageInvert = invert;
1612*8975f5c5SAndroid Build Coastguard Worker         mFunctions->sampleCoverage(mSampleCoverageValue, mSampleCoverageInvert);
1613*8975f5c5SAndroid Build Coastguard Worker 
1614*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SAMPLE_COVERAGE);
1615*8975f5c5SAndroid Build Coastguard Worker     }
1616*8975f5c5SAndroid Build Coastguard Worker }
1617*8975f5c5SAndroid Build Coastguard Worker 
setSampleMaskEnabled(bool enabled)1618*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setSampleMaskEnabled(bool enabled)
1619*8975f5c5SAndroid Build Coastguard Worker {
1620*8975f5c5SAndroid Build Coastguard Worker     if (mSampleMaskEnabled != enabled)
1621*8975f5c5SAndroid Build Coastguard Worker     {
1622*8975f5c5SAndroid Build Coastguard Worker         mSampleMaskEnabled = enabled;
1623*8975f5c5SAndroid Build Coastguard Worker         if (mSampleMaskEnabled)
1624*8975f5c5SAndroid Build Coastguard Worker         {
1625*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_SAMPLE_MASK);
1626*8975f5c5SAndroid Build Coastguard Worker         }
1627*8975f5c5SAndroid Build Coastguard Worker         else
1628*8975f5c5SAndroid Build Coastguard Worker         {
1629*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_SAMPLE_MASK);
1630*8975f5c5SAndroid Build Coastguard Worker         }
1631*8975f5c5SAndroid Build Coastguard Worker 
1632*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SAMPLE_MASK_ENABLED);
1633*8975f5c5SAndroid Build Coastguard Worker     }
1634*8975f5c5SAndroid Build Coastguard Worker }
1635*8975f5c5SAndroid Build Coastguard Worker 
setSampleMaski(GLuint maskNumber,GLbitfield mask)1636*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setSampleMaski(GLuint maskNumber, GLbitfield mask)
1637*8975f5c5SAndroid Build Coastguard Worker {
1638*8975f5c5SAndroid Build Coastguard Worker     ASSERT(maskNumber < mSampleMaskValues.size());
1639*8975f5c5SAndroid Build Coastguard Worker     if (mSampleMaskValues[maskNumber] != mask)
1640*8975f5c5SAndroid Build Coastguard Worker     {
1641*8975f5c5SAndroid Build Coastguard Worker         mSampleMaskValues[maskNumber] = mask;
1642*8975f5c5SAndroid Build Coastguard Worker         mFunctions->sampleMaski(maskNumber, mask);
1643*8975f5c5SAndroid Build Coastguard Worker 
1644*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SAMPLE_MASK);
1645*8975f5c5SAndroid Build Coastguard Worker     }
1646*8975f5c5SAndroid Build Coastguard Worker }
1647*8975f5c5SAndroid Build Coastguard Worker 
1648*8975f5c5SAndroid Build Coastguard Worker // Depth and stencil redundant state changes are guarded in the
1649*8975f5c5SAndroid Build Coastguard Worker // frontend so for related cases here just set the dirty bit
1650*8975f5c5SAndroid Build Coastguard Worker // and update backend states.
setDepthTestEnabled(bool enabled)1651*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setDepthTestEnabled(bool enabled)
1652*8975f5c5SAndroid Build Coastguard Worker {
1653*8975f5c5SAndroid Build Coastguard Worker     mDepthTestEnabled = enabled;
1654*8975f5c5SAndroid Build Coastguard Worker     if (mDepthTestEnabled)
1655*8975f5c5SAndroid Build Coastguard Worker     {
1656*8975f5c5SAndroid Build Coastguard Worker         mFunctions->enable(GL_DEPTH_TEST);
1657*8975f5c5SAndroid Build Coastguard Worker     }
1658*8975f5c5SAndroid Build Coastguard Worker     else
1659*8975f5c5SAndroid Build Coastguard Worker     {
1660*8975f5c5SAndroid Build Coastguard Worker         mFunctions->disable(GL_DEPTH_TEST);
1661*8975f5c5SAndroid Build Coastguard Worker     }
1662*8975f5c5SAndroid Build Coastguard Worker 
1663*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_DEPTH_TEST_ENABLED);
1664*8975f5c5SAndroid Build Coastguard Worker }
1665*8975f5c5SAndroid Build Coastguard Worker 
setDepthFunc(GLenum depthFunc)1666*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setDepthFunc(GLenum depthFunc)
1667*8975f5c5SAndroid Build Coastguard Worker {
1668*8975f5c5SAndroid Build Coastguard Worker     mDepthFunc = depthFunc;
1669*8975f5c5SAndroid Build Coastguard Worker     mFunctions->depthFunc(mDepthFunc);
1670*8975f5c5SAndroid Build Coastguard Worker 
1671*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_DEPTH_FUNC);
1672*8975f5c5SAndroid Build Coastguard Worker }
1673*8975f5c5SAndroid Build Coastguard Worker 
setDepthMask(bool mask)1674*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setDepthMask(bool mask)
1675*8975f5c5SAndroid Build Coastguard Worker {
1676*8975f5c5SAndroid Build Coastguard Worker     mDepthMask = mask;
1677*8975f5c5SAndroid Build Coastguard Worker     mFunctions->depthMask(mDepthMask);
1678*8975f5c5SAndroid Build Coastguard Worker 
1679*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_DEPTH_MASK);
1680*8975f5c5SAndroid Build Coastguard Worker }
1681*8975f5c5SAndroid Build Coastguard Worker 
setStencilTestEnabled(bool enabled)1682*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setStencilTestEnabled(bool enabled)
1683*8975f5c5SAndroid Build Coastguard Worker {
1684*8975f5c5SAndroid Build Coastguard Worker     mStencilTestEnabled = enabled;
1685*8975f5c5SAndroid Build Coastguard Worker     if (mStencilTestEnabled)
1686*8975f5c5SAndroid Build Coastguard Worker     {
1687*8975f5c5SAndroid Build Coastguard Worker         mFunctions->enable(GL_STENCIL_TEST);
1688*8975f5c5SAndroid Build Coastguard Worker     }
1689*8975f5c5SAndroid Build Coastguard Worker     else
1690*8975f5c5SAndroid Build Coastguard Worker     {
1691*8975f5c5SAndroid Build Coastguard Worker         mFunctions->disable(GL_STENCIL_TEST);
1692*8975f5c5SAndroid Build Coastguard Worker     }
1693*8975f5c5SAndroid Build Coastguard Worker 
1694*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_TEST_ENABLED);
1695*8975f5c5SAndroid Build Coastguard Worker }
1696*8975f5c5SAndroid Build Coastguard Worker 
setStencilFrontWritemask(GLuint mask)1697*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setStencilFrontWritemask(GLuint mask)
1698*8975f5c5SAndroid Build Coastguard Worker {
1699*8975f5c5SAndroid Build Coastguard Worker     mStencilFrontWritemask = mask;
1700*8975f5c5SAndroid Build Coastguard Worker     mFunctions->stencilMaskSeparate(GL_FRONT, mStencilFrontWritemask);
1701*8975f5c5SAndroid Build Coastguard Worker 
1702*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
1703*8975f5c5SAndroid Build Coastguard Worker }
1704*8975f5c5SAndroid Build Coastguard Worker 
setStencilBackWritemask(GLuint mask)1705*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setStencilBackWritemask(GLuint mask)
1706*8975f5c5SAndroid Build Coastguard Worker {
1707*8975f5c5SAndroid Build Coastguard Worker     mStencilBackWritemask = mask;
1708*8975f5c5SAndroid Build Coastguard Worker     mFunctions->stencilMaskSeparate(GL_BACK, mStencilBackWritemask);
1709*8975f5c5SAndroid Build Coastguard Worker 
1710*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_WRITEMASK_BACK);
1711*8975f5c5SAndroid Build Coastguard Worker }
1712*8975f5c5SAndroid Build Coastguard Worker 
setStencilFrontFuncs(GLenum func,GLint ref,GLuint mask)1713*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setStencilFrontFuncs(GLenum func, GLint ref, GLuint mask)
1714*8975f5c5SAndroid Build Coastguard Worker {
1715*8975f5c5SAndroid Build Coastguard Worker     mStencilFrontFunc      = func;
1716*8975f5c5SAndroid Build Coastguard Worker     mStencilFrontRef       = ref;
1717*8975f5c5SAndroid Build Coastguard Worker     mStencilFrontValueMask = mask;
1718*8975f5c5SAndroid Build Coastguard Worker     mFunctions->stencilFuncSeparate(GL_FRONT, mStencilFrontFunc, mStencilFrontRef,
1719*8975f5c5SAndroid Build Coastguard Worker                                     mStencilFrontValueMask);
1720*8975f5c5SAndroid Build Coastguard Worker 
1721*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_FUNCS_FRONT);
1722*8975f5c5SAndroid Build Coastguard Worker }
1723*8975f5c5SAndroid Build Coastguard Worker 
setStencilBackFuncs(GLenum func,GLint ref,GLuint mask)1724*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setStencilBackFuncs(GLenum func, GLint ref, GLuint mask)
1725*8975f5c5SAndroid Build Coastguard Worker {
1726*8975f5c5SAndroid Build Coastguard Worker     mStencilBackFunc      = func;
1727*8975f5c5SAndroid Build Coastguard Worker     mStencilBackRef       = ref;
1728*8975f5c5SAndroid Build Coastguard Worker     mStencilBackValueMask = mask;
1729*8975f5c5SAndroid Build Coastguard Worker     mFunctions->stencilFuncSeparate(GL_BACK, mStencilBackFunc, mStencilBackRef,
1730*8975f5c5SAndroid Build Coastguard Worker                                     mStencilBackValueMask);
1731*8975f5c5SAndroid Build Coastguard Worker 
1732*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_FUNCS_BACK);
1733*8975f5c5SAndroid Build Coastguard Worker }
1734*8975f5c5SAndroid Build Coastguard Worker 
setStencilFrontOps(GLenum sfail,GLenum dpfail,GLenum dppass)1735*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setStencilFrontOps(GLenum sfail, GLenum dpfail, GLenum dppass)
1736*8975f5c5SAndroid Build Coastguard Worker {
1737*8975f5c5SAndroid Build Coastguard Worker     mStencilFrontStencilFailOp          = sfail;
1738*8975f5c5SAndroid Build Coastguard Worker     mStencilFrontStencilPassDepthFailOp = dpfail;
1739*8975f5c5SAndroid Build Coastguard Worker     mStencilFrontStencilPassDepthPassOp = dppass;
1740*8975f5c5SAndroid Build Coastguard Worker     mFunctions->stencilOpSeparate(GL_FRONT, mStencilFrontStencilFailOp,
1741*8975f5c5SAndroid Build Coastguard Worker                                   mStencilFrontStencilPassDepthFailOp,
1742*8975f5c5SAndroid Build Coastguard Worker                                   mStencilFrontStencilPassDepthPassOp);
1743*8975f5c5SAndroid Build Coastguard Worker 
1744*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_OPS_FRONT);
1745*8975f5c5SAndroid Build Coastguard Worker }
1746*8975f5c5SAndroid Build Coastguard Worker 
setStencilBackOps(GLenum sfail,GLenum dpfail,GLenum dppass)1747*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setStencilBackOps(GLenum sfail, GLenum dpfail, GLenum dppass)
1748*8975f5c5SAndroid Build Coastguard Worker {
1749*8975f5c5SAndroid Build Coastguard Worker     mStencilBackStencilFailOp          = sfail;
1750*8975f5c5SAndroid Build Coastguard Worker     mStencilBackStencilPassDepthFailOp = dpfail;
1751*8975f5c5SAndroid Build Coastguard Worker     mStencilBackStencilPassDepthPassOp = dppass;
1752*8975f5c5SAndroid Build Coastguard Worker     mFunctions->stencilOpSeparate(GL_BACK, mStencilBackStencilFailOp,
1753*8975f5c5SAndroid Build Coastguard Worker                                   mStencilBackStencilPassDepthFailOp,
1754*8975f5c5SAndroid Build Coastguard Worker                                   mStencilBackStencilPassDepthPassOp);
1755*8975f5c5SAndroid Build Coastguard Worker 
1756*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_OPS_BACK);
1757*8975f5c5SAndroid Build Coastguard Worker }
1758*8975f5c5SAndroid Build Coastguard Worker 
setCullFaceEnabled(bool enabled)1759*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setCullFaceEnabled(bool enabled)
1760*8975f5c5SAndroid Build Coastguard Worker {
1761*8975f5c5SAndroid Build Coastguard Worker     if (mCullFaceEnabled != enabled)
1762*8975f5c5SAndroid Build Coastguard Worker     {
1763*8975f5c5SAndroid Build Coastguard Worker         mCullFaceEnabled = enabled;
1764*8975f5c5SAndroid Build Coastguard Worker         if (mCullFaceEnabled)
1765*8975f5c5SAndroid Build Coastguard Worker         {
1766*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_CULL_FACE);
1767*8975f5c5SAndroid Build Coastguard Worker         }
1768*8975f5c5SAndroid Build Coastguard Worker         else
1769*8975f5c5SAndroid Build Coastguard Worker         {
1770*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_CULL_FACE);
1771*8975f5c5SAndroid Build Coastguard Worker         }
1772*8975f5c5SAndroid Build Coastguard Worker 
1773*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_CULL_FACE_ENABLED);
1774*8975f5c5SAndroid Build Coastguard Worker     }
1775*8975f5c5SAndroid Build Coastguard Worker }
1776*8975f5c5SAndroid Build Coastguard Worker 
setCullFace(gl::CullFaceMode cullFace)1777*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setCullFace(gl::CullFaceMode cullFace)
1778*8975f5c5SAndroid Build Coastguard Worker {
1779*8975f5c5SAndroid Build Coastguard Worker     if (mCullFace != cullFace)
1780*8975f5c5SAndroid Build Coastguard Worker     {
1781*8975f5c5SAndroid Build Coastguard Worker         mCullFace = cullFace;
1782*8975f5c5SAndroid Build Coastguard Worker         mFunctions->cullFace(ToGLenum(mCullFace));
1783*8975f5c5SAndroid Build Coastguard Worker 
1784*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_CULL_FACE);
1785*8975f5c5SAndroid Build Coastguard Worker     }
1786*8975f5c5SAndroid Build Coastguard Worker }
1787*8975f5c5SAndroid Build Coastguard Worker 
setFrontFace(GLenum frontFace)1788*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setFrontFace(GLenum frontFace)
1789*8975f5c5SAndroid Build Coastguard Worker {
1790*8975f5c5SAndroid Build Coastguard Worker     if (mFrontFace != frontFace)
1791*8975f5c5SAndroid Build Coastguard Worker     {
1792*8975f5c5SAndroid Build Coastguard Worker         mFrontFace = frontFace;
1793*8975f5c5SAndroid Build Coastguard Worker         mFunctions->frontFace(mFrontFace);
1794*8975f5c5SAndroid Build Coastguard Worker 
1795*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_FRONT_FACE);
1796*8975f5c5SAndroid Build Coastguard Worker     }
1797*8975f5c5SAndroid Build Coastguard Worker }
1798*8975f5c5SAndroid Build Coastguard Worker 
setPolygonMode(gl::PolygonMode mode)1799*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setPolygonMode(gl::PolygonMode mode)
1800*8975f5c5SAndroid Build Coastguard Worker {
1801*8975f5c5SAndroid Build Coastguard Worker     if (mPolygonMode != mode)
1802*8975f5c5SAndroid Build Coastguard Worker     {
1803*8975f5c5SAndroid Build Coastguard Worker         mPolygonMode = mode;
1804*8975f5c5SAndroid Build Coastguard Worker         if (mFunctions->standard == STANDARD_GL_DESKTOP)
1805*8975f5c5SAndroid Build Coastguard Worker         {
1806*8975f5c5SAndroid Build Coastguard Worker             mFunctions->polygonMode(GL_FRONT_AND_BACK, ToGLenum(mPolygonMode));
1807*8975f5c5SAndroid Build Coastguard Worker         }
1808*8975f5c5SAndroid Build Coastguard Worker         else
1809*8975f5c5SAndroid Build Coastguard Worker         {
1810*8975f5c5SAndroid Build Coastguard Worker             ASSERT(mFunctions->polygonModeNV);
1811*8975f5c5SAndroid Build Coastguard Worker             mFunctions->polygonModeNV(GL_FRONT_AND_BACK, ToGLenum(mPolygonMode));
1812*8975f5c5SAndroid Build Coastguard Worker         }
1813*8975f5c5SAndroid Build Coastguard Worker 
1814*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
1815*8975f5c5SAndroid Build Coastguard Worker         mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_POLYGON_MODE);
1816*8975f5c5SAndroid Build Coastguard Worker     }
1817*8975f5c5SAndroid Build Coastguard Worker }
1818*8975f5c5SAndroid Build Coastguard Worker 
setPolygonOffsetPointEnabled(bool enabled)1819*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setPolygonOffsetPointEnabled(bool enabled)
1820*8975f5c5SAndroid Build Coastguard Worker {
1821*8975f5c5SAndroid Build Coastguard Worker     if (mPolygonOffsetPointEnabled != enabled)
1822*8975f5c5SAndroid Build Coastguard Worker     {
1823*8975f5c5SAndroid Build Coastguard Worker         mPolygonOffsetPointEnabled = enabled;
1824*8975f5c5SAndroid Build Coastguard Worker         if (mPolygonOffsetPointEnabled)
1825*8975f5c5SAndroid Build Coastguard Worker         {
1826*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_POLYGON_OFFSET_POINT_NV);
1827*8975f5c5SAndroid Build Coastguard Worker         }
1828*8975f5c5SAndroid Build Coastguard Worker         else
1829*8975f5c5SAndroid Build Coastguard Worker         {
1830*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_POLYGON_OFFSET_POINT_NV);
1831*8975f5c5SAndroid Build Coastguard Worker         }
1832*8975f5c5SAndroid Build Coastguard Worker 
1833*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
1834*8975f5c5SAndroid Build Coastguard Worker         mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_POLYGON_OFFSET_POINT_ENABLED);
1835*8975f5c5SAndroid Build Coastguard Worker     }
1836*8975f5c5SAndroid Build Coastguard Worker }
1837*8975f5c5SAndroid Build Coastguard Worker 
setPolygonOffsetLineEnabled(bool enabled)1838*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setPolygonOffsetLineEnabled(bool enabled)
1839*8975f5c5SAndroid Build Coastguard Worker {
1840*8975f5c5SAndroid Build Coastguard Worker     if (mPolygonOffsetLineEnabled != enabled)
1841*8975f5c5SAndroid Build Coastguard Worker     {
1842*8975f5c5SAndroid Build Coastguard Worker         mPolygonOffsetLineEnabled = enabled;
1843*8975f5c5SAndroid Build Coastguard Worker         if (mPolygonOffsetLineEnabled)
1844*8975f5c5SAndroid Build Coastguard Worker         {
1845*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_POLYGON_OFFSET_LINE_NV);
1846*8975f5c5SAndroid Build Coastguard Worker         }
1847*8975f5c5SAndroid Build Coastguard Worker         else
1848*8975f5c5SAndroid Build Coastguard Worker         {
1849*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_POLYGON_OFFSET_LINE_NV);
1850*8975f5c5SAndroid Build Coastguard Worker         }
1851*8975f5c5SAndroid Build Coastguard Worker 
1852*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
1853*8975f5c5SAndroid Build Coastguard Worker         mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_POLYGON_OFFSET_LINE_ENABLED);
1854*8975f5c5SAndroid Build Coastguard Worker     }
1855*8975f5c5SAndroid Build Coastguard Worker }
1856*8975f5c5SAndroid Build Coastguard Worker 
setPolygonOffsetFillEnabled(bool enabled)1857*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setPolygonOffsetFillEnabled(bool enabled)
1858*8975f5c5SAndroid Build Coastguard Worker {
1859*8975f5c5SAndroid Build Coastguard Worker     if (mPolygonOffsetFillEnabled != enabled)
1860*8975f5c5SAndroid Build Coastguard Worker     {
1861*8975f5c5SAndroid Build Coastguard Worker         mPolygonOffsetFillEnabled = enabled;
1862*8975f5c5SAndroid Build Coastguard Worker         if (mPolygonOffsetFillEnabled)
1863*8975f5c5SAndroid Build Coastguard Worker         {
1864*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_POLYGON_OFFSET_FILL);
1865*8975f5c5SAndroid Build Coastguard Worker         }
1866*8975f5c5SAndroid Build Coastguard Worker         else
1867*8975f5c5SAndroid Build Coastguard Worker         {
1868*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_POLYGON_OFFSET_FILL);
1869*8975f5c5SAndroid Build Coastguard Worker         }
1870*8975f5c5SAndroid Build Coastguard Worker 
1871*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
1872*8975f5c5SAndroid Build Coastguard Worker     }
1873*8975f5c5SAndroid Build Coastguard Worker }
1874*8975f5c5SAndroid Build Coastguard Worker 
setPolygonOffset(float factor,float units,float clamp)1875*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setPolygonOffset(float factor, float units, float clamp)
1876*8975f5c5SAndroid Build Coastguard Worker {
1877*8975f5c5SAndroid Build Coastguard Worker     if (mPolygonOffsetFactor != factor || mPolygonOffsetUnits != units ||
1878*8975f5c5SAndroid Build Coastguard Worker         mPolygonOffsetClamp != clamp)
1879*8975f5c5SAndroid Build Coastguard Worker     {
1880*8975f5c5SAndroid Build Coastguard Worker         mPolygonOffsetFactor = factor;
1881*8975f5c5SAndroid Build Coastguard Worker         mPolygonOffsetUnits  = units;
1882*8975f5c5SAndroid Build Coastguard Worker         mPolygonOffsetClamp  = clamp;
1883*8975f5c5SAndroid Build Coastguard Worker 
1884*8975f5c5SAndroid Build Coastguard Worker         if (clamp == 0.0f)
1885*8975f5c5SAndroid Build Coastguard Worker         {
1886*8975f5c5SAndroid Build Coastguard Worker             mFunctions->polygonOffset(mPolygonOffsetFactor, mPolygonOffsetUnits);
1887*8975f5c5SAndroid Build Coastguard Worker         }
1888*8975f5c5SAndroid Build Coastguard Worker         else
1889*8975f5c5SAndroid Build Coastguard Worker         {
1890*8975f5c5SAndroid Build Coastguard Worker             ASSERT(mFunctions->polygonOffsetClampEXT);
1891*8975f5c5SAndroid Build Coastguard Worker             mFunctions->polygonOffsetClampEXT(mPolygonOffsetFactor, mPolygonOffsetUnits,
1892*8975f5c5SAndroid Build Coastguard Worker                                               mPolygonOffsetClamp);
1893*8975f5c5SAndroid Build Coastguard Worker         }
1894*8975f5c5SAndroid Build Coastguard Worker 
1895*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_POLYGON_OFFSET);
1896*8975f5c5SAndroid Build Coastguard Worker     }
1897*8975f5c5SAndroid Build Coastguard Worker }
1898*8975f5c5SAndroid Build Coastguard Worker 
setDepthClampEnabled(bool enabled)1899*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setDepthClampEnabled(bool enabled)
1900*8975f5c5SAndroid Build Coastguard Worker {
1901*8975f5c5SAndroid Build Coastguard Worker     if (mDepthClampEnabled != enabled)
1902*8975f5c5SAndroid Build Coastguard Worker     {
1903*8975f5c5SAndroid Build Coastguard Worker         mDepthClampEnabled = enabled;
1904*8975f5c5SAndroid Build Coastguard Worker         if (mDepthClampEnabled)
1905*8975f5c5SAndroid Build Coastguard Worker         {
1906*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_DEPTH_CLAMP_EXT);
1907*8975f5c5SAndroid Build Coastguard Worker         }
1908*8975f5c5SAndroid Build Coastguard Worker         else
1909*8975f5c5SAndroid Build Coastguard Worker         {
1910*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_DEPTH_CLAMP_EXT);
1911*8975f5c5SAndroid Build Coastguard Worker         }
1912*8975f5c5SAndroid Build Coastguard Worker 
1913*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
1914*8975f5c5SAndroid Build Coastguard Worker         mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED);
1915*8975f5c5SAndroid Build Coastguard Worker     }
1916*8975f5c5SAndroid Build Coastguard Worker }
1917*8975f5c5SAndroid Build Coastguard Worker 
setRasterizerDiscardEnabled(bool enabled)1918*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setRasterizerDiscardEnabled(bool enabled)
1919*8975f5c5SAndroid Build Coastguard Worker {
1920*8975f5c5SAndroid Build Coastguard Worker     if (mRasterizerDiscardEnabled != enabled)
1921*8975f5c5SAndroid Build Coastguard Worker     {
1922*8975f5c5SAndroid Build Coastguard Worker         mRasterizerDiscardEnabled = enabled;
1923*8975f5c5SAndroid Build Coastguard Worker         if (mRasterizerDiscardEnabled)
1924*8975f5c5SAndroid Build Coastguard Worker         {
1925*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_RASTERIZER_DISCARD);
1926*8975f5c5SAndroid Build Coastguard Worker         }
1927*8975f5c5SAndroid Build Coastguard Worker         else
1928*8975f5c5SAndroid Build Coastguard Worker         {
1929*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_RASTERIZER_DISCARD);
1930*8975f5c5SAndroid Build Coastguard Worker         }
1931*8975f5c5SAndroid Build Coastguard Worker 
1932*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED);
1933*8975f5c5SAndroid Build Coastguard Worker     }
1934*8975f5c5SAndroid Build Coastguard Worker }
1935*8975f5c5SAndroid Build Coastguard Worker 
setLineWidth(float width)1936*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setLineWidth(float width)
1937*8975f5c5SAndroid Build Coastguard Worker {
1938*8975f5c5SAndroid Build Coastguard Worker     if (mLineWidth != width)
1939*8975f5c5SAndroid Build Coastguard Worker     {
1940*8975f5c5SAndroid Build Coastguard Worker         mLineWidth = width;
1941*8975f5c5SAndroid Build Coastguard Worker         mFunctions->lineWidth(mLineWidth);
1942*8975f5c5SAndroid Build Coastguard Worker 
1943*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_LINE_WIDTH);
1944*8975f5c5SAndroid Build Coastguard Worker     }
1945*8975f5c5SAndroid Build Coastguard Worker }
1946*8975f5c5SAndroid Build Coastguard Worker 
setPrimitiveRestartEnabled(const gl::Context * context,bool enabled)1947*8975f5c5SAndroid Build Coastguard Worker angle::Result StateManagerGL::setPrimitiveRestartEnabled(const gl::Context *context, bool enabled)
1948*8975f5c5SAndroid Build Coastguard Worker {
1949*8975f5c5SAndroid Build Coastguard Worker     if (mPrimitiveRestartEnabled != enabled)
1950*8975f5c5SAndroid Build Coastguard Worker     {
1951*8975f5c5SAndroid Build Coastguard Worker         GLenum cap = mFeatures.emulatePrimitiveRestartFixedIndex.enabled
1952*8975f5c5SAndroid Build Coastguard Worker                          ? GL_PRIMITIVE_RESTART
1953*8975f5c5SAndroid Build Coastguard Worker                          : GL_PRIMITIVE_RESTART_FIXED_INDEX;
1954*8975f5c5SAndroid Build Coastguard Worker 
1955*8975f5c5SAndroid Build Coastguard Worker         if (enabled)
1956*8975f5c5SAndroid Build Coastguard Worker         {
1957*8975f5c5SAndroid Build Coastguard Worker             ANGLE_GL_TRY(context, mFunctions->enable(cap));
1958*8975f5c5SAndroid Build Coastguard Worker         }
1959*8975f5c5SAndroid Build Coastguard Worker         else
1960*8975f5c5SAndroid Build Coastguard Worker         {
1961*8975f5c5SAndroid Build Coastguard Worker             ANGLE_GL_TRY(context, mFunctions->disable(cap));
1962*8975f5c5SAndroid Build Coastguard Worker         }
1963*8975f5c5SAndroid Build Coastguard Worker         mPrimitiveRestartEnabled = enabled;
1964*8975f5c5SAndroid Build Coastguard Worker 
1965*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED);
1966*8975f5c5SAndroid Build Coastguard Worker     }
1967*8975f5c5SAndroid Build Coastguard Worker 
1968*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
1969*8975f5c5SAndroid Build Coastguard Worker }
1970*8975f5c5SAndroid Build Coastguard Worker 
setPrimitiveRestartIndex(const gl::Context * context,GLuint index)1971*8975f5c5SAndroid Build Coastguard Worker angle::Result StateManagerGL::setPrimitiveRestartIndex(const gl::Context *context, GLuint index)
1972*8975f5c5SAndroid Build Coastguard Worker {
1973*8975f5c5SAndroid Build Coastguard Worker     if (mPrimitiveRestartIndex != index)
1974*8975f5c5SAndroid Build Coastguard Worker     {
1975*8975f5c5SAndroid Build Coastguard Worker         ANGLE_GL_TRY(context, mFunctions->primitiveRestartIndex(index));
1976*8975f5c5SAndroid Build Coastguard Worker         mPrimitiveRestartIndex = index;
1977*8975f5c5SAndroid Build Coastguard Worker 
1978*8975f5c5SAndroid Build Coastguard Worker         // No dirty bit for this state, it is not exposed to the frontend.
1979*8975f5c5SAndroid Build Coastguard Worker     }
1980*8975f5c5SAndroid Build Coastguard Worker 
1981*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
1982*8975f5c5SAndroid Build Coastguard Worker }
1983*8975f5c5SAndroid Build Coastguard Worker 
setClearDepth(float clearDepth)1984*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setClearDepth(float clearDepth)
1985*8975f5c5SAndroid Build Coastguard Worker {
1986*8975f5c5SAndroid Build Coastguard Worker     if (mClearDepth != clearDepth)
1987*8975f5c5SAndroid Build Coastguard Worker     {
1988*8975f5c5SAndroid Build Coastguard Worker         mClearDepth = clearDepth;
1989*8975f5c5SAndroid Build Coastguard Worker 
1990*8975f5c5SAndroid Build Coastguard Worker         // The glClearDepthf function isn't available until OpenGL 4.1.  Prefer it when it is
1991*8975f5c5SAndroid Build Coastguard Worker         // available because OpenGL ES only works in floats.
1992*8975f5c5SAndroid Build Coastguard Worker         if (mFunctions->clearDepthf)
1993*8975f5c5SAndroid Build Coastguard Worker         {
1994*8975f5c5SAndroid Build Coastguard Worker             mFunctions->clearDepthf(mClearDepth);
1995*8975f5c5SAndroid Build Coastguard Worker         }
1996*8975f5c5SAndroid Build Coastguard Worker         else
1997*8975f5c5SAndroid Build Coastguard Worker         {
1998*8975f5c5SAndroid Build Coastguard Worker             ASSERT(mFunctions->clearDepth);
1999*8975f5c5SAndroid Build Coastguard Worker             mFunctions->clearDepth(mClearDepth);
2000*8975f5c5SAndroid Build Coastguard Worker         }
2001*8975f5c5SAndroid Build Coastguard Worker 
2002*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_CLEAR_DEPTH);
2003*8975f5c5SAndroid Build Coastguard Worker     }
2004*8975f5c5SAndroid Build Coastguard Worker }
2005*8975f5c5SAndroid Build Coastguard Worker 
setClearColor(const gl::ColorF & clearColor)2006*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setClearColor(const gl::ColorF &clearColor)
2007*8975f5c5SAndroid Build Coastguard Worker {
2008*8975f5c5SAndroid Build Coastguard Worker     gl::ColorF modifiedClearColor = clearColor;
2009*8975f5c5SAndroid Build Coastguard Worker     if (mFeatures.clearToZeroOrOneBroken.enabled &&
2010*8975f5c5SAndroid Build Coastguard Worker         (clearColor.red == 1.0f || clearColor.red == 0.0f) &&
2011*8975f5c5SAndroid Build Coastguard Worker         (clearColor.green == 1.0f || clearColor.green == 0.0f) &&
2012*8975f5c5SAndroid Build Coastguard Worker         (clearColor.blue == 1.0f || clearColor.blue == 0.0f) &&
2013*8975f5c5SAndroid Build Coastguard Worker         (clearColor.alpha == 1.0f || clearColor.alpha == 0.0f))
2014*8975f5c5SAndroid Build Coastguard Worker     {
2015*8975f5c5SAndroid Build Coastguard Worker         if (clearColor.alpha == 1.0f)
2016*8975f5c5SAndroid Build Coastguard Worker         {
2017*8975f5c5SAndroid Build Coastguard Worker             modifiedClearColor.alpha = 2.0f;
2018*8975f5c5SAndroid Build Coastguard Worker         }
2019*8975f5c5SAndroid Build Coastguard Worker         else
2020*8975f5c5SAndroid Build Coastguard Worker         {
2021*8975f5c5SAndroid Build Coastguard Worker             modifiedClearColor.alpha = -1.0f;
2022*8975f5c5SAndroid Build Coastguard Worker         }
2023*8975f5c5SAndroid Build Coastguard Worker     }
2024*8975f5c5SAndroid Build Coastguard Worker 
2025*8975f5c5SAndroid Build Coastguard Worker     if (mClearColor != modifiedClearColor)
2026*8975f5c5SAndroid Build Coastguard Worker     {
2027*8975f5c5SAndroid Build Coastguard Worker         mClearColor = modifiedClearColor;
2028*8975f5c5SAndroid Build Coastguard Worker         mFunctions->clearColor(mClearColor.red, mClearColor.green, mClearColor.blue,
2029*8975f5c5SAndroid Build Coastguard Worker                                mClearColor.alpha);
2030*8975f5c5SAndroid Build Coastguard Worker 
2031*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_CLEAR_COLOR);
2032*8975f5c5SAndroid Build Coastguard Worker     }
2033*8975f5c5SAndroid Build Coastguard Worker }
2034*8975f5c5SAndroid Build Coastguard Worker 
setClearStencil(GLint clearStencil)2035*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setClearStencil(GLint clearStencil)
2036*8975f5c5SAndroid Build Coastguard Worker {
2037*8975f5c5SAndroid Build Coastguard Worker     if (mClearStencil != clearStencil)
2038*8975f5c5SAndroid Build Coastguard Worker     {
2039*8975f5c5SAndroid Build Coastguard Worker         mClearStencil = clearStencil;
2040*8975f5c5SAndroid Build Coastguard Worker         mFunctions->clearStencil(mClearStencil);
2041*8975f5c5SAndroid Build Coastguard Worker 
2042*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_CLEAR_STENCIL);
2043*8975f5c5SAndroid Build Coastguard Worker     }
2044*8975f5c5SAndroid Build Coastguard Worker }
2045*8975f5c5SAndroid Build Coastguard Worker 
syncState(const gl::Context * context,const gl::state::DirtyBits & glDirtyBits,const gl::state::DirtyBits & bitMask,const gl::state::ExtendedDirtyBits & extendedDirtyBits,const gl::state::ExtendedDirtyBits & extendedBitMask)2046*8975f5c5SAndroid Build Coastguard Worker angle::Result StateManagerGL::syncState(const gl::Context *context,
2047*8975f5c5SAndroid Build Coastguard Worker                                         const gl::state::DirtyBits &glDirtyBits,
2048*8975f5c5SAndroid Build Coastguard Worker                                         const gl::state::DirtyBits &bitMask,
2049*8975f5c5SAndroid Build Coastguard Worker                                         const gl::state::ExtendedDirtyBits &extendedDirtyBits,
2050*8975f5c5SAndroid Build Coastguard Worker                                         const gl::state::ExtendedDirtyBits &extendedBitMask)
2051*8975f5c5SAndroid Build Coastguard Worker {
2052*8975f5c5SAndroid Build Coastguard Worker     const gl::State &state = context->getState();
2053*8975f5c5SAndroid Build Coastguard Worker 
2054*8975f5c5SAndroid Build Coastguard Worker     const gl::state::DirtyBits glAndLocalDirtyBits = (glDirtyBits | mLocalDirtyBits) & bitMask;
2055*8975f5c5SAndroid Build Coastguard Worker     if (!glAndLocalDirtyBits.any())
2056*8975f5c5SAndroid Build Coastguard Worker     {
2057*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Continue;
2058*8975f5c5SAndroid Build Coastguard Worker     }
2059*8975f5c5SAndroid Build Coastguard Worker 
2060*8975f5c5SAndroid Build Coastguard Worker     // TODO(jmadill): Investigate only syncing vertex state for active attributes
2061*8975f5c5SAndroid Build Coastguard Worker     for (auto iter = glAndLocalDirtyBits.begin(), endIter = glAndLocalDirtyBits.end();
2062*8975f5c5SAndroid Build Coastguard Worker          iter != endIter; ++iter)
2063*8975f5c5SAndroid Build Coastguard Worker     {
2064*8975f5c5SAndroid Build Coastguard Worker         switch (*iter)
2065*8975f5c5SAndroid Build Coastguard Worker         {
2066*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_SCISSOR_TEST_ENABLED:
2067*8975f5c5SAndroid Build Coastguard Worker                 setScissorTestEnabled(state.isScissorTestEnabled());
2068*8975f5c5SAndroid Build Coastguard Worker                 break;
2069*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_SCISSOR:
2070*8975f5c5SAndroid Build Coastguard Worker             {
2071*8975f5c5SAndroid Build Coastguard Worker                 const gl::Rectangle &scissor = state.getScissor();
2072*8975f5c5SAndroid Build Coastguard Worker                 setScissor(scissor);
2073*8975f5c5SAndroid Build Coastguard Worker             }
2074*8975f5c5SAndroid Build Coastguard Worker             break;
2075*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_VIEWPORT:
2076*8975f5c5SAndroid Build Coastguard Worker             {
2077*8975f5c5SAndroid Build Coastguard Worker                 const gl::Rectangle &viewport = state.getViewport();
2078*8975f5c5SAndroid Build Coastguard Worker                 setViewport(viewport);
2079*8975f5c5SAndroid Build Coastguard Worker             }
2080*8975f5c5SAndroid Build Coastguard Worker             break;
2081*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_DEPTH_RANGE:
2082*8975f5c5SAndroid Build Coastguard Worker                 setDepthRange(state.getNearPlane(), state.getFarPlane());
2083*8975f5c5SAndroid Build Coastguard Worker                 break;
2084*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_BLEND_ENABLED:
2085*8975f5c5SAndroid Build Coastguard Worker                 if (mIndependentBlendStates)
2086*8975f5c5SAndroid Build Coastguard Worker                 {
2087*8975f5c5SAndroid Build Coastguard Worker                     setBlendEnabledIndexed(state.getBlendEnabledDrawBufferMask());
2088*8975f5c5SAndroid Build Coastguard Worker                 }
2089*8975f5c5SAndroid Build Coastguard Worker                 else
2090*8975f5c5SAndroid Build Coastguard Worker                 {
2091*8975f5c5SAndroid Build Coastguard Worker                     setBlendEnabled(state.isBlendEnabled());
2092*8975f5c5SAndroid Build Coastguard Worker                 }
2093*8975f5c5SAndroid Build Coastguard Worker                 break;
2094*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_BLEND_COLOR:
2095*8975f5c5SAndroid Build Coastguard Worker                 setBlendColor(state.getBlendColor());
2096*8975f5c5SAndroid Build Coastguard Worker                 break;
2097*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_BLEND_FUNCS:
2098*8975f5c5SAndroid Build Coastguard Worker             {
2099*8975f5c5SAndroid Build Coastguard Worker                 setBlendFuncs(state.getBlendStateExt());
2100*8975f5c5SAndroid Build Coastguard Worker                 break;
2101*8975f5c5SAndroid Build Coastguard Worker             }
2102*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_BLEND_EQUATIONS:
2103*8975f5c5SAndroid Build Coastguard Worker             {
2104*8975f5c5SAndroid Build Coastguard Worker                 setBlendEquations(state.getBlendStateExt());
2105*8975f5c5SAndroid Build Coastguard Worker                 break;
2106*8975f5c5SAndroid Build Coastguard Worker             }
2107*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_COLOR_MASK:
2108*8975f5c5SAndroid Build Coastguard Worker             {
2109*8975f5c5SAndroid Build Coastguard Worker                 const gl::Framebuffer *framebuffer = state.getDrawFramebuffer();
2110*8975f5c5SAndroid Build Coastguard Worker                 const FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
2111*8975f5c5SAndroid Build Coastguard Worker                 const bool disableAlphaWrite =
2112*8975f5c5SAndroid Build Coastguard Worker                     framebufferGL->hasEmulatedAlphaChannelTextureAttachment();
2113*8975f5c5SAndroid Build Coastguard Worker 
2114*8975f5c5SAndroid Build Coastguard Worker                 setColorMaskForFramebuffer(state.getBlendStateExt(), disableAlphaWrite);
2115*8975f5c5SAndroid Build Coastguard Worker                 break;
2116*8975f5c5SAndroid Build Coastguard Worker             }
2117*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_SAMPLE_ALPHA_TO_COVERAGE_ENABLED:
2118*8975f5c5SAndroid Build Coastguard Worker                 setSampleAlphaToCoverageEnabled(state.isSampleAlphaToCoverageEnabled());
2119*8975f5c5SAndroid Build Coastguard Worker                 break;
2120*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED:
2121*8975f5c5SAndroid Build Coastguard Worker                 setSampleCoverageEnabled(state.isSampleCoverageEnabled());
2122*8975f5c5SAndroid Build Coastguard Worker                 break;
2123*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_SAMPLE_COVERAGE:
2124*8975f5c5SAndroid Build Coastguard Worker                 setSampleCoverage(state.getSampleCoverageValue(), state.getSampleCoverageInvert());
2125*8975f5c5SAndroid Build Coastguard Worker                 break;
2126*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_DEPTH_TEST_ENABLED:
2127*8975f5c5SAndroid Build Coastguard Worker                 setDepthTestEnabled(state.isDepthTestEnabled());
2128*8975f5c5SAndroid Build Coastguard Worker                 break;
2129*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_DEPTH_FUNC:
2130*8975f5c5SAndroid Build Coastguard Worker                 setDepthFunc(state.getDepthStencilState().depthFunc);
2131*8975f5c5SAndroid Build Coastguard Worker                 break;
2132*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_DEPTH_MASK:
2133*8975f5c5SAndroid Build Coastguard Worker                 setDepthMask(state.getDepthStencilState().depthMask);
2134*8975f5c5SAndroid Build Coastguard Worker                 break;
2135*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_STENCIL_TEST_ENABLED:
2136*8975f5c5SAndroid Build Coastguard Worker                 setStencilTestEnabled(state.isStencilTestEnabled());
2137*8975f5c5SAndroid Build Coastguard Worker                 break;
2138*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_STENCIL_FUNCS_FRONT:
2139*8975f5c5SAndroid Build Coastguard Worker             {
2140*8975f5c5SAndroid Build Coastguard Worker                 const auto &depthStencilState = state.getDepthStencilState();
2141*8975f5c5SAndroid Build Coastguard Worker                 setStencilFrontFuncs(depthStencilState.stencilFunc, state.getStencilRef(),
2142*8975f5c5SAndroid Build Coastguard Worker                                      depthStencilState.stencilMask);
2143*8975f5c5SAndroid Build Coastguard Worker                 break;
2144*8975f5c5SAndroid Build Coastguard Worker             }
2145*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_STENCIL_FUNCS_BACK:
2146*8975f5c5SAndroid Build Coastguard Worker             {
2147*8975f5c5SAndroid Build Coastguard Worker                 const auto &depthStencilState = state.getDepthStencilState();
2148*8975f5c5SAndroid Build Coastguard Worker                 setStencilBackFuncs(depthStencilState.stencilBackFunc, state.getStencilBackRef(),
2149*8975f5c5SAndroid Build Coastguard Worker                                     depthStencilState.stencilBackMask);
2150*8975f5c5SAndroid Build Coastguard Worker                 break;
2151*8975f5c5SAndroid Build Coastguard Worker             }
2152*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_STENCIL_OPS_FRONT:
2153*8975f5c5SAndroid Build Coastguard Worker             {
2154*8975f5c5SAndroid Build Coastguard Worker                 const auto &depthStencilState = state.getDepthStencilState();
2155*8975f5c5SAndroid Build Coastguard Worker                 setStencilFrontOps(depthStencilState.stencilFail,
2156*8975f5c5SAndroid Build Coastguard Worker                                    depthStencilState.stencilPassDepthFail,
2157*8975f5c5SAndroid Build Coastguard Worker                                    depthStencilState.stencilPassDepthPass);
2158*8975f5c5SAndroid Build Coastguard Worker                 break;
2159*8975f5c5SAndroid Build Coastguard Worker             }
2160*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_STENCIL_OPS_BACK:
2161*8975f5c5SAndroid Build Coastguard Worker             {
2162*8975f5c5SAndroid Build Coastguard Worker                 const auto &depthStencilState = state.getDepthStencilState();
2163*8975f5c5SAndroid Build Coastguard Worker                 setStencilBackOps(depthStencilState.stencilBackFail,
2164*8975f5c5SAndroid Build Coastguard Worker                                   depthStencilState.stencilBackPassDepthFail,
2165*8975f5c5SAndroid Build Coastguard Worker                                   depthStencilState.stencilBackPassDepthPass);
2166*8975f5c5SAndroid Build Coastguard Worker                 break;
2167*8975f5c5SAndroid Build Coastguard Worker             }
2168*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_STENCIL_WRITEMASK_FRONT:
2169*8975f5c5SAndroid Build Coastguard Worker                 setStencilFrontWritemask(state.getDepthStencilState().stencilWritemask);
2170*8975f5c5SAndroid Build Coastguard Worker                 break;
2171*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_STENCIL_WRITEMASK_BACK:
2172*8975f5c5SAndroid Build Coastguard Worker                 setStencilBackWritemask(state.getDepthStencilState().stencilBackWritemask);
2173*8975f5c5SAndroid Build Coastguard Worker                 break;
2174*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_CULL_FACE_ENABLED:
2175*8975f5c5SAndroid Build Coastguard Worker                 setCullFaceEnabled(state.isCullFaceEnabled());
2176*8975f5c5SAndroid Build Coastguard Worker                 break;
2177*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_CULL_FACE:
2178*8975f5c5SAndroid Build Coastguard Worker                 setCullFace(state.getRasterizerState().cullMode);
2179*8975f5c5SAndroid Build Coastguard Worker                 break;
2180*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_FRONT_FACE:
2181*8975f5c5SAndroid Build Coastguard Worker                 if (mFeatures.emulateClipOrigin.enabled)
2182*8975f5c5SAndroid Build Coastguard Worker                 {
2183*8975f5c5SAndroid Build Coastguard Worker                     static_assert((GL_CW ^ GL_CCW) ==
2184*8975f5c5SAndroid Build Coastguard Worker                                   static_cast<GLenum>(gl::ClipOrigin::UpperLeft));
2185*8975f5c5SAndroid Build Coastguard Worker                     setFrontFace(state.getRasterizerState().frontFace ^
2186*8975f5c5SAndroid Build Coastguard Worker                                  static_cast<GLenum>(state.getClipOrigin()));
2187*8975f5c5SAndroid Build Coastguard Worker                     break;
2188*8975f5c5SAndroid Build Coastguard Worker                 }
2189*8975f5c5SAndroid Build Coastguard Worker                 setFrontFace(state.getRasterizerState().frontFace);
2190*8975f5c5SAndroid Build Coastguard Worker                 break;
2191*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED:
2192*8975f5c5SAndroid Build Coastguard Worker                 setPolygonOffsetFillEnabled(state.isPolygonOffsetFillEnabled());
2193*8975f5c5SAndroid Build Coastguard Worker                 break;
2194*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_POLYGON_OFFSET:
2195*8975f5c5SAndroid Build Coastguard Worker             {
2196*8975f5c5SAndroid Build Coastguard Worker                 const auto &rasterizerState = state.getRasterizerState();
2197*8975f5c5SAndroid Build Coastguard Worker                 setPolygonOffset(rasterizerState.polygonOffsetFactor,
2198*8975f5c5SAndroid Build Coastguard Worker                                  rasterizerState.polygonOffsetUnits,
2199*8975f5c5SAndroid Build Coastguard Worker                                  rasterizerState.polygonOffsetClamp);
2200*8975f5c5SAndroid Build Coastguard Worker                 break;
2201*8975f5c5SAndroid Build Coastguard Worker             }
2202*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
2203*8975f5c5SAndroid Build Coastguard Worker                 setRasterizerDiscardEnabled(state.isRasterizerDiscardEnabled());
2204*8975f5c5SAndroid Build Coastguard Worker                 break;
2205*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_LINE_WIDTH:
2206*8975f5c5SAndroid Build Coastguard Worker                 setLineWidth(state.getLineWidth());
2207*8975f5c5SAndroid Build Coastguard Worker                 break;
2208*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_PRIMITIVE_RESTART_ENABLED:
2209*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_TRY(setPrimitiveRestartEnabled(context, state.isPrimitiveRestartEnabled()));
2210*8975f5c5SAndroid Build Coastguard Worker                 break;
2211*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_CLEAR_COLOR:
2212*8975f5c5SAndroid Build Coastguard Worker                 setClearColor(state.getColorClearValue());
2213*8975f5c5SAndroid Build Coastguard Worker                 break;
2214*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_CLEAR_DEPTH:
2215*8975f5c5SAndroid Build Coastguard Worker                 setClearDepth(state.getDepthClearValue());
2216*8975f5c5SAndroid Build Coastguard Worker                 break;
2217*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_CLEAR_STENCIL:
2218*8975f5c5SAndroid Build Coastguard Worker                 setClearStencil(state.getStencilClearValue());
2219*8975f5c5SAndroid Build Coastguard Worker                 break;
2220*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_UNPACK_STATE:
2221*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_TRY(setPixelUnpackState(context, state.getUnpackState()));
2222*8975f5c5SAndroid Build Coastguard Worker                 break;
2223*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_UNPACK_BUFFER_BINDING:
2224*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_TRY(setPixelUnpackBuffer(
2225*8975f5c5SAndroid Build Coastguard Worker                     context, state.getTargetBuffer(gl::BufferBinding::PixelUnpack)));
2226*8975f5c5SAndroid Build Coastguard Worker                 break;
2227*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_PACK_STATE:
2228*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_TRY(setPixelPackState(context, state.getPackState()));
2229*8975f5c5SAndroid Build Coastguard Worker                 break;
2230*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_PACK_BUFFER_BINDING:
2231*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_TRY(setPixelPackBuffer(context,
2232*8975f5c5SAndroid Build Coastguard Worker                                              state.getTargetBuffer(gl::BufferBinding::PixelPack)));
2233*8975f5c5SAndroid Build Coastguard Worker                 break;
2234*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_DITHER_ENABLED:
2235*8975f5c5SAndroid Build Coastguard Worker                 setDitherEnabled(state.isDitherEnabled());
2236*8975f5c5SAndroid Build Coastguard Worker                 break;
2237*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_READ_FRAMEBUFFER_BINDING:
2238*8975f5c5SAndroid Build Coastguard Worker             {
2239*8975f5c5SAndroid Build Coastguard Worker                 gl::Framebuffer *framebuffer = state.getReadFramebuffer();
2240*8975f5c5SAndroid Build Coastguard Worker 
2241*8975f5c5SAndroid Build Coastguard Worker                 // Necessary for an Intel TexImage workaround.
2242*8975f5c5SAndroid Build Coastguard Worker                 if (!framebuffer)
2243*8975f5c5SAndroid Build Coastguard Worker                     continue;
2244*8975f5c5SAndroid Build Coastguard Worker 
2245*8975f5c5SAndroid Build Coastguard Worker                 FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
2246*8975f5c5SAndroid Build Coastguard Worker                 bindFramebuffer(
2247*8975f5c5SAndroid Build Coastguard Worker                     mHasSeparateFramebufferBindings ? GL_READ_FRAMEBUFFER : GL_FRAMEBUFFER,
2248*8975f5c5SAndroid Build Coastguard Worker                     framebufferGL->getFramebufferID());
2249*8975f5c5SAndroid Build Coastguard Worker                 break;
2250*8975f5c5SAndroid Build Coastguard Worker             }
2251*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING:
2252*8975f5c5SAndroid Build Coastguard Worker             {
2253*8975f5c5SAndroid Build Coastguard Worker                 gl::Framebuffer *framebuffer = state.getDrawFramebuffer();
2254*8975f5c5SAndroid Build Coastguard Worker 
2255*8975f5c5SAndroid Build Coastguard Worker                 // Necessary for an Intel TexImage workaround.
2256*8975f5c5SAndroid Build Coastguard Worker                 if (!framebuffer)
2257*8975f5c5SAndroid Build Coastguard Worker                     continue;
2258*8975f5c5SAndroid Build Coastguard Worker 
2259*8975f5c5SAndroid Build Coastguard Worker                 FramebufferGL *framebufferGL = GetImplAs<FramebufferGL>(framebuffer);
2260*8975f5c5SAndroid Build Coastguard Worker                 bindFramebuffer(
2261*8975f5c5SAndroid Build Coastguard Worker                     mHasSeparateFramebufferBindings ? GL_DRAW_FRAMEBUFFER : GL_FRAMEBUFFER,
2262*8975f5c5SAndroid Build Coastguard Worker                     framebufferGL->getFramebufferID());
2263*8975f5c5SAndroid Build Coastguard Worker 
2264*8975f5c5SAndroid Build Coastguard Worker                 const gl::ProgramExecutable *executable = state.getProgramExecutable();
2265*8975f5c5SAndroid Build Coastguard Worker                 if (executable)
2266*8975f5c5SAndroid Build Coastguard Worker                 {
2267*8975f5c5SAndroid Build Coastguard Worker                     updateMultiviewBaseViewLayerIndexUniform(executable, framebufferGL->getState());
2268*8975f5c5SAndroid Build Coastguard Worker                 }
2269*8975f5c5SAndroid Build Coastguard Worker 
2270*8975f5c5SAndroid Build Coastguard Worker                 // Changing the draw framebuffer binding sometimes requires resetting srgb blending.
2271*8975f5c5SAndroid Build Coastguard Worker                 iter.setLaterBit(gl::state::DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
2272*8975f5c5SAndroid Build Coastguard Worker 
2273*8975f5c5SAndroid Build Coastguard Worker                 // If the framebuffer is emulating RGB on top of RGBA, the color mask has to be
2274*8975f5c5SAndroid Build Coastguard Worker                 // updated
2275*8975f5c5SAndroid Build Coastguard Worker                 iter.setLaterBit(gl::state::DIRTY_BIT_COLOR_MASK);
2276*8975f5c5SAndroid Build Coastguard Worker                 break;
2277*8975f5c5SAndroid Build Coastguard Worker             }
2278*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_RENDERBUFFER_BINDING:
2279*8975f5c5SAndroid Build Coastguard Worker                 // TODO(jmadill): implement this
2280*8975f5c5SAndroid Build Coastguard Worker                 break;
2281*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_VERTEX_ARRAY_BINDING:
2282*8975f5c5SAndroid Build Coastguard Worker             {
2283*8975f5c5SAndroid Build Coastguard Worker                 VertexArrayGL *vaoGL = GetImplAs<VertexArrayGL>(state.getVertexArray());
2284*8975f5c5SAndroid Build Coastguard Worker                 bindVertexArray(vaoGL->getVertexArrayID(), vaoGL->getNativeState());
2285*8975f5c5SAndroid Build Coastguard Worker 
2286*8975f5c5SAndroid Build Coastguard Worker                 ANGLE_TRY(propagateProgramToVAO(context, state.getProgramExecutable(),
2287*8975f5c5SAndroid Build Coastguard Worker                                                 GetImplAs<VertexArrayGL>(state.getVertexArray())));
2288*8975f5c5SAndroid Build Coastguard Worker 
2289*8975f5c5SAndroid Build Coastguard Worker                 if (vaoGL->syncsToSharedState())
2290*8975f5c5SAndroid Build Coastguard Worker                 {
2291*8975f5c5SAndroid Build Coastguard Worker                     // Re-sync the vertex array because all frontend VAOs share the same backend
2292*8975f5c5SAndroid Build Coastguard Worker                     // state. Only sync bits that can be set in ES2.0 or 3.0
2293*8975f5c5SAndroid Build Coastguard Worker                     gl::VertexArray::DirtyBits dirtyBits;
2294*8975f5c5SAndroid Build Coastguard Worker                     gl::VertexArray::DirtyAttribBitsArray dirtyAttribBits;
2295*8975f5c5SAndroid Build Coastguard Worker                     gl::VertexArray::DirtyBindingBitsArray dirtBindingBits;
2296*8975f5c5SAndroid Build Coastguard Worker 
2297*8975f5c5SAndroid Build Coastguard Worker                     dirtyBits.set(gl::VertexArray::DIRTY_BIT_ELEMENT_ARRAY_BUFFER);
2298*8975f5c5SAndroid Build Coastguard Worker                     for (GLint attrib = 0; attrib < context->getCaps().maxVertexAttributes;
2299*8975f5c5SAndroid Build Coastguard Worker                          attrib++)
2300*8975f5c5SAndroid Build Coastguard Worker                     {
2301*8975f5c5SAndroid Build Coastguard Worker                         dirtyBits.set(gl::VertexArray::DIRTY_BIT_ATTRIB_0 + attrib);
2302*8975f5c5SAndroid Build Coastguard Worker                         dirtyAttribBits[attrib].set(gl::VertexArray::DIRTY_ATTRIB_ENABLED);
2303*8975f5c5SAndroid Build Coastguard Worker                         dirtyAttribBits[attrib].set(gl::VertexArray::DIRTY_ATTRIB_POINTER);
2304*8975f5c5SAndroid Build Coastguard Worker                         dirtyAttribBits[attrib].set(gl::VertexArray::DIRTY_ATTRIB_POINTER_BUFFER);
2305*8975f5c5SAndroid Build Coastguard Worker                     }
2306*8975f5c5SAndroid Build Coastguard Worker                     for (GLint binding = 0; binding < context->getCaps().maxVertexAttribBindings;
2307*8975f5c5SAndroid Build Coastguard Worker                          binding++)
2308*8975f5c5SAndroid Build Coastguard Worker                     {
2309*8975f5c5SAndroid Build Coastguard Worker                         dirtyBits.set(gl::VertexArray::DIRTY_BIT_BINDING_0 + binding);
2310*8975f5c5SAndroid Build Coastguard Worker                         dirtBindingBits[binding].set(gl::VertexArray::DIRTY_BINDING_DIVISOR);
2311*8975f5c5SAndroid Build Coastguard Worker                     }
2312*8975f5c5SAndroid Build Coastguard Worker 
2313*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_TRY(
2314*8975f5c5SAndroid Build Coastguard Worker                         vaoGL->syncState(context, dirtyBits, &dirtyAttribBits, &dirtBindingBits));
2315*8975f5c5SAndroid Build Coastguard Worker                 }
2316*8975f5c5SAndroid Build Coastguard Worker                 break;
2317*8975f5c5SAndroid Build Coastguard Worker             }
2318*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_DRAW_INDIRECT_BUFFER_BINDING:
2319*8975f5c5SAndroid Build Coastguard Worker                 updateDrawIndirectBufferBinding(context);
2320*8975f5c5SAndroid Build Coastguard Worker                 break;
2321*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_DISPATCH_INDIRECT_BUFFER_BINDING:
2322*8975f5c5SAndroid Build Coastguard Worker                 updateDispatchIndirectBufferBinding(context);
2323*8975f5c5SAndroid Build Coastguard Worker                 break;
2324*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_PROGRAM_BINDING:
2325*8975f5c5SAndroid Build Coastguard Worker             {
2326*8975f5c5SAndroid Build Coastguard Worker                 gl::Program *program = state.getProgram();
2327*8975f5c5SAndroid Build Coastguard Worker                 if (program != nullptr)
2328*8975f5c5SAndroid Build Coastguard Worker                 {
2329*8975f5c5SAndroid Build Coastguard Worker                     useProgram(GetImplAs<ProgramGL>(program)->getProgramID());
2330*8975f5c5SAndroid Build Coastguard Worker                 }
2331*8975f5c5SAndroid Build Coastguard Worker                 break;
2332*8975f5c5SAndroid Build Coastguard Worker             }
2333*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_PROGRAM_EXECUTABLE:
2334*8975f5c5SAndroid Build Coastguard Worker             {
2335*8975f5c5SAndroid Build Coastguard Worker                 const gl::ProgramExecutable *executable = state.getProgramExecutable();
2336*8975f5c5SAndroid Build Coastguard Worker 
2337*8975f5c5SAndroid Build Coastguard Worker                 if (executable)
2338*8975f5c5SAndroid Build Coastguard Worker                 {
2339*8975f5c5SAndroid Build Coastguard Worker                     iter.setLaterBit(gl::state::DIRTY_BIT_TEXTURE_BINDINGS);
2340*8975f5c5SAndroid Build Coastguard Worker 
2341*8975f5c5SAndroid Build Coastguard Worker                     if (executable->getActiveImagesMask().any())
2342*8975f5c5SAndroid Build Coastguard Worker                     {
2343*8975f5c5SAndroid Build Coastguard Worker                         iter.setLaterBit(gl::state::DIRTY_BIT_IMAGE_BINDINGS);
2344*8975f5c5SAndroid Build Coastguard Worker                     }
2345*8975f5c5SAndroid Build Coastguard Worker 
2346*8975f5c5SAndroid Build Coastguard Worker                     if (executable->getShaderStorageBlocks().size() > 0)
2347*8975f5c5SAndroid Build Coastguard Worker                     {
2348*8975f5c5SAndroid Build Coastguard Worker                         iter.setLaterBit(gl::state::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING);
2349*8975f5c5SAndroid Build Coastguard Worker                     }
2350*8975f5c5SAndroid Build Coastguard Worker 
2351*8975f5c5SAndroid Build Coastguard Worker                     if (executable->getUniformBlocks().size() > 0)
2352*8975f5c5SAndroid Build Coastguard Worker                     {
2353*8975f5c5SAndroid Build Coastguard Worker                         iter.setLaterBit(gl::state::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS);
2354*8975f5c5SAndroid Build Coastguard Worker                     }
2355*8975f5c5SAndroid Build Coastguard Worker 
2356*8975f5c5SAndroid Build Coastguard Worker                     if (executable->getAtomicCounterBuffers().size() > 0)
2357*8975f5c5SAndroid Build Coastguard Worker                     {
2358*8975f5c5SAndroid Build Coastguard Worker                         iter.setLaterBit(gl::state::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING);
2359*8975f5c5SAndroid Build Coastguard Worker                     }
2360*8975f5c5SAndroid Build Coastguard Worker 
2361*8975f5c5SAndroid Build Coastguard Worker                     if (mIsMultiviewEnabled && executable->usesMultiview())
2362*8975f5c5SAndroid Build Coastguard Worker                     {
2363*8975f5c5SAndroid Build Coastguard Worker                         updateMultiviewBaseViewLayerIndexUniform(
2364*8975f5c5SAndroid Build Coastguard Worker                             executable,
2365*8975f5c5SAndroid Build Coastguard Worker                             state.getDrawFramebuffer()->getImplementation()->getState());
2366*8975f5c5SAndroid Build Coastguard Worker                     }
2367*8975f5c5SAndroid Build Coastguard Worker 
2368*8975f5c5SAndroid Build Coastguard Worker                     // If the current executable does not use clip distances, the related API
2369*8975f5c5SAndroid Build Coastguard Worker                     // state has to be disabled to avoid runtime failures on certain drivers.
2370*8975f5c5SAndroid Build Coastguard Worker                     // On other drivers, that state is always emulated via a special uniform,
2371*8975f5c5SAndroid Build Coastguard Worker                     // which needs to be updated when switching programs.
2372*8975f5c5SAndroid Build Coastguard Worker                     if (mMaxClipDistances > 0)
2373*8975f5c5SAndroid Build Coastguard Worker                     {
2374*8975f5c5SAndroid Build Coastguard Worker                         iter.setLaterBit(gl::state::DIRTY_BIT_EXTENDED);
2375*8975f5c5SAndroid Build Coastguard Worker                         mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_CLIP_DISTANCES);
2376*8975f5c5SAndroid Build Coastguard Worker                     }
2377*8975f5c5SAndroid Build Coastguard Worker 
2378*8975f5c5SAndroid Build Coastguard Worker                     if (mFeatures.emulateClipOrigin.enabled)
2379*8975f5c5SAndroid Build Coastguard Worker                     {
2380*8975f5c5SAndroid Build Coastguard Worker                         updateEmulatedClipOriginUniform(executable, state.getClipOrigin());
2381*8975f5c5SAndroid Build Coastguard Worker                     }
2382*8975f5c5SAndroid Build Coastguard Worker                 }
2383*8975f5c5SAndroid Build Coastguard Worker 
2384*8975f5c5SAndroid Build Coastguard Worker                 if (!executable || !executable->hasLinkedShaderStage(gl::ShaderType::Compute))
2385*8975f5c5SAndroid Build Coastguard Worker                 {
2386*8975f5c5SAndroid Build Coastguard Worker                     ANGLE_TRY(propagateProgramToVAO(
2387*8975f5c5SAndroid Build Coastguard Worker                         context, executable, GetImplAs<VertexArrayGL>(state.getVertexArray())));
2388*8975f5c5SAndroid Build Coastguard Worker                 }
2389*8975f5c5SAndroid Build Coastguard Worker                 break;
2390*8975f5c5SAndroid Build Coastguard Worker             }
2391*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_TEXTURE_BINDINGS:
2392*8975f5c5SAndroid Build Coastguard Worker                 updateProgramTextureBindings(context);
2393*8975f5c5SAndroid Build Coastguard Worker                 break;
2394*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_SAMPLER_BINDINGS:
2395*8975f5c5SAndroid Build Coastguard Worker                 syncSamplersState(context);
2396*8975f5c5SAndroid Build Coastguard Worker                 break;
2397*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_IMAGE_BINDINGS:
2398*8975f5c5SAndroid Build Coastguard Worker                 updateProgramImageBindings(context);
2399*8975f5c5SAndroid Build Coastguard Worker                 break;
2400*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_TRANSFORM_FEEDBACK_BINDING:
2401*8975f5c5SAndroid Build Coastguard Worker                 syncTransformFeedbackState(context);
2402*8975f5c5SAndroid Build Coastguard Worker                 break;
2403*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_SHADER_STORAGE_BUFFER_BINDING:
2404*8975f5c5SAndroid Build Coastguard Worker                 updateProgramStorageBufferBindings(context);
2405*8975f5c5SAndroid Build Coastguard Worker                 break;
2406*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_UNIFORM_BUFFER_BINDINGS:
2407*8975f5c5SAndroid Build Coastguard Worker                 updateProgramUniformBufferBindings(context);
2408*8975f5c5SAndroid Build Coastguard Worker                 break;
2409*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_ATOMIC_COUNTER_BUFFER_BINDING:
2410*8975f5c5SAndroid Build Coastguard Worker                 updateProgramAtomicCounterBufferBindings(context);
2411*8975f5c5SAndroid Build Coastguard Worker                 break;
2412*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_MULTISAMPLING:
2413*8975f5c5SAndroid Build Coastguard Worker                 setMultisamplingStateEnabled(state.isMultisamplingEnabled());
2414*8975f5c5SAndroid Build Coastguard Worker                 break;
2415*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE:
2416*8975f5c5SAndroid Build Coastguard Worker                 setSampleAlphaToOneStateEnabled(state.isSampleAlphaToOneEnabled());
2417*8975f5c5SAndroid Build Coastguard Worker                 break;
2418*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_COVERAGE_MODULATION:
2419*8975f5c5SAndroid Build Coastguard Worker                 setCoverageModulation(state.getCoverageModulation());
2420*8975f5c5SAndroid Build Coastguard Worker                 break;
2421*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE:
2422*8975f5c5SAndroid Build Coastguard Worker                 setFramebufferSRGBEnabledForFramebuffer(
2423*8975f5c5SAndroid Build Coastguard Worker                     context, state.getFramebufferSRGB(),
2424*8975f5c5SAndroid Build Coastguard Worker                     GetImplAs<FramebufferGL>(state.getDrawFramebuffer()));
2425*8975f5c5SAndroid Build Coastguard Worker                 break;
2426*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_SAMPLE_MASK_ENABLED:
2427*8975f5c5SAndroid Build Coastguard Worker                 setSampleMaskEnabled(state.isSampleMaskEnabled());
2428*8975f5c5SAndroid Build Coastguard Worker                 break;
2429*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_SAMPLE_MASK:
2430*8975f5c5SAndroid Build Coastguard Worker             {
2431*8975f5c5SAndroid Build Coastguard Worker                 for (GLuint maskNumber = 0; maskNumber < state.getMaxSampleMaskWords();
2432*8975f5c5SAndroid Build Coastguard Worker                      ++maskNumber)
2433*8975f5c5SAndroid Build Coastguard Worker                 {
2434*8975f5c5SAndroid Build Coastguard Worker                     setSampleMaski(maskNumber, state.getSampleMaskWord(maskNumber));
2435*8975f5c5SAndroid Build Coastguard Worker                 }
2436*8975f5c5SAndroid Build Coastguard Worker                 break;
2437*8975f5c5SAndroid Build Coastguard Worker             }
2438*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_CURRENT_VALUES:
2439*8975f5c5SAndroid Build Coastguard Worker             {
2440*8975f5c5SAndroid Build Coastguard Worker                 gl::AttributesMask combinedMask =
2441*8975f5c5SAndroid Build Coastguard Worker                     (state.getAndResetDirtyCurrentValues() | mLocalDirtyCurrentValues);
2442*8975f5c5SAndroid Build Coastguard Worker 
2443*8975f5c5SAndroid Build Coastguard Worker                 for (auto attribIndex : combinedMask)
2444*8975f5c5SAndroid Build Coastguard Worker                 {
2445*8975f5c5SAndroid Build Coastguard Worker                     setAttributeCurrentData(attribIndex,
2446*8975f5c5SAndroid Build Coastguard Worker                                             state.getVertexAttribCurrentValue(attribIndex));
2447*8975f5c5SAndroid Build Coastguard Worker                 }
2448*8975f5c5SAndroid Build Coastguard Worker 
2449*8975f5c5SAndroid Build Coastguard Worker                 mLocalDirtyCurrentValues.reset();
2450*8975f5c5SAndroid Build Coastguard Worker                 break;
2451*8975f5c5SAndroid Build Coastguard Worker             }
2452*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_PROVOKING_VERTEX:
2453*8975f5c5SAndroid Build Coastguard Worker                 setProvokingVertex(ToGLenum(state.getProvokingVertex()));
2454*8975f5c5SAndroid Build Coastguard Worker                 break;
2455*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_EXTENDED:
2456*8975f5c5SAndroid Build Coastguard Worker             {
2457*8975f5c5SAndroid Build Coastguard Worker                 const gl::state::ExtendedDirtyBits glAndLocalExtendedDirtyBits =
2458*8975f5c5SAndroid Build Coastguard Worker                     (extendedDirtyBits | mLocalExtendedDirtyBits) & extendedBitMask;
2459*8975f5c5SAndroid Build Coastguard Worker                 for (size_t extendedDirtyBit : glAndLocalExtendedDirtyBits)
2460*8975f5c5SAndroid Build Coastguard Worker                 {
2461*8975f5c5SAndroid Build Coastguard Worker                     switch (extendedDirtyBit)
2462*8975f5c5SAndroid Build Coastguard Worker                     {
2463*8975f5c5SAndroid Build Coastguard Worker                         case gl::state::EXTENDED_DIRTY_BIT_CLIP_CONTROL:
2464*8975f5c5SAndroid Build Coastguard Worker                             if (mFeatures.emulateClipOrigin.enabled)
2465*8975f5c5SAndroid Build Coastguard Worker                             {
2466*8975f5c5SAndroid Build Coastguard Worker                                 setClipControlWithEmulatedClipOrigin(
2467*8975f5c5SAndroid Build Coastguard Worker                                     state.getProgramExecutable(),
2468*8975f5c5SAndroid Build Coastguard Worker                                     state.getRasterizerState().frontFace, state.getClipOrigin(),
2469*8975f5c5SAndroid Build Coastguard Worker                                     state.getClipDepthMode());
2470*8975f5c5SAndroid Build Coastguard Worker                                 break;
2471*8975f5c5SAndroid Build Coastguard Worker                             }
2472*8975f5c5SAndroid Build Coastguard Worker                             setClipControl(state.getClipOrigin(), state.getClipDepthMode());
2473*8975f5c5SAndroid Build Coastguard Worker                             break;
2474*8975f5c5SAndroid Build Coastguard Worker                         case gl::state::EXTENDED_DIRTY_BIT_CLIP_DISTANCES:
2475*8975f5c5SAndroid Build Coastguard Worker                         {
2476*8975f5c5SAndroid Build Coastguard Worker                             const gl::ProgramExecutable *executable = state.getProgramExecutable();
2477*8975f5c5SAndroid Build Coastguard Worker                             if (executable && executable->hasClipDistance())
2478*8975f5c5SAndroid Build Coastguard Worker                             {
2479*8975f5c5SAndroid Build Coastguard Worker                                 setClipDistancesEnable(state.getEnabledClipDistances());
2480*8975f5c5SAndroid Build Coastguard Worker                                 if (mFeatures.emulateClipDistanceState.enabled)
2481*8975f5c5SAndroid Build Coastguard Worker                                 {
2482*8975f5c5SAndroid Build Coastguard Worker                                     updateEmulatedClipDistanceState(
2483*8975f5c5SAndroid Build Coastguard Worker                                         executable, state.getEnabledClipDistances());
2484*8975f5c5SAndroid Build Coastguard Worker                                 }
2485*8975f5c5SAndroid Build Coastguard Worker                             }
2486*8975f5c5SAndroid Build Coastguard Worker                             else
2487*8975f5c5SAndroid Build Coastguard Worker                             {
2488*8975f5c5SAndroid Build Coastguard Worker                                 setClipDistancesEnable(gl::ClipDistanceEnableBits());
2489*8975f5c5SAndroid Build Coastguard Worker                             }
2490*8975f5c5SAndroid Build Coastguard Worker                             break;
2491*8975f5c5SAndroid Build Coastguard Worker                         }
2492*8975f5c5SAndroid Build Coastguard Worker                         case gl::state::EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED:
2493*8975f5c5SAndroid Build Coastguard Worker                             setDepthClampEnabled(state.isDepthClampEnabled());
2494*8975f5c5SAndroid Build Coastguard Worker                             break;
2495*8975f5c5SAndroid Build Coastguard Worker                         case gl::state::EXTENDED_DIRTY_BIT_LOGIC_OP_ENABLED:
2496*8975f5c5SAndroid Build Coastguard Worker                             setLogicOpEnabled(state.isLogicOpEnabled());
2497*8975f5c5SAndroid Build Coastguard Worker                             break;
2498*8975f5c5SAndroid Build Coastguard Worker                         case gl::state::EXTENDED_DIRTY_BIT_LOGIC_OP:
2499*8975f5c5SAndroid Build Coastguard Worker                             setLogicOp(state.getLogicOp());
2500*8975f5c5SAndroid Build Coastguard Worker                             break;
2501*8975f5c5SAndroid Build Coastguard Worker                         case gl::state::EXTENDED_DIRTY_BIT_MIPMAP_GENERATION_HINT:
2502*8975f5c5SAndroid Build Coastguard Worker                             break;
2503*8975f5c5SAndroid Build Coastguard Worker                         case gl::state::EXTENDED_DIRTY_BIT_POLYGON_MODE:
2504*8975f5c5SAndroid Build Coastguard Worker                             setPolygonMode(state.getPolygonMode());
2505*8975f5c5SAndroid Build Coastguard Worker                             break;
2506*8975f5c5SAndroid Build Coastguard Worker                         case gl::state::EXTENDED_DIRTY_BIT_POLYGON_OFFSET_POINT_ENABLED:
2507*8975f5c5SAndroid Build Coastguard Worker                             setPolygonOffsetPointEnabled(state.isPolygonOffsetPointEnabled());
2508*8975f5c5SAndroid Build Coastguard Worker                             break;
2509*8975f5c5SAndroid Build Coastguard Worker                         case gl::state::EXTENDED_DIRTY_BIT_POLYGON_OFFSET_LINE_ENABLED:
2510*8975f5c5SAndroid Build Coastguard Worker                             setPolygonOffsetLineEnabled(state.isPolygonOffsetLineEnabled());
2511*8975f5c5SAndroid Build Coastguard Worker                             break;
2512*8975f5c5SAndroid Build Coastguard Worker                         case gl::state::EXTENDED_DIRTY_BIT_SHADER_DERIVATIVE_HINT:
2513*8975f5c5SAndroid Build Coastguard Worker                             // These hints aren't forwarded to GL yet.
2514*8975f5c5SAndroid Build Coastguard Worker                             break;
2515*8975f5c5SAndroid Build Coastguard Worker                         case gl::state::EXTENDED_DIRTY_BIT_SHADING_RATE:
2516*8975f5c5SAndroid Build Coastguard Worker                             // Unimplemented extensions.
2517*8975f5c5SAndroid Build Coastguard Worker                             break;
2518*8975f5c5SAndroid Build Coastguard Worker                         case gl::state::EXTENDED_DIRTY_BIT_BLEND_ADVANCED_COHERENT:
2519*8975f5c5SAndroid Build Coastguard Worker                             setBlendAdvancedCoherent(state.isBlendAdvancedCoherentEnabled());
2520*8975f5c5SAndroid Build Coastguard Worker                             break;
2521*8975f5c5SAndroid Build Coastguard Worker                         default:
2522*8975f5c5SAndroid Build Coastguard Worker                             UNREACHABLE();
2523*8975f5c5SAndroid Build Coastguard Worker                             break;
2524*8975f5c5SAndroid Build Coastguard Worker                     }
2525*8975f5c5SAndroid Build Coastguard Worker                     mLocalExtendedDirtyBits &= ~extendedBitMask;
2526*8975f5c5SAndroid Build Coastguard Worker                 }
2527*8975f5c5SAndroid Build Coastguard Worker                 break;
2528*8975f5c5SAndroid Build Coastguard Worker             }
2529*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_SAMPLE_SHADING:
2530*8975f5c5SAndroid Build Coastguard Worker                 // Nothing to do until OES_sample_shading is implemented.
2531*8975f5c5SAndroid Build Coastguard Worker                 break;
2532*8975f5c5SAndroid Build Coastguard Worker             case gl::state::DIRTY_BIT_PATCH_VERTICES:
2533*8975f5c5SAndroid Build Coastguard Worker                 // Nothing to do until EXT_tessellation_shader is implemented.
2534*8975f5c5SAndroid Build Coastguard Worker                 break;
2535*8975f5c5SAndroid Build Coastguard Worker             default:
2536*8975f5c5SAndroid Build Coastguard Worker                 UNREACHABLE();
2537*8975f5c5SAndroid Build Coastguard Worker                 break;
2538*8975f5c5SAndroid Build Coastguard Worker         }
2539*8975f5c5SAndroid Build Coastguard Worker     }
2540*8975f5c5SAndroid Build Coastguard Worker 
2541*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits &= ~bitMask;
2542*8975f5c5SAndroid Build Coastguard Worker 
2543*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
2544*8975f5c5SAndroid Build Coastguard Worker }
2545*8975f5c5SAndroid Build Coastguard Worker 
setFramebufferSRGBEnabled(const gl::Context * context,bool enabled)2546*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setFramebufferSRGBEnabled(const gl::Context *context, bool enabled)
2547*8975f5c5SAndroid Build Coastguard Worker {
2548*8975f5c5SAndroid Build Coastguard Worker     if (!mFramebufferSRGBAvailable)
2549*8975f5c5SAndroid Build Coastguard Worker     {
2550*8975f5c5SAndroid Build Coastguard Worker         return;
2551*8975f5c5SAndroid Build Coastguard Worker     }
2552*8975f5c5SAndroid Build Coastguard Worker 
2553*8975f5c5SAndroid Build Coastguard Worker     if (mFramebufferSRGBEnabled != enabled)
2554*8975f5c5SAndroid Build Coastguard Worker     {
2555*8975f5c5SAndroid Build Coastguard Worker         mFramebufferSRGBEnabled = enabled;
2556*8975f5c5SAndroid Build Coastguard Worker         if (mFramebufferSRGBEnabled)
2557*8975f5c5SAndroid Build Coastguard Worker         {
2558*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_FRAMEBUFFER_SRGB);
2559*8975f5c5SAndroid Build Coastguard Worker         }
2560*8975f5c5SAndroid Build Coastguard Worker         else
2561*8975f5c5SAndroid Build Coastguard Worker         {
2562*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_FRAMEBUFFER_SRGB);
2563*8975f5c5SAndroid Build Coastguard Worker         }
2564*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_FRAMEBUFFER_SRGB_WRITE_CONTROL_MODE);
2565*8975f5c5SAndroid Build Coastguard Worker     }
2566*8975f5c5SAndroid Build Coastguard Worker }
2567*8975f5c5SAndroid Build Coastguard Worker 
setFramebufferSRGBEnabledForFramebuffer(const gl::Context * context,bool enabled,const FramebufferGL * framebuffer)2568*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setFramebufferSRGBEnabledForFramebuffer(const gl::Context *context,
2569*8975f5c5SAndroid Build Coastguard Worker                                                              bool enabled,
2570*8975f5c5SAndroid Build Coastguard Worker                                                              const FramebufferGL *framebuffer)
2571*8975f5c5SAndroid Build Coastguard Worker {
2572*8975f5c5SAndroid Build Coastguard Worker     if (framebuffer->isDefault())
2573*8975f5c5SAndroid Build Coastguard Worker     {
2574*8975f5c5SAndroid Build Coastguard Worker         // Obey the framebuffer sRGB state for blending on all framebuffers except the default
2575*8975f5c5SAndroid Build Coastguard Worker         // framebuffer.
2576*8975f5c5SAndroid Build Coastguard Worker         // When SRGB blending is enabled, only SRGB capable formats will use it but the default
2577*8975f5c5SAndroid Build Coastguard Worker         // framebuffer will always use it if it is enabled.
2578*8975f5c5SAndroid Build Coastguard Worker         // TODO(geofflang): Update this when the framebuffer binding dirty changes, when it exists.
2579*8975f5c5SAndroid Build Coastguard Worker         setFramebufferSRGBEnabled(context, false);
2580*8975f5c5SAndroid Build Coastguard Worker     }
2581*8975f5c5SAndroid Build Coastguard Worker     else
2582*8975f5c5SAndroid Build Coastguard Worker     {
2583*8975f5c5SAndroid Build Coastguard Worker         setFramebufferSRGBEnabled(context, enabled);
2584*8975f5c5SAndroid Build Coastguard Worker     }
2585*8975f5c5SAndroid Build Coastguard Worker }
2586*8975f5c5SAndroid Build Coastguard Worker 
setColorMaskForFramebuffer(const gl::BlendStateExt & blendStateExt,const bool disableAlpha)2587*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setColorMaskForFramebuffer(const gl::BlendStateExt &blendStateExt,
2588*8975f5c5SAndroid Build Coastguard Worker                                                 const bool disableAlpha)
2589*8975f5c5SAndroid Build Coastguard Worker {
2590*8975f5c5SAndroid Build Coastguard Worker     bool r, g, b, a;
2591*8975f5c5SAndroid Build Coastguard Worker 
2592*8975f5c5SAndroid Build Coastguard Worker     // Given that disableAlpha can be true only on macOS backbuffers and color mask is re-synced on
2593*8975f5c5SAndroid Build Coastguard Worker     // bound draw framebuffer change, switch all draw buffers color masks to avoid special case
2594*8975f5c5SAndroid Build Coastguard Worker     // later.
2595*8975f5c5SAndroid Build Coastguard Worker     if (!mIndependentBlendStates || disableAlpha)
2596*8975f5c5SAndroid Build Coastguard Worker     {
2597*8975f5c5SAndroid Build Coastguard Worker         blendStateExt.getColorMaskIndexed(0, &r, &g, &b, &a);
2598*8975f5c5SAndroid Build Coastguard Worker         setColorMask(r, g, b, disableAlpha ? false : a);
2599*8975f5c5SAndroid Build Coastguard Worker         return;
2600*8975f5c5SAndroid Build Coastguard Worker     }
2601*8975f5c5SAndroid Build Coastguard Worker 
2602*8975f5c5SAndroid Build Coastguard Worker     // Check if the current mask already matches the new state
2603*8975f5c5SAndroid Build Coastguard Worker     if (mBlendStateExt.getColorMaskBits() == blendStateExt.getColorMaskBits())
2604*8975f5c5SAndroid Build Coastguard Worker     {
2605*8975f5c5SAndroid Build Coastguard Worker         return;
2606*8975f5c5SAndroid Build Coastguard Worker     }
2607*8975f5c5SAndroid Build Coastguard Worker 
2608*8975f5c5SAndroid Build Coastguard Worker     // Get DrawBufferMask of buffers with different color masks
2609*8975f5c5SAndroid Build Coastguard Worker     gl::DrawBufferMask diffMask = mBlendStateExt.compareColorMask(blendStateExt.getColorMaskBits());
2610*8975f5c5SAndroid Build Coastguard Worker     size_t diffCount            = diffMask.count();
2611*8975f5c5SAndroid Build Coastguard Worker 
2612*8975f5c5SAndroid Build Coastguard Worker     // Check if setting all buffers to the same value reduces the number of subsequent indexed
2613*8975f5c5SAndroid Build Coastguard Worker     // commands. Implicitly handles the case when the new mask is the same for all buffers.
2614*8975f5c5SAndroid Build Coastguard Worker     // For instance, let's say that previously synced mask is ccccff00 and the new state is
2615*8975f5c5SAndroid Build Coastguard Worker     // ffeeeeee. Instead of calling colorMaski 8 times, ANGLE can set all buffers to `e` and then
2616*8975f5c5SAndroid Build Coastguard Worker     // use colorMaski only twice. On the other hand, if the new state is cceeee00, a non-indexed
2617*8975f5c5SAndroid Build Coastguard Worker     // call will increase the total number of GL commands.
2618*8975f5c5SAndroid Build Coastguard Worker     if (diffCount > 1)
2619*8975f5c5SAndroid Build Coastguard Worker     {
2620*8975f5c5SAndroid Build Coastguard Worker         bool found                                                = false;
2621*8975f5c5SAndroid Build Coastguard Worker         gl::BlendStateExt::ColorMaskStorage::Type commonColorMask = 0;
2622*8975f5c5SAndroid Build Coastguard Worker         for (size_t i = 0; i < mBlendStateExt.getDrawBufferCount() - 1; i++)
2623*8975f5c5SAndroid Build Coastguard Worker         {
2624*8975f5c5SAndroid Build Coastguard Worker             const gl::BlendStateExt::ColorMaskStorage::Type tempCommonColorMask =
2625*8975f5c5SAndroid Build Coastguard Worker                 blendStateExt.expandColorMaskIndexed(i);
2626*8975f5c5SAndroid Build Coastguard Worker             const gl::DrawBufferMask tempDiffMask =
2627*8975f5c5SAndroid Build Coastguard Worker                 blendStateExt.compareColorMask(tempCommonColorMask);
2628*8975f5c5SAndroid Build Coastguard Worker             const size_t tempDiffCount = tempDiffMask.count();
2629*8975f5c5SAndroid Build Coastguard Worker             if (tempDiffCount < diffCount)
2630*8975f5c5SAndroid Build Coastguard Worker             {
2631*8975f5c5SAndroid Build Coastguard Worker                 found           = true;
2632*8975f5c5SAndroid Build Coastguard Worker                 diffMask        = tempDiffMask;
2633*8975f5c5SAndroid Build Coastguard Worker                 diffCount       = tempDiffCount;
2634*8975f5c5SAndroid Build Coastguard Worker                 commonColorMask = tempCommonColorMask;
2635*8975f5c5SAndroid Build Coastguard Worker                 if (tempDiffCount == 0)
2636*8975f5c5SAndroid Build Coastguard Worker                 {
2637*8975f5c5SAndroid Build Coastguard Worker                     break;  // the new mask is the same for all buffers
2638*8975f5c5SAndroid Build Coastguard Worker                 }
2639*8975f5c5SAndroid Build Coastguard Worker             }
2640*8975f5c5SAndroid Build Coastguard Worker         }
2641*8975f5c5SAndroid Build Coastguard Worker         if (found)
2642*8975f5c5SAndroid Build Coastguard Worker         {
2643*8975f5c5SAndroid Build Coastguard Worker             gl::BlendStateExt::UnpackColorMask(commonColorMask, &r, &g, &b, &a);
2644*8975f5c5SAndroid Build Coastguard Worker             mFunctions->colorMask(r, g, b, a);
2645*8975f5c5SAndroid Build Coastguard Worker         }
2646*8975f5c5SAndroid Build Coastguard Worker     }
2647*8975f5c5SAndroid Build Coastguard Worker 
2648*8975f5c5SAndroid Build Coastguard Worker     for (size_t drawBufferIndex : diffMask)
2649*8975f5c5SAndroid Build Coastguard Worker     {
2650*8975f5c5SAndroid Build Coastguard Worker         blendStateExt.getColorMaskIndexed(drawBufferIndex, &r, &g, &b, &a);
2651*8975f5c5SAndroid Build Coastguard Worker         mFunctions->colorMaski(static_cast<GLuint>(drawBufferIndex), r, g, b, a);
2652*8975f5c5SAndroid Build Coastguard Worker     }
2653*8975f5c5SAndroid Build Coastguard Worker 
2654*8975f5c5SAndroid Build Coastguard Worker     mBlendStateExt.setColorMaskBits(blendStateExt.getColorMaskBits());
2655*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_COLOR_MASK);
2656*8975f5c5SAndroid Build Coastguard Worker }
2657*8975f5c5SAndroid Build Coastguard Worker 
setDitherEnabled(bool enabled)2658*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setDitherEnabled(bool enabled)
2659*8975f5c5SAndroid Build Coastguard Worker {
2660*8975f5c5SAndroid Build Coastguard Worker     if (mDitherEnabled != enabled)
2661*8975f5c5SAndroid Build Coastguard Worker     {
2662*8975f5c5SAndroid Build Coastguard Worker         mDitherEnabled = enabled;
2663*8975f5c5SAndroid Build Coastguard Worker         if (mDitherEnabled)
2664*8975f5c5SAndroid Build Coastguard Worker         {
2665*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_DITHER);
2666*8975f5c5SAndroid Build Coastguard Worker         }
2667*8975f5c5SAndroid Build Coastguard Worker         else
2668*8975f5c5SAndroid Build Coastguard Worker         {
2669*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_DITHER);
2670*8975f5c5SAndroid Build Coastguard Worker         }
2671*8975f5c5SAndroid Build Coastguard Worker     }
2672*8975f5c5SAndroid Build Coastguard Worker }
2673*8975f5c5SAndroid Build Coastguard Worker 
setMultisamplingStateEnabled(bool enabled)2674*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setMultisamplingStateEnabled(bool enabled)
2675*8975f5c5SAndroid Build Coastguard Worker {
2676*8975f5c5SAndroid Build Coastguard Worker     if (mMultisamplingEnabled != enabled)
2677*8975f5c5SAndroid Build Coastguard Worker     {
2678*8975f5c5SAndroid Build Coastguard Worker         mMultisamplingEnabled = enabled;
2679*8975f5c5SAndroid Build Coastguard Worker         if (mMultisamplingEnabled)
2680*8975f5c5SAndroid Build Coastguard Worker         {
2681*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_MULTISAMPLE_EXT);
2682*8975f5c5SAndroid Build Coastguard Worker         }
2683*8975f5c5SAndroid Build Coastguard Worker         else
2684*8975f5c5SAndroid Build Coastguard Worker         {
2685*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_MULTISAMPLE_EXT);
2686*8975f5c5SAndroid Build Coastguard Worker         }
2687*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_MULTISAMPLING);
2688*8975f5c5SAndroid Build Coastguard Worker     }
2689*8975f5c5SAndroid Build Coastguard Worker }
2690*8975f5c5SAndroid Build Coastguard Worker 
setSampleAlphaToOneStateEnabled(bool enabled)2691*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setSampleAlphaToOneStateEnabled(bool enabled)
2692*8975f5c5SAndroid Build Coastguard Worker {
2693*8975f5c5SAndroid Build Coastguard Worker     if (mSampleAlphaToOneEnabled != enabled)
2694*8975f5c5SAndroid Build Coastguard Worker     {
2695*8975f5c5SAndroid Build Coastguard Worker         mSampleAlphaToOneEnabled = enabled;
2696*8975f5c5SAndroid Build Coastguard Worker         if (mSampleAlphaToOneEnabled)
2697*8975f5c5SAndroid Build Coastguard Worker         {
2698*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_SAMPLE_ALPHA_TO_ONE);
2699*8975f5c5SAndroid Build Coastguard Worker         }
2700*8975f5c5SAndroid Build Coastguard Worker         else
2701*8975f5c5SAndroid Build Coastguard Worker         {
2702*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_SAMPLE_ALPHA_TO_ONE);
2703*8975f5c5SAndroid Build Coastguard Worker         }
2704*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
2705*8975f5c5SAndroid Build Coastguard Worker     }
2706*8975f5c5SAndroid Build Coastguard Worker }
2707*8975f5c5SAndroid Build Coastguard Worker 
setCoverageModulation(GLenum components)2708*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setCoverageModulation(GLenum components)
2709*8975f5c5SAndroid Build Coastguard Worker {
2710*8975f5c5SAndroid Build Coastguard Worker     if (mCoverageModulation != components)
2711*8975f5c5SAndroid Build Coastguard Worker     {
2712*8975f5c5SAndroid Build Coastguard Worker         mCoverageModulation = components;
2713*8975f5c5SAndroid Build Coastguard Worker         mFunctions->coverageModulationNV(components);
2714*8975f5c5SAndroid Build Coastguard Worker 
2715*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_COVERAGE_MODULATION);
2716*8975f5c5SAndroid Build Coastguard Worker     }
2717*8975f5c5SAndroid Build Coastguard Worker }
2718*8975f5c5SAndroid Build Coastguard Worker 
setProvokingVertex(GLenum mode)2719*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setProvokingVertex(GLenum mode)
2720*8975f5c5SAndroid Build Coastguard Worker {
2721*8975f5c5SAndroid Build Coastguard Worker     if (mode != mProvokingVertex)
2722*8975f5c5SAndroid Build Coastguard Worker     {
2723*8975f5c5SAndroid Build Coastguard Worker         mFunctions->provokingVertex(mode);
2724*8975f5c5SAndroid Build Coastguard Worker         mProvokingVertex = mode;
2725*8975f5c5SAndroid Build Coastguard Worker 
2726*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_PROVOKING_VERTEX);
2727*8975f5c5SAndroid Build Coastguard Worker     }
2728*8975f5c5SAndroid Build Coastguard Worker }
2729*8975f5c5SAndroid Build Coastguard Worker 
setClipDistancesEnable(const gl::ClipDistanceEnableBits & enables)2730*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setClipDistancesEnable(const gl::ClipDistanceEnableBits &enables)
2731*8975f5c5SAndroid Build Coastguard Worker {
2732*8975f5c5SAndroid Build Coastguard Worker     if (enables == mEnabledClipDistances)
2733*8975f5c5SAndroid Build Coastguard Worker     {
2734*8975f5c5SAndroid Build Coastguard Worker         return;
2735*8975f5c5SAndroid Build Coastguard Worker     }
2736*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mMaxClipDistances <= gl::IMPLEMENTATION_MAX_CLIP_DISTANCES);
2737*8975f5c5SAndroid Build Coastguard Worker 
2738*8975f5c5SAndroid Build Coastguard Worker     gl::ClipDistanceEnableBits diff = enables ^ mEnabledClipDistances;
2739*8975f5c5SAndroid Build Coastguard Worker     for (size_t i : diff)
2740*8975f5c5SAndroid Build Coastguard Worker     {
2741*8975f5c5SAndroid Build Coastguard Worker         if (enables.test(i))
2742*8975f5c5SAndroid Build Coastguard Worker         {
2743*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_CLIP_DISTANCE0_EXT + static_cast<uint32_t>(i));
2744*8975f5c5SAndroid Build Coastguard Worker         }
2745*8975f5c5SAndroid Build Coastguard Worker         else
2746*8975f5c5SAndroid Build Coastguard Worker         {
2747*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_CLIP_DISTANCE0_EXT + static_cast<uint32_t>(i));
2748*8975f5c5SAndroid Build Coastguard Worker         }
2749*8975f5c5SAndroid Build Coastguard Worker     }
2750*8975f5c5SAndroid Build Coastguard Worker 
2751*8975f5c5SAndroid Build Coastguard Worker     mEnabledClipDistances = enables;
2752*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
2753*8975f5c5SAndroid Build Coastguard Worker     mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_CLIP_DISTANCES);
2754*8975f5c5SAndroid Build Coastguard Worker }
2755*8975f5c5SAndroid Build Coastguard Worker 
setLogicOpEnabled(bool enabled)2756*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setLogicOpEnabled(bool enabled)
2757*8975f5c5SAndroid Build Coastguard Worker {
2758*8975f5c5SAndroid Build Coastguard Worker     if (enabled == mLogicOpEnabled)
2759*8975f5c5SAndroid Build Coastguard Worker     {
2760*8975f5c5SAndroid Build Coastguard Worker         return;
2761*8975f5c5SAndroid Build Coastguard Worker     }
2762*8975f5c5SAndroid Build Coastguard Worker     mLogicOpEnabled = enabled;
2763*8975f5c5SAndroid Build Coastguard Worker 
2764*8975f5c5SAndroid Build Coastguard Worker     if (enabled)
2765*8975f5c5SAndroid Build Coastguard Worker     {
2766*8975f5c5SAndroid Build Coastguard Worker         mFunctions->enable(GL_COLOR_LOGIC_OP);
2767*8975f5c5SAndroid Build Coastguard Worker     }
2768*8975f5c5SAndroid Build Coastguard Worker     else
2769*8975f5c5SAndroid Build Coastguard Worker     {
2770*8975f5c5SAndroid Build Coastguard Worker         mFunctions->disable(GL_COLOR_LOGIC_OP);
2771*8975f5c5SAndroid Build Coastguard Worker     }
2772*8975f5c5SAndroid Build Coastguard Worker 
2773*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
2774*8975f5c5SAndroid Build Coastguard Worker     mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_LOGIC_OP_ENABLED);
2775*8975f5c5SAndroid Build Coastguard Worker }
2776*8975f5c5SAndroid Build Coastguard Worker 
setLogicOp(gl::LogicalOperation opcode)2777*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setLogicOp(gl::LogicalOperation opcode)
2778*8975f5c5SAndroid Build Coastguard Worker {
2779*8975f5c5SAndroid Build Coastguard Worker     if (opcode == mLogicOp)
2780*8975f5c5SAndroid Build Coastguard Worker     {
2781*8975f5c5SAndroid Build Coastguard Worker         return;
2782*8975f5c5SAndroid Build Coastguard Worker     }
2783*8975f5c5SAndroid Build Coastguard Worker     mLogicOp = opcode;
2784*8975f5c5SAndroid Build Coastguard Worker 
2785*8975f5c5SAndroid Build Coastguard Worker     mFunctions->logicOp(ToGLenum(opcode));
2786*8975f5c5SAndroid Build Coastguard Worker 
2787*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
2788*8975f5c5SAndroid Build Coastguard Worker     mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_LOGIC_OP_ENABLED);
2789*8975f5c5SAndroid Build Coastguard Worker }
2790*8975f5c5SAndroid Build Coastguard Worker 
setTextureCubemapSeamlessEnabled(bool enabled)2791*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setTextureCubemapSeamlessEnabled(bool enabled)
2792*8975f5c5SAndroid Build Coastguard Worker {
2793*8975f5c5SAndroid Build Coastguard Worker     // TODO(jmadill): Also check for seamless extension.
2794*8975f5c5SAndroid Build Coastguard Worker     if (!mFunctions->isAtLeastGL(gl::Version(3, 2)))
2795*8975f5c5SAndroid Build Coastguard Worker     {
2796*8975f5c5SAndroid Build Coastguard Worker         return;
2797*8975f5c5SAndroid Build Coastguard Worker     }
2798*8975f5c5SAndroid Build Coastguard Worker 
2799*8975f5c5SAndroid Build Coastguard Worker     if (mTextureCubemapSeamlessEnabled != enabled)
2800*8975f5c5SAndroid Build Coastguard Worker     {
2801*8975f5c5SAndroid Build Coastguard Worker         mTextureCubemapSeamlessEnabled = enabled;
2802*8975f5c5SAndroid Build Coastguard Worker         if (mTextureCubemapSeamlessEnabled)
2803*8975f5c5SAndroid Build Coastguard Worker         {
2804*8975f5c5SAndroid Build Coastguard Worker             mFunctions->enable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
2805*8975f5c5SAndroid Build Coastguard Worker         }
2806*8975f5c5SAndroid Build Coastguard Worker         else
2807*8975f5c5SAndroid Build Coastguard Worker         {
2808*8975f5c5SAndroid Build Coastguard Worker             mFunctions->disable(GL_TEXTURE_CUBE_MAP_SEAMLESS);
2809*8975f5c5SAndroid Build Coastguard Worker         }
2810*8975f5c5SAndroid Build Coastguard Worker     }
2811*8975f5c5SAndroid Build Coastguard Worker }
2812*8975f5c5SAndroid Build Coastguard Worker 
propagateProgramToVAO(const gl::Context * context,const gl::ProgramExecutable * executable,VertexArrayGL * vao)2813*8975f5c5SAndroid Build Coastguard Worker angle::Result StateManagerGL::propagateProgramToVAO(const gl::Context *context,
2814*8975f5c5SAndroid Build Coastguard Worker                                                     const gl::ProgramExecutable *executable,
2815*8975f5c5SAndroid Build Coastguard Worker                                                     VertexArrayGL *vao)
2816*8975f5c5SAndroid Build Coastguard Worker {
2817*8975f5c5SAndroid Build Coastguard Worker     if (vao == nullptr)
2818*8975f5c5SAndroid Build Coastguard Worker     {
2819*8975f5c5SAndroid Build Coastguard Worker         return angle::Result::Continue;
2820*8975f5c5SAndroid Build Coastguard Worker     }
2821*8975f5c5SAndroid Build Coastguard Worker 
2822*8975f5c5SAndroid Build Coastguard Worker     // Number of views:
2823*8975f5c5SAndroid Build Coastguard Worker     if (mIsMultiviewEnabled)
2824*8975f5c5SAndroid Build Coastguard Worker     {
2825*8975f5c5SAndroid Build Coastguard Worker         int numViews = 1;
2826*8975f5c5SAndroid Build Coastguard Worker         if (executable && executable->usesMultiview())
2827*8975f5c5SAndroid Build Coastguard Worker         {
2828*8975f5c5SAndroid Build Coastguard Worker             numViews = executable->getNumViews();
2829*8975f5c5SAndroid Build Coastguard Worker         }
2830*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(vao->applyNumViewsToDivisor(context, numViews));
2831*8975f5c5SAndroid Build Coastguard Worker     }
2832*8975f5c5SAndroid Build Coastguard Worker 
2833*8975f5c5SAndroid Build Coastguard Worker     // Attribute enabled mask:
2834*8975f5c5SAndroid Build Coastguard Worker     if (executable)
2835*8975f5c5SAndroid Build Coastguard Worker     {
2836*8975f5c5SAndroid Build Coastguard Worker         ANGLE_TRY(vao->applyActiveAttribLocationsMask(context,
2837*8975f5c5SAndroid Build Coastguard Worker                                                       executable->getActiveAttribLocationsMask()));
2838*8975f5c5SAndroid Build Coastguard Worker     }
2839*8975f5c5SAndroid Build Coastguard Worker 
2840*8975f5c5SAndroid Build Coastguard Worker     return angle::Result::Continue;
2841*8975f5c5SAndroid Build Coastguard Worker }
2842*8975f5c5SAndroid Build Coastguard Worker 
updateMultiviewBaseViewLayerIndexUniformImpl(const gl::ProgramExecutable * executable,const gl::FramebufferState & drawFramebufferState) const2843*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::updateMultiviewBaseViewLayerIndexUniformImpl(
2844*8975f5c5SAndroid Build Coastguard Worker     const gl::ProgramExecutable *executable,
2845*8975f5c5SAndroid Build Coastguard Worker     const gl::FramebufferState &drawFramebufferState) const
2846*8975f5c5SAndroid Build Coastguard Worker {
2847*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mIsMultiviewEnabled && executable && executable->usesMultiview());
2848*8975f5c5SAndroid Build Coastguard Worker     const ProgramExecutableGL *executableGL = GetImplAs<ProgramExecutableGL>(executable);
2849*8975f5c5SAndroid Build Coastguard Worker     if (drawFramebufferState.isMultiview())
2850*8975f5c5SAndroid Build Coastguard Worker     {
2851*8975f5c5SAndroid Build Coastguard Worker         executableGL->enableLayeredRenderingPath(drawFramebufferState.getBaseViewIndex());
2852*8975f5c5SAndroid Build Coastguard Worker     }
2853*8975f5c5SAndroid Build Coastguard Worker }
2854*8975f5c5SAndroid Build Coastguard Worker 
updateEmulatedClipDistanceState(const gl::ProgramExecutable * executable,const gl::ClipDistanceEnableBits enables) const2855*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::updateEmulatedClipDistanceState(const gl::ProgramExecutable *executable,
2856*8975f5c5SAndroid Build Coastguard Worker                                                      const gl::ClipDistanceEnableBits enables) const
2857*8975f5c5SAndroid Build Coastguard Worker {
2858*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mFeatures.emulateClipDistanceState.enabled);
2859*8975f5c5SAndroid Build Coastguard Worker     ASSERT(executable && executable->hasClipDistance());
2860*8975f5c5SAndroid Build Coastguard Worker     const ProgramExecutableGL *executableGL = GetImplAs<ProgramExecutableGL>(executable);
2861*8975f5c5SAndroid Build Coastguard Worker     executableGL->updateEnabledClipDistances(static_cast<uint8_t>(enables.bits()));
2862*8975f5c5SAndroid Build Coastguard Worker }
2863*8975f5c5SAndroid Build Coastguard Worker 
syncSamplersState(const gl::Context * context)2864*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::syncSamplersState(const gl::Context *context)
2865*8975f5c5SAndroid Build Coastguard Worker {
2866*8975f5c5SAndroid Build Coastguard Worker     const gl::SamplerBindingVector &samplers = context->getState().getSamplers();
2867*8975f5c5SAndroid Build Coastguard Worker 
2868*8975f5c5SAndroid Build Coastguard Worker     // This could be optimized by using a separate binding dirty bit per sampler.
2869*8975f5c5SAndroid Build Coastguard Worker     for (size_t samplerIndex = 0; samplerIndex < samplers.size(); ++samplerIndex)
2870*8975f5c5SAndroid Build Coastguard Worker     {
2871*8975f5c5SAndroid Build Coastguard Worker         const gl::Sampler *sampler = samplers[samplerIndex].get();
2872*8975f5c5SAndroid Build Coastguard Worker         if (sampler != nullptr)
2873*8975f5c5SAndroid Build Coastguard Worker         {
2874*8975f5c5SAndroid Build Coastguard Worker             SamplerGL *samplerGL = GetImplAs<SamplerGL>(sampler);
2875*8975f5c5SAndroid Build Coastguard Worker             bindSampler(samplerIndex, samplerGL->getSamplerID());
2876*8975f5c5SAndroid Build Coastguard Worker         }
2877*8975f5c5SAndroid Build Coastguard Worker         else
2878*8975f5c5SAndroid Build Coastguard Worker         {
2879*8975f5c5SAndroid Build Coastguard Worker             bindSampler(samplerIndex, 0);
2880*8975f5c5SAndroid Build Coastguard Worker         }
2881*8975f5c5SAndroid Build Coastguard Worker     }
2882*8975f5c5SAndroid Build Coastguard Worker }
2883*8975f5c5SAndroid Build Coastguard Worker 
syncTransformFeedbackState(const gl::Context * context)2884*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::syncTransformFeedbackState(const gl::Context *context)
2885*8975f5c5SAndroid Build Coastguard Worker {
2886*8975f5c5SAndroid Build Coastguard Worker     // Set the current transform feedback state
2887*8975f5c5SAndroid Build Coastguard Worker     gl::TransformFeedback *transformFeedback = context->getState().getCurrentTransformFeedback();
2888*8975f5c5SAndroid Build Coastguard Worker     if (transformFeedback)
2889*8975f5c5SAndroid Build Coastguard Worker     {
2890*8975f5c5SAndroid Build Coastguard Worker         TransformFeedbackGL *transformFeedbackGL =
2891*8975f5c5SAndroid Build Coastguard Worker             GetImplAs<TransformFeedbackGL>(transformFeedback);
2892*8975f5c5SAndroid Build Coastguard Worker         bindTransformFeedback(GL_TRANSFORM_FEEDBACK, transformFeedbackGL->getTransformFeedbackID());
2893*8975f5c5SAndroid Build Coastguard Worker         transformFeedbackGL->syncActiveState(context, transformFeedback->isActive(),
2894*8975f5c5SAndroid Build Coastguard Worker                                              transformFeedback->getPrimitiveMode());
2895*8975f5c5SAndroid Build Coastguard Worker         transformFeedbackGL->syncPausedState(transformFeedback->isPaused());
2896*8975f5c5SAndroid Build Coastguard Worker         mCurrentTransformFeedback = transformFeedbackGL;
2897*8975f5c5SAndroid Build Coastguard Worker     }
2898*8975f5c5SAndroid Build Coastguard Worker     else
2899*8975f5c5SAndroid Build Coastguard Worker     {
2900*8975f5c5SAndroid Build Coastguard Worker         bindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0);
2901*8975f5c5SAndroid Build Coastguard Worker         mCurrentTransformFeedback = nullptr;
2902*8975f5c5SAndroid Build Coastguard Worker     }
2903*8975f5c5SAndroid Build Coastguard Worker }
2904*8975f5c5SAndroid Build Coastguard Worker 
getDefaultVAO() const2905*8975f5c5SAndroid Build Coastguard Worker GLuint StateManagerGL::getDefaultVAO() const
2906*8975f5c5SAndroid Build Coastguard Worker {
2907*8975f5c5SAndroid Build Coastguard Worker     return mDefaultVAO;
2908*8975f5c5SAndroid Build Coastguard Worker }
2909*8975f5c5SAndroid Build Coastguard Worker 
getDefaultVAOState()2910*8975f5c5SAndroid Build Coastguard Worker VertexArrayStateGL *StateManagerGL::getDefaultVAOState()
2911*8975f5c5SAndroid Build Coastguard Worker {
2912*8975f5c5SAndroid Build Coastguard Worker     return &mDefaultVAOState;
2913*8975f5c5SAndroid Build Coastguard Worker }
2914*8975f5c5SAndroid Build Coastguard Worker 
validateState() const2915*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::validateState() const
2916*8975f5c5SAndroid Build Coastguard Worker {
2917*8975f5c5SAndroid Build Coastguard Worker     // Current program
2918*8975f5c5SAndroid Build Coastguard Worker     ValidateStateHelper(mFunctions, mProgram, GL_CURRENT_PROGRAM, "mProgram", "GL_CURRENT_PROGRAM");
2919*8975f5c5SAndroid Build Coastguard Worker 
2920*8975f5c5SAndroid Build Coastguard Worker     // Buffers
2921*8975f5c5SAndroid Build Coastguard Worker     for (gl::BufferBinding bindingType : angle::AllEnums<gl::BufferBinding>())
2922*8975f5c5SAndroid Build Coastguard Worker     {
2923*8975f5c5SAndroid Build Coastguard Worker         // These binding types need compute support to be queried
2924*8975f5c5SAndroid Build Coastguard Worker         if (bindingType == gl::BufferBinding::AtomicCounter ||
2925*8975f5c5SAndroid Build Coastguard Worker             bindingType == gl::BufferBinding::DispatchIndirect ||
2926*8975f5c5SAndroid Build Coastguard Worker             bindingType == gl::BufferBinding::ShaderStorage)
2927*8975f5c5SAndroid Build Coastguard Worker         {
2928*8975f5c5SAndroid Build Coastguard Worker             if (!nativegl::SupportsCompute(mFunctions))
2929*8975f5c5SAndroid Build Coastguard Worker             {
2930*8975f5c5SAndroid Build Coastguard Worker                 continue;
2931*8975f5c5SAndroid Build Coastguard Worker             }
2932*8975f5c5SAndroid Build Coastguard Worker         }
2933*8975f5c5SAndroid Build Coastguard Worker 
2934*8975f5c5SAndroid Build Coastguard Worker         // Transform feedback buffer bindings are tracked in TransformFeedbackGL
2935*8975f5c5SAndroid Build Coastguard Worker         if (bindingType == gl::BufferBinding::TransformFeedback)
2936*8975f5c5SAndroid Build Coastguard Worker         {
2937*8975f5c5SAndroid Build Coastguard Worker             continue;
2938*8975f5c5SAndroid Build Coastguard Worker         }
2939*8975f5c5SAndroid Build Coastguard Worker 
2940*8975f5c5SAndroid Build Coastguard Worker         GLenum bindingTypeGL  = nativegl::GetBufferBindingQuery(bindingType);
2941*8975f5c5SAndroid Build Coastguard Worker         std::string localName = "mBuffers[" + ToString(bindingType) + "]";
2942*8975f5c5SAndroid Build Coastguard Worker         ValidateStateHelper(mFunctions, mBuffers[bindingType], bindingTypeGL, localName.c_str(),
2943*8975f5c5SAndroid Build Coastguard Worker                             nativegl::GetBufferBindingString(bindingType).c_str());
2944*8975f5c5SAndroid Build Coastguard Worker     }
2945*8975f5c5SAndroid Build Coastguard Worker 
2946*8975f5c5SAndroid Build Coastguard Worker     // Vertex array object
2947*8975f5c5SAndroid Build Coastguard Worker     ValidateStateHelper(mFunctions, mVAO, GL_VERTEX_ARRAY_BINDING, "mVAO",
2948*8975f5c5SAndroid Build Coastguard Worker                         "GL_VERTEX_ARRAY_BINDING");
2949*8975f5c5SAndroid Build Coastguard Worker }
2950*8975f5c5SAndroid Build Coastguard Worker 
2951*8975f5c5SAndroid Build Coastguard Worker template <>
get(GLenum name,GLboolean * value)2952*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::get(GLenum name, GLboolean *value)
2953*8975f5c5SAndroid Build Coastguard Worker {
2954*8975f5c5SAndroid Build Coastguard Worker     mFunctions->getBooleanv(name, value);
2955*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mFunctions->getError() == GL_NO_ERROR);
2956*8975f5c5SAndroid Build Coastguard Worker }
2957*8975f5c5SAndroid Build Coastguard Worker 
2958*8975f5c5SAndroid Build Coastguard Worker template <>
get(GLenum name,bool * value)2959*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::get(GLenum name, bool *value)
2960*8975f5c5SAndroid Build Coastguard Worker {
2961*8975f5c5SAndroid Build Coastguard Worker     GLboolean v;
2962*8975f5c5SAndroid Build Coastguard Worker     get(name, &v);
2963*8975f5c5SAndroid Build Coastguard Worker     *value = (v == GL_TRUE);
2964*8975f5c5SAndroid Build Coastguard Worker }
2965*8975f5c5SAndroid Build Coastguard Worker 
2966*8975f5c5SAndroid Build Coastguard Worker template <>
get(GLenum name,std::array<bool,4> * values)2967*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::get(GLenum name, std::array<bool, 4> *values)
2968*8975f5c5SAndroid Build Coastguard Worker {
2969*8975f5c5SAndroid Build Coastguard Worker     GLboolean v[4];
2970*8975f5c5SAndroid Build Coastguard Worker     get(name, v);
2971*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < 4; i++)
2972*8975f5c5SAndroid Build Coastguard Worker     {
2973*8975f5c5SAndroid Build Coastguard Worker         (*values)[i] = (v[i] == GL_TRUE);
2974*8975f5c5SAndroid Build Coastguard Worker     }
2975*8975f5c5SAndroid Build Coastguard Worker }
2976*8975f5c5SAndroid Build Coastguard Worker 
2977*8975f5c5SAndroid Build Coastguard Worker template <>
get(GLenum name,GLint * value)2978*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::get(GLenum name, GLint *value)
2979*8975f5c5SAndroid Build Coastguard Worker {
2980*8975f5c5SAndroid Build Coastguard Worker     mFunctions->getIntegerv(name, value);
2981*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mFunctions->getError() == GL_NO_ERROR);
2982*8975f5c5SAndroid Build Coastguard Worker }
2983*8975f5c5SAndroid Build Coastguard Worker 
2984*8975f5c5SAndroid Build Coastguard Worker template <>
get(GLenum name,GLenum * value)2985*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::get(GLenum name, GLenum *value)
2986*8975f5c5SAndroid Build Coastguard Worker {
2987*8975f5c5SAndroid Build Coastguard Worker     GLint v;
2988*8975f5c5SAndroid Build Coastguard Worker     get(name, &v);
2989*8975f5c5SAndroid Build Coastguard Worker     *value = static_cast<GLenum>(v);
2990*8975f5c5SAndroid Build Coastguard Worker }
2991*8975f5c5SAndroid Build Coastguard Worker 
2992*8975f5c5SAndroid Build Coastguard Worker template <>
get(GLenum name,gl::Rectangle * rect)2993*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::get(GLenum name, gl::Rectangle *rect)
2994*8975f5c5SAndroid Build Coastguard Worker {
2995*8975f5c5SAndroid Build Coastguard Worker     GLint v[4];
2996*8975f5c5SAndroid Build Coastguard Worker     get(name, v);
2997*8975f5c5SAndroid Build Coastguard Worker     *rect = gl::Rectangle(v[0], v[1], v[2], v[3]);
2998*8975f5c5SAndroid Build Coastguard Worker }
2999*8975f5c5SAndroid Build Coastguard Worker 
3000*8975f5c5SAndroid Build Coastguard Worker template <>
get(GLenum name,GLfloat * value)3001*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::get(GLenum name, GLfloat *value)
3002*8975f5c5SAndroid Build Coastguard Worker {
3003*8975f5c5SAndroid Build Coastguard Worker     mFunctions->getFloatv(name, value);
3004*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mFunctions->getError() == GL_NO_ERROR);
3005*8975f5c5SAndroid Build Coastguard Worker }
3006*8975f5c5SAndroid Build Coastguard Worker 
3007*8975f5c5SAndroid Build Coastguard Worker template <>
get(GLenum name,gl::ColorF * color)3008*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::get(GLenum name, gl::ColorF *color)
3009*8975f5c5SAndroid Build Coastguard Worker {
3010*8975f5c5SAndroid Build Coastguard Worker     GLfloat v[4];
3011*8975f5c5SAndroid Build Coastguard Worker     get(name, v);
3012*8975f5c5SAndroid Build Coastguard Worker     *color = gl::ColorF(v[0], v[1], v[2], v[3]);
3013*8975f5c5SAndroid Build Coastguard Worker }
3014*8975f5c5SAndroid Build Coastguard Worker 
syncFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3015*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::syncFromNativeContext(const gl::Extensions &extensions,
3016*8975f5c5SAndroid Build Coastguard Worker                                            ExternalContextState *state)
3017*8975f5c5SAndroid Build Coastguard Worker {
3018*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mFunctions->getError() == GL_NO_ERROR);
3019*8975f5c5SAndroid Build Coastguard Worker 
3020*8975f5c5SAndroid Build Coastguard Worker     auto *platform   = ANGLEPlatformCurrent();
3021*8975f5c5SAndroid Build Coastguard Worker     double startTime = platform->currentTime(platform);
3022*8975f5c5SAndroid Build Coastguard Worker 
3023*8975f5c5SAndroid Build Coastguard Worker     get(GL_VIEWPORT, &state->viewport);
3024*8975f5c5SAndroid Build Coastguard Worker     if (mViewport != state->viewport)
3025*8975f5c5SAndroid Build Coastguard Worker     {
3026*8975f5c5SAndroid Build Coastguard Worker         mViewport = state->viewport;
3027*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_VIEWPORT);
3028*8975f5c5SAndroid Build Coastguard Worker     }
3029*8975f5c5SAndroid Build Coastguard Worker 
3030*8975f5c5SAndroid Build Coastguard Worker     if (extensions.clipControlEXT)
3031*8975f5c5SAndroid Build Coastguard Worker     {
3032*8975f5c5SAndroid Build Coastguard Worker         get(GL_CLIP_ORIGIN, &state->clipOrigin);
3033*8975f5c5SAndroid Build Coastguard Worker         get(GL_CLIP_DEPTH_MODE, &state->clipDepthMode);
3034*8975f5c5SAndroid Build Coastguard Worker         if (mClipOrigin != gl::FromGLenum<gl::ClipOrigin>(state->clipOrigin) ||
3035*8975f5c5SAndroid Build Coastguard Worker             mClipDepthMode != gl::FromGLenum<gl::ClipDepthMode>(state->clipDepthMode))
3036*8975f5c5SAndroid Build Coastguard Worker         {
3037*8975f5c5SAndroid Build Coastguard Worker             mClipOrigin    = gl::FromGLenum<gl::ClipOrigin>(state->clipOrigin);
3038*8975f5c5SAndroid Build Coastguard Worker             mClipDepthMode = gl::FromGLenum<gl::ClipDepthMode>(state->clipDepthMode);
3039*8975f5c5SAndroid Build Coastguard Worker             mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
3040*8975f5c5SAndroid Build Coastguard Worker             mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_CLIP_CONTROL);
3041*8975f5c5SAndroid Build Coastguard Worker         }
3042*8975f5c5SAndroid Build Coastguard Worker     }
3043*8975f5c5SAndroid Build Coastguard Worker 
3044*8975f5c5SAndroid Build Coastguard Worker     get(GL_SCISSOR_TEST, &state->scissorTest);
3045*8975f5c5SAndroid Build Coastguard Worker     if (mScissorTestEnabled != static_cast<bool>(state->scissorTest))
3046*8975f5c5SAndroid Build Coastguard Worker     {
3047*8975f5c5SAndroid Build Coastguard Worker         mScissorTestEnabled = state->scissorTest;
3048*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SCISSOR_TEST_ENABLED);
3049*8975f5c5SAndroid Build Coastguard Worker     }
3050*8975f5c5SAndroid Build Coastguard Worker 
3051*8975f5c5SAndroid Build Coastguard Worker     get(GL_SCISSOR_BOX, &state->scissorBox);
3052*8975f5c5SAndroid Build Coastguard Worker     if (mScissor != state->scissorBox)
3053*8975f5c5SAndroid Build Coastguard Worker     {
3054*8975f5c5SAndroid Build Coastguard Worker         mScissor = state->scissorBox;
3055*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SCISSOR);
3056*8975f5c5SAndroid Build Coastguard Worker     }
3057*8975f5c5SAndroid Build Coastguard Worker 
3058*8975f5c5SAndroid Build Coastguard Worker     get(GL_DEPTH_TEST, &state->depthTest);
3059*8975f5c5SAndroid Build Coastguard Worker     if (mDepthTestEnabled != state->depthTest)
3060*8975f5c5SAndroid Build Coastguard Worker     {
3061*8975f5c5SAndroid Build Coastguard Worker         mDepthTestEnabled = state->depthTest;
3062*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_DEPTH_TEST_ENABLED);
3063*8975f5c5SAndroid Build Coastguard Worker     }
3064*8975f5c5SAndroid Build Coastguard Worker 
3065*8975f5c5SAndroid Build Coastguard Worker     get(GL_CULL_FACE, &state->cullFace);
3066*8975f5c5SAndroid Build Coastguard Worker     if (mCullFaceEnabled != state->cullFace)
3067*8975f5c5SAndroid Build Coastguard Worker     {
3068*8975f5c5SAndroid Build Coastguard Worker         mCullFaceEnabled = state->cullFace;
3069*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_CULL_FACE_ENABLED);
3070*8975f5c5SAndroid Build Coastguard Worker     }
3071*8975f5c5SAndroid Build Coastguard Worker 
3072*8975f5c5SAndroid Build Coastguard Worker     get(GL_CULL_FACE_MODE, &state->cullFaceMode);
3073*8975f5c5SAndroid Build Coastguard Worker     if (mCullFace != gl::FromGLenum<gl::CullFaceMode>(state->cullFaceMode))
3074*8975f5c5SAndroid Build Coastguard Worker     {
3075*8975f5c5SAndroid Build Coastguard Worker         mCullFace = gl::FromGLenum<gl::CullFaceMode>(state->cullFaceMode);
3076*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_CULL_FACE);
3077*8975f5c5SAndroid Build Coastguard Worker     }
3078*8975f5c5SAndroid Build Coastguard Worker 
3079*8975f5c5SAndroid Build Coastguard Worker     get(GL_COLOR_WRITEMASK, &state->colorMask);
3080*8975f5c5SAndroid Build Coastguard Worker     auto colorMask = mBlendStateExt.expandColorMaskValue(state->colorMask[0], state->colorMask[1],
3081*8975f5c5SAndroid Build Coastguard Worker                                                          state->colorMask[2], state->colorMask[3]);
3082*8975f5c5SAndroid Build Coastguard Worker     if (mBlendStateExt.getColorMaskBits() != colorMask)
3083*8975f5c5SAndroid Build Coastguard Worker     {
3084*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.setColorMaskBits(colorMask);
3085*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_COLOR_MASK);
3086*8975f5c5SAndroid Build Coastguard Worker     }
3087*8975f5c5SAndroid Build Coastguard Worker 
3088*8975f5c5SAndroid Build Coastguard Worker     get(GL_CURRENT_PROGRAM, &state->currentProgram);
3089*8975f5c5SAndroid Build Coastguard Worker     if (mProgram != static_cast<GLuint>(state->currentProgram))
3090*8975f5c5SAndroid Build Coastguard Worker     {
3091*8975f5c5SAndroid Build Coastguard Worker         mProgram = state->currentProgram;
3092*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_PROGRAM_BINDING);
3093*8975f5c5SAndroid Build Coastguard Worker     }
3094*8975f5c5SAndroid Build Coastguard Worker 
3095*8975f5c5SAndroid Build Coastguard Worker     get(GL_COLOR_CLEAR_VALUE, &state->colorClear);
3096*8975f5c5SAndroid Build Coastguard Worker     if (mClearColor != state->colorClear)
3097*8975f5c5SAndroid Build Coastguard Worker     {
3098*8975f5c5SAndroid Build Coastguard Worker         mClearColor = state->colorClear;
3099*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_CLEAR_COLOR);
3100*8975f5c5SAndroid Build Coastguard Worker     }
3101*8975f5c5SAndroid Build Coastguard Worker 
3102*8975f5c5SAndroid Build Coastguard Worker     get(GL_DEPTH_CLEAR_VALUE, &state->depthClear);
3103*8975f5c5SAndroid Build Coastguard Worker     if (mClearDepth != state->depthClear)
3104*8975f5c5SAndroid Build Coastguard Worker     {
3105*8975f5c5SAndroid Build Coastguard Worker         mClearDepth = state->depthClear;
3106*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_CLEAR_DEPTH);
3107*8975f5c5SAndroid Build Coastguard Worker     }
3108*8975f5c5SAndroid Build Coastguard Worker 
3109*8975f5c5SAndroid Build Coastguard Worker     get(GL_DEPTH_FUNC, &state->depthFunc);
3110*8975f5c5SAndroid Build Coastguard Worker     if (mDepthFunc != static_cast<GLenum>(state->depthFunc))
3111*8975f5c5SAndroid Build Coastguard Worker     {
3112*8975f5c5SAndroid Build Coastguard Worker         mDepthFunc = state->depthFunc;
3113*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_DEPTH_FUNC);
3114*8975f5c5SAndroid Build Coastguard Worker     }
3115*8975f5c5SAndroid Build Coastguard Worker 
3116*8975f5c5SAndroid Build Coastguard Worker     get(GL_DEPTH_WRITEMASK, &state->depthMask);
3117*8975f5c5SAndroid Build Coastguard Worker     if (mDepthMask != state->depthMask)
3118*8975f5c5SAndroid Build Coastguard Worker     {
3119*8975f5c5SAndroid Build Coastguard Worker         mDepthMask = state->depthMask;
3120*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_DEPTH_MASK);
3121*8975f5c5SAndroid Build Coastguard Worker     }
3122*8975f5c5SAndroid Build Coastguard Worker 
3123*8975f5c5SAndroid Build Coastguard Worker     get(GL_DEPTH_RANGE, state->depthRage);
3124*8975f5c5SAndroid Build Coastguard Worker     if (mNear != state->depthRage[0] || mFar != state->depthRage[1])
3125*8975f5c5SAndroid Build Coastguard Worker     {
3126*8975f5c5SAndroid Build Coastguard Worker         mNear = state->depthRage[0];
3127*8975f5c5SAndroid Build Coastguard Worker         mFar  = state->depthRage[1];
3128*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_DEPTH_RANGE);
3129*8975f5c5SAndroid Build Coastguard Worker     }
3130*8975f5c5SAndroid Build Coastguard Worker 
3131*8975f5c5SAndroid Build Coastguard Worker     get(GL_FRONT_FACE, &state->frontFace);
3132*8975f5c5SAndroid Build Coastguard Worker     if (mFrontFace != static_cast<GLenum>(state->frontFace))
3133*8975f5c5SAndroid Build Coastguard Worker     {
3134*8975f5c5SAndroid Build Coastguard Worker         mFrontFace = state->frontFace;
3135*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_FRONT_FACE);
3136*8975f5c5SAndroid Build Coastguard Worker     }
3137*8975f5c5SAndroid Build Coastguard Worker 
3138*8975f5c5SAndroid Build Coastguard Worker     get(GL_LINE_WIDTH, &state->lineWidth);
3139*8975f5c5SAndroid Build Coastguard Worker     if (mLineWidth != state->lineWidth)
3140*8975f5c5SAndroid Build Coastguard Worker     {
3141*8975f5c5SAndroid Build Coastguard Worker         mLineWidth = state->lineWidth;
3142*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_LINE_WIDTH);
3143*8975f5c5SAndroid Build Coastguard Worker     }
3144*8975f5c5SAndroid Build Coastguard Worker 
3145*8975f5c5SAndroid Build Coastguard Worker     get(GL_POLYGON_OFFSET_FACTOR, &state->polygonOffsetFactor);
3146*8975f5c5SAndroid Build Coastguard Worker     get(GL_POLYGON_OFFSET_UNITS, &state->polygonOffsetUnits);
3147*8975f5c5SAndroid Build Coastguard Worker     if (mPolygonOffsetFactor != state->polygonOffsetFactor ||
3148*8975f5c5SAndroid Build Coastguard Worker         mPolygonOffsetUnits != state->polygonOffsetUnits)
3149*8975f5c5SAndroid Build Coastguard Worker     {
3150*8975f5c5SAndroid Build Coastguard Worker         mPolygonOffsetFactor = state->polygonOffsetFactor;
3151*8975f5c5SAndroid Build Coastguard Worker         mPolygonOffsetUnits  = state->polygonOffsetUnits;
3152*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_POLYGON_OFFSET);
3153*8975f5c5SAndroid Build Coastguard Worker     }
3154*8975f5c5SAndroid Build Coastguard Worker 
3155*8975f5c5SAndroid Build Coastguard Worker     if (extensions.polygonOffsetClampEXT)
3156*8975f5c5SAndroid Build Coastguard Worker     {
3157*8975f5c5SAndroid Build Coastguard Worker         get(GL_POLYGON_OFFSET_CLAMP_EXT, &state->polygonOffsetClamp);
3158*8975f5c5SAndroid Build Coastguard Worker         if (mPolygonOffsetClamp != state->polygonOffsetClamp)
3159*8975f5c5SAndroid Build Coastguard Worker         {
3160*8975f5c5SAndroid Build Coastguard Worker             mPolygonOffsetClamp = state->polygonOffsetClamp;
3161*8975f5c5SAndroid Build Coastguard Worker             mLocalDirtyBits.set(gl::state::DIRTY_BIT_POLYGON_OFFSET);
3162*8975f5c5SAndroid Build Coastguard Worker         }
3163*8975f5c5SAndroid Build Coastguard Worker     }
3164*8975f5c5SAndroid Build Coastguard Worker 
3165*8975f5c5SAndroid Build Coastguard Worker     if (extensions.depthClampEXT)
3166*8975f5c5SAndroid Build Coastguard Worker     {
3167*8975f5c5SAndroid Build Coastguard Worker         get(GL_DEPTH_CLAMP_EXT, &state->enableDepthClamp);
3168*8975f5c5SAndroid Build Coastguard Worker         if (mDepthClampEnabled != state->enableDepthClamp)
3169*8975f5c5SAndroid Build Coastguard Worker         {
3170*8975f5c5SAndroid Build Coastguard Worker             mDepthClampEnabled = state->enableDepthClamp;
3171*8975f5c5SAndroid Build Coastguard Worker             mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
3172*8975f5c5SAndroid Build Coastguard Worker             mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_DEPTH_CLAMP_ENABLED);
3173*8975f5c5SAndroid Build Coastguard Worker         }
3174*8975f5c5SAndroid Build Coastguard Worker     }
3175*8975f5c5SAndroid Build Coastguard Worker 
3176*8975f5c5SAndroid Build Coastguard Worker     get(GL_SAMPLE_COVERAGE_VALUE, &state->sampleCoverageValue);
3177*8975f5c5SAndroid Build Coastguard Worker     get(GL_SAMPLE_COVERAGE_INVERT, &state->sampleCoverageInvert);
3178*8975f5c5SAndroid Build Coastguard Worker     if (mSampleCoverageValue != state->sampleCoverageValue ||
3179*8975f5c5SAndroid Build Coastguard Worker         mSampleCoverageInvert != state->sampleCoverageInvert)
3180*8975f5c5SAndroid Build Coastguard Worker     {
3181*8975f5c5SAndroid Build Coastguard Worker         mSampleCoverageValue  = state->sampleCoverageValue;
3182*8975f5c5SAndroid Build Coastguard Worker         mSampleCoverageInvert = state->sampleCoverageInvert;
3183*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SAMPLE_COVERAGE);
3184*8975f5c5SAndroid Build Coastguard Worker     }
3185*8975f5c5SAndroid Build Coastguard Worker 
3186*8975f5c5SAndroid Build Coastguard Worker     get(GL_DITHER, &state->enableDither);
3187*8975f5c5SAndroid Build Coastguard Worker     if (mDitherEnabled != state->enableDither)
3188*8975f5c5SAndroid Build Coastguard Worker     {
3189*8975f5c5SAndroid Build Coastguard Worker         mDitherEnabled = state->enableDither;
3190*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_DITHER_ENABLED);
3191*8975f5c5SAndroid Build Coastguard Worker     }
3192*8975f5c5SAndroid Build Coastguard Worker 
3193*8975f5c5SAndroid Build Coastguard Worker     if (extensions.polygonModeAny())
3194*8975f5c5SAndroid Build Coastguard Worker     {
3195*8975f5c5SAndroid Build Coastguard Worker         get(GL_POLYGON_MODE_NV, &state->polygonMode);
3196*8975f5c5SAndroid Build Coastguard Worker         if (mPolygonMode != gl::FromGLenum<gl::PolygonMode>(state->polygonMode))
3197*8975f5c5SAndroid Build Coastguard Worker         {
3198*8975f5c5SAndroid Build Coastguard Worker             mPolygonMode = gl::FromGLenum<gl::PolygonMode>(state->polygonMode);
3199*8975f5c5SAndroid Build Coastguard Worker             mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
3200*8975f5c5SAndroid Build Coastguard Worker             mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_POLYGON_MODE);
3201*8975f5c5SAndroid Build Coastguard Worker         }
3202*8975f5c5SAndroid Build Coastguard Worker 
3203*8975f5c5SAndroid Build Coastguard Worker         if (extensions.polygonModeNV)
3204*8975f5c5SAndroid Build Coastguard Worker         {
3205*8975f5c5SAndroid Build Coastguard Worker             get(GL_POLYGON_OFFSET_POINT_NV, &state->enablePolygonOffsetPoint);
3206*8975f5c5SAndroid Build Coastguard Worker             if (mPolygonOffsetPointEnabled != state->enablePolygonOffsetPoint)
3207*8975f5c5SAndroid Build Coastguard Worker             {
3208*8975f5c5SAndroid Build Coastguard Worker                 mPolygonOffsetPointEnabled = state->enablePolygonOffsetPoint;
3209*8975f5c5SAndroid Build Coastguard Worker                 mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
3210*8975f5c5SAndroid Build Coastguard Worker                 mLocalExtendedDirtyBits.set(
3211*8975f5c5SAndroid Build Coastguard Worker                     gl::state::EXTENDED_DIRTY_BIT_POLYGON_OFFSET_POINT_ENABLED);
3212*8975f5c5SAndroid Build Coastguard Worker             }
3213*8975f5c5SAndroid Build Coastguard Worker         }
3214*8975f5c5SAndroid Build Coastguard Worker 
3215*8975f5c5SAndroid Build Coastguard Worker         get(GL_POLYGON_OFFSET_LINE_NV, &state->enablePolygonOffsetLine);
3216*8975f5c5SAndroid Build Coastguard Worker         if (mPolygonOffsetLineEnabled != state->enablePolygonOffsetLine)
3217*8975f5c5SAndroid Build Coastguard Worker         {
3218*8975f5c5SAndroid Build Coastguard Worker             mPolygonOffsetLineEnabled = state->enablePolygonOffsetLine;
3219*8975f5c5SAndroid Build Coastguard Worker             mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
3220*8975f5c5SAndroid Build Coastguard Worker             mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_POLYGON_OFFSET_LINE_ENABLED);
3221*8975f5c5SAndroid Build Coastguard Worker         }
3222*8975f5c5SAndroid Build Coastguard Worker     }
3223*8975f5c5SAndroid Build Coastguard Worker 
3224*8975f5c5SAndroid Build Coastguard Worker     get(GL_POLYGON_OFFSET_FILL, &state->enablePolygonOffsetFill);
3225*8975f5c5SAndroid Build Coastguard Worker     if (mPolygonOffsetFillEnabled != state->enablePolygonOffsetFill)
3226*8975f5c5SAndroid Build Coastguard Worker     {
3227*8975f5c5SAndroid Build Coastguard Worker         mPolygonOffsetFillEnabled = state->enablePolygonOffsetFill;
3228*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_POLYGON_OFFSET_FILL_ENABLED);
3229*8975f5c5SAndroid Build Coastguard Worker     }
3230*8975f5c5SAndroid Build Coastguard Worker 
3231*8975f5c5SAndroid Build Coastguard Worker     get(GL_SAMPLE_ALPHA_TO_COVERAGE, &state->enableSampleAlphaToCoverage);
3232*8975f5c5SAndroid Build Coastguard Worker     if (mSampleAlphaToOneEnabled != state->enableSampleAlphaToCoverage)
3233*8975f5c5SAndroid Build Coastguard Worker     {
3234*8975f5c5SAndroid Build Coastguard Worker         mSampleAlphaToOneEnabled = state->enableSampleAlphaToCoverage;
3235*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SAMPLE_ALPHA_TO_ONE);
3236*8975f5c5SAndroid Build Coastguard Worker     }
3237*8975f5c5SAndroid Build Coastguard Worker 
3238*8975f5c5SAndroid Build Coastguard Worker     get(GL_SAMPLE_COVERAGE, &state->enableSampleCoverage);
3239*8975f5c5SAndroid Build Coastguard Worker     if (mSampleCoverageEnabled != state->enableSampleCoverage)
3240*8975f5c5SAndroid Build Coastguard Worker     {
3241*8975f5c5SAndroid Build Coastguard Worker         mSampleCoverageEnabled = state->enableSampleCoverage;
3242*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_SAMPLE_COVERAGE_ENABLED);
3243*8975f5c5SAndroid Build Coastguard Worker     }
3244*8975f5c5SAndroid Build Coastguard Worker 
3245*8975f5c5SAndroid Build Coastguard Worker     if (extensions.multisampleCompatibilityEXT)
3246*8975f5c5SAndroid Build Coastguard Worker     {
3247*8975f5c5SAndroid Build Coastguard Worker         get(GL_MULTISAMPLE, &state->multisampleEnabled);
3248*8975f5c5SAndroid Build Coastguard Worker         if (mMultisamplingEnabled != state->multisampleEnabled)
3249*8975f5c5SAndroid Build Coastguard Worker         {
3250*8975f5c5SAndroid Build Coastguard Worker             mMultisamplingEnabled = state->multisampleEnabled;
3251*8975f5c5SAndroid Build Coastguard Worker             mLocalDirtyBits.set(gl::state::DIRTY_BIT_MULTISAMPLING);
3252*8975f5c5SAndroid Build Coastguard Worker         }
3253*8975f5c5SAndroid Build Coastguard Worker     }
3254*8975f5c5SAndroid Build Coastguard Worker 
3255*8975f5c5SAndroid Build Coastguard Worker     syncBlendFromNativeContext(extensions, state);
3256*8975f5c5SAndroid Build Coastguard Worker     syncFramebufferFromNativeContext(extensions, state);
3257*8975f5c5SAndroid Build Coastguard Worker     syncPixelPackUnpackFromNativeContext(extensions, state);
3258*8975f5c5SAndroid Build Coastguard Worker     syncStencilFromNativeContext(extensions, state);
3259*8975f5c5SAndroid Build Coastguard Worker     syncVertexArraysFromNativeContext(extensions, state);
3260*8975f5c5SAndroid Build Coastguard Worker     syncBufferBindingsFromNativeContext(extensions, state);
3261*8975f5c5SAndroid Build Coastguard Worker     syncTextureUnitsFromNativeContext(extensions, state);
3262*8975f5c5SAndroid Build Coastguard Worker 
3263*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mFunctions->getError() == GL_NO_ERROR);
3264*8975f5c5SAndroid Build Coastguard Worker 
3265*8975f5c5SAndroid Build Coastguard Worker     double delta = platform->currentTime(platform) - startTime;
3266*8975f5c5SAndroid Build Coastguard Worker     int us       = static_cast<int>(delta * 1000000.0);
3267*8975f5c5SAndroid Build Coastguard Worker     ANGLE_HISTOGRAM_COUNTS("GPU.ANGLE.SyncFromNativeContextMicroseconds", us);
3268*8975f5c5SAndroid Build Coastguard Worker }
3269*8975f5c5SAndroid Build Coastguard Worker 
restoreNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3270*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::restoreNativeContext(const gl::Extensions &extensions,
3271*8975f5c5SAndroid Build Coastguard Worker                                           const ExternalContextState *state)
3272*8975f5c5SAndroid Build Coastguard Worker {
3273*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mFunctions->getError() == GL_NO_ERROR);
3274*8975f5c5SAndroid Build Coastguard Worker 
3275*8975f5c5SAndroid Build Coastguard Worker     setViewport(state->viewport);
3276*8975f5c5SAndroid Build Coastguard Worker     if (extensions.clipControlEXT)
3277*8975f5c5SAndroid Build Coastguard Worker     {
3278*8975f5c5SAndroid Build Coastguard Worker         setClipControl(gl::FromGLenum<gl::ClipOrigin>(state->clipOrigin),
3279*8975f5c5SAndroid Build Coastguard Worker                        gl::FromGLenum<gl::ClipDepthMode>(state->clipDepthMode));
3280*8975f5c5SAndroid Build Coastguard Worker     }
3281*8975f5c5SAndroid Build Coastguard Worker 
3282*8975f5c5SAndroid Build Coastguard Worker     setScissorTestEnabled(state->scissorTest);
3283*8975f5c5SAndroid Build Coastguard Worker     setScissor(state->scissorBox);
3284*8975f5c5SAndroid Build Coastguard Worker 
3285*8975f5c5SAndroid Build Coastguard Worker     setDepthTestEnabled(state->depthTest);
3286*8975f5c5SAndroid Build Coastguard Worker 
3287*8975f5c5SAndroid Build Coastguard Worker     setCullFaceEnabled(state->cullFace);
3288*8975f5c5SAndroid Build Coastguard Worker     setCullFace(gl::FromGLenum<gl::CullFaceMode>(state->cullFaceMode));
3289*8975f5c5SAndroid Build Coastguard Worker 
3290*8975f5c5SAndroid Build Coastguard Worker     setColorMask(state->colorMask[0], state->colorMask[1], state->colorMask[2],
3291*8975f5c5SAndroid Build Coastguard Worker                  state->colorMask[3]);
3292*8975f5c5SAndroid Build Coastguard Worker 
3293*8975f5c5SAndroid Build Coastguard Worker     forceUseProgram(state->currentProgram);
3294*8975f5c5SAndroid Build Coastguard Worker 
3295*8975f5c5SAndroid Build Coastguard Worker     setClearColor(state->colorClear);
3296*8975f5c5SAndroid Build Coastguard Worker 
3297*8975f5c5SAndroid Build Coastguard Worker     setClearDepth(state->depthClear);
3298*8975f5c5SAndroid Build Coastguard Worker     setDepthFunc(state->depthFunc);
3299*8975f5c5SAndroid Build Coastguard Worker     setDepthMask(state->depthMask);
3300*8975f5c5SAndroid Build Coastguard Worker     setDepthRange(state->depthRage[0], state->depthRage[1]);
3301*8975f5c5SAndroid Build Coastguard Worker 
3302*8975f5c5SAndroid Build Coastguard Worker     setFrontFace(state->frontFace);
3303*8975f5c5SAndroid Build Coastguard Worker 
3304*8975f5c5SAndroid Build Coastguard Worker     setLineWidth(state->lineWidth);
3305*8975f5c5SAndroid Build Coastguard Worker 
3306*8975f5c5SAndroid Build Coastguard Worker     setPolygonOffset(state->polygonOffsetFactor, state->polygonOffsetUnits,
3307*8975f5c5SAndroid Build Coastguard Worker                      state->polygonOffsetClamp);
3308*8975f5c5SAndroid Build Coastguard Worker 
3309*8975f5c5SAndroid Build Coastguard Worker     if (extensions.depthClampEXT)
3310*8975f5c5SAndroid Build Coastguard Worker     {
3311*8975f5c5SAndroid Build Coastguard Worker         setDepthClampEnabled(state->enableDepthClamp);
3312*8975f5c5SAndroid Build Coastguard Worker     }
3313*8975f5c5SAndroid Build Coastguard Worker 
3314*8975f5c5SAndroid Build Coastguard Worker     setSampleCoverage(state->sampleCoverageValue, state->sampleCoverageInvert);
3315*8975f5c5SAndroid Build Coastguard Worker 
3316*8975f5c5SAndroid Build Coastguard Worker     setDitherEnabled(state->enableDither);
3317*8975f5c5SAndroid Build Coastguard Worker 
3318*8975f5c5SAndroid Build Coastguard Worker     if (extensions.polygonModeAny())
3319*8975f5c5SAndroid Build Coastguard Worker     {
3320*8975f5c5SAndroid Build Coastguard Worker         setPolygonMode(gl::FromGLenum<gl::PolygonMode>(state->polygonMode));
3321*8975f5c5SAndroid Build Coastguard Worker         if (extensions.polygonModeNV)
3322*8975f5c5SAndroid Build Coastguard Worker         {
3323*8975f5c5SAndroid Build Coastguard Worker             setPolygonOffsetPointEnabled(state->enablePolygonOffsetPoint);
3324*8975f5c5SAndroid Build Coastguard Worker         }
3325*8975f5c5SAndroid Build Coastguard Worker         setPolygonOffsetLineEnabled(state->enablePolygonOffsetLine);
3326*8975f5c5SAndroid Build Coastguard Worker     }
3327*8975f5c5SAndroid Build Coastguard Worker 
3328*8975f5c5SAndroid Build Coastguard Worker     setPolygonOffsetFillEnabled(state->enablePolygonOffsetFill);
3329*8975f5c5SAndroid Build Coastguard Worker 
3330*8975f5c5SAndroid Build Coastguard Worker     setSampleAlphaToOneStateEnabled(state->enableSampleAlphaToCoverage);
3331*8975f5c5SAndroid Build Coastguard Worker 
3332*8975f5c5SAndroid Build Coastguard Worker     setSampleCoverageEnabled(state->enableSampleCoverage);
3333*8975f5c5SAndroid Build Coastguard Worker 
3334*8975f5c5SAndroid Build Coastguard Worker     if (extensions.multisampleCompatibilityEXT)
3335*8975f5c5SAndroid Build Coastguard Worker         setMultisamplingStateEnabled(state->multisampleEnabled);
3336*8975f5c5SAndroid Build Coastguard Worker 
3337*8975f5c5SAndroid Build Coastguard Worker     restoreBlendNativeContext(extensions, state);
3338*8975f5c5SAndroid Build Coastguard Worker     restoreFramebufferNativeContext(extensions, state);
3339*8975f5c5SAndroid Build Coastguard Worker     restorePixelPackUnpackNativeContext(extensions, state);
3340*8975f5c5SAndroid Build Coastguard Worker     restoreStencilNativeContext(extensions, state);
3341*8975f5c5SAndroid Build Coastguard Worker     restoreVertexArraysNativeContext(extensions, state);
3342*8975f5c5SAndroid Build Coastguard Worker     restoreBufferBindingsNativeContext(extensions, state);
3343*8975f5c5SAndroid Build Coastguard Worker     restoreTextureUnitsNativeContext(extensions, state);
3344*8975f5c5SAndroid Build Coastguard Worker 
3345*8975f5c5SAndroid Build Coastguard Worker     // if (mFunctions->coverageModulationNV) ?
3346*8975f5c5SAndroid Build Coastguard Worker     setCoverageModulation(GL_NONE);
3347*8975f5c5SAndroid Build Coastguard Worker 
3348*8975f5c5SAndroid Build Coastguard Worker     ASSERT(mFunctions->getError() == GL_NO_ERROR);
3349*8975f5c5SAndroid Build Coastguard Worker }
3350*8975f5c5SAndroid Build Coastguard Worker 
syncBlendFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3351*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::syncBlendFromNativeContext(const gl::Extensions &extensions,
3352*8975f5c5SAndroid Build Coastguard Worker                                                 ExternalContextState *state)
3353*8975f5c5SAndroid Build Coastguard Worker {
3354*8975f5c5SAndroid Build Coastguard Worker     get(GL_BLEND, &state->blendEnabled);
3355*8975f5c5SAndroid Build Coastguard Worker     if (mBlendStateExt.getEnabledMask() !=
3356*8975f5c5SAndroid Build Coastguard Worker         (state->blendEnabled ? mBlendStateExt.getAllEnabledMask() : gl::DrawBufferMask::Zero()))
3357*8975f5c5SAndroid Build Coastguard Worker     {
3358*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.setEnabled(state->blendEnabled);
3359*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_BLEND_ENABLED);
3360*8975f5c5SAndroid Build Coastguard Worker     }
3361*8975f5c5SAndroid Build Coastguard Worker 
3362*8975f5c5SAndroid Build Coastguard Worker     get(GL_BLEND_SRC_RGB, &state->blendSrcRgb);
3363*8975f5c5SAndroid Build Coastguard Worker     get(GL_BLEND_DST_RGB, &state->blendDestRgb);
3364*8975f5c5SAndroid Build Coastguard Worker     get(GL_BLEND_SRC_ALPHA, &state->blendSrcAlpha);
3365*8975f5c5SAndroid Build Coastguard Worker     get(GL_BLEND_DST_ALPHA, &state->blendDestAlpha);
3366*8975f5c5SAndroid Build Coastguard Worker     if (mBlendStateExt.getSrcColorBits() != mBlendStateExt.expandFactorValue(state->blendSrcRgb) ||
3367*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.getDstColorBits() != mBlendStateExt.expandFactorValue(state->blendDestRgb) ||
3368*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.getSrcAlphaBits() !=
3369*8975f5c5SAndroid Build Coastguard Worker             mBlendStateExt.expandFactorValue(state->blendSrcAlpha) ||
3370*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.getDstAlphaBits() != mBlendStateExt.expandFactorValue(state->blendDestAlpha))
3371*8975f5c5SAndroid Build Coastguard Worker     {
3372*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.setFactors(state->blendSrcRgb, state->blendDestRgb, state->blendSrcAlpha,
3373*8975f5c5SAndroid Build Coastguard Worker                                   state->blendDestAlpha);
3374*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_BLEND_FUNCS);
3375*8975f5c5SAndroid Build Coastguard Worker     }
3376*8975f5c5SAndroid Build Coastguard Worker 
3377*8975f5c5SAndroid Build Coastguard Worker     get(GL_BLEND_COLOR, &state->blendColor);
3378*8975f5c5SAndroid Build Coastguard Worker     if (mBlendColor != state->blendColor)
3379*8975f5c5SAndroid Build Coastguard Worker     {
3380*8975f5c5SAndroid Build Coastguard Worker         mBlendColor = state->blendColor;
3381*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_BLEND_COLOR);
3382*8975f5c5SAndroid Build Coastguard Worker     }
3383*8975f5c5SAndroid Build Coastguard Worker 
3384*8975f5c5SAndroid Build Coastguard Worker     get(GL_BLEND_EQUATION_RGB, &state->blendEquationRgb);
3385*8975f5c5SAndroid Build Coastguard Worker     get(GL_BLEND_EQUATION_ALPHA, &state->blendEquationAlpha);
3386*8975f5c5SAndroid Build Coastguard Worker     if (mBlendStateExt.getEquationColorBits() !=
3387*8975f5c5SAndroid Build Coastguard Worker             mBlendStateExt.expandEquationValue(state->blendEquationRgb) ||
3388*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.getEquationAlphaBits() !=
3389*8975f5c5SAndroid Build Coastguard Worker             mBlendStateExt.expandEquationValue(state->blendEquationAlpha))
3390*8975f5c5SAndroid Build Coastguard Worker     {
3391*8975f5c5SAndroid Build Coastguard Worker         mBlendStateExt.setEquations(state->blendEquationRgb, state->blendEquationAlpha);
3392*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_BLEND_EQUATIONS);
3393*8975f5c5SAndroid Build Coastguard Worker     }
3394*8975f5c5SAndroid Build Coastguard Worker 
3395*8975f5c5SAndroid Build Coastguard Worker     if (extensions.blendEquationAdvancedCoherentKHR)
3396*8975f5c5SAndroid Build Coastguard Worker     {
3397*8975f5c5SAndroid Build Coastguard Worker         get(GL_BLEND_ADVANCED_COHERENT_KHR, &state->enableBlendEquationAdvancedCoherent);
3398*8975f5c5SAndroid Build Coastguard Worker         if (mBlendAdvancedCoherent != state->enableBlendEquationAdvancedCoherent)
3399*8975f5c5SAndroid Build Coastguard Worker         {
3400*8975f5c5SAndroid Build Coastguard Worker             setBlendAdvancedCoherent(state->enableBlendEquationAdvancedCoherent);
3401*8975f5c5SAndroid Build Coastguard Worker             mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
3402*8975f5c5SAndroid Build Coastguard Worker             mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_BLEND_ADVANCED_COHERENT);
3403*8975f5c5SAndroid Build Coastguard Worker         }
3404*8975f5c5SAndroid Build Coastguard Worker     }
3405*8975f5c5SAndroid Build Coastguard Worker }
3406*8975f5c5SAndroid Build Coastguard Worker 
restoreBlendNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3407*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::restoreBlendNativeContext(const gl::Extensions &extensions,
3408*8975f5c5SAndroid Build Coastguard Worker                                                const ExternalContextState *state)
3409*8975f5c5SAndroid Build Coastguard Worker {
3410*8975f5c5SAndroid Build Coastguard Worker     setBlendEnabled(state->blendEnabled);
3411*8975f5c5SAndroid Build Coastguard Worker 
3412*8975f5c5SAndroid Build Coastguard Worker     mFunctions->blendFuncSeparate(state->blendSrcRgb, state->blendDestRgb, state->blendSrcAlpha,
3413*8975f5c5SAndroid Build Coastguard Worker                                   state->blendDestAlpha);
3414*8975f5c5SAndroid Build Coastguard Worker     mBlendStateExt.setFactors(state->blendSrcRgb, state->blendDestRgb, state->blendSrcAlpha,
3415*8975f5c5SAndroid Build Coastguard Worker                               state->blendDestAlpha);
3416*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_BLEND_FUNCS);
3417*8975f5c5SAndroid Build Coastguard Worker 
3418*8975f5c5SAndroid Build Coastguard Worker     setBlendColor(state->blendColor);
3419*8975f5c5SAndroid Build Coastguard Worker 
3420*8975f5c5SAndroid Build Coastguard Worker     mFunctions->blendEquationSeparate(state->blendEquationRgb, state->blendEquationAlpha);
3421*8975f5c5SAndroid Build Coastguard Worker     mBlendStateExt.setEquations(state->blendEquationRgb, state->blendEquationAlpha);
3422*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_BLEND_EQUATIONS);
3423*8975f5c5SAndroid Build Coastguard Worker 
3424*8975f5c5SAndroid Build Coastguard Worker     if (extensions.blendEquationAdvancedCoherentKHR)
3425*8975f5c5SAndroid Build Coastguard Worker     {
3426*8975f5c5SAndroid Build Coastguard Worker         setBlendAdvancedCoherent(state->enableBlendEquationAdvancedCoherent);
3427*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_EXTENDED);
3428*8975f5c5SAndroid Build Coastguard Worker         mLocalExtendedDirtyBits.set(gl::state::EXTENDED_DIRTY_BIT_BLEND_ADVANCED_COHERENT);
3429*8975f5c5SAndroid Build Coastguard Worker     }
3430*8975f5c5SAndroid Build Coastguard Worker }
3431*8975f5c5SAndroid Build Coastguard Worker 
syncFramebufferFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3432*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::syncFramebufferFromNativeContext(const gl::Extensions &extensions,
3433*8975f5c5SAndroid Build Coastguard Worker                                                       ExternalContextState *state)
3434*8975f5c5SAndroid Build Coastguard Worker {
3435*8975f5c5SAndroid Build Coastguard Worker     // TODO: wrap fbo into an EGLSurface
3436*8975f5c5SAndroid Build Coastguard Worker     get(GL_FRAMEBUFFER_BINDING, &state->framebufferBinding);
3437*8975f5c5SAndroid Build Coastguard Worker     if (mFramebuffers[angle::FramebufferBindingDraw] !=
3438*8975f5c5SAndroid Build Coastguard Worker         static_cast<GLenum>(state->framebufferBinding))
3439*8975f5c5SAndroid Build Coastguard Worker     {
3440*8975f5c5SAndroid Build Coastguard Worker         mFramebuffers[angle::FramebufferBindingDraw] =
3441*8975f5c5SAndroid Build Coastguard Worker             static_cast<GLenum>(state->framebufferBinding);
3442*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING);
3443*8975f5c5SAndroid Build Coastguard Worker     }
3444*8975f5c5SAndroid Build Coastguard Worker     if (mFramebuffers[angle::FramebufferBindingRead] !=
3445*8975f5c5SAndroid Build Coastguard Worker         static_cast<GLenum>(state->framebufferBinding))
3446*8975f5c5SAndroid Build Coastguard Worker     {
3447*8975f5c5SAndroid Build Coastguard Worker         mFramebuffers[angle::FramebufferBindingRead] =
3448*8975f5c5SAndroid Build Coastguard Worker             static_cast<GLenum>(state->framebufferBinding);
3449*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_READ_FRAMEBUFFER_BINDING);
3450*8975f5c5SAndroid Build Coastguard Worker     }
3451*8975f5c5SAndroid Build Coastguard Worker }
3452*8975f5c5SAndroid Build Coastguard Worker 
restoreFramebufferNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3453*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::restoreFramebufferNativeContext(const gl::Extensions &extensions,
3454*8975f5c5SAndroid Build Coastguard Worker                                                      const ExternalContextState *state)
3455*8975f5c5SAndroid Build Coastguard Worker {
3456*8975f5c5SAndroid Build Coastguard Worker     bindFramebuffer(GL_FRAMEBUFFER, state->framebufferBinding);
3457*8975f5c5SAndroid Build Coastguard Worker }
3458*8975f5c5SAndroid Build Coastguard Worker 
syncPixelPackUnpackFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3459*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::syncPixelPackUnpackFromNativeContext(const gl::Extensions &extensions,
3460*8975f5c5SAndroid Build Coastguard Worker                                                           ExternalContextState *state)
3461*8975f5c5SAndroid Build Coastguard Worker {
3462*8975f5c5SAndroid Build Coastguard Worker     get(GL_PACK_ALIGNMENT, &state->packAlignment);
3463*8975f5c5SAndroid Build Coastguard Worker     if (mPackAlignment != state->packAlignment)
3464*8975f5c5SAndroid Build Coastguard Worker     {
3465*8975f5c5SAndroid Build Coastguard Worker         mPackAlignment = state->packAlignment;
3466*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_PACK_STATE);
3467*8975f5c5SAndroid Build Coastguard Worker     }
3468*8975f5c5SAndroid Build Coastguard Worker 
3469*8975f5c5SAndroid Build Coastguard Worker     get(GL_UNPACK_ALIGNMENT, &state->unpackAlignment);
3470*8975f5c5SAndroid Build Coastguard Worker     if (mUnpackAlignment != state->unpackAlignment)
3471*8975f5c5SAndroid Build Coastguard Worker     {
3472*8975f5c5SAndroid Build Coastguard Worker         mUnpackAlignment = state->unpackAlignment;
3473*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_UNPACK_STATE);
3474*8975f5c5SAndroid Build Coastguard Worker     }
3475*8975f5c5SAndroid Build Coastguard Worker }
3476*8975f5c5SAndroid Build Coastguard Worker 
restorePixelPackUnpackNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3477*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::restorePixelPackUnpackNativeContext(const gl::Extensions &extensions,
3478*8975f5c5SAndroid Build Coastguard Worker                                                          const ExternalContextState *state)
3479*8975f5c5SAndroid Build Coastguard Worker {
3480*8975f5c5SAndroid Build Coastguard Worker     if (mPackAlignment != state->packAlignment)
3481*8975f5c5SAndroid Build Coastguard Worker     {
3482*8975f5c5SAndroid Build Coastguard Worker         mFunctions->pixelStorei(GL_PACK_ALIGNMENT, state->packAlignment);
3483*8975f5c5SAndroid Build Coastguard Worker         mPackAlignment = state->packAlignment;
3484*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_PACK_STATE);
3485*8975f5c5SAndroid Build Coastguard Worker     }
3486*8975f5c5SAndroid Build Coastguard Worker 
3487*8975f5c5SAndroid Build Coastguard Worker     if (mUnpackAlignment != state->unpackAlignment)
3488*8975f5c5SAndroid Build Coastguard Worker     {
3489*8975f5c5SAndroid Build Coastguard Worker         mFunctions->pixelStorei(GL_UNPACK_ALIGNMENT, state->unpackAlignment);
3490*8975f5c5SAndroid Build Coastguard Worker         mUnpackAlignment = state->unpackAlignment;
3491*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_UNPACK_STATE);
3492*8975f5c5SAndroid Build Coastguard Worker     }
3493*8975f5c5SAndroid Build Coastguard Worker }
3494*8975f5c5SAndroid Build Coastguard Worker 
syncStencilFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3495*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::syncStencilFromNativeContext(const gl::Extensions &extensions,
3496*8975f5c5SAndroid Build Coastguard Worker                                                   ExternalContextState *state)
3497*8975f5c5SAndroid Build Coastguard Worker {
3498*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_TEST, &state->stencilState.stencilTestEnabled);
3499*8975f5c5SAndroid Build Coastguard Worker     if (state->stencilState.stencilTestEnabled != mStencilTestEnabled)
3500*8975f5c5SAndroid Build Coastguard Worker     {
3501*8975f5c5SAndroid Build Coastguard Worker         mStencilTestEnabled = state->stencilState.stencilTestEnabled;
3502*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_TEST_ENABLED);
3503*8975f5c5SAndroid Build Coastguard Worker     }
3504*8975f5c5SAndroid Build Coastguard Worker 
3505*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_FUNC, &state->stencilState.stencilFrontFunc);
3506*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_VALUE_MASK, &state->stencilState.stencilFrontMask);
3507*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_REF, &state->stencilState.stencilFrontRef);
3508*8975f5c5SAndroid Build Coastguard Worker     if (state->stencilState.stencilFrontFunc != mStencilFrontFunc ||
3509*8975f5c5SAndroid Build Coastguard Worker         state->stencilState.stencilFrontMask != mStencilFrontValueMask ||
3510*8975f5c5SAndroid Build Coastguard Worker         state->stencilState.stencilFrontRef != mStencilFrontRef)
3511*8975f5c5SAndroid Build Coastguard Worker     {
3512*8975f5c5SAndroid Build Coastguard Worker         mStencilFrontFunc      = state->stencilState.stencilFrontFunc;
3513*8975f5c5SAndroid Build Coastguard Worker         mStencilFrontValueMask = state->stencilState.stencilFrontMask;
3514*8975f5c5SAndroid Build Coastguard Worker         mStencilFrontRef       = state->stencilState.stencilFrontRef;
3515*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_FUNCS_FRONT);
3516*8975f5c5SAndroid Build Coastguard Worker     }
3517*8975f5c5SAndroid Build Coastguard Worker 
3518*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_BACK_FUNC, &state->stencilState.stencilBackFunc);
3519*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_BACK_VALUE_MASK, &state->stencilState.stencilBackMask);
3520*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_BACK_REF, &state->stencilState.stencilBackRef);
3521*8975f5c5SAndroid Build Coastguard Worker     if (state->stencilState.stencilBackFunc != mStencilBackFunc ||
3522*8975f5c5SAndroid Build Coastguard Worker         state->stencilState.stencilBackMask != mStencilBackValueMask ||
3523*8975f5c5SAndroid Build Coastguard Worker         state->stencilState.stencilBackRef != mStencilBackRef)
3524*8975f5c5SAndroid Build Coastguard Worker     {
3525*8975f5c5SAndroid Build Coastguard Worker         mStencilBackFunc      = state->stencilState.stencilBackFunc;
3526*8975f5c5SAndroid Build Coastguard Worker         mStencilBackValueMask = state->stencilState.stencilBackMask;
3527*8975f5c5SAndroid Build Coastguard Worker         mStencilBackRef       = state->stencilState.stencilBackRef;
3528*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_FUNCS_BACK);
3529*8975f5c5SAndroid Build Coastguard Worker     }
3530*8975f5c5SAndroid Build Coastguard Worker 
3531*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_CLEAR_VALUE, &state->stencilState.stencilClear);
3532*8975f5c5SAndroid Build Coastguard Worker     if (mClearStencil != state->stencilState.stencilClear)
3533*8975f5c5SAndroid Build Coastguard Worker     {
3534*8975f5c5SAndroid Build Coastguard Worker         mClearStencil = state->stencilState.stencilClear;
3535*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_CLEAR_STENCIL);
3536*8975f5c5SAndroid Build Coastguard Worker     }
3537*8975f5c5SAndroid Build Coastguard Worker 
3538*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_WRITEMASK, &state->stencilState.stencilFrontWritemask);
3539*8975f5c5SAndroid Build Coastguard Worker     if (mStencilFrontWritemask != static_cast<GLenum>(state->stencilState.stencilFrontWritemask))
3540*8975f5c5SAndroid Build Coastguard Worker     {
3541*8975f5c5SAndroid Build Coastguard Worker         mStencilFrontWritemask = state->stencilState.stencilFrontWritemask;
3542*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
3543*8975f5c5SAndroid Build Coastguard Worker     }
3544*8975f5c5SAndroid Build Coastguard Worker 
3545*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_BACK_WRITEMASK, &state->stencilState.stencilBackWritemask);
3546*8975f5c5SAndroid Build Coastguard Worker     if (mStencilBackWritemask != static_cast<GLenum>(state->stencilState.stencilBackWritemask))
3547*8975f5c5SAndroid Build Coastguard Worker     {
3548*8975f5c5SAndroid Build Coastguard Worker         mStencilBackWritemask = state->stencilState.stencilBackWritemask;
3549*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_WRITEMASK_FRONT);
3550*8975f5c5SAndroid Build Coastguard Worker     }
3551*8975f5c5SAndroid Build Coastguard Worker 
3552*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_FAIL, &state->stencilState.stencilFrontFailOp);
3553*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_PASS_DEPTH_FAIL, &state->stencilState.stencilFrontZFailOp);
3554*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_PASS_DEPTH_PASS, &state->stencilState.stencilFrontZPassOp);
3555*8975f5c5SAndroid Build Coastguard Worker     if (mStencilFrontStencilFailOp != static_cast<GLenum>(state->stencilState.stencilFrontFailOp) ||
3556*8975f5c5SAndroid Build Coastguard Worker         mStencilFrontStencilPassDepthFailOp !=
3557*8975f5c5SAndroid Build Coastguard Worker             static_cast<GLenum>(state->stencilState.stencilFrontZFailOp) ||
3558*8975f5c5SAndroid Build Coastguard Worker         mStencilFrontStencilPassDepthPassOp !=
3559*8975f5c5SAndroid Build Coastguard Worker             static_cast<GLenum>(state->stencilState.stencilFrontZPassOp))
3560*8975f5c5SAndroid Build Coastguard Worker     {
3561*8975f5c5SAndroid Build Coastguard Worker         mStencilFrontStencilFailOp = static_cast<GLenum>(state->stencilState.stencilFrontFailOp);
3562*8975f5c5SAndroid Build Coastguard Worker         mStencilFrontStencilPassDepthFailOp =
3563*8975f5c5SAndroid Build Coastguard Worker             static_cast<GLenum>(state->stencilState.stencilFrontZFailOp);
3564*8975f5c5SAndroid Build Coastguard Worker         mStencilFrontStencilPassDepthPassOp =
3565*8975f5c5SAndroid Build Coastguard Worker             static_cast<GLenum>(state->stencilState.stencilFrontZPassOp);
3566*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_OPS_FRONT);
3567*8975f5c5SAndroid Build Coastguard Worker     }
3568*8975f5c5SAndroid Build Coastguard Worker 
3569*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_BACK_FAIL, &state->stencilState.stencilBackFailOp);
3570*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_BACK_PASS_DEPTH_FAIL, &state->stencilState.stencilBackZFailOp);
3571*8975f5c5SAndroid Build Coastguard Worker     get(GL_STENCIL_BACK_PASS_DEPTH_PASS, &state->stencilState.stencilBackZPassOp);
3572*8975f5c5SAndroid Build Coastguard Worker     if (mStencilBackStencilFailOp != static_cast<GLenum>(state->stencilState.stencilBackFailOp) ||
3573*8975f5c5SAndroid Build Coastguard Worker         mStencilBackStencilPassDepthFailOp !=
3574*8975f5c5SAndroid Build Coastguard Worker             static_cast<GLenum>(state->stencilState.stencilBackZFailOp) ||
3575*8975f5c5SAndroid Build Coastguard Worker         mStencilBackStencilPassDepthPassOp !=
3576*8975f5c5SAndroid Build Coastguard Worker             static_cast<GLenum>(state->stencilState.stencilBackZPassOp))
3577*8975f5c5SAndroid Build Coastguard Worker     {
3578*8975f5c5SAndroid Build Coastguard Worker         mStencilBackStencilFailOp = static_cast<GLenum>(state->stencilState.stencilBackFailOp);
3579*8975f5c5SAndroid Build Coastguard Worker         mStencilBackStencilPassDepthFailOp =
3580*8975f5c5SAndroid Build Coastguard Worker             static_cast<GLenum>(state->stencilState.stencilBackZFailOp);
3581*8975f5c5SAndroid Build Coastguard Worker         mStencilBackStencilPassDepthPassOp =
3582*8975f5c5SAndroid Build Coastguard Worker             static_cast<GLenum>(state->stencilState.stencilBackZPassOp);
3583*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_STENCIL_OPS_BACK);
3584*8975f5c5SAndroid Build Coastguard Worker     }
3585*8975f5c5SAndroid Build Coastguard Worker }
3586*8975f5c5SAndroid Build Coastguard Worker 
restoreStencilNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3587*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::restoreStencilNativeContext(const gl::Extensions &extensions,
3588*8975f5c5SAndroid Build Coastguard Worker                                                  const ExternalContextState *state)
3589*8975f5c5SAndroid Build Coastguard Worker {
3590*8975f5c5SAndroid Build Coastguard Worker     setStencilTestEnabled(state->stencilState.stencilTestEnabled);
3591*8975f5c5SAndroid Build Coastguard Worker     setStencilFrontFuncs(state->stencilState.stencilFrontFunc, state->stencilState.stencilFrontMask,
3592*8975f5c5SAndroid Build Coastguard Worker                          state->stencilState.stencilFrontRef);
3593*8975f5c5SAndroid Build Coastguard Worker     setStencilBackFuncs(state->stencilState.stencilBackFunc, state->stencilState.stencilBackMask,
3594*8975f5c5SAndroid Build Coastguard Worker                         state->stencilState.stencilBackRef);
3595*8975f5c5SAndroid Build Coastguard Worker     setClearStencil(state->stencilState.stencilClear);
3596*8975f5c5SAndroid Build Coastguard Worker     setStencilFrontWritemask(state->stencilState.stencilFrontWritemask);
3597*8975f5c5SAndroid Build Coastguard Worker     setStencilBackWritemask(state->stencilState.stencilBackWritemask);
3598*8975f5c5SAndroid Build Coastguard Worker     setStencilFrontOps(state->stencilState.stencilFrontFailOp,
3599*8975f5c5SAndroid Build Coastguard Worker                        state->stencilState.stencilFrontZFailOp,
3600*8975f5c5SAndroid Build Coastguard Worker                        state->stencilState.stencilFrontZPassOp);
3601*8975f5c5SAndroid Build Coastguard Worker     setStencilBackOps(state->stencilState.stencilBackFailOp, state->stencilState.stencilBackZFailOp,
3602*8975f5c5SAndroid Build Coastguard Worker                       state->stencilState.stencilBackZPassOp);
3603*8975f5c5SAndroid Build Coastguard Worker }
3604*8975f5c5SAndroid Build Coastguard Worker 
syncBufferBindingsFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3605*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::syncBufferBindingsFromNativeContext(const gl::Extensions &extensions,
3606*8975f5c5SAndroid Build Coastguard Worker                                                          ExternalContextState *state)
3607*8975f5c5SAndroid Build Coastguard Worker {
3608*8975f5c5SAndroid Build Coastguard Worker     get(GL_ARRAY_BUFFER_BINDING, &state->vertexArrayBufferBinding);
3609*8975f5c5SAndroid Build Coastguard Worker     mBuffers[gl::BufferBinding::Array] = state->vertexArrayBufferBinding;
3610*8975f5c5SAndroid Build Coastguard Worker 
3611*8975f5c5SAndroid Build Coastguard Worker     get(GL_ELEMENT_ARRAY_BUFFER_BINDING, &state->elementArrayBufferBinding);
3612*8975f5c5SAndroid Build Coastguard Worker     mBuffers[gl::BufferBinding::ElementArray] = state->elementArrayBufferBinding;
3613*8975f5c5SAndroid Build Coastguard Worker 
3614*8975f5c5SAndroid Build Coastguard Worker     if (mVAOState && mVAOState->elementArrayBuffer != state->elementArrayBufferBinding)
3615*8975f5c5SAndroid Build Coastguard Worker     {
3616*8975f5c5SAndroid Build Coastguard Worker         mVAOState->elementArrayBuffer = state->elementArrayBufferBinding;
3617*8975f5c5SAndroid Build Coastguard Worker         mLocalDirtyBits.set(gl::state::DIRTY_BIT_VERTEX_ARRAY_BINDING);
3618*8975f5c5SAndroid Build Coastguard Worker     }
3619*8975f5c5SAndroid Build Coastguard Worker }
3620*8975f5c5SAndroid Build Coastguard Worker 
restoreBufferBindingsNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3621*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::restoreBufferBindingsNativeContext(const gl::Extensions &extensions,
3622*8975f5c5SAndroid Build Coastguard Worker                                                         const ExternalContextState *state)
3623*8975f5c5SAndroid Build Coastguard Worker {
3624*8975f5c5SAndroid Build Coastguard Worker     bindBuffer(gl::BufferBinding::Array, state->vertexArrayBufferBinding);
3625*8975f5c5SAndroid Build Coastguard Worker     bindBuffer(gl::BufferBinding::ElementArray, state->elementArrayBufferBinding);
3626*8975f5c5SAndroid Build Coastguard Worker }
3627*8975f5c5SAndroid Build Coastguard Worker 
syncTextureUnitsFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3628*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::syncTextureUnitsFromNativeContext(const gl::Extensions &extensions,
3629*8975f5c5SAndroid Build Coastguard Worker                                                        ExternalContextState *state)
3630*8975f5c5SAndroid Build Coastguard Worker {
3631*8975f5c5SAndroid Build Coastguard Worker     get(GL_ACTIVE_TEXTURE, &state->activeTexture);
3632*8975f5c5SAndroid Build Coastguard Worker 
3633*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < state->textureBindings.size(); ++i)
3634*8975f5c5SAndroid Build Coastguard Worker     {
3635*8975f5c5SAndroid Build Coastguard Worker         auto &bindings = state->textureBindings[i];
3636*8975f5c5SAndroid Build Coastguard Worker         activeTexture(i);
3637*8975f5c5SAndroid Build Coastguard Worker         get(GL_TEXTURE_BINDING_2D, &bindings.texture2d);
3638*8975f5c5SAndroid Build Coastguard Worker         get(GL_TEXTURE_BINDING_CUBE_MAP, &bindings.textureCubeMap);
3639*8975f5c5SAndroid Build Coastguard Worker         get(GL_TEXTURE_BINDING_EXTERNAL_OES, &bindings.textureExternalOES);
3640*8975f5c5SAndroid Build Coastguard Worker         if (mTextures[gl::TextureType::_2D][i] != static_cast<GLuint>(bindings.texture2d) ||
3641*8975f5c5SAndroid Build Coastguard Worker             mTextures[gl::TextureType::CubeMap][i] !=
3642*8975f5c5SAndroid Build Coastguard Worker                 static_cast<GLuint>(bindings.textureCubeMap) ||
3643*8975f5c5SAndroid Build Coastguard Worker             mTextures[gl::TextureType::External][i] !=
3644*8975f5c5SAndroid Build Coastguard Worker                 static_cast<GLuint>(bindings.textureExternalOES))
3645*8975f5c5SAndroid Build Coastguard Worker         {
3646*8975f5c5SAndroid Build Coastguard Worker             mTextures[gl::TextureType::_2D][i]      = bindings.texture2d;
3647*8975f5c5SAndroid Build Coastguard Worker             mTextures[gl::TextureType::CubeMap][i]  = bindings.textureCubeMap;
3648*8975f5c5SAndroid Build Coastguard Worker             mTextures[gl::TextureType::External][i] = bindings.textureExternalOES;
3649*8975f5c5SAndroid Build Coastguard Worker             mLocalDirtyBits.set(gl::state::DIRTY_BIT_TEXTURE_BINDINGS);
3650*8975f5c5SAndroid Build Coastguard Worker         }
3651*8975f5c5SAndroid Build Coastguard Worker     }
3652*8975f5c5SAndroid Build Coastguard Worker }
3653*8975f5c5SAndroid Build Coastguard Worker 
restoreTextureUnitsNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3654*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::restoreTextureUnitsNativeContext(const gl::Extensions &extensions,
3655*8975f5c5SAndroid Build Coastguard Worker                                                       const ExternalContextState *state)
3656*8975f5c5SAndroid Build Coastguard Worker {
3657*8975f5c5SAndroid Build Coastguard Worker     for (size_t i = 0; i < state->textureBindings.size(); ++i)
3658*8975f5c5SAndroid Build Coastguard Worker     {
3659*8975f5c5SAndroid Build Coastguard Worker         const auto &bindings = state->textureBindings[i];
3660*8975f5c5SAndroid Build Coastguard Worker         activeTexture(i);
3661*8975f5c5SAndroid Build Coastguard Worker         bindTexture(gl::TextureType::_2D, bindings.texture2d);
3662*8975f5c5SAndroid Build Coastguard Worker         bindTexture(gl::TextureType::CubeMap, bindings.textureCubeMap);
3663*8975f5c5SAndroid Build Coastguard Worker         bindTexture(gl::TextureType::External, bindings.textureExternalOES);
3664*8975f5c5SAndroid Build Coastguard Worker         bindSampler(i, 0);
3665*8975f5c5SAndroid Build Coastguard Worker     }
3666*8975f5c5SAndroid Build Coastguard Worker     activeTexture(state->activeTexture - GL_TEXTURE0);
3667*8975f5c5SAndroid Build Coastguard Worker }
3668*8975f5c5SAndroid Build Coastguard Worker 
syncVertexArraysFromNativeContext(const gl::Extensions & extensions,ExternalContextState * state)3669*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::syncVertexArraysFromNativeContext(const gl::Extensions &extensions,
3670*8975f5c5SAndroid Build Coastguard Worker                                                        ExternalContextState *state)
3671*8975f5c5SAndroid Build Coastguard Worker {
3672*8975f5c5SAndroid Build Coastguard Worker     if (mSupportsVertexArrayObjects)
3673*8975f5c5SAndroid Build Coastguard Worker     {
3674*8975f5c5SAndroid Build Coastguard Worker         get(GL_VERTEX_ARRAY_BINDING, &state->vertexArrayBinding);
3675*8975f5c5SAndroid Build Coastguard Worker 
3676*8975f5c5SAndroid Build Coastguard Worker         if (state->vertexArrayBinding != 0 || mVAO != 0)
3677*8975f5c5SAndroid Build Coastguard Worker         {
3678*8975f5c5SAndroid Build Coastguard Worker             // Force-bind VAO 0 if it's either not already bound or StateManagerGL thinks it's not
3679*8975f5c5SAndroid Build Coastguard Worker             // bound.
3680*8975f5c5SAndroid Build Coastguard Worker             forceBindVertexArray(0, &mDefaultVAOState);
3681*8975f5c5SAndroid Build Coastguard Worker         }
3682*8975f5c5SAndroid Build Coastguard Worker     }
3683*8975f5c5SAndroid Build Coastguard Worker 
3684*8975f5c5SAndroid Build Coastguard Worker     // Save the state of the default VAO
3685*8975f5c5SAndroid Build Coastguard Worker     state->defaultVertexArrayAttributes.resize(mDefaultVAOState.attributes.size());
3686*8975f5c5SAndroid Build Coastguard Worker     for (GLint i = 0; i < static_cast<GLint>(state->defaultVertexArrayAttributes.size()); i++)
3687*8975f5c5SAndroid Build Coastguard Worker     {
3688*8975f5c5SAndroid Build Coastguard Worker         ExternalContextVertexAttribute &externalAttrib = state->defaultVertexArrayAttributes[i];
3689*8975f5c5SAndroid Build Coastguard Worker 
3690*8975f5c5SAndroid Build Coastguard Worker         GLint enabled = 0;
3691*8975f5c5SAndroid Build Coastguard Worker         mFunctions->getVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_ENABLED, &enabled);
3692*8975f5c5SAndroid Build Coastguard Worker         externalAttrib.enabled = (enabled != GL_FALSE);
3693*8975f5c5SAndroid Build Coastguard Worker 
3694*8975f5c5SAndroid Build Coastguard Worker         GLint size = 0;
3695*8975f5c5SAndroid Build Coastguard Worker         mFunctions->getVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_SIZE, &size);
3696*8975f5c5SAndroid Build Coastguard Worker         GLint type = 0;
3697*8975f5c5SAndroid Build Coastguard Worker         mFunctions->getVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_TYPE, &type);
3698*8975f5c5SAndroid Build Coastguard Worker         GLint normalized = 0;
3699*8975f5c5SAndroid Build Coastguard Worker         mFunctions->getVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_NORMALIZED, &normalized);
3700*8975f5c5SAndroid Build Coastguard Worker         externalAttrib.format = &angle::Format::Get(gl::GetVertexFormatID(
3701*8975f5c5SAndroid Build Coastguard Worker             gl::FromGLenum<gl::VertexAttribType>(type), normalized != GL_FALSE, size, false));
3702*8975f5c5SAndroid Build Coastguard Worker 
3703*8975f5c5SAndroid Build Coastguard Worker         GLint stride = 0;
3704*8975f5c5SAndroid Build Coastguard Worker         mFunctions->getVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_STRIDE, &stride);
3705*8975f5c5SAndroid Build Coastguard Worker         externalAttrib.stride = stride;
3706*8975f5c5SAndroid Build Coastguard Worker 
3707*8975f5c5SAndroid Build Coastguard Worker         mFunctions->getVertexAttribPointerv(i, GL_VERTEX_ATTRIB_ARRAY_POINTER,
3708*8975f5c5SAndroid Build Coastguard Worker                                             &externalAttrib.pointer);
3709*8975f5c5SAndroid Build Coastguard Worker 
3710*8975f5c5SAndroid Build Coastguard Worker         GLint buffer = 0;
3711*8975f5c5SAndroid Build Coastguard Worker         mFunctions->getVertexAttribiv(i, GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING, &buffer);
3712*8975f5c5SAndroid Build Coastguard Worker         externalAttrib.buffer = buffer;
3713*8975f5c5SAndroid Build Coastguard Worker 
3714*8975f5c5SAndroid Build Coastguard Worker         GLfloat currentData[4] = {0};
3715*8975f5c5SAndroid Build Coastguard Worker         mFunctions->getVertexAttribfv(i, GL_CURRENT_VERTEX_ATTRIB, currentData);
3716*8975f5c5SAndroid Build Coastguard Worker         externalAttrib.currentData.setFloatValues(currentData);
3717*8975f5c5SAndroid Build Coastguard Worker 
3718*8975f5c5SAndroid Build Coastguard Worker         // Update our local state to reflect the external context state
3719*8975f5c5SAndroid Build Coastguard Worker         VertexAttributeGL &localAttribute = mDefaultVAOState.attributes[i];
3720*8975f5c5SAndroid Build Coastguard Worker         localAttribute.enabled            = externalAttrib.enabled;
3721*8975f5c5SAndroid Build Coastguard Worker         localAttribute.format             = externalAttrib.format;
3722*8975f5c5SAndroid Build Coastguard Worker         localAttribute.pointer            = externalAttrib.pointer;
3723*8975f5c5SAndroid Build Coastguard Worker         localAttribute.relativeOffset     = 0;
3724*8975f5c5SAndroid Build Coastguard Worker         localAttribute.bindingIndex       = i;
3725*8975f5c5SAndroid Build Coastguard Worker 
3726*8975f5c5SAndroid Build Coastguard Worker         VertexBindingGL &localBinding = mDefaultVAOState.bindings[i];
3727*8975f5c5SAndroid Build Coastguard Worker         localBinding.stride           = externalAttrib.stride;
3728*8975f5c5SAndroid Build Coastguard Worker         localBinding.buffer           = externalAttrib.buffer;
3729*8975f5c5SAndroid Build Coastguard Worker         localBinding.divisor          = 0;
3730*8975f5c5SAndroid Build Coastguard Worker         localBinding.offset           = 0;
3731*8975f5c5SAndroid Build Coastguard Worker 
3732*8975f5c5SAndroid Build Coastguard Worker         gl::VertexAttribCurrentValueData &localCurrentData = mVertexAttribCurrentValues[i];
3733*8975f5c5SAndroid Build Coastguard Worker         if (localCurrentData != externalAttrib.currentData)
3734*8975f5c5SAndroid Build Coastguard Worker         {
3735*8975f5c5SAndroid Build Coastguard Worker             localCurrentData = externalAttrib.currentData;
3736*8975f5c5SAndroid Build Coastguard Worker             mLocalDirtyBits.set(gl::state::DIRTY_BIT_CURRENT_VALUES);
3737*8975f5c5SAndroid Build Coastguard Worker             mLocalDirtyCurrentValues.set(i);
3738*8975f5c5SAndroid Build Coastguard Worker         }
3739*8975f5c5SAndroid Build Coastguard Worker     }
3740*8975f5c5SAndroid Build Coastguard Worker 
3741*8975f5c5SAndroid Build Coastguard Worker     // Mark VAO state dirty and force it to be re-synced on the next draw
3742*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_VERTEX_ARRAY_BINDING);
3743*8975f5c5SAndroid Build Coastguard Worker }
3744*8975f5c5SAndroid Build Coastguard Worker 
restoreVertexArraysNativeContext(const gl::Extensions & extensions,const ExternalContextState * state)3745*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::restoreVertexArraysNativeContext(const gl::Extensions &extensions,
3746*8975f5c5SAndroid Build Coastguard Worker                                                       const ExternalContextState *state)
3747*8975f5c5SAndroid Build Coastguard Worker {
3748*8975f5c5SAndroid Build Coastguard Worker     if (mSupportsVertexArrayObjects)
3749*8975f5c5SAndroid Build Coastguard Worker     {
3750*8975f5c5SAndroid Build Coastguard Worker         // Restore the default VAO state first.
3751*8975f5c5SAndroid Build Coastguard Worker         bindVertexArray(0, &mDefaultVAOState);
3752*8975f5c5SAndroid Build Coastguard Worker     }
3753*8975f5c5SAndroid Build Coastguard Worker 
3754*8975f5c5SAndroid Build Coastguard Worker     for (GLint i = 0; i < static_cast<GLint>(state->defaultVertexArrayAttributes.size()); i++)
3755*8975f5c5SAndroid Build Coastguard Worker     {
3756*8975f5c5SAndroid Build Coastguard Worker         const ExternalContextVertexAttribute &externalAttrib =
3757*8975f5c5SAndroid Build Coastguard Worker             state->defaultVertexArrayAttributes[i];
3758*8975f5c5SAndroid Build Coastguard Worker         VertexAttributeGL &localAttribute = mDefaultVAOState.attributes[i];
3759*8975f5c5SAndroid Build Coastguard Worker         VertexBindingGL &localBinding     = mDefaultVAOState.bindings[i];
3760*8975f5c5SAndroid Build Coastguard Worker 
3761*8975f5c5SAndroid Build Coastguard Worker         if (externalAttrib.format != localAttribute.format ||
3762*8975f5c5SAndroid Build Coastguard Worker             externalAttrib.stride != localBinding.stride ||
3763*8975f5c5SAndroid Build Coastguard Worker             externalAttrib.pointer != localAttribute.pointer ||
3764*8975f5c5SAndroid Build Coastguard Worker             externalAttrib.buffer != localBinding.buffer)
3765*8975f5c5SAndroid Build Coastguard Worker         {
3766*8975f5c5SAndroid Build Coastguard Worker             bindBuffer(gl::BufferBinding::Array, externalAttrib.buffer);
3767*8975f5c5SAndroid Build Coastguard Worker             mFunctions->vertexAttribPointer(i, externalAttrib.format->channelCount,
3768*8975f5c5SAndroid Build Coastguard Worker                                             gl::ToGLenum(externalAttrib.format->vertexAttribType),
3769*8975f5c5SAndroid Build Coastguard Worker                                             externalAttrib.format->isNorm(), externalAttrib.stride,
3770*8975f5c5SAndroid Build Coastguard Worker                                             externalAttrib.pointer);
3771*8975f5c5SAndroid Build Coastguard Worker             if (mFunctions->vertexAttribDivisor)
3772*8975f5c5SAndroid Build Coastguard Worker             {
3773*8975f5c5SAndroid Build Coastguard Worker                 mFunctions->vertexAttribDivisor(i, 0);
3774*8975f5c5SAndroid Build Coastguard Worker             }
3775*8975f5c5SAndroid Build Coastguard Worker 
3776*8975f5c5SAndroid Build Coastguard Worker             localAttribute.format         = externalAttrib.format;
3777*8975f5c5SAndroid Build Coastguard Worker             localAttribute.pointer        = externalAttrib.pointer;
3778*8975f5c5SAndroid Build Coastguard Worker             localAttribute.relativeOffset = 0;
3779*8975f5c5SAndroid Build Coastguard Worker             localAttribute.bindingIndex   = i;
3780*8975f5c5SAndroid Build Coastguard Worker 
3781*8975f5c5SAndroid Build Coastguard Worker             localBinding.stride  = externalAttrib.stride;
3782*8975f5c5SAndroid Build Coastguard Worker             localBinding.buffer  = externalAttrib.buffer;
3783*8975f5c5SAndroid Build Coastguard Worker             localBinding.divisor = 0;
3784*8975f5c5SAndroid Build Coastguard Worker             localBinding.offset  = 0;
3785*8975f5c5SAndroid Build Coastguard Worker         }
3786*8975f5c5SAndroid Build Coastguard Worker 
3787*8975f5c5SAndroid Build Coastguard Worker         if (externalAttrib.enabled != localAttribute.enabled)
3788*8975f5c5SAndroid Build Coastguard Worker         {
3789*8975f5c5SAndroid Build Coastguard Worker             if (externalAttrib.enabled)
3790*8975f5c5SAndroid Build Coastguard Worker             {
3791*8975f5c5SAndroid Build Coastguard Worker                 mFunctions->enableVertexAttribArray(i);
3792*8975f5c5SAndroid Build Coastguard Worker             }
3793*8975f5c5SAndroid Build Coastguard Worker             else
3794*8975f5c5SAndroid Build Coastguard Worker             {
3795*8975f5c5SAndroid Build Coastguard Worker                 mFunctions->disableVertexAttribArray(i);
3796*8975f5c5SAndroid Build Coastguard Worker             }
3797*8975f5c5SAndroid Build Coastguard Worker 
3798*8975f5c5SAndroid Build Coastguard Worker             localAttribute.enabled = externalAttrib.enabled;
3799*8975f5c5SAndroid Build Coastguard Worker         }
3800*8975f5c5SAndroid Build Coastguard Worker 
3801*8975f5c5SAndroid Build Coastguard Worker         setAttributeCurrentData(i, externalAttrib.currentData);
3802*8975f5c5SAndroid Build Coastguard Worker     }
3803*8975f5c5SAndroid Build Coastguard Worker 
3804*8975f5c5SAndroid Build Coastguard Worker     if (mSupportsVertexArrayObjects)
3805*8975f5c5SAndroid Build Coastguard Worker     {
3806*8975f5c5SAndroid Build Coastguard Worker         // Restore the VAO binding
3807*8975f5c5SAndroid Build Coastguard Worker         bindVertexArray(state->vertexArrayBinding, nullptr);
3808*8975f5c5SAndroid Build Coastguard Worker     }
3809*8975f5c5SAndroid Build Coastguard Worker 
3810*8975f5c5SAndroid Build Coastguard Worker     // Mark VAO state dirty and force it to be re-synced on the next draw
3811*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_VERTEX_ARRAY_BINDING);
3812*8975f5c5SAndroid Build Coastguard Worker }
3813*8975f5c5SAndroid Build Coastguard Worker 
setDefaultVAOStateDirty()3814*8975f5c5SAndroid Build Coastguard Worker void StateManagerGL::setDefaultVAOStateDirty()
3815*8975f5c5SAndroid Build Coastguard Worker {
3816*8975f5c5SAndroid Build Coastguard Worker     mLocalDirtyBits.set(gl::state::DIRTY_BIT_VERTEX_ARRAY_BINDING);
3817*8975f5c5SAndroid Build Coastguard Worker }
3818*8975f5c5SAndroid Build Coastguard Worker 
3819*8975f5c5SAndroid Build Coastguard Worker }  // namespace rx
3820