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