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