Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 1 | // Copyright 2016 The SwiftShader Authors. All Rights Reserved. |
| 2 | // |
| 3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | // you may not use this file except in compliance with the License. |
| 5 | // You may obtain a copy of the License at |
| 6 | // |
| 7 | // http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | // |
| 9 | // Unless required by applicable law or agreed to in writing, software |
| 10 | // distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | // See the License for the specific language governing permissions and |
| 13 | // limitations under the License. |
| 14 | |
| 15 | // Context.h: Defines the Context class, managing all GL state and performing |
| 16 | // rendering operations. It is the GLES2 specific implementation of EGLContext. |
| 17 | |
| 18 | #ifndef LIBGLESV2_CONTEXT_H_ |
| 19 | #define LIBGLESV2_CONTEXT_H_ |
| 20 | |
| 21 | #include "ResourceManager.h" |
| 22 | #include "Buffer.h" |
| 23 | #include "libEGL/Context.hpp" |
| 24 | #include "common/NameSpace.hpp" |
| 25 | #include "common/Object.hpp" |
| 26 | #include "common/Image.hpp" |
| 27 | #include "Renderer/Sampler.hpp" |
| 28 | |
| 29 | #include <GLES2/gl2.h> |
| 30 | #include <GLES2/gl2ext.h> |
| 31 | #include <GLES3/gl3.h> |
| 32 | #include <EGL/egl.h> |
| 33 | |
| 34 | #include <map> |
| 35 | #include <string> |
| 36 | |
| 37 | namespace egl |
| 38 | { |
| 39 | class Display; |
| 40 | class Surface; |
| 41 | class Config; |
| 42 | } |
| 43 | |
| 44 | namespace es2 |
| 45 | { |
| 46 | struct TranslatedAttribute; |
| 47 | struct TranslatedIndexData; |
| 48 | |
| 49 | class Device; |
| 50 | class Shader; |
| 51 | class Program; |
| 52 | class Texture; |
| 53 | class Texture2D; |
| 54 | class Texture3D; |
| 55 | class Texture2DArray; |
| 56 | class TextureCubeMap; |
| 57 | class TextureExternal; |
| 58 | class Framebuffer; |
| 59 | class Renderbuffer; |
| 60 | class RenderbufferStorage; |
| 61 | class Colorbuffer; |
| 62 | class Depthbuffer; |
| 63 | class StreamingIndexBuffer; |
| 64 | class Stencilbuffer; |
| 65 | class DepthStencilbuffer; |
| 66 | class VertexDataManager; |
| 67 | class IndexDataManager; |
| 68 | class Fence; |
| 69 | class FenceSync; |
| 70 | class Query; |
| 71 | class Sampler; |
| 72 | class VertexArray; |
| 73 | class TransformFeedback; |
| 74 | |
| 75 | enum |
| 76 | { |
Nicolas Capens | f0aef1a | 2016-05-18 14:44:21 -0400 | [diff] [blame] | 77 | MAX_VERTEX_ATTRIBS = sw::MAX_VERTEX_INPUTS, |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 78 | MAX_UNIFORM_VECTORS = 256, // Device limit |
| 79 | MAX_VERTEX_UNIFORM_VECTORS = sw::VERTEX_UNIFORM_VECTORS - 3, // Reserve space for gl_DepthRange |
| 80 | MAX_VARYING_VECTORS = 10, |
| 81 | MAX_TEXTURE_IMAGE_UNITS = sw::TEXTURE_IMAGE_UNITS, |
| 82 | MAX_VERTEX_TEXTURE_IMAGE_UNITS = sw::VERTEX_TEXTURE_IMAGE_UNITS, |
| 83 | MAX_COMBINED_TEXTURE_IMAGE_UNITS = MAX_TEXTURE_IMAGE_UNITS + MAX_VERTEX_TEXTURE_IMAGE_UNITS, |
| 84 | MAX_FRAGMENT_UNIFORM_VECTORS = sw::FRAGMENT_UNIFORM_VECTORS - 3, // Reserve space for gl_DepthRange |
| 85 | MAX_ELEMENT_INDEX = 0x7FFFFFFF, |
| 86 | MAX_ELEMENTS_INDICES = 0x7FFFFFFF, |
| 87 | MAX_ELEMENTS_VERTICES = 0x7FFFFFFF, |
| 88 | MAX_VERTEX_OUTPUT_VECTORS = 16, |
| 89 | MAX_FRAGMENT_INPUT_VECTORS = 15, |
Nicolas Capens | e7e70d0 | 2016-06-07 14:40:12 -0400 | [diff] [blame] | 90 | MIN_PROGRAM_TEXEL_OFFSET = sw::MIN_PROGRAM_TEXEL_OFFSET, |
Meng-Lin Wu | 2337a19 | 2016-06-01 13:54:07 -0400 | [diff] [blame] | 91 | MAX_PROGRAM_TEXEL_OFFSET = sw::MAX_PROGRAM_TEXEL_OFFSET, |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 92 | MAX_DRAW_BUFFERS = sw::RENDERTARGETS, |
| 93 | MAX_COLOR_ATTACHMENTS = MAX(MAX_DRAW_BUFFERS, 8), |
| 94 | MAX_FRAGMENT_UNIFORM_BLOCKS = sw::MAX_FRAGMENT_UNIFORM_BLOCKS, |
| 95 | MAX_VERTEX_UNIFORM_BLOCKS = sw::MAX_VERTEX_UNIFORM_BLOCKS, |
| 96 | MAX_FRAGMENT_UNIFORM_COMPONENTS = sw::FRAGMENT_UNIFORM_VECTORS * 4, |
| 97 | MAX_VERTEX_UNIFORM_COMPONENTS = sw::VERTEX_UNIFORM_VECTORS * 4, |
| 98 | MAX_UNIFORM_BLOCK_SIZE = sw::MAX_UNIFORM_BLOCK_SIZE, |
| 99 | MAX_FRAGMENT_UNIFORM_BLOCKS_COMPONENTS = sw::MAX_FRAGMENT_UNIFORM_BLOCKS * MAX_UNIFORM_BLOCK_SIZE / 4, |
| 100 | MAX_VERTEX_UNIFORM_BLOCKS_COMPONENTS = MAX_VERTEX_UNIFORM_BLOCKS * MAX_UNIFORM_BLOCK_SIZE / 4, |
| 101 | MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS = MAX_FRAGMENT_UNIFORM_BLOCKS_COMPONENTS + MAX_FRAGMENT_UNIFORM_COMPONENTS, |
| 102 | MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS = MAX_VERTEX_UNIFORM_BLOCKS_COMPONENTS + MAX_VERTEX_UNIFORM_COMPONENTS, |
| 103 | MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 4, |
| 104 | MAX_UNIFORM_BUFFER_BINDINGS = sw::MAX_UNIFORM_BUFFER_BINDINGS, |
| 105 | UNIFORM_BUFFER_OFFSET_ALIGNMENT = 1, |
| 106 | }; |
| 107 | |
| 108 | const GLenum compressedTextureFormats[] = |
| 109 | { |
| 110 | GL_ETC1_RGB8_OES, |
| 111 | #if (S3TC_SUPPORT) |
| 112 | GL_COMPRESSED_RGB_S3TC_DXT1_EXT, |
| 113 | GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, |
| 114 | GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, |
| 115 | GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, |
| 116 | #endif |
| 117 | #if (GL_ES_VERSION_3_0) |
| 118 | GL_COMPRESSED_R11_EAC, |
| 119 | GL_COMPRESSED_SIGNED_R11_EAC, |
| 120 | GL_COMPRESSED_RG11_EAC, |
| 121 | GL_COMPRESSED_SIGNED_RG11_EAC, |
| 122 | GL_COMPRESSED_RGB8_ETC2, |
| 123 | GL_COMPRESSED_SRGB8_ETC2, |
| 124 | GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2, |
| 125 | GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2, |
| 126 | GL_COMPRESSED_RGBA8_ETC2_EAC, |
| 127 | GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC, |
| 128 | GL_COMPRESSED_RGBA_ASTC_4x4_KHR, |
| 129 | GL_COMPRESSED_RGBA_ASTC_5x4_KHR, |
| 130 | GL_COMPRESSED_RGBA_ASTC_5x5_KHR, |
| 131 | GL_COMPRESSED_RGBA_ASTC_6x5_KHR, |
| 132 | GL_COMPRESSED_RGBA_ASTC_6x6_KHR, |
| 133 | GL_COMPRESSED_RGBA_ASTC_8x5_KHR, |
| 134 | GL_COMPRESSED_RGBA_ASTC_8x6_KHR, |
| 135 | GL_COMPRESSED_RGBA_ASTC_8x8_KHR, |
| 136 | GL_COMPRESSED_RGBA_ASTC_10x5_KHR, |
| 137 | GL_COMPRESSED_RGBA_ASTC_10x6_KHR, |
| 138 | GL_COMPRESSED_RGBA_ASTC_10x8_KHR, |
| 139 | GL_COMPRESSED_RGBA_ASTC_10x10_KHR, |
| 140 | GL_COMPRESSED_RGBA_ASTC_12x10_KHR, |
| 141 | GL_COMPRESSED_RGBA_ASTC_12x12_KHR, |
| 142 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR, |
| 143 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR, |
| 144 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR, |
| 145 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR, |
| 146 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR, |
| 147 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR, |
| 148 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR, |
| 149 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR, |
| 150 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR, |
| 151 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR, |
| 152 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR, |
| 153 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR, |
| 154 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR, |
| 155 | GL_COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR, |
| 156 | #endif |
| 157 | }; |
| 158 | |
| 159 | const GLint NUM_COMPRESSED_TEXTURE_FORMATS = sizeof(compressedTextureFormats) / sizeof(compressedTextureFormats[0]); |
| 160 | |
| 161 | const GLint multisampleCount[] = {4, 2, 1}; |
| 162 | const GLint NUM_MULTISAMPLE_COUNTS = sizeof(multisampleCount) / sizeof(multisampleCount[0]); |
| 163 | const GLint IMPLEMENTATION_MAX_SAMPLES = multisampleCount[0]; |
| 164 | |
| 165 | const float ALIASED_LINE_WIDTH_RANGE_MIN = 1.0f; |
| 166 | const float ALIASED_LINE_WIDTH_RANGE_MAX = 1.0f; |
| 167 | const float ALIASED_POINT_SIZE_RANGE_MIN = 0.125f; |
| 168 | const float ALIASED_POINT_SIZE_RANGE_MAX = 8192.0f; |
| 169 | const float MAX_TEXTURE_MAX_ANISOTROPY = 16.0f; |
| 170 | |
| 171 | enum QueryType |
| 172 | { |
| 173 | QUERY_ANY_SAMPLES_PASSED, |
| 174 | QUERY_ANY_SAMPLES_PASSED_CONSERVATIVE, |
| 175 | QUERY_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN, |
| 176 | |
| 177 | QUERY_TYPE_COUNT |
| 178 | }; |
| 179 | |
| 180 | struct Color |
| 181 | { |
| 182 | float red; |
| 183 | float green; |
| 184 | float blue; |
| 185 | float alpha; |
| 186 | }; |
| 187 | |
| 188 | // Helper structure describing a single vertex attribute |
| 189 | class VertexAttribute |
| 190 | { |
| 191 | public: |
| 192 | VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mDivisor(0), mPointer(nullptr), mArrayEnabled(false) |
| 193 | { |
| 194 | mCurrentValue[0].f = 0.0f; |
| 195 | mCurrentValue[1].f = 0.0f; |
| 196 | mCurrentValue[2].f = 0.0f; |
| 197 | mCurrentValue[3].f = 1.0f; |
| 198 | mCurrentValueType = ValueUnion::FloatType; |
| 199 | } |
| 200 | |
| 201 | int typeSize() const |
| 202 | { |
| 203 | switch(mType) |
| 204 | { |
| 205 | case GL_BYTE: return mSize * sizeof(GLbyte); |
| 206 | case GL_UNSIGNED_BYTE: return mSize * sizeof(GLubyte); |
| 207 | case GL_SHORT: return mSize * sizeof(GLshort); |
| 208 | case GL_UNSIGNED_SHORT: return mSize * sizeof(GLushort); |
| 209 | case GL_INT: return mSize * sizeof(GLint); |
| 210 | case GL_UNSIGNED_INT: return mSize * sizeof(GLuint); |
| 211 | case GL_FIXED: return mSize * sizeof(GLfixed); |
| 212 | case GL_FLOAT: return mSize * sizeof(GLfloat); |
Alexis Hetu | 70085ba | 2016-05-13 22:40:02 -0400 | [diff] [blame] | 213 | case GL_HALF_FLOAT: return mSize * sizeof(GLhalf); |
| 214 | case GL_INT_2_10_10_10_REV: return sizeof(GLint); |
| 215 | case GL_UNSIGNED_INT_2_10_10_10_REV: return sizeof(GLuint); |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 216 | default: UNREACHABLE(mType); return mSize * sizeof(GLfloat); |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | GLsizei stride() const |
| 221 | { |
| 222 | return mStride ? mStride : typeSize(); |
| 223 | } |
| 224 | |
| 225 | inline float getCurrentValueBitsAsFloat(int i) const |
| 226 | { |
| 227 | return mCurrentValue[i].f; |
| 228 | } |
| 229 | |
| 230 | inline float getCurrentValueF(int i) const |
| 231 | { |
| 232 | switch(mCurrentValueType) |
| 233 | { |
| 234 | case ValueUnion::FloatType: return mCurrentValue[i].f; |
| 235 | case ValueUnion::IntType: return static_cast<float>(mCurrentValue[i].i); |
| 236 | case ValueUnion::UIntType: return static_cast<float>(mCurrentValue[i].ui); |
| 237 | default: UNREACHABLE(mCurrentValueType); return mCurrentValue[i].f; |
| 238 | } |
| 239 | } |
| 240 | |
| 241 | inline GLint getCurrentValueI(int i) const |
| 242 | { |
| 243 | switch(mCurrentValueType) |
| 244 | { |
| 245 | case ValueUnion::FloatType: return static_cast<GLint>(mCurrentValue[i].f); |
| 246 | case ValueUnion::IntType: return mCurrentValue[i].i; |
| 247 | case ValueUnion::UIntType: return static_cast<GLint>(mCurrentValue[i].ui); |
| 248 | default: UNREACHABLE(mCurrentValueType); return mCurrentValue[i].i; |
| 249 | } |
| 250 | } |
| 251 | |
| 252 | inline GLuint getCurrentValueUI(int i) const |
| 253 | { |
| 254 | switch(mCurrentValueType) |
| 255 | { |
| 256 | case ValueUnion::FloatType: return static_cast<GLuint>(mCurrentValue[i].f); |
| 257 | case ValueUnion::IntType: return static_cast<GLuint>(mCurrentValue[i].i); |
| 258 | case ValueUnion::UIntType: return mCurrentValue[i].ui; |
| 259 | default: UNREACHABLE(mCurrentValueType); return mCurrentValue[i].ui; |
| 260 | } |
| 261 | } |
| 262 | |
| 263 | inline void setCurrentValue(const GLfloat *values) |
| 264 | { |
| 265 | mCurrentValue[0].f = values[0]; |
| 266 | mCurrentValue[1].f = values[1]; |
| 267 | mCurrentValue[2].f = values[2]; |
| 268 | mCurrentValue[3].f = values[3]; |
| 269 | mCurrentValueType = ValueUnion::FloatType; |
| 270 | } |
| 271 | |
| 272 | inline void setCurrentValue(const GLint *values) |
| 273 | { |
| 274 | mCurrentValue[0].i = values[0]; |
| 275 | mCurrentValue[1].i = values[1]; |
| 276 | mCurrentValue[2].i = values[2]; |
| 277 | mCurrentValue[3].i = values[3]; |
| 278 | mCurrentValueType = ValueUnion::IntType; |
| 279 | } |
| 280 | |
| 281 | inline void setCurrentValue(const GLuint *values) |
| 282 | { |
| 283 | mCurrentValue[0].ui = values[0]; |
| 284 | mCurrentValue[1].ui = values[1]; |
| 285 | mCurrentValue[2].ui = values[2]; |
| 286 | mCurrentValue[3].ui = values[3]; |
| 287 | mCurrentValueType = ValueUnion::UIntType; |
| 288 | } |
| 289 | |
| 290 | // From glVertexAttribPointer |
| 291 | GLenum mType; |
| 292 | GLint mSize; |
| 293 | bool mNormalized; |
| 294 | GLsizei mStride; // 0 means natural stride |
| 295 | GLuint mDivisor; // From glVertexAttribDivisor |
| 296 | |
| 297 | union |
| 298 | { |
| 299 | const void *mPointer; |
| 300 | intptr_t mOffset; |
| 301 | }; |
| 302 | |
| 303 | gl::BindingPointer<Buffer> mBoundBuffer; // Captured when glVertexAttribPointer is called. |
| 304 | |
| 305 | bool mArrayEnabled; // From glEnable/DisableVertexAttribArray |
| 306 | |
| 307 | private: |
| 308 | union ValueUnion |
| 309 | { |
| 310 | enum Type { FloatType, IntType, UIntType }; |
| 311 | |
| 312 | float f; |
| 313 | GLint i; |
| 314 | GLuint ui; |
| 315 | }; |
| 316 | |
| 317 | ValueUnion mCurrentValue[4]; // From glVertexAttrib |
| 318 | ValueUnion::Type mCurrentValueType; |
| 319 | }; |
| 320 | |
| 321 | typedef VertexAttribute VertexAttributeArray[MAX_VERTEX_ATTRIBS]; |
| 322 | |
| 323 | // Helper structure to store all raw state |
| 324 | struct State |
| 325 | { |
| 326 | Color colorClearValue; |
| 327 | GLclampf depthClearValue; |
| 328 | int stencilClearValue; |
| 329 | |
| 330 | bool cullFaceEnabled; |
| 331 | GLenum cullMode; |
| 332 | GLenum frontFace; |
| 333 | bool depthTestEnabled; |
| 334 | GLenum depthFunc; |
| 335 | bool blendEnabled; |
| 336 | GLenum sourceBlendRGB; |
| 337 | GLenum destBlendRGB; |
| 338 | GLenum sourceBlendAlpha; |
| 339 | GLenum destBlendAlpha; |
| 340 | GLenum blendEquationRGB; |
| 341 | GLenum blendEquationAlpha; |
| 342 | Color blendColor; |
| 343 | bool stencilTestEnabled; |
| 344 | GLenum stencilFunc; |
| 345 | GLint stencilRef; |
| 346 | GLuint stencilMask; |
| 347 | GLenum stencilFail; |
| 348 | GLenum stencilPassDepthFail; |
| 349 | GLenum stencilPassDepthPass; |
| 350 | GLuint stencilWritemask; |
| 351 | GLenum stencilBackFunc; |
| 352 | GLint stencilBackRef; |
| 353 | GLuint stencilBackMask; |
| 354 | GLenum stencilBackFail; |
| 355 | GLenum stencilBackPassDepthFail; |
| 356 | GLenum stencilBackPassDepthPass; |
| 357 | GLuint stencilBackWritemask; |
| 358 | bool polygonOffsetFillEnabled; |
| 359 | GLfloat polygonOffsetFactor; |
| 360 | GLfloat polygonOffsetUnits; |
| 361 | bool sampleAlphaToCoverageEnabled; |
| 362 | bool sampleCoverageEnabled; |
| 363 | GLclampf sampleCoverageValue; |
| 364 | bool sampleCoverageInvert; |
| 365 | bool scissorTestEnabled; |
| 366 | bool ditherEnabled; |
| 367 | bool primitiveRestartFixedIndexEnabled; |
| 368 | bool rasterizerDiscardEnabled; |
| 369 | bool colorLogicOpEnabled; |
| 370 | GLenum logicalOperation; |
| 371 | |
| 372 | GLfloat lineWidth; |
| 373 | |
| 374 | GLenum generateMipmapHint; |
| 375 | GLenum fragmentShaderDerivativeHint; |
| 376 | |
| 377 | GLint viewportX; |
| 378 | GLint viewportY; |
| 379 | GLsizei viewportWidth; |
| 380 | GLsizei viewportHeight; |
| 381 | float zNear; |
| 382 | float zFar; |
| 383 | |
| 384 | GLint scissorX; |
| 385 | GLint scissorY; |
| 386 | GLsizei scissorWidth; |
| 387 | GLsizei scissorHeight; |
| 388 | |
| 389 | bool colorMaskRed; |
| 390 | bool colorMaskGreen; |
| 391 | bool colorMaskBlue; |
| 392 | bool colorMaskAlpha; |
| 393 | bool depthMask; |
| 394 | |
| 395 | unsigned int activeSampler; // Active texture unit selector - GL_TEXTURE0 |
| 396 | gl::BindingPointer<Buffer> arrayBuffer; |
| 397 | gl::BindingPointer<Buffer> copyReadBuffer; |
| 398 | gl::BindingPointer<Buffer> copyWriteBuffer; |
| 399 | gl::BindingPointer<Buffer> pixelPackBuffer; |
| 400 | gl::BindingPointer<Buffer> pixelUnpackBuffer; |
| 401 | gl::BindingPointer<Buffer> genericUniformBuffer; |
| 402 | BufferBinding uniformBuffers[MAX_UNIFORM_BUFFER_BINDINGS]; |
| 403 | |
| 404 | GLuint readFramebuffer; |
| 405 | GLuint drawFramebuffer; |
| 406 | gl::BindingPointer<Renderbuffer> renderbuffer; |
| 407 | GLuint currentProgram; |
| 408 | GLuint vertexArray; |
| 409 | GLuint transformFeedback; |
| 410 | gl::BindingPointer<Sampler> sampler[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; |
| 411 | |
| 412 | VertexAttribute vertexAttribute[MAX_VERTEX_ATTRIBS]; |
| 413 | gl::BindingPointer<Texture> samplerTexture[TEXTURE_TYPE_COUNT][MAX_COMBINED_TEXTURE_IMAGE_UNITS]; |
| 414 | gl::BindingPointer<Query> activeQuery[QUERY_TYPE_COUNT]; |
| 415 | |
| 416 | egl::Image::UnpackInfo unpackInfo; |
| 417 | GLint packAlignment; |
| 418 | GLint packRowLength; |
| 419 | GLint packImageHeight; |
| 420 | GLint packSkipPixels; |
| 421 | GLint packSkipRows; |
| 422 | GLint packSkipImages; |
| 423 | }; |
| 424 | |
| 425 | class Context : public egl::Context |
| 426 | { |
| 427 | public: |
Alexis Hetu | cc5c464 | 2016-06-08 15:04:56 -0400 | [diff] [blame] | 428 | Context(egl::Display *display, const Context *shareContext, EGLint clientVersion); |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 429 | |
| 430 | virtual void makeCurrent(egl::Surface *surface); |
| 431 | virtual EGLint getClientVersion() const; |
| 432 | |
| 433 | void markAllStateDirty(); |
| 434 | |
| 435 | // State manipulation |
| 436 | void setClearColor(float red, float green, float blue, float alpha); |
| 437 | void setClearDepth(float depth); |
| 438 | void setClearStencil(int stencil); |
| 439 | |
| 440 | void setCullFaceEnabled(bool enabled); |
| 441 | bool isCullFaceEnabled() const; |
| 442 | void setCullMode(GLenum mode); |
| 443 | void setFrontFace(GLenum front); |
| 444 | |
| 445 | void setDepthTestEnabled(bool enabled); |
| 446 | bool isDepthTestEnabled() const; |
| 447 | void setDepthFunc(GLenum depthFunc); |
| 448 | void setDepthRange(float zNear, float zFar); |
| 449 | |
| 450 | void setBlendEnabled(bool enabled); |
| 451 | bool isBlendEnabled() const; |
| 452 | void setBlendFactors(GLenum sourceRGB, GLenum destRGB, GLenum sourceAlpha, GLenum destAlpha); |
| 453 | void setBlendColor(float red, float green, float blue, float alpha); |
| 454 | void setBlendEquation(GLenum rgbEquation, GLenum alphaEquation); |
| 455 | |
| 456 | void setStencilTestEnabled(bool enabled); |
| 457 | bool isStencilTestEnabled() const; |
| 458 | void setStencilParams(GLenum stencilFunc, GLint stencilRef, GLuint stencilMask); |
| 459 | void setStencilBackParams(GLenum stencilBackFunc, GLint stencilBackRef, GLuint stencilBackMask); |
| 460 | void setStencilWritemask(GLuint stencilWritemask); |
| 461 | void setStencilBackWritemask(GLuint stencilBackWritemask); |
| 462 | void setStencilOperations(GLenum stencilFail, GLenum stencilPassDepthFail, GLenum stencilPassDepthPass); |
| 463 | void setStencilBackOperations(GLenum stencilBackFail, GLenum stencilBackPassDepthFail, GLenum stencilBackPassDepthPass); |
| 464 | |
| 465 | void setPolygonOffsetFillEnabled(bool enabled); |
| 466 | bool isPolygonOffsetFillEnabled() const; |
| 467 | void setPolygonOffsetParams(GLfloat factor, GLfloat units); |
| 468 | |
| 469 | void setSampleAlphaToCoverageEnabled(bool enabled); |
| 470 | bool isSampleAlphaToCoverageEnabled() const; |
| 471 | void setSampleCoverageEnabled(bool enabled); |
| 472 | bool isSampleCoverageEnabled() const; |
| 473 | void setSampleCoverageParams(GLclampf value, bool invert); |
| 474 | |
| 475 | void setDitherEnabled(bool enabled); |
| 476 | bool isDitherEnabled() const; |
| 477 | |
| 478 | void setPrimitiveRestartFixedIndexEnabled(bool enabled); |
| 479 | bool isPrimitiveRestartFixedIndexEnabled() const; |
| 480 | |
| 481 | void setRasterizerDiscardEnabled(bool enabled); |
| 482 | bool isRasterizerDiscardEnabled() const; |
| 483 | |
| 484 | void setLineWidth(GLfloat width); |
| 485 | |
| 486 | void setGenerateMipmapHint(GLenum hint); |
| 487 | void setFragmentShaderDerivativeHint(GLenum hint); |
| 488 | |
| 489 | void setViewportParams(GLint x, GLint y, GLsizei width, GLsizei height); |
| 490 | |
| 491 | void setScissorTestEnabled(bool enabled); |
| 492 | bool isScissorTestEnabled() const; |
| 493 | void setScissorParams(GLint x, GLint y, GLsizei width, GLsizei height); |
| 494 | |
| 495 | void setColorMask(bool red, bool green, bool blue, bool alpha); |
| 496 | unsigned int getColorMask() const; |
| 497 | void setDepthMask(bool mask); |
| 498 | |
| 499 | void setActiveSampler(unsigned int active); |
| 500 | |
| 501 | GLuint getReadFramebufferName() const; |
| 502 | GLuint getDrawFramebufferName() const; |
| 503 | GLuint getRenderbufferName() const; |
| 504 | |
| 505 | void setFramebufferReadBuffer(GLenum buf); |
| 506 | void setFramebufferDrawBuffers(GLsizei n, const GLenum *bufs); |
| 507 | GLuint getReadFramebufferColorIndex() const; |
| 508 | |
| 509 | GLuint getActiveQuery(GLenum target) const; |
| 510 | |
| 511 | GLuint getArrayBufferName() const; |
| 512 | GLuint getElementArrayBufferName() const; |
| 513 | |
| 514 | void setVertexAttribArrayEnabled(unsigned int attribNum, bool enabled); |
| 515 | void setVertexAttribDivisor(unsigned int attribNum, GLuint divisor); |
| 516 | const VertexAttribute &getVertexAttribState(unsigned int attribNum) const; |
| 517 | void setVertexAttribState(unsigned int attribNum, Buffer *boundBuffer, GLint size, GLenum type, |
| 518 | bool normalized, GLsizei stride, const void *pointer); |
| 519 | const void *getVertexAttribPointer(unsigned int attribNum) const; |
| 520 | |
| 521 | const VertexAttributeArray &getVertexArrayAttributes(); |
| 522 | // Context attribute current values can be queried independently from VAO current values |
| 523 | const VertexAttributeArray &getCurrentVertexAttributes(); |
| 524 | |
| 525 | void setUnpackAlignment(GLint alignment); |
| 526 | void setUnpackRowLength(GLint rowLength); |
| 527 | void setUnpackImageHeight(GLint imageHeight); |
| 528 | void setUnpackSkipPixels(GLint skipPixels); |
| 529 | void setUnpackSkipRows(GLint skipRows); |
| 530 | void setUnpackSkipImages(GLint skipImages); |
| 531 | const egl::Image::UnpackInfo& getUnpackInfo() const; |
| 532 | |
| 533 | void setPackAlignment(GLint alignment); |
| 534 | void setPackRowLength(GLint rowLength); |
| 535 | void setPackImageHeight(GLint imageHeight); |
| 536 | void setPackSkipPixels(GLint skipPixels); |
| 537 | void setPackSkipRows(GLint skipRows); |
| 538 | void setPackSkipImages(GLint skipImages); |
| 539 | |
| 540 | // These create and destroy methods are merely pass-throughs to |
| 541 | // ResourceManager, which owns these object types |
| 542 | GLuint createBuffer(); |
| 543 | GLuint createShader(GLenum type); |
| 544 | GLuint createProgram(); |
| 545 | GLuint createTexture(); |
| 546 | GLuint createRenderbuffer(); |
| 547 | GLuint createSampler(); |
| 548 | GLsync createFenceSync(GLenum condition, GLbitfield flags); |
| 549 | |
| 550 | void deleteBuffer(GLuint buffer); |
| 551 | void deleteShader(GLuint shader); |
| 552 | void deleteProgram(GLuint program); |
| 553 | void deleteTexture(GLuint texture); |
| 554 | void deleteRenderbuffer(GLuint renderbuffer); |
| 555 | void deleteSampler(GLuint sampler); |
| 556 | void deleteFenceSync(GLsync fenceSync); |
| 557 | |
| 558 | // Framebuffers are owned by the Context, so these methods do not pass through |
| 559 | GLuint createFramebuffer(); |
| 560 | void deleteFramebuffer(GLuint framebuffer); |
| 561 | |
| 562 | // Fences are owned by the Context |
| 563 | GLuint createFence(); |
| 564 | void deleteFence(GLuint fence); |
| 565 | |
| 566 | // Queries are owned by the Context |
| 567 | GLuint createQuery(); |
| 568 | void deleteQuery(GLuint query); |
| 569 | |
| 570 | // Vertex arrays are owned by the Context |
| 571 | GLuint createVertexArray(); |
| 572 | void deleteVertexArray(GLuint array); |
| 573 | |
| 574 | // Transform feedbacks are owned by the Context |
| 575 | GLuint createTransformFeedback(); |
| 576 | void deleteTransformFeedback(GLuint transformFeedback); |
| 577 | |
| 578 | void bindArrayBuffer(GLuint buffer); |
| 579 | void bindElementArrayBuffer(GLuint buffer); |
| 580 | void bindCopyReadBuffer(GLuint buffer); |
| 581 | void bindCopyWriteBuffer(GLuint buffer); |
| 582 | void bindPixelPackBuffer(GLuint buffer); |
| 583 | void bindPixelUnpackBuffer(GLuint buffer); |
| 584 | void bindTransformFeedbackBuffer(GLuint buffer); |
| 585 | void bindTexture2D(GLuint texture); |
| 586 | void bindTextureCubeMap(GLuint texture); |
| 587 | void bindTextureExternal(GLuint texture); |
| 588 | void bindTexture3D(GLuint texture); |
| 589 | void bindTexture2DArray(GLuint texture); |
| 590 | void bindReadFramebuffer(GLuint framebuffer); |
| 591 | void bindDrawFramebuffer(GLuint framebuffer); |
| 592 | void bindRenderbuffer(GLuint renderbuffer); |
| 593 | void bindVertexArray(GLuint array); |
| 594 | void bindGenericUniformBuffer(GLuint buffer); |
| 595 | void bindIndexedUniformBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size); |
| 596 | void bindGenericTransformFeedbackBuffer(GLuint buffer); |
| 597 | void bindIndexedTransformFeedbackBuffer(GLuint buffer, GLuint index, GLintptr offset, GLsizeiptr size); |
| 598 | void bindTransformFeedback(GLuint transformFeedback); |
| 599 | bool bindSampler(GLuint unit, GLuint sampler); |
| 600 | void useProgram(GLuint program); |
| 601 | |
| 602 | void beginQuery(GLenum target, GLuint query); |
| 603 | void endQuery(GLenum target); |
| 604 | |
| 605 | void setFramebufferZero(Framebuffer *framebuffer); |
| 606 | |
| 607 | void setRenderbufferStorage(RenderbufferStorage *renderbuffer); |
| 608 | |
| 609 | void setVertexAttrib(GLuint index, const GLfloat *values); |
| 610 | void setVertexAttrib(GLuint index, const GLint *values); |
| 611 | void setVertexAttrib(GLuint index, const GLuint *values); |
| 612 | |
| 613 | Buffer *getBuffer(GLuint handle) const; |
| 614 | Fence *getFence(GLuint handle) const; |
| 615 | FenceSync *getFenceSync(GLsync handle) const; |
| 616 | Shader *getShader(GLuint handle) const; |
| 617 | Program *getProgram(GLuint handle) const; |
| 618 | virtual Texture *getTexture(GLuint handle) const; |
| 619 | Framebuffer *getFramebuffer(GLuint handle) const; |
| 620 | virtual Renderbuffer *getRenderbuffer(GLuint handle) const; |
| 621 | Query *getQuery(GLuint handle) const; |
| 622 | VertexArray *getVertexArray(GLuint array) const; |
| 623 | VertexArray *getCurrentVertexArray() const; |
| 624 | bool isVertexArray(GLuint array) const; |
| 625 | TransformFeedback *getTransformFeedback(GLuint transformFeedback) const; |
| 626 | TransformFeedback *getTransformFeedback() const; |
| 627 | Sampler *getSampler(GLuint sampler) const; |
| 628 | bool isSampler(GLuint sampler) const; |
| 629 | |
| 630 | Buffer *getArrayBuffer() const; |
| 631 | Buffer *getElementArrayBuffer() const; |
| 632 | Buffer *getCopyReadBuffer() const; |
| 633 | Buffer *getCopyWriteBuffer() const; |
| 634 | Buffer *getPixelPackBuffer() const; |
| 635 | Buffer *getPixelUnpackBuffer() const; |
| 636 | Buffer *getGenericUniformBuffer() const; |
Alexis Hetu | 53f4809 | 2016-06-17 14:08:06 -0400 | [diff] [blame] | 637 | const GLvoid* getPixels(const GLvoid* data) const; |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 638 | bool getBuffer(GLenum target, es2::Buffer **buffer) const; |
| 639 | Program *getCurrentProgram() const; |
| 640 | Texture2D *getTexture2D() const; |
| 641 | Texture3D *getTexture3D() const; |
| 642 | Texture2DArray *getTexture2DArray() const; |
| 643 | TextureCubeMap *getTextureCubeMap() const; |
| 644 | TextureExternal *getTextureExternal() const; |
| 645 | Texture *getSamplerTexture(unsigned int sampler, TextureType type) const; |
| 646 | Framebuffer *getReadFramebuffer() const; |
| 647 | Framebuffer *getDrawFramebuffer() const; |
| 648 | |
| 649 | bool getFloatv(GLenum pname, GLfloat *params) const; |
| 650 | template<typename T> bool getIntegerv(GLenum pname, T *params) const; |
| 651 | bool getBooleanv(GLenum pname, GLboolean *params) const; |
| 652 | template<typename T> bool getTransformFeedbackiv(GLuint index, GLenum pname, T *param) const; |
| 653 | template<typename T> bool getUniformBufferiv(GLuint index, GLenum pname, T *param) const; |
| 654 | void samplerParameteri(GLuint sampler, GLenum pname, GLint param); |
| 655 | void samplerParameterf(GLuint sampler, GLenum pname, GLfloat param); |
| 656 | GLint getSamplerParameteri(GLuint sampler, GLenum pname); |
| 657 | GLfloat getSamplerParameterf(GLuint sampler, GLenum pname); |
| 658 | |
| 659 | bool getQueryParameterInfo(GLenum pname, GLenum *type, unsigned int *numParams) const; |
| 660 | |
| 661 | bool hasZeroDivisor() const; |
| 662 | |
| 663 | void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei *bufSize, void* pixels); |
| 664 | void clear(GLbitfield mask); |
| 665 | void clearColorBuffer(GLint drawbuffer, const GLint *value); |
| 666 | void clearColorBuffer(GLint drawbuffer, const GLuint *value); |
| 667 | void clearColorBuffer(GLint drawbuffer, const GLfloat *value); |
| 668 | void clearDepthBuffer(const GLfloat value); |
| 669 | void clearStencilBuffer(const GLint value); |
| 670 | void drawArrays(GLenum mode, GLint first, GLsizei count, GLsizei instanceCount = 1); |
| 671 | void drawElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLsizei instanceCount = 1); |
| 672 | void finish(); |
| 673 | void flush(); |
| 674 | |
| 675 | void recordInvalidEnum(); |
| 676 | void recordInvalidValue(); |
| 677 | void recordInvalidOperation(); |
| 678 | void recordOutOfMemory(); |
| 679 | void recordInvalidFramebufferOperation(); |
| 680 | |
| 681 | GLenum getError(); |
| 682 | |
| 683 | static int getSupportedMultisampleCount(int requested); |
| 684 | |
| 685 | void blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, |
| 686 | GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, |
Alexis Hetu | b9dda64 | 2016-10-06 11:25:32 -0400 | [diff] [blame] | 687 | GLbitfield mask, bool filter, bool allowPartialDepthStencilBlit); |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 688 | |
| 689 | virtual void bindTexImage(egl::Surface *surface); |
| 690 | virtual EGLenum validateSharedImage(EGLenum target, GLuint name, GLuint textureLevel); |
| 691 | virtual egl::Image *createSharedImage(EGLenum target, GLuint name, GLuint textureLevel); |
Nicolas Capens | 58df2f6 | 2016-06-07 14:48:56 -0400 | [diff] [blame] | 692 | egl::Image *getSharedImage(GLeglImageOES image); |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 693 | |
| 694 | Device *getDevice(); |
| 695 | |
| 696 | const GLubyte* getExtensions(GLuint index, GLuint* numExt = nullptr) const; |
| 697 | |
| 698 | private: |
| 699 | virtual ~Context(); |
| 700 | |
| 701 | void applyScissor(int width, int height); |
| 702 | bool applyRenderTarget(); |
| 703 | void applyState(GLenum drawMode); |
| 704 | GLenum applyVertexBuffer(GLint base, GLint first, GLsizei count, GLsizei instanceId); |
| 705 | GLenum applyIndexBuffer(const void *indices, GLuint start, GLuint end, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); |
| 706 | void applyShaders(); |
| 707 | void applyTextures(); |
| 708 | void applyTextures(sw::SamplerType type); |
| 709 | void applyTexture(sw::SamplerType type, int sampler, Texture *texture); |
| 710 | void clearColorBuffer(GLint drawbuffer, void *value, sw::Format format); |
| 711 | |
| 712 | void detachBuffer(GLuint buffer); |
| 713 | void detachTexture(GLuint texture); |
| 714 | void detachFramebuffer(GLuint framebuffer); |
| 715 | void detachRenderbuffer(GLuint renderbuffer); |
| 716 | void detachSampler(GLuint sampler); |
| 717 | |
| 718 | bool cullSkipsDraw(GLenum drawMode); |
| 719 | bool isTriangleMode(GLenum drawMode); |
| 720 | |
| 721 | Query *createQuery(GLuint handle, GLenum type); |
| 722 | |
| 723 | const EGLint clientVersion; |
Nicolas Capens | 0bac285 | 2016-05-07 06:09:58 -0400 | [diff] [blame] | 724 | |
| 725 | State mState; |
| 726 | |
| 727 | gl::BindingPointer<Texture2D> mTexture2DZero; |
| 728 | gl::BindingPointer<Texture3D> mTexture3DZero; |
| 729 | gl::BindingPointer<Texture2DArray> mTexture2DArrayZero; |
| 730 | gl::BindingPointer<TextureCubeMap> mTextureCubeMapZero; |
| 731 | gl::BindingPointer<TextureExternal> mTextureExternalZero; |
| 732 | |
| 733 | gl::NameSpace<Framebuffer> mFramebufferNameSpace; |
| 734 | gl::NameSpace<Fence, 0> mFenceNameSpace; |
| 735 | gl::NameSpace<Query> mQueryNameSpace; |
| 736 | gl::NameSpace<VertexArray> mVertexArrayNameSpace; |
| 737 | gl::NameSpace<TransformFeedback> mTransformFeedbackNameSpace; |
| 738 | |
| 739 | VertexDataManager *mVertexDataManager; |
| 740 | IndexDataManager *mIndexDataManager; |
| 741 | |
| 742 | // Recorded errors |
| 743 | bool mInvalidEnum; |
| 744 | bool mInvalidValue; |
| 745 | bool mInvalidOperation; |
| 746 | bool mOutOfMemory; |
| 747 | bool mInvalidFramebufferOperation; |
| 748 | |
| 749 | bool mHasBeenCurrent; |
| 750 | |
| 751 | unsigned int mAppliedProgramSerial; |
| 752 | |
| 753 | // state caching flags |
| 754 | bool mDepthStateDirty; |
| 755 | bool mMaskStateDirty; |
| 756 | bool mBlendStateDirty; |
| 757 | bool mStencilStateDirty; |
| 758 | bool mPolygonOffsetStateDirty; |
| 759 | bool mSampleStateDirty; |
| 760 | bool mFrontFaceDirty; |
| 761 | bool mDitherStateDirty; |
| 762 | |
| 763 | Device *device; |
| 764 | ResourceManager *mResourceManager; |
| 765 | }; |
| 766 | } |
| 767 | |
| 768 | #endif // INCLUDE_CONTEXT_H_ |