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 <map>
20 
21 namespace gl
22 {
23 struct Caps;
24 class FramebufferState;
25 class State;
26 }  // namespace gl
27 
28 namespace rx
29 {
30 
31 class FramebufferGL;
32 class FunctionsGL;
33 class TransformFeedbackGL;
34 class VertexArrayGL;
35 class QueryGL;
36 
37 class StateManagerGL final : angle::NonCopyable
38 {
39   public:
40     StateManagerGL(const FunctionsGL *functions,
41                    const gl::Caps &rendererCaps,
42                    const gl::Extensions &extensions,
43                    const angle::FeaturesGL &features);
44     ~StateManagerGL();
45 
46     void deleteProgram(GLuint program);
47     void deleteVertexArray(GLuint vao);
48     void deleteTexture(GLuint texture);
49     void deleteSampler(GLuint sampler);
50     void deleteBuffer(GLuint buffer);
51     void deleteFramebuffer(GLuint fbo);
52     void deleteRenderbuffer(GLuint rbo);
53     void deleteTransformFeedback(GLuint transformFeedback);
54 
55     void useProgram(GLuint program);
56     void forceUseProgram(GLuint program);
57     void bindVertexArray(GLuint vao, GLuint elementArrayBuffer);
58     void bindBuffer(gl::BufferBinding target, GLuint buffer);
59     void bindBufferBase(gl::BufferBinding target, size_t index, GLuint buffer);
60     void bindBufferRange(gl::BufferBinding target,
61                          size_t index,
62                          GLuint buffer,
63                          size_t offset,
64                          size_t size);
65     void activeTexture(size_t unit);
66     void bindTexture(gl::TextureType type, GLuint texture);
67     void invalidateTexture(gl::TextureType type);
68     void bindSampler(size_t unit, GLuint sampler);
69     void bindImageTexture(size_t unit,
70                           GLuint texture,
71                           GLint level,
72                           GLboolean layered,
73                           GLint layer,
74                           GLenum access,
75                           GLenum format);
76     void bindFramebuffer(GLenum type, GLuint framebuffer);
77     void bindRenderbuffer(GLenum type, GLuint renderbuffer);
78     void bindTransformFeedback(GLenum type, GLuint transformFeedback);
79     void onTransformFeedbackStateChange();
80     void beginQuery(gl::QueryType type, QueryGL *queryObject, GLuint queryId);
81     void endQuery(gl::QueryType type, QueryGL *queryObject, GLuint queryId);
82 
83     void setAttributeCurrentData(size_t index, const gl::VertexAttribCurrentValueData &data);
84 
85     void setScissorTestEnabled(bool enabled);
86     void setScissor(const gl::Rectangle &scissor);
87 
88     void setViewport(const gl::Rectangle &viewport);
89     void setDepthRange(float near, float far);
90 
91     void setBlendEnabled(bool enabled);
92     void setBlendEnabledIndexed(const gl::DrawBufferMask blendEnabledMask);
93     void setBlendColor(const gl::ColorF &blendColor);
94     void setBlendFuncs(const gl::BlendStateExt &blendStateExt);
95     void setBlendEquations(const gl::BlendStateExt &blendStateExt);
96     void setColorMask(bool red, bool green, bool blue, bool alpha);
97     void setSampleAlphaToCoverageEnabled(bool enabled);
98     void setSampleCoverageEnabled(bool enabled);
99     void setSampleCoverage(float value, bool invert);
100     void setSampleMaskEnabled(bool enabled);
101     void setSampleMaski(GLuint maskNumber, GLbitfield mask);
102 
103     void setDepthTestEnabled(bool enabled);
104     void setDepthFunc(GLenum depthFunc);
105     void setDepthMask(bool mask);
106     void setStencilTestEnabled(bool enabled);
107     void setStencilFrontWritemask(GLuint mask);
108     void setStencilBackWritemask(GLuint mask);
109     void setStencilFrontFuncs(GLenum func, GLint ref, GLuint mask);
110     void setStencilBackFuncs(GLenum func, GLint ref, GLuint mask);
111     void setStencilFrontOps(GLenum sfail, GLenum dpfail, GLenum dppass);
112     void setStencilBackOps(GLenum sfail, GLenum dpfail, GLenum dppass);
113 
114     void setCullFaceEnabled(bool enabled);
115     void setCullFace(gl::CullFaceMode cullFace);
116     void setFrontFace(GLenum frontFace);
117     void setPolygonOffsetFillEnabled(bool enabled);
118     void setPolygonOffset(float factor, float units);
119     void setRasterizerDiscardEnabled(bool enabled);
120     void setLineWidth(float width);
121 
122     angle::Result setPrimitiveRestartEnabled(const gl::Context *context, bool enabled);
123     angle::Result setPrimitiveRestartIndex(const gl::Context *context, GLuint index);
124 
125     void setClearColor(const gl::ColorF &clearColor);
126     void setClearDepth(float clearDepth);
127     void setClearStencil(GLint clearStencil);
128 
129     angle::Result setPixelUnpackState(const gl::Context *context,
130                                       const gl::PixelUnpackState &unpack);
131     angle::Result setPixelUnpackBuffer(const gl::Context *context, const gl::Buffer *pixelBuffer);
132     angle::Result setPixelPackState(const gl::Context *context, const gl::PixelPackState &pack);
133     angle::Result setPixelPackBuffer(const gl::Context *context, const gl::Buffer *pixelBuffer);
134 
135     void setFramebufferSRGBEnabled(const gl::Context *context, bool enabled);
136     void setFramebufferSRGBEnabledForFramebuffer(const gl::Context *context,
137                                                  bool enabled,
138                                                  const FramebufferGL *framebuffer);
139     void setColorMaskForFramebuffer(const gl::BlendStateExt &blendStateExt,
140                                     const bool disableAlpha);
141 
142     void setDitherEnabled(bool enabled);
143 
144     void setMultisamplingStateEnabled(bool enabled);
145     void setSampleAlphaToOneStateEnabled(bool enabled);
146 
147     void setCoverageModulation(GLenum components);
148 
149     void setProvokingVertex(GLenum mode);
150 
151     void setClipDistancesEnable(const gl::State::ClipDistanceEnableBits &enables);
152 
153     void pauseTransformFeedback();
154     angle::Result pauseAllQueries(const gl::Context *context);
155     angle::Result pauseQuery(const gl::Context *context, gl::QueryType type);
156     angle::Result resumeAllQueries(const gl::Context *context);
157     angle::Result resumeQuery(const gl::Context *context, gl::QueryType type);
158     angle::Result onMakeCurrent(const gl::Context *context);
159 
160     angle::Result syncState(const gl::Context *context,
161                             const gl::State::DirtyBits &glDirtyBits,
162                             const gl::State::DirtyBits &bitMask);
163 
updateMultiviewBaseViewLayerIndexUniform(const gl::Program * program,const gl::FramebufferState & drawFramebufferState)164     ANGLE_INLINE void updateMultiviewBaseViewLayerIndexUniform(
165         const gl::Program *program,
166         const gl::FramebufferState &drawFramebufferState) const
167     {
168         if (mIsMultiviewEnabled && program && program->usesMultiview())
169         {
170             updateMultiviewBaseViewLayerIndexUniformImpl(program, drawFramebufferState);
171         }
172     }
173 
getProgramID()174     GLuint getProgramID() const { return mProgram; }
getVertexArrayID()175     GLuint getVertexArrayID() const { return mVAO; }
getFramebufferID(angle::FramebufferBinding binding)176     GLuint getFramebufferID(angle::FramebufferBinding binding) const
177     {
178         return mFramebuffers[binding];
179     }
getBufferID(gl::BufferBinding binding)180     GLuint getBufferID(gl::BufferBinding binding) const { return mBuffers[binding]; }
181 
182     void validateState() const;
183 
184   private:
185     void setTextureCubemapSeamlessEnabled(bool enabled);
186 
187     void propagateProgramToVAO(const gl::Program *program, VertexArrayGL *vao);
188 
189     void updateProgramTextureBindings(const gl::Context *context);
190     void updateProgramStorageBufferBindings(const gl::Context *context);
191     void updateProgramUniformBufferBindings(const gl::Context *context);
192     void updateProgramAtomicCounterBufferBindings(const gl::Context *context);
193     void updateProgramImageBindings(const gl::Context *context);
194 
195     void updateDispatchIndirectBufferBinding(const gl::Context *context);
196     void updateDrawIndirectBufferBinding(const gl::Context *context);
197 
198     void syncSamplersState(const gl::Context *context);
199     void syncTransformFeedbackState(const gl::Context *context);
200 
201     void updateMultiviewBaseViewLayerIndexUniformImpl(
202         const gl::Program *program,
203         const gl::FramebufferState &drawFramebufferState) const;
204 
205     const FunctionsGL *mFunctions;
206     const angle::FeaturesGL &mFeatures;
207 
208     GLuint mProgram;
209 
210     GLuint mVAO;
211     std::vector<gl::VertexAttribCurrentValueData> mVertexAttribCurrentValues;
212 
213     angle::PackedEnumMap<gl::BufferBinding, GLuint> mBuffers;
214 
215     struct IndexedBufferBinding
216     {
217         IndexedBufferBinding();
218 
219         size_t offset;
220         size_t size;
221         GLuint buffer;
222     };
223     angle::PackedEnumMap<gl::BufferBinding, std::vector<IndexedBufferBinding>> mIndexedBuffers;
224 
225     size_t mTextureUnitIndex;
226     angle::PackedEnumMap<gl::TextureType, gl::ActiveTextureArray<GLuint>> mTextures;
227     gl::ActiveTextureArray<GLuint> mSamplers;
228 
229     struct ImageUnitBinding
230     {
ImageUnitBindingImageUnitBinding231         ImageUnitBinding()
232             : texture(0), level(0), layered(false), layer(0), access(GL_READ_ONLY), format(GL_R32UI)
233         {}
234 
235         GLuint texture;
236         GLint level;
237         GLboolean layered;
238         GLint layer;
239         GLenum access;
240         GLenum format;
241     };
242     std::vector<ImageUnitBinding> mImages;
243 
244     GLuint mTransformFeedback;
245     TransformFeedbackGL *mCurrentTransformFeedback;
246 
247     // Queries that are currently running on the driver
248     angle::PackedEnumMap<gl::QueryType, QueryGL *> mQueries;
249 
250     // Queries that are temporarily in the paused state so that their results will not be affected
251     // by other operations
252     angle::PackedEnumMap<gl::QueryType, QueryGL *> mTemporaryPausedQueries;
253 
254     gl::ContextID mPrevDrawContext;
255 
256     GLint mUnpackAlignment;
257     GLint mUnpackRowLength;
258     GLint mUnpackSkipRows;
259     GLint mUnpackSkipPixels;
260     GLint mUnpackImageHeight;
261     GLint mUnpackSkipImages;
262 
263     GLint mPackAlignment;
264     GLint mPackRowLength;
265     GLint mPackSkipRows;
266     GLint mPackSkipPixels;
267 
268     // TODO(jmadill): Convert to std::array when available
269     std::vector<GLenum> mFramebuffers;
270     GLuint mRenderbuffer;
271 
272     bool mScissorTestEnabled;
273     gl::Rectangle mScissor;
274     gl::Rectangle mViewport;
275     float mNear;
276     float mFar;
277 
278     gl::ColorF mBlendColor;
279     gl::BlendStateExt mBlendStateExt;
280     const bool mIndependentBlendStates;
281 
282     bool mSampleAlphaToCoverageEnabled;
283     bool mSampleCoverageEnabled;
284     float mSampleCoverageValue;
285     bool mSampleCoverageInvert;
286     bool mSampleMaskEnabled;
287     std::array<GLbitfield, gl::MAX_SAMPLE_MASK_WORDS> mSampleMaskValues;
288 
289     bool mDepthTestEnabled;
290     GLenum mDepthFunc;
291     bool mDepthMask;
292     bool mStencilTestEnabled;
293     GLenum mStencilFrontFunc;
294     GLint mStencilFrontRef;
295     GLuint mStencilFrontValueMask;
296     GLenum mStencilFrontStencilFailOp;
297     GLenum mStencilFrontStencilPassDepthFailOp;
298     GLenum mStencilFrontStencilPassDepthPassOp;
299     GLuint mStencilFrontWritemask;
300     GLenum mStencilBackFunc;
301     GLint mStencilBackRef;
302     GLuint mStencilBackValueMask;
303     GLenum mStencilBackStencilFailOp;
304     GLenum mStencilBackStencilPassDepthFailOp;
305     GLenum mStencilBackStencilPassDepthPassOp;
306     GLuint mStencilBackWritemask;
307 
308     bool mCullFaceEnabled;
309     gl::CullFaceMode mCullFace;
310     GLenum mFrontFace;
311     bool mPolygonOffsetFillEnabled;
312     GLfloat mPolygonOffsetFactor;
313     GLfloat mPolygonOffsetUnits;
314     bool mRasterizerDiscardEnabled;
315     float mLineWidth;
316 
317     bool mPrimitiveRestartEnabled;
318     GLuint mPrimitiveRestartIndex;
319 
320     gl::ColorF mClearColor;
321     float mClearDepth;
322     GLint mClearStencil;
323 
324     bool mFramebufferSRGBAvailable;
325     bool mFramebufferSRGBEnabled;
326 
327     bool mDitherEnabled;
328     bool mTextureCubemapSeamlessEnabled;
329 
330     bool mMultisamplingEnabled;
331     bool mSampleAlphaToOneEnabled;
332 
333     GLenum mCoverageModulation;
334 
335     const bool mIsMultiviewEnabled;
336 
337     GLenum mProvokingVertex;
338 
339     gl::State::ClipDistanceEnableBits mEnabledClipDistances;
340     const size_t mMaxClipDistances;
341 
342     gl::State::DirtyBits mLocalDirtyBits;
343     gl::AttributesMask mLocalDirtyCurrentValues;
344 };
345 }  // namespace rx
346 
347 #endif  // LIBANGLE_RENDERER_GL_STATEMANAGERGL_H_
348