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