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