1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #ifndef _GL_CLIENT_STATE_H_
17 #define _GL_CLIENT_STATE_H_
18 
19 #include <GLES/gl.h>
20 #include <GLES/glext.h>
21 #include <GLES2/gl2.h>
22 #include <GLES2/gl2ext.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 
26 #include <map>
27 #include <memory>
28 #include <set>
29 #include <string>
30 #include <vector>
31 
32 #include "StateTrackingSupport.h"
33 #include "TextureSharedData.h"
34 #include "codec_defs.h"
35 
36 namespace gfxstream {
37 namespace guest {
38 
39 // Caps of host driver that make it easy to validate stuff
40 struct HostDriverCaps {
41     // ES 2
42     int max_vertex_attribs;
43     int max_combined_texture_image_units;
44     int max_color_attachments;
45 
46     int max_texture_size;
47     int max_texture_size_cube_map;
48     int max_renderbuffer_size;
49 
50     // ES 3.0
51     int max_draw_buffers;
52 
53     int ubo_offset_alignment;
54     int max_uniform_buffer_bindings;
55     int max_transform_feedback_separate_attribs;
56 
57     int max_texture_size_3d;
58     int max_array_texture_layers;
59 
60     // ES 3.1
61     int max_atomic_counter_buffer_bindings;
62     int max_shader_storage_buffer_bindings;
63     int max_vertex_attrib_bindings;
64     int max_vertex_attrib_stride;
65     int ssbo_offset_alignment;
66 };
67 
68 // Tracking framebuffer objects:
69 // which framebuffer is bound,
70 // and which texture names
71 // are currently bound to which attachment points.
72 struct FboProps {
73     GLuint name;
74     bool previouslyBound;
75     bool completenessDirty;
76     GLenum cachedCompleteness;
77     std::vector<std::shared_ptr<TextureRec>> colorAttachmenti_textures;
78     std::vector<GLint> colorAttachmenti_texture_levels;
79     std::vector<GLint> colorAttachmenti_texture_layers;
80 
81     GLint depthAttachment_texture_level;
82     GLint depthAttachment_texture_layer;
83     GLint stencilAttachment_texture_level;
84     GLint stencilAttachment_texture_layer;
85 
86     std::shared_ptr<TextureRec> depthAttachment_texture;
87     std::shared_ptr<TextureRec> stencilAttachment_texture;
88     std::shared_ptr<TextureRec> depthstencilAttachment_texture;
89 
90     std::vector<bool> colorAttachmenti_hasTex;
91     bool depthAttachment_hasTexObj;
92     bool stencilAttachment_hasTexObj;
93     bool depthstencilAttachment_hasTexObj;
94 
95     std::vector<std::shared_ptr<RboProps>> colorAttachmenti_rbos;
96     std::shared_ptr<RboProps> depthAttachment_rbo = 0;
97     std::shared_ptr<RboProps> stencilAttachment_rbo = 0;
98     std::shared_ptr<RboProps> depthstencilAttachment_rbo = 0;
99 
100     std::vector<bool> colorAttachmenti_hasRbo;
101     bool depthAttachment_hasRbo = false;
102     bool stencilAttachment_hasRbo = false;
103     bool depthstencilAttachment_hasRbo = false;
104 
105     GLuint defaultWidth;
106     GLuint defaultHeight;
107 };
108 
109 // Enum for describing whether a framebuffer attachment
110 // is a texture or renderbuffer.
111 enum FboAttachmentType {
112     FBO_ATTACHMENT_RENDERBUFFER = 0,
113     FBO_ATTACHMENT_TEXTURE = 1,
114     FBO_ATTACHMENT_NONE = 2
115 };
116 
117 // Tracking FBO format
118 struct FboFormatInfo {
119     FboAttachmentType type;
120     GLenum rb_format;
121     GLsizei rb_multisamples;
122     bool rb_external;
123 
124     GLint tex_internalformat;
125     GLenum tex_format;
126     GLenum tex_type;
127     GLsizei tex_multisamples;
128     GLint tex_level;
129     GLint tex_layer;
130     bool tex_external;
131 };
132 
133 class GLClientState {
134 public:
135     // TODO: Unify everything in here
136     typedef enum {
137         Buffer,
138         TransformFeedback,
139         Sampler,
140         Query,
141     } ObjectType;
142 
143     typedef enum {
144         VERTEX_LOCATION = 0,
145         NORMAL_LOCATION = 1,
146         COLOR_LOCATION = 2,
147         POINTSIZE_LOCATION = 3,
148         TEXCOORD0_LOCATION = 4,
149         TEXCOORD1_LOCATION = 5,
150         TEXCOORD2_LOCATION = 6,
151         TEXCOORD3_LOCATION = 7,
152         TEXCOORD4_LOCATION = 8,
153         TEXCOORD5_LOCATION = 9,
154         TEXCOORD6_LOCATION = 10,
155         TEXCOORD7_LOCATION = 11,
156         MATRIXINDEX_LOCATION = 12,
157         WEIGHT_LOCATION = 13,
158         LAST_LOCATION = 14
159     } StateLocation;
160 
161     typedef struct {
162         GLint enabled;
163         GLint size;
164         GLenum type;
165         GLsizei stride;
166         void *data;
167         GLuint reloffset;
168         GLuint bufferObject;
169         GLenum glConst;
170         unsigned int elementSize;
171         bool enableDirty;  // true if any enable state has changed since last draw
172         bool normalized;
173         GLuint divisor;
174         bool isInt;
175         int bindingindex;
176     } VertexAttribState;
177 
178     struct BufferBinding {
179         GLintptr offset;
180         GLintptr stride;
181         GLintptr effectiveStride;
182         GLsizeiptr size;
183         GLuint buffer;
184         GLuint divisor;
185         GLint vertexAttribLoc;
186     };
187 
188     typedef std::vector<VertexAttribState> VertexAttribStateVector;
189     typedef std::vector<BufferBinding> VertexAttribBindingVector;
190 
191     struct VAOState {
VAOStateVAOState192         VAOState(GLuint ibo, int nLoc, int nBindings) :
193             attribState(nLoc),
194             bindingState(nBindings),
195             element_array_buffer_binding(ibo),
196             element_array_buffer_binding_lastEncode(ibo) { }
197         VertexAttribStateVector attribState;
198         VertexAttribBindingVector bindingState;
199         GLuint element_array_buffer_binding;
200         GLuint element_array_buffer_binding_lastEncode;
201         int attributesNeedingUpdateForDraw[CODEC_MAX_VERTEX_ATTRIBUTES];
202         int numAttributesNeedingUpdateForDraw;
203     };
204 
205     typedef std::map<GLuint, VAOState> VAOStateMap;
206     struct VAOStateRef {
VAOStateRefVAOStateRef207         VAOStateRef() { }
VAOStateRefVAOStateRef208         VAOStateRef(
209                 VAOStateMap::iterator iter) : it(iter) { }
vaoStateVAOStateRef210         VAOState& vaoState() { return it->second; }
211         VertexAttribState& operator[](size_t k) { return it->second.attribState[k]; }
bufferBindingVAOStateRef212         BufferBinding& bufferBinding(size_t k) { return it->second.bindingState[k]; }
bufferBindingsVAOStateRef213         VertexAttribBindingVector& bufferBindings() { return it->second.bindingState; }
bufferBindings_constVAOStateRef214         const VertexAttribBindingVector& bufferBindings_const() const { return it->second.bindingState; }
vaoIdVAOStateRef215         GLuint vaoId() const { return it->first; }
iboIdVAOStateRef216         GLuint& iboId() { return it->second.element_array_buffer_binding; }
iboIdLastEncodeVAOStateRef217         GLuint& iboIdLastEncode() { return it->second.element_array_buffer_binding_lastEncode; }
218         VAOStateMap::iterator it;
219     };
220 
221     typedef struct {
222         int unpack_alignment;
223 
224         int unpack_row_length;
225         int unpack_image_height;
226         int unpack_skip_pixels;
227         int unpack_skip_rows;
228         int unpack_skip_images;
229 
230         int pack_alignment;
231 
232         int pack_row_length;
233         int pack_skip_pixels;
234         int pack_skip_rows;
235     } PixelStoreState;
236 
237     enum {
238         MAX_TEXTURE_UNITS = 256,
239     };
240 
241 public:
242     GLClientState();
243     GLClientState(int majorVersion, int minorVersion);
244     ~GLClientState();
nLocations()245     int nLocations() { return CODEC_MAX_VERTEX_ATTRIBUTES; }
pixelStoreState()246     const PixelStoreState *pixelStoreState() { return &m_pixelStore; }
247     int setPixelStore(GLenum param, GLint value);
currentVertexArrayObject()248     GLuint currentVertexArrayObject() const { return m_currVaoState.vaoId(); }
currentVertexBufferBindings()249     const VertexAttribBindingVector& currentVertexBufferBindings() const {
250         return m_currVaoState.bufferBindings_const();
251     }
252 
currentArrayVbo()253     GLuint currentArrayVbo() { return m_arrayBuffer; }
currentIndexVbo()254     GLuint currentIndexVbo() { return m_currVaoState.iboId(); }
255     void enable(int location, int state);
256     // Vertex array objects and vertex attributes
257     void addVertexArrayObjects(GLsizei n, GLuint* arrays);
258     void removeVertexArrayObjects(GLsizei n, const GLuint* arrays);
259     void addVertexArrayObject(GLuint name);
260     void removeVertexArrayObject(GLuint name);
261     void setVertexArrayObject(GLuint vao);
262     bool isVertexArrayObject(GLuint vao) const;
263     void setVertexAttribState(int  location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data, bool isInt = false);
264     void setVertexBindingDivisor(int bindingindex, GLuint divisor);
265     const BufferBinding& getCurrAttributeBindingInfo(int attribindex);
266     void setVertexAttribBinding(int attribindex, int bindingindex);
267     void setVertexAttribFormat(int location, int size, GLenum type, GLboolean normalized, GLuint reloffset, bool isInt = false);
268     void getVBOUsage(bool* hasClientArrays, bool* hasVBOs);
269     const VertexAttribState& getState(int location);
270     const VertexAttribState& getStateAndEnableDirty(int location, bool *enableChanged);
271     void updateEnableDirtyArrayForDraw();
272     VAOState& currentVaoState();
273     int getLocation(GLenum loc);
setActiveTexture(int texUnit)274     void setActiveTexture(int texUnit) {m_activeTexture = texUnit; };
getActiveTexture()275     int getActiveTexture() const { return m_activeTexture; }
276 
277     void addBuffer(GLuint id);
278     void removeBuffer(GLuint id);
279     bool bufferIdExists(GLuint id) const;
280     void unBindBuffer(GLuint id);
281 
282     void setBufferHostMapDirty(GLuint id, bool dirty);
283     bool isBufferHostMapDirty(GLuint id) const;
284 
285     void setExistence(ObjectType type, bool exists, GLsizei count, const GLuint* ids);
286     bool queryExistence(ObjectType type, GLuint id) const;
287     bool samplerExists(GLuint id) const;
288     bool tryBind(GLenum target, GLuint id);
289     bool isBoundTargetValid(GLenum target);
290     bool isQueryBound(GLenum target);
291     bool isQueryObjectActive(GLuint id);
292     void setLastQueryTarget(GLenum target, GLuint id);
293     GLenum getLastQueryTarget(GLuint id);
294 
295     static void onFenceCreated(GLsync sync);
296     static void onFenceDestroyed(GLsync sync);
297     static bool fenceExists(GLsync sync);
298 
299     void setBoundPixelPackBufferDirtyForHostMap();
300     void setBoundTransformFeedbackBuffersDirtyForHostMap();
301     void setBoundShaderStorageBuffersDirtyForHostMap();
302     void setBoundAtomicCounterBuffersDirtyForHostMap();
303 
304     int bindBuffer(GLenum target, GLuint id);
305     void bindIndexedBuffer(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride);
306     int getMaxIndexedBufferBindings(GLenum target) const;
307     bool isNonIndexedBindNoOp(GLenum target, GLuint buffer);
308     bool isIndexedBindNoOp(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size, GLintptr stride, GLintptr effectiveStride);
309 
310     int getMaxTextureSize() const;
311     int getMaxTextureSize3D() const;
312     int getMaxTextureSizeCubeMap() const;
313     int getLog2MaxTextureSize() const;
314 
315     void postDraw();
316     void postReadPixels();
317     void postDispatchCompute();
318 
319     bool shouldSkipHostMapBuffer(GLenum target);
320     void onHostMappedBuffer(GLenum target);
321 
322     int getBuffer(GLenum target);
323     GLuint getLastEncodedBufferBind(GLenum target);
324     void setLastEncodedBufferBind(GLenum target, GLuint id);
325 
326     size_t pixelDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack) const;
327     size_t pboNeededDataSize(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int pack, int ignoreTrailing = 0) const;
328     size_t clearBufferNumElts(GLenum buffer) const;
329     void getPackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const;
330     void getUnpackingOffsets2D(GLsizei width, GLsizei height, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* skipRows) const;
331     void getUnpackingOffsets3D(GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, int* bpp, int* startOffset, int* pixelRowSize, int* totalRowSize, int* pixelImageSize, int* totalImageSize, int* skipRows, int* skipImages) const;
332 
setCurrentProgram(GLint program)333     void setCurrentProgram(GLint program) { m_currentProgram = program; }
setCurrentShaderProgram(GLint program)334     void setCurrentShaderProgram(GLint program) { m_currentShaderProgram = program; }
currentProgram()335     GLint currentProgram() const { return m_currentProgram; }
currentShaderProgram()336     GLint currentShaderProgram() const { return m_currentShaderProgram; }
337 
338     struct UniformBlockInfoKey {
339         GLuint program;
340         GLuint uniformBlockIndex;
341     };
342     struct UniformBlockInfoKeyCompare {
operatorUniformBlockInfoKeyCompare343         bool operator() (const UniformBlockInfoKey& a,
344                          const UniformBlockInfoKey& b) const {
345             if (a.program != b.program) return a.program < b.program;
346             if (a.uniformBlockIndex != b.uniformBlockIndex) return a.uniformBlockIndex < b.uniformBlockIndex;
347             return false;
348         }
349     };
350     struct UniformBlockUniformInfo {
351         size_t numActiveUniforms;
352     };
353 
354     typedef std::map<UniformBlockInfoKey, UniformBlockUniformInfo, UniformBlockInfoKeyCompare> UniformBlockInfoMap;
355     UniformBlockInfoMap m_uniformBlockInfoMap;
356 
357     void setNumActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex, GLint numActiveUniforms);
358     size_t numActiveUniformsInUniformBlock(GLuint program, GLuint uniformBlockIndex) const;
359 
360     typedef std::map<GLuint, GLuint> ProgramPipelineMap;
361     typedef ProgramPipelineMap::iterator ProgramPipelineIterator;
362     void associateProgramWithPipeline(GLuint program, GLuint pipeline);
363     ProgramPipelineIterator programPipelineBegin();
364     ProgramPipelineIterator programPipelineEnd();
365 
366     /* OES_EGL_image_external
367      *
368      * These functions manipulate GL state which interacts with the
369      * OES_EGL_image_external extension, to support client-side emulation on
370      * top of host implementations that don't have it.
371      *
372      * Most of these calls should only be used with TEXTURE_2D or
373      * TEXTURE_EXTERNAL_OES texture targets; TEXTURE_CUBE_MAP or other extension
374      * targets should bypass this. An exception is bindTexture(), which should
375      * see all glBindTexture() calls for any target.
376      */
377 
378     // glActiveTexture(GL_TEXTURE0 + i)
379     // Sets the active texture unit. Up to MAX_TEXTURE_UNITS are supported.
380     GLenum setActiveTextureUnit(GLenum texture);
381     GLenum getActiveTextureUnit() const;
382 
383     // glEnable(GL_TEXTURE_(2D|EXTERNAL_OES))
384     void enableTextureTarget(GLenum target);
385 
386     // glDisable(GL_TEXTURE_(2D|EXTERNAL_OES))
387     void disableTextureTarget(GLenum target);
388 
389     bool bindSampler(GLuint unit, GLuint sampler);
390     bool isSamplerBindNoOp(GLuint unit, GLuint sampler);
391     void onDeleteSamplers(GLsizei n, const GLuint* samplers);
392 
393     // Implements the target priority logic:
394     // * Return GL_TEXTURE_EXTERNAL_OES if enabled, else
395     // * Return GL_TEXTURE_2D if enabled, else
396     // * Return the allDisabled value.
397     // For some cases passing GL_TEXTURE_2D for allDisabled makes callee code
398     // simpler; for other cases passing a recognizable enum like GL_ZERO or
399     // GL_INVALID_ENUM is appropriate.
400     GLenum getPriorityEnabledTarget(GLenum allDisabled) const;
401 
402     // glBindTexture(GL_TEXTURE_*, ...)
403     // Set the target binding of the active texture unit to texture. Returns
404     // GL_NO_ERROR on success or GL_INVALID_OPERATION if the texture has
405     // previously been bound to a different target. If firstUse is not NULL,
406     // it is set to indicate whether this is the first use of the texture.
407     // For accurate error detection, bindTexture should be called for *all*
408     // targets, not just 2D and EXTERNAL_OES.
409     GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);
410     void setBoundEGLImage(GLenum target, GLeglImageOES image, int width, int height);
411 
412     // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
413     GLuint getBoundTexture(GLenum target) const;
414     // Return bound framebuffer for target
415     GLuint getBoundFramebuffer(GLenum target) const;
416 
417     // Check framebuffer completeness
418     GLenum checkFramebufferCompleteness(GLenum target);
419     // |currentSamples|: threads through the current sample count of attachments so far,
420     // for validating consistent number of samples across attachments
421     GLenum checkFramebufferAttachmentCompleteness(GLenum target, GLenum attachment, int* currentSamples) const;
422 
423     // Other publicly-visible texture queries
424     GLenum queryTexLastBoundTarget(GLuint name) const;
425     GLenum queryTexFormat(GLuint name) const;
426     GLint queryTexInternalFormat(GLuint name) const;
427     GLsizei queryTexWidth(GLsizei level, GLuint name) const;
428     GLsizei queryTexHeight(GLsizei level, GLuint name) const;
429     GLsizei queryTexDepth(GLsizei level, GLuint name) const;
430     bool queryTexEGLImageBacked(GLuint name) const;
431 
432     // For AMD GPUs, it is easy for the emulator to segfault
433     // (esp. in dEQP) when a cube map is defined using glCopyTexImage2D
434     // and uses GL_LUMINANCE as internal format.
435     // In particular, the segfault happens when negative components of
436     // cube maps are defined before positive ones,
437     // This procedure checks internal state to see if we have defined
438     // the positive component of a cube map already. If not, it returns
439     // which positive component needs to be defined first.
440     // If there is no need for the extra definition, 0 is returned.
441     GLenum copyTexImageLuminanceCubeMapAMDWorkaround(GLenum target, GLint level,
442                                                      GLenum internalformat);
443 
444     // Tracks the format of the currently bound texture.
445     // This is to pass dEQP tests for fbo completeness.
446     void setBoundTextureInternalFormat(GLenum target, GLint format);
447     void setBoundTextureFormat(GLenum target, GLenum format);
448     void setBoundTextureType(GLenum target, GLenum type);
449     void setBoundTextureDims(GLenum target, GLenum cubetarget, GLsizei level, GLsizei width, GLsizei height, GLsizei depth);
450     void setBoundTextureSamples(GLenum target, GLsizei samples);
451     void addTextureCubeMapImage(GLenum stateTarget, GLenum cubeTarget);
452 
453     // glTexStorage2D disallows any change in texture format after it is set for a particular texture.
454     void setBoundTextureImmutableFormat(GLenum target);
455     bool isBoundTextureImmutableFormat(GLenum target) const;
456     bool isBoundTextureComplete(GLenum target) const;
457 
458     // glDeleteTextures(...)
459     // Remove references to the to-be-deleted textures.
460     void deleteTextures(GLsizei n, const GLuint* textures);
461 
462     // Render buffer objects
463     void addRenderbuffers(GLsizei n, GLuint* renderbuffers);
464     void removeRenderbuffers(GLsizei n, const GLuint* renderbuffers);
465     bool usedRenderbufferName(GLuint name) const;
466     void bindRenderbuffer(GLenum target, GLuint name);
467     GLuint boundRenderbuffer() const;
468     void setBoundRenderbufferFormat(GLenum format);
469     void setBoundRenderbufferSamples(GLsizei samples);
470     void setBoundRenderbufferDimensions(GLsizei width, GLsizei height);
471     void setBoundRenderbufferEGLImageBacked();
472 
473     // Frame buffer objects
474     void addFramebuffers(GLsizei n, GLuint* framebuffers);
475     void removeFramebuffers(GLsizei n, const GLuint* framebuffers);
476     bool usedFramebufferName(GLuint name) const;
477     void bindFramebuffer(GLenum target, GLuint name);
478     void setCheckFramebufferStatus(GLenum target, GLenum status);
479     void setFramebufferParameter(GLenum target, GLenum pname, GLint param);
480     GLenum getCheckFramebufferStatus(GLenum target) const;
481     GLuint boundFramebuffer(GLenum target) const;
482 
483     // Texture object -> FBO
484     void attachTextureObject(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer);
485     std::shared_ptr<TextureRec> getFboAttachmentTexture(GLenum target, GLenum attachment) const;
486 
487     // RBO -> FBO
488     void detachRbo(GLuint renderbuffer);
489     void detachRboFromFbo(GLenum target, GLenum attachment, GLuint renderbuffer);
490     void attachRbo(GLenum target, GLenum attachment, GLuint renderbuffer);
491     std::shared_ptr<RboProps> getFboAttachmentRbo(GLenum target, GLenum attachment) const;
492 
493     // FBO attachments in general
494     bool attachmentHasObject(GLenum target, GLenum attachment) const;
495     bool depthStencilHasSameObject(GLenum target) const;
496 
497     // Dirty FBO completeness
498     void setFboCompletenessDirtyForTexture(GLuint texture);
499     void setFboCompletenessDirtyForRbo(std::shared_ptr<RboProps> rbo);
500 
501     // Transform feedback state
502     void setTransformFeedbackActive(bool active);
503     void setTransformFeedbackUnpaused(bool unpaused);
504     void setTransformFeedbackVaryingsCountForLinking(uint32_t count);
505     bool getTransformFeedbackActive() const;
506     bool getTransformFeedbackUnpaused() const;
507     bool getTransformFeedbackActiveUnpaused() const;
508     uint32_t getTransformFeedbackVaryingsCountForLinking() const;
509 
510     // Stencil state
511     void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
512     void stencilMaskSeparate(GLenum face, GLuint mask);
513     void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
514 
515     void setTextureData(SharedTextureDataMap* sharedTexData);
516     void setRenderbufferInfo(RenderbufferInfo* rbInfo);
517     void setSamplerInfo(SamplerInfo* samplerInfo);
518 
519     bool compressedTexImageSizeCompatible(GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLsizei imageSize);
520     // set eglsurface property on default framebuffer
521     // if coming from eglMakeCurrent
522     void fromMakeCurrent();
523     // set indexed buffer state.
524     // We need to query the underlying OpenGL to get
525     // accurate values for indexed buffers
526     // and # render targets.
527     void initFromCaps(
528         const HostDriverCaps& caps);
529     bool needsInitFromCaps() const;
530     void setExtensions(const std::string& extensions);
531     bool hasExtension(const char* ext) const;
532 
533     // Queries the format backing the current framebuffer.
534     // Type differs depending on whether the attachment
535     // is a texture or renderbuffer.
536     void getBoundFramebufferFormat(
537             GLenum target,
538             GLenum attachment,
539             FboFormatInfo* res_info) const;
540     FboAttachmentType getBoundFramebufferAttachmentType(
541             GLenum target,
542             GLenum attachment) const;
543     int getMaxColorAttachments() const;
544     int getMaxDrawBuffers() const;
545 
546     // Uniform/attribute validation info
547     UniformValidationInfo currentUniformValidationInfo;
548     AttribValidationInfo currentAttribValidationInfo;;
549 
550     // Uniform validation api
551     void validateUniform(bool isFloat, bool isUnsigned, GLint columns, GLint rows, GLint location, GLsizei count, GLenum* err);
552     // Attrib validation
553     bool isAttribIndexUsedByProgram(int attribIndex);
554 
555     // Fast access to some enables and stencil related glGet's
556     bool state_GL_STENCIL_TEST;
557     GLenum state_GL_STENCIL_FUNC;
558     unsigned int state_GL_STENCIL_VALUE_MASK;
559     int state_GL_STENCIL_REF;
560     GLenum state_GL_STENCIL_FAIL;
561     GLenum state_GL_STENCIL_PASS_DEPTH_FAIL;
562     GLenum state_GL_STENCIL_PASS_DEPTH_PASS;
563     GLenum state_GL_STENCIL_BACK_FUNC;
564     unsigned int state_GL_STENCIL_BACK_VALUE_MASK;
565     int state_GL_STENCIL_BACK_REF;
566     GLenum state_GL_STENCIL_BACK_FAIL;
567     GLenum state_GL_STENCIL_BACK_PASS_DEPTH_FAIL;
568     GLenum state_GL_STENCIL_BACK_PASS_DEPTH_PASS;
569     unsigned int state_GL_STENCIL_WRITEMASK;
570     unsigned int state_GL_STENCIL_BACK_WRITEMASK;
571     int state_GL_STENCIL_CLEAR_VALUE;
572 private:
573     void init();
574     bool m_initialized;
575     PixelStoreState m_pixelStore;
576 
577     using DirtyMap = PredicateMap<uint32_t, true>;
578 
579     ExistenceMap mBufferIds;
580     ExistenceMap mTransformFeedbackIds;
581     SamplerInfo* mSamplerInfo;
582     ExistenceMap mQueryIds;
583     LastQueryTargetInfo mLastQueryTargets;
584 
585     // Bound query target validity and tracking
586     struct BoundTargetInfo {
587         GLuint id;
588         bool valid;
589     };
590 
591     // Transform feedback
592     BoundTargetInfo mBoundTransformFeedbackValidity;
593 
594     // Queries
595     // GL_ANY_SAMPLES_PASSED
596     BoundTargetInfo mBoundQueryValidity_AnySamplesPassed;
597     // GL_ANY_SAMPLES_PASSED_CONSERVATIVE
598     BoundTargetInfo mBoundQueryValidity_AnySamplesPassedConservative;
599     // GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN
600     BoundTargetInfo mBoundQueryValidity_TransformFeedbackPrimitivesWritten;
601 
602     // Dirty maps
603     DirtyMap mHostMappedBufferDirty;
604 
605     // GL_ARRAY_BUFFER_BINDING is separate from VAO state
606     GLuint m_arrayBuffer;
607     GLuint m_arrayBuffer_lastEncode;
608     VAOStateMap m_vaoMap;
609     VAOStateRef m_currVaoState;
610 
611     uint16_t m_attribEnableCache;
612     uint16_t m_vaoAttribBindingCacheInvalid;
613     uint16_t m_vaoAttribBindingHasClientArrayCache;
614     uint16_t m_vaoAttribBindingHasVboCache;
615     uint8_t m_noClientArraysCache;
616 
617     // Other buffer id's, other targets
618     GLuint m_copyReadBuffer;
619     GLuint m_copyWriteBuffer;
620 
621     GLuint m_pixelPackBuffer;
622     GLuint m_pixelUnpackBuffer;
623 
624     GLuint m_transformFeedbackBuffer;
625     GLuint m_uniformBuffer;
626 
627     GLuint m_atomicCounterBuffer;
628     GLuint m_dispatchIndirectBuffer;
629     GLuint m_drawIndirectBuffer;
630     GLuint m_shaderStorageBuffer;
631     GLuint m_textureBuffer;
632 
633     bool m_transformFeedbackActive;
634     bool m_transformFeedbackUnpaused;
635     uint32_t m_transformFeedbackVaryingsCountForLinking;
636 
637     HostDriverCaps m_hostDriverCaps;
638     bool m_extensions_set;
639     std::string m_extensions;
640     bool m_has_color_buffer_float_extension;
641     bool m_has_color_buffer_half_float_extension;
642     std::vector<BufferBinding> m_indexedTransformFeedbackBuffers;
643     std::vector<BufferBinding> m_indexedUniformBuffers;
644     std::vector<BufferBinding> m_indexedAtomicCounterBuffers;
645     std::vector<BufferBinding> m_indexedShaderStorageBuffers;
646     int m_log2MaxTextureSize;
647 
648     int m_glesMajorVersion;
649     int m_glesMinorVersion;
650     int m_activeTexture;
651     GLint m_currentProgram;
652     GLint m_currentShaderProgram;
653     ProgramPipelineMap m_programPipelines;
654 
655     enum TextureTarget {
656         TEXTURE_2D = 0,
657         TEXTURE_EXTERNAL = 1,
658         TEXTURE_CUBE_MAP = 2,
659         TEXTURE_2D_ARRAY = 3,
660         TEXTURE_3D = 4,
661         TEXTURE_2D_MULTISAMPLE = 5,
662         TEXTURE_BUFFER = 6,
663         TEXTURE_TARGET_COUNT
664     };
665     struct TextureUnit {
666         unsigned int enables;
667         GLuint texture[TEXTURE_TARGET_COUNT];
668         GLuint boundSampler;
669     };
670     struct TextureState {
671         TextureUnit unit[MAX_TEXTURE_UNITS];
672         TextureUnit* activeUnit;
673         // Initialized from shared group.
674         SharedTextureDataMap* textureRecs;
675     };
676     TextureState m_tex;
677 
678     // State tracking of cube map definitions.
679     // Currently used only for driver workarounds
680     // when using GL_LUMINANCE and defining cube maps with
681     // glCopyTexImage2D.
682     struct CubeMapDef {
683         GLuint id;
684         GLenum target;
685         GLint level;
686         GLenum internalformat;
687     };
688     struct CubeMapDefCompare {
operatorCubeMapDefCompare689         bool operator() (const CubeMapDef& a,
690                          const CubeMapDef& b) const {
691             if (a.id != b.id) return a.id < b.id;
692             if (a.target != b.target) return a.target < b.target;
693             if (a.level != b.level) return a.level < b.level;
694             if (a.internalformat != b.internalformat)
695                 return a.internalformat < b.internalformat;
696             return false;
697         }
698     };
699     std::set<CubeMapDef, CubeMapDefCompare> m_cubeMapDefs;
700     void writeCopyTexImageState(GLenum target, GLint level,
701                                 GLenum internalformat);
702     GLenum copyTexImageNeededTarget(GLenum target, GLint level,
703                                     GLenum internalformat);
704 
705     struct RboState {
706         std::shared_ptr<RboProps> boundRenderbuffer;
707         // Connects to share group.
708         // Expected that share group lifetime outlives this context.
709         RenderbufferInfo* rboData;
710     };
711     RboState mRboState;
712     void addFreshRenderbuffer(GLuint name);
713 
714     struct FboState {
715         GLuint boundDrawFramebuffer;
716         GLuint boundReadFramebuffer;
717         size_t boundFramebufferIndex;
718         std::map<GLuint, FboProps> fboData;
719         GLenum drawFboCheckStatus;
720         GLenum readFboCheckStatus;
721     };
722     FboState mFboState;
723     void addFreshFramebuffer(GLuint name);
724     FboProps& boundFboProps(GLenum target);
725     const FboProps& boundFboProps_const(GLenum target) const;
726 
727     // Querying framebuffer format
728     GLenum queryTexType(GLuint name) const;
729     GLsizei queryTexSamples(GLuint name) const;
730 
731     static int compareTexId(const void* pid, const void* prec);
732     TextureRec* addTextureRec(GLuint id, GLenum target);
733     std::shared_ptr<TextureRec> getTextureRec(GLuint id) const;
734     TextureRec* getTextureRecPtr(GLuint id) const;
735     TextureRec* getTextureRecPtrLocked(GLuint id) const;
736 
737 public:
738     bool isTexture(GLuint name) const;
739     bool isTextureWithStorage(GLuint name) const;
740     bool isTextureWithTarget(GLuint name) const;
741     bool isTextureCubeMap(GLuint name) const;
742     bool isRenderbuffer(GLuint name) const;
743     bool isRenderbufferThatWasBound(GLuint name) const;
744 
745     void getClientStatePointer(GLenum pname, GLvoid** params);
746 
747     template <class T>
getVertexAttribParameter(GLuint index,GLenum param,T * ptr)748     int getVertexAttribParameter(GLuint index, GLenum param, T *ptr)
749     {
750         bool handled = true;
751         const VertexAttribState& vertexAttrib = getState(index);
752         const BufferBinding& vertexAttribBufferBinding =
753             m_currVaoState.bufferBindings_const()[vertexAttrib.bindingindex];
754 
755         switch(param) {
756 #define GL_VERTEX_ATTRIB_BINDING 0x82D4
757         case GL_VERTEX_ATTRIB_BINDING:
758             *ptr = (T)vertexAttrib.bindingindex;
759             break;
760 #define GL_VERTEX_ATTRIB_RELATIVE_OFFSET 0x82D5
761         case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
762             *ptr = (T)vertexAttrib.reloffset;
763             break;
764         case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
765             *ptr = (T)(vertexAttribBufferBinding.buffer);
766             break;
767         case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
768             *ptr = (T)(vertexAttrib.enabled);
769             break;
770 #define GL_VERTEX_ATTRIB_ARRAY_INTEGER 0x88FD
771         case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
772             *ptr = (T)(vertexAttrib.isInt);
773             break;
774         case GL_VERTEX_ATTRIB_ARRAY_SIZE:
775             *ptr = (T)(vertexAttrib.size);
776             break;
777         case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
778             *ptr = (T)(vertexAttribBufferBinding.stride);
779             break;
780         case GL_VERTEX_ATTRIB_ARRAY_TYPE:
781             *ptr = (T)(vertexAttrib.type);
782             break;
783         case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
784             *ptr = (T)(vertexAttrib.normalized);
785             break;
786         case GL_CURRENT_VERTEX_ATTRIB:
787             handled = false;
788             break;
789         default:
790             handled = false;
791         }
792         return handled;
793     }
794 
795     template <class T>
getClientStateParameter(GLenum param,T * out)796     bool getClientStateParameter(GLenum param, T* out)
797     {
798         bool isClientStateParam = false;
799         switch (param) {
800         case GL_CLIENT_ACTIVE_TEXTURE: {
801             GLint tex = getActiveTexture() + GL_TEXTURE0;
802             *out = tex;
803             isClientStateParam = true;
804             break;
805             }
806         case GL_VERTEX_ARRAY_SIZE: {
807             const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
808             *out = state.size;
809             isClientStateParam = true;
810             break;
811             }
812         case GL_VERTEX_ARRAY_TYPE: {
813             const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
814             *out = state.type;
815             isClientStateParam = true;
816             break;
817             }
818         case GL_VERTEX_ARRAY_STRIDE: {
819             const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
820             *out = state.stride;
821             isClientStateParam = true;
822             break;
823             }
824         case GL_COLOR_ARRAY_SIZE: {
825             const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
826             *out = state.size;
827             isClientStateParam = true;
828             break;
829             }
830         case GL_COLOR_ARRAY_TYPE: {
831             const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
832             *out = state.type;
833             isClientStateParam = true;
834             break;
835             }
836         case GL_COLOR_ARRAY_STRIDE: {
837             const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
838             *out = state.stride;
839             isClientStateParam = true;
840             break;
841             }
842         case GL_NORMAL_ARRAY_TYPE: {
843             const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION);
844             *out = state.type;
845             isClientStateParam = true;
846             break;
847             }
848         case GL_NORMAL_ARRAY_STRIDE: {
849             const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION);
850             *out = state.stride;
851             isClientStateParam = true;
852             break;
853             }
854         case GL_TEXTURE_COORD_ARRAY_SIZE: {
855             const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
856             *out = state.size;
857             isClientStateParam = true;
858             break;
859             }
860         case GL_TEXTURE_COORD_ARRAY_TYPE: {
861             const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
862             *out = state.type;
863             isClientStateParam = true;
864             break;
865             }
866         case GL_TEXTURE_COORD_ARRAY_STRIDE: {
867             const GLClientState::VertexAttribState& state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
868             *out = state.stride;
869             isClientStateParam = true;
870             break;
871             }
872         case GL_POINT_SIZE_ARRAY_TYPE_OES: {
873             const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION);
874             *out = state.type;
875             isClientStateParam = true;
876             break;
877             }
878         case GL_POINT_SIZE_ARRAY_STRIDE_OES: {
879             const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION);
880             *out = state.stride;
881             isClientStateParam = true;
882             break;
883             }
884         case GL_MATRIX_INDEX_ARRAY_SIZE_OES: {
885             const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
886             *out = state.size;
887             isClientStateParam = true;
888             break;
889             }
890         case GL_MATRIX_INDEX_ARRAY_TYPE_OES: {
891             const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
892             *out = state.type;
893             isClientStateParam = true;
894             break;
895             }
896         case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: {
897             const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
898             *out = state.stride;
899             isClientStateParam = true;
900             break;
901             }
902         case GL_WEIGHT_ARRAY_SIZE_OES: {
903             const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
904             *out = state.size;
905             isClientStateParam = true;
906             break;
907             }
908         case GL_WEIGHT_ARRAY_TYPE_OES: {
909             const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
910             *out = state.type;
911             isClientStateParam = true;
912             break;
913             }
914         case GL_WEIGHT_ARRAY_STRIDE_OES: {
915             const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
916             *out = state.stride;
917             isClientStateParam = true;
918             break;
919             }
920         case GL_VERTEX_ARRAY_BUFFER_BINDING: {
921             const GLClientState::VertexAttribState& state = getState(GLClientState::VERTEX_LOCATION);
922             *out = state.bufferObject;
923             isClientStateParam = true;
924             break;
925             }
926         case GL_NORMAL_ARRAY_BUFFER_BINDING: {
927             const GLClientState::VertexAttribState& state = getState(GLClientState::NORMAL_LOCATION);
928             *out = state.bufferObject;
929             isClientStateParam = true;
930             break;
931             }
932         case GL_COLOR_ARRAY_BUFFER_BINDING: {
933             const GLClientState::VertexAttribState& state = getState(GLClientState::COLOR_LOCATION);
934             *out = state.bufferObject;
935             isClientStateParam = true;
936             break;
937             }
938         case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: {
939             const GLClientState::VertexAttribState& state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION);
940             *out = state.bufferObject;
941             isClientStateParam = true;
942             break;
943             }
944         case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: {
945             const GLClientState::VertexAttribState& state = getState(GLClientState::POINTSIZE_LOCATION);
946             *out = state.bufferObject;
947             isClientStateParam = true;
948             break;
949             }
950         case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: {
951             const GLClientState::VertexAttribState& state = getState(GLClientState::MATRIXINDEX_LOCATION);
952             *out = state.bufferObject;
953             isClientStateParam = true;
954             break;
955             }
956         case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: {
957             const GLClientState::VertexAttribState& state = getState(GLClientState::WEIGHT_LOCATION);
958             *out = state.bufferObject;
959             isClientStateParam = true;
960             break;
961             }
962         case GL_ARRAY_BUFFER_BINDING: {
963             int buffer = getBuffer(GL_ARRAY_BUFFER);
964             *out = buffer;
965             isClientStateParam = true;
966             break;
967             }
968         case GL_ELEMENT_ARRAY_BUFFER_BINDING: {
969             int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER);
970             *out = buffer;
971             isClientStateParam = true;
972             break;
973             }
974         case GL_MAX_VERTEX_ATTRIBS: {
975             *out = CODEC_MAX_VERTEX_ATTRIBUTES;
976             isClientStateParam = true;
977             break;
978         }
979         case GL_FRAMEBUFFER_BINDING:
980         // also case GL_DRAW_FRAMEBUFFER_BINDING:
981             *out = (T)mFboState.boundDrawFramebuffer;
982             isClientStateParam = true;
983             break;
984         case 0x8CAA: // GL_READ_FRAMEBUFFER_BINDING
985             *out = (T)mFboState.boundReadFramebuffer;
986             isClientStateParam = true;
987             break;
988         case GL_STENCIL_TEST:
989             *out = (T)state_GL_STENCIL_TEST;
990             isClientStateParam = true;
991             break;
992         case GL_STENCIL_FUNC:
993             *out = (T)state_GL_STENCIL_FUNC;
994             isClientStateParam = true;
995             break;
996         case GL_STENCIL_VALUE_MASK:
997             *out = (T)state_GL_STENCIL_VALUE_MASK;
998             isClientStateParam = true;
999             break;
1000         case GL_STENCIL_REF:
1001             *out = (T)state_GL_STENCIL_REF;
1002             isClientStateParam = true;
1003             break;
1004         case GL_STENCIL_FAIL:
1005             *out = (T)state_GL_STENCIL_FAIL;
1006             isClientStateParam = true;
1007             break;
1008         case GL_STENCIL_PASS_DEPTH_FAIL:
1009             *out = (T)state_GL_STENCIL_PASS_DEPTH_FAIL;
1010             isClientStateParam = true;
1011             break;
1012         case GL_STENCIL_PASS_DEPTH_PASS:
1013             *out = (T)state_GL_STENCIL_PASS_DEPTH_PASS;
1014             isClientStateParam = true;
1015             break;
1016         case GL_STENCIL_BACK_FUNC:
1017             *out = (T)state_GL_STENCIL_BACK_FUNC;
1018             isClientStateParam = true;
1019             break;
1020         case GL_STENCIL_BACK_VALUE_MASK:
1021             *out = (T)state_GL_STENCIL_BACK_VALUE_MASK;
1022             isClientStateParam = true;
1023             break;
1024         case GL_STENCIL_BACK_REF:
1025             *out = (T)state_GL_STENCIL_BACK_REF;
1026             isClientStateParam = true;
1027             break;
1028         case GL_STENCIL_BACK_FAIL:
1029             *out = (T)state_GL_STENCIL_BACK_FAIL;
1030             isClientStateParam = true;
1031             break;
1032         case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
1033             *out = (T)state_GL_STENCIL_BACK_PASS_DEPTH_FAIL;
1034             isClientStateParam = true;
1035             break;
1036         case GL_STENCIL_BACK_PASS_DEPTH_PASS:
1037             *out = (T)state_GL_STENCIL_BACK_PASS_DEPTH_PASS;
1038             isClientStateParam = true;
1039             break;
1040         case GL_STENCIL_WRITEMASK:
1041             *out = (T)state_GL_STENCIL_WRITEMASK;
1042             isClientStateParam = true;
1043             break;
1044         case GL_STENCIL_BACK_WRITEMASK:
1045             *out = (T)state_GL_STENCIL_BACK_WRITEMASK;
1046             isClientStateParam = true;
1047             break;
1048         case GL_STENCIL_CLEAR_VALUE:
1049             *out = (T)state_GL_STENCIL_CLEAR_VALUE;
1050             isClientStateParam = true;
1051             break;
1052         }
1053         return isClientStateParam;
1054     }
1055 
1056 };
1057 
1058 }  // namespace guest
1059 }  // namespace gfxstream
1060 
1061 #endif
1062