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