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