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