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