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