1 //
2 // Copyright 2015 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // StateManagerGL.h: Defines a class for caching applied OpenGL state
8 
9 #ifndef LIBANGLE_RENDERER_GL_STATEMANAGERGL_H_
10 #define LIBANGLE_RENDERER_GL_STATEMANAGERGL_H_
11 
12 #include "common/debug.h"
13 #include "libANGLE/Error.h"
14 #include "libANGLE/State.h"
15 #include "libANGLE/angletypes.h"
16 #include "libANGLE/renderer/gl/functionsgl_typedefs.h"
17 #include "platform/FeaturesGL.h"
18 
19 #include <array>
20 #include <map>
21 
22 namespace gl
23 {
24 struct Caps;
25 class FramebufferState;
26 class State;
27 }  // namespace gl
28 
29 namespace rx
30 {
31 
32 class FramebufferGL;
33 class FunctionsGL;
34 class TransformFeedbackGL;
35 class VertexArrayGL;
36 class QueryGL;
37 
38 // TODO(penghuang): use gl::State?
39 struct ExternalContextState
40 {
41     GLint packAlignment;
42     GLint unpackAlignment;
43 
44     GLenum vertexArrayBufferBinding;
45     GLenum elementArrayBufferBinding;
46 
47     bool depthTest;
48     bool cullFace;
49     GLenum cullFaceMode;
50     std::array<bool, 4> colorMask;
51     gl::ColorF colorClear;
52     gl::ColorF blendColor;
53     GLfloat depthClear;
54     GLenum currentProgram;
55     GLenum depthFunc;
56     bool depthMask;
57     GLfloat depthRage[2];
58     GLenum frontFace;
59     GLfloat lineWidth;
60     GLfloat polygonOffsetFactor;
61     GLfloat polygonOffsetUnits;
62     GLfloat sampleCoverageValue;
63     bool sampleCoverageInvert;
64     GLenum blendEquationRgb;
65     GLenum blendEquationAlpha;
66 
67     bool enableDither;
68     bool enablePolygonOffsetFill;
69     bool enableSampleAlphaToCoverage;
70     bool enableSampleCoverage;
71     bool multisampleEnabled;
72 
73     bool blendEnabled;
74     GLenum blendSrcRgb;
75     GLenum blendSrcAlpha;
76     GLenum blendDestRgb;
77     GLenum blendDestAlpha;
78     GLenum activeTexture;
79     gl::Rectangle viewport;
80     bool scissorTest;
81     gl::Rectangle scissorBox;
82 
83     struct StencilState
84     {
85         bool stencilTestEnabled;
86         GLenum stencilFrontFunc;
87         GLint stencilFrontRef;
88         GLenum stencilFrontMask;
89         GLenum stencilBackFunc;
90         GLint stencilBackRef;
91         GLenum stencilBackMask;
92         GLint stencilClear;
93         GLenum stencilFrontWritemask;
94         GLenum stencilBackWritemask;
95         GLenum stencilFrontFailOp;
96         GLenum stencilFrontZFailOp;
97         GLenum stencilFrontZPassOp;
98         GLenum stencilBackFailOp;
99         GLenum stencilBackZFailOp;
100         GLenum stencilBackZPassOp;
101     };
102     StencilState stencilState;
103 
104     GLenum framebufferBinding;
105 
106     struct TextureBindings
107     {
108         GLenum texture2d;
109         GLenum textureCubeMap;
110         GLenum textureExternalOES;
111         // TODO(boliu): TEXTURE_RECTANGLE_ARB
112     };
113     std::vector<TextureBindings> textureBindings;
114 
115     GLenum vertexArrayBinding;
116 };
117 
118 struct VertexAttributeGL
119 {
120     bool enabled                = false;
121     const angle::Format *format = &angle::Format::Get(angle::FormatID::R32G32B32A32_FLOAT);
122 
123     const void *pointer   = nullptr;
124     GLuint relativeOffset = 0;
125 
126     GLuint bindingIndex = 0;
127 };
128 
129 struct VertexBindingGL
130 {
131     GLuint stride   = 16;
132     GLuint divisor  = 0;
133     GLintptr offset = 0;
134 
135     GLuint buffer = 0;
136 };
137 
138 struct VertexArrayStateGL
139 {
140     VertexArrayStateGL(size_t maxAttribs, size_t maxBindings);
141 
142     GLuint elementArrayBuffer = 0;
143 
144     angle::FixedVector<VertexAttributeGL, gl::MAX_VERTEX_ATTRIBS> attributes;
145     angle::FixedVector<VertexBindingGL, gl::MAX_VERTEX_ATTRIBS> bindings;
146 };
147 
148 class StateManagerGL final : angle::NonCopyable
149 {
150   public:
151     StateManagerGL(const FunctionsGL *functions,
152                    const gl::Caps &rendererCaps,
153                    const gl::Extensions &extensions,
154                    const angle::FeaturesGL &features);
155     ~StateManagerGL();
156 
157     void deleteProgram(GLuint program);
158     void deleteVertexArray(GLuint vao);
159     void deleteTexture(GLuint texture);
160     void deleteSampler(GLuint sampler);
161     void deleteBuffer(GLuint buffer);
162     void deleteFramebuffer(GLuint fbo);
163     void deleteRenderbuffer(GLuint rbo);
164     void deleteTransformFeedback(GLuint transformFeedback);
165 
166     void useProgram(GLuint program);
167     void forceUseProgram(GLuint program);
168     void bindVertexArray(GLuint vao, VertexArrayStateGL *vaoState);
169     void bindBuffer(gl::BufferBinding target, GLuint buffer);
170     void bindBufferBase(gl::BufferBinding target, size_t index, GLuint buffer);
171     void bindBufferRange(gl::BufferBinding target,
172                          size_t index,
173                          GLuint buffer,
174                          size_t offset,
175                          size_t size);
176     void activeTexture(size_t unit);
177     void bindTexture(gl::TextureType type, GLuint texture);
178     void invalidateTexture(gl::TextureType type);
179     void bindSampler(size_t unit, GLuint sampler);
180     void bindImageTexture(size_t unit,
181                           GLuint texture,
182                           GLint level,
183                           GLboolean layered,
184                           GLint layer,
185                           GLenum access,
186                           GLenum format);
187     void bindFramebuffer(GLenum type, GLuint framebuffer);
188     void bindRenderbuffer(GLenum type, GLuint renderbuffer);
189     void bindTransformFeedback(GLenum type, GLuint transformFeedback);
190     void onTransformFeedbackStateChange();
191     void beginQuery(gl::QueryType type, QueryGL *queryObject, GLuint queryId);
192     void endQuery(gl::QueryType type, QueryGL *queryObject, GLuint queryId);
193 
194     void setAttributeCurrentData(size_t index, const gl::VertexAttribCurrentValueData &data);
195 
196     void setScissorTestEnabled(bool enabled);
197     void setScissor(const gl::Rectangle &scissor);
198 
199     void setViewport(const gl::Rectangle &viewport);
200     void setDepthRange(float near, float far);
201 
202     void setBlendEnabled(bool enabled);
203     void setBlendEnabledIndexed(const gl::DrawBufferMask blendEnabledMask);
204     void setBlendColor(const gl::ColorF &blendColor);
205     void setBlendFuncs(const gl::BlendStateExt &blendStateExt);
206     void setBlendEquations(const gl::BlendStateExt &blendStateExt);
207     void setColorMask(bool red, bool green, bool blue, bool alpha);
208     void setSampleAlphaToCoverageEnabled(bool enabled);
209     void setSampleCoverageEnabled(bool enabled);
210     void setSampleCoverage(float value, bool invert);
211     void setSampleMaskEnabled(bool enabled);
212     void setSampleMaski(GLuint maskNumber, GLbitfield mask);
213 
214     void setDepthTestEnabled(bool enabled);
215     void setDepthFunc(GLenum depthFunc);
216     void setDepthMask(bool mask);
217     void setStencilTestEnabled(bool enabled);
218     void setStencilFrontWritemask(GLuint mask);
219     void setStencilBackWritemask(GLuint mask);
220     void setStencilFrontFuncs(GLenum func, GLint ref, GLuint mask);
221     void setStencilBackFuncs(GLenum func, GLint ref, GLuint mask);
222     void setStencilFrontOps(GLenum sfail, GLenum dpfail, GLenum dppass);
223     void setStencilBackOps(GLenum sfail, GLenum dpfail, GLenum dppass);
224 
225     void setCullFaceEnabled(bool enabled);
226     void setCullFace(gl::CullFaceMode cullFace);
227     void setFrontFace(GLenum frontFace);
228     void setPolygonOffsetFillEnabled(bool enabled);
229     void setPolygonOffset(float factor, float units);
230     void setRasterizerDiscardEnabled(bool enabled);
231     void setLineWidth(float width);
232 
233     angle::Result setPrimitiveRestartEnabled(const gl::Context *context, bool enabled);
234     angle::Result setPrimitiveRestartIndex(const gl::Context *context, GLuint index);
235 
236     void setClearColor(const gl::ColorF &clearColor);
237     void setClearDepth(float clearDepth);
238     void setClearStencil(GLint clearStencil);
239 
240     angle::Result setPixelUnpackState(const gl::Context *context,
241                                       const gl::PixelUnpackState &unpack);
242     angle::Result setPixelUnpackBuffer(const gl::Context *context, const gl::Buffer *pixelBuffer);
243     angle::Result setPixelPackState(const gl::Context *context, const gl::PixelPackState &pack);
244     angle::Result setPixelPackBuffer(const gl::Context *context, const gl::Buffer *pixelBuffer);
245 
246     void setFramebufferSRGBEnabled(const gl::Context *context, bool enabled);
247     void setFramebufferSRGBEnabledForFramebuffer(const gl::Context *context,
248                                                  bool enabled,
249                                                  const FramebufferGL *framebuffer);
250     void setColorMaskForFramebuffer(const gl::BlendStateExt &blendStateExt,
251                                     const bool disableAlpha);
252 
253     void setDitherEnabled(bool enabled);
254 
255     void setMultisamplingStateEnabled(bool enabled);
256     void setSampleAlphaToOneStateEnabled(bool enabled);
257 
258     void setCoverageModulation(GLenum components);
259 
260     void setProvokingVertex(GLenum mode);
261 
262     void setClipDistancesEnable(const gl::State::ClipDistanceEnableBits &enables);
263 
264     void pauseTransformFeedback();
265     angle::Result pauseAllQueries(const gl::Context *context);
266     angle::Result pauseQuery(const gl::Context *context, gl::QueryType type);
267     angle::Result resumeAllQueries(const gl::Context *context);
268     angle::Result resumeQuery(const gl::Context *context, gl::QueryType type);
269     angle::Result onMakeCurrent(const gl::Context *context);
270 
271     angle::Result syncState(const gl::Context *context,
272                             const gl::State::DirtyBits &glDirtyBits,
273                             const gl::State::DirtyBits &bitMask);
274 
updateMultiviewBaseViewLayerIndexUniform(const gl::Program * program,const gl::FramebufferState & drawFramebufferState)275     ANGLE_INLINE void updateMultiviewBaseViewLayerIndexUniform(
276         const gl::Program *program,
277         const gl::FramebufferState &drawFramebufferState) const
278     {
279         if (mIsMultiviewEnabled && program && program->usesMultiview())
280         {
281             updateMultiviewBaseViewLayerIndexUniformImpl(program, drawFramebufferState);
282         }
283     }
284 
getProgramID()285     GLuint getProgramID() const { return mProgram; }
getVertexArrayID()286     GLuint getVertexArrayID() const { return mVAO; }
getFramebufferID(angle::FramebufferBinding binding)287     GLuint getFramebufferID(angle::FramebufferBinding binding) const
288     {
289         return mFramebuffers[binding];
290     }
getBufferID(gl::BufferBinding binding)291     GLuint getBufferID(gl::BufferBinding binding) const { return mBuffers[binding]; }
292 
getHasSeparateFramebufferBindings()293     bool getHasSeparateFramebufferBindings() const { return mHasSeparateFramebufferBindings; }
294 
295     GLuint getDefaultVAO() const;
296     VertexArrayStateGL *getDefaultVAOState();
297     void setDefaultVAOStateDirty();
298 
299     void validateState() const;
300 
301     void syncFromNativeContext(const gl::Extensions &extensions, ExternalContextState *state);
302     void restoreNativeContext(const gl::Extensions &extensions, const ExternalContextState *state);
303 
304   private:
305     void setTextureCubemapSeamlessEnabled(bool enabled);
306 
307     void propagateProgramToVAO(const gl::Context *context,
308                                const gl::Program *program,
309                                VertexArrayGL *vao);
310 
311     void updateProgramTextureBindings(const gl::Context *context);
312     void updateProgramStorageBufferBindings(const gl::Context *context);
313     void updateProgramUniformBufferBindings(const gl::Context *context);
314     void updateProgramAtomicCounterBufferBindings(const gl::Context *context);
315     void updateProgramImageBindings(const gl::Context *context);
316 
317     void updateDispatchIndirectBufferBinding(const gl::Context *context);
318     void updateDrawIndirectBufferBinding(const gl::Context *context);
319 
320     template <typename T>
321     void get(GLenum name, T *value);
322 
323     template <size_t n, typename T>
324     void get(GLenum name, std::array<T, n> *values);
325 
326     void syncSamplersState(const gl::Context *context);
327     void syncTransformFeedbackState(const gl::Context *context);
328 
329     void updateMultiviewBaseViewLayerIndexUniformImpl(
330         const gl::Program *program,
331         const gl::FramebufferState &drawFramebufferState) const;
332 
333     void syncBlendFromNativeContext(const gl::Extensions &extensions, ExternalContextState *state);
334     void restoreBlendNativeContext(const gl::Extensions &extensions,
335                                    const ExternalContextState *state);
336 
337     void syncFramebufferFromNativeContext(const gl::Extensions &extensions,
338                                           ExternalContextState *state);
339     void restoreFramebufferNativeContext(const gl::Extensions &extensions,
340                                          const ExternalContextState *state);
341 
342     void syncPixelPackUnpackFromNativeContext(const gl::Extensions &extensions,
343                                               ExternalContextState *state);
344     void restorePixelPackUnpackNativeContext(const gl::Extensions &extensions,
345                                              const ExternalContextState *state);
346 
347     void syncStencilFromNativeContext(const gl::Extensions &extensions,
348                                       ExternalContextState *state);
349     void restoreStencilNativeContext(const gl::Extensions &extensions,
350                                      const ExternalContextState *state);
351 
352     void syncBufferBindingsFromNativeContext(const gl::Extensions &extensions,
353                                              ExternalContextState *state);
354     void restoreBufferBindingsNativeContext(const gl::Extensions &extensions,
355                                             const ExternalContextState *state);
356 
357     void syncTextureUnitsFromNativeContext(const gl::Extensions &extensions,
358                                            ExternalContextState *state);
359     void restoreTextureUnitsNativeContext(const gl::Extensions &extensions,
360                                           const ExternalContextState *state);
361 
362     void syncVertexArraysFromNativeContext(const gl::Extensions &extensions,
363                                            ExternalContextState *state);
364     void restoreVertexArraysNativeContext(const gl::Extensions &extensions,
365                                           const ExternalContextState *state);
366 
367     const FunctionsGL *mFunctions;
368     const angle::FeaturesGL &mFeatures;
369 
370     GLuint mProgram;
371 
372     GLuint mVAO;
373     std::vector<gl::VertexAttribCurrentValueData> mVertexAttribCurrentValues;
374 
375     GLuint mDefaultVAO = 0;
376     // The current state of the default VAO is owned by StateManagerGL. It may be shared between
377     // multiple VertexArrayGL objects if the native driver does not support vertex array objects.
378     // When this object is shared, StateManagerGL forces VertexArrayGL to resynchronize itself every
379     // time a new vertex array is bound.
380     VertexArrayStateGL mDefaultVAOState;
381 
382     // The state of the currently bound vertex array object so StateManagerGL can know about the
383     // current element array buffer.
384     VertexArrayStateGL *mVAOState = nullptr;
385 
386     angle::PackedEnumMap<gl::BufferBinding, GLuint> mBuffers;
387 
388     struct IndexedBufferBinding
389     {
390         IndexedBufferBinding();
391 
392         size_t offset;
393         size_t size;
394         GLuint buffer;
395     };
396     angle::PackedEnumMap<gl::BufferBinding, std::vector<IndexedBufferBinding>> mIndexedBuffers;
397 
398     size_t mTextureUnitIndex;
399     angle::PackedEnumMap<gl::TextureType, gl::ActiveTextureArray<GLuint>> mTextures;
400     gl::ActiveTextureArray<GLuint> mSamplers;
401 
402     struct ImageUnitBinding
403     {
ImageUnitBindingImageUnitBinding404         ImageUnitBinding()
405             : texture(0), level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI)
406         {}
407 
408         GLuint texture;
409         GLint level;
410         GLboolean layered;
411         GLint layer;
412         GLenum access;
413         GLenum format;
414     };
415     std::vector<ImageUnitBinding> mImages;
416 
417     GLuint mTransformFeedback;
418     TransformFeedbackGL *mCurrentTransformFeedback;
419 
420     // Queries that are currently running on the driver
421     angle::PackedEnumMap<gl::QueryType, QueryGL *> mQueries;
422 
423     // Queries that are temporarily in the paused state so that their results will not be affected
424     // by other operations
425     angle::PackedEnumMap<gl::QueryType, QueryGL *> mTemporaryPausedQueries;
426 
427     gl::ContextID mPrevDrawContext;
428 
429     GLint mUnpackAlignment;
430     GLint mUnpackRowLength;
431     GLint mUnpackSkipRows;
432     GLint mUnpackSkipPixels;
433     GLint mUnpackImageHeight;
434     GLint mUnpackSkipImages;
435 
436     GLint mPackAlignment;
437     GLint mPackRowLength;
438     GLint mPackSkipRows;
439     GLint mPackSkipPixels;
440 
441     // TODO(jmadill): Convert to std::array when available
442     std::vector<GLenum> mFramebuffers;
443     GLuint mRenderbuffer;
444 
445     bool mScissorTestEnabled;
446     gl::Rectangle mScissor;
447     gl::Rectangle mViewport;
448     float mNear;
449     float mFar;
450 
451     gl::ColorF mBlendColor;
452     gl::BlendStateExt mBlendStateExt;
453     const bool mIndependentBlendStates;
454 
455     bool mSampleAlphaToCoverageEnabled;
456     bool mSampleCoverageEnabled;
457     float mSampleCoverageValue;
458     bool mSampleCoverageInvert;
459     bool mSampleMaskEnabled;
460     std::array<GLbitfield, gl::MAX_SAMPLE_MASK_WORDS> mSampleMaskValues;
461 
462     bool mDepthTestEnabled;
463     GLenum mDepthFunc;
464     bool mDepthMask;
465     bool mStencilTestEnabled;
466     GLenum mStencilFrontFunc;
467     GLint mStencilFrontRef;
468     GLuint mStencilFrontValueMask;
469     GLenum mStencilFrontStencilFailOp;
470     GLenum mStencilFrontStencilPassDepthFailOp;
471     GLenum mStencilFrontStencilPassDepthPassOp;
472     GLuint mStencilFrontWritemask;
473     GLenum mStencilBackFunc;
474     GLint mStencilBackRef;
475     GLuint mStencilBackValueMask;
476     GLenum mStencilBackStencilFailOp;
477     GLenum mStencilBackStencilPassDepthFailOp;
478     GLenum mStencilBackStencilPassDepthPassOp;
479     GLuint mStencilBackWritemask;
480 
481     bool mCullFaceEnabled;
482     gl::CullFaceMode mCullFace;
483     GLenum mFrontFace;
484     bool mPolygonOffsetFillEnabled;
485     GLfloat mPolygonOffsetFactor;
486     GLfloat mPolygonOffsetUnits;
487     bool mRasterizerDiscardEnabled;
488     float mLineWidth;
489 
490     bool mPrimitiveRestartEnabled;
491     GLuint mPrimitiveRestartIndex;
492 
493     gl::ColorF mClearColor;
494     float mClearDepth;
495     GLint mClearStencil;
496 
497     bool mFramebufferSRGBAvailable;
498     bool mFramebufferSRGBEnabled;
499     const bool mHasSeparateFramebufferBindings;
500 
501     bool mDitherEnabled;
502     bool mTextureCubemapSeamlessEnabled;
503 
504     bool mMultisamplingEnabled;
505     bool mSampleAlphaToOneEnabled;
506 
507     GLenum mCoverageModulation;
508 
509     const bool mIsMultiviewEnabled;
510 
511     GLenum mProvokingVertex;
512 
513     gl::State::ClipDistanceEnableBits mEnabledClipDistances;
514     const size_t mMaxClipDistances;
515 
516     gl::State::DirtyBits mLocalDirtyBits;
517     gl::AttributesMask mLocalDirtyCurrentValues;
518 };
519 
520 }  // namespace rx
521 
522 #endif  // LIBANGLE_RENDERER_GL_STATEMANAGERGL_H_
523