• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // queryutils.cpp: Utilities for querying values from GL objects
8 
9 #include "libANGLE/queryutils.h"
10 
11 #include "common/utilities.h"
12 
13 #include "libANGLE/Buffer.h"
14 #include "libANGLE/Config.h"
15 #include "libANGLE/Context.h"
16 #include "libANGLE/Display.h"
17 #include "libANGLE/EGLSync.h"
18 #include "libANGLE/Fence.h"
19 #include "libANGLE/Framebuffer.h"
20 #include "libANGLE/GLES1State.h"
21 #include "libANGLE/MemoryObject.h"
22 #include "libANGLE/Program.h"
23 #include "libANGLE/Renderbuffer.h"
24 #include "libANGLE/Sampler.h"
25 #include "libANGLE/Shader.h"
26 #include "libANGLE/Surface.h"
27 #include "libANGLE/Texture.h"
28 #include "libANGLE/Uniform.h"
29 #include "libANGLE/VertexAttribute.h"
30 #include "libANGLE/queryconversions.h"
31 
32 namespace gl
33 {
34 
35 namespace
36 {
37 
38 template <bool isPureInteger>
ConvertToColor(const GLfloat * params)39 ColorGeneric ConvertToColor(const GLfloat *params)
40 {
41     if (isPureInteger)
42     {
43         UNREACHABLE();
44         return ColorGeneric(ColorI());
45     }
46     else
47     {
48         return ColorGeneric(ColorF::fromData(params));
49     }
50 }
51 
52 template <bool isPureInteger>
ConvertToColor(const GLint * params)53 ColorGeneric ConvertToColor(const GLint *params)
54 {
55     if (isPureInteger)
56     {
57         return ColorGeneric(ColorI(params[0], params[1], params[2], params[3]));
58     }
59     else
60     {
61         return ColorGeneric(ColorF(normalizedToFloat(params[0]), normalizedToFloat(params[1]),
62                                    normalizedToFloat(params[2]), normalizedToFloat(params[3])));
63     }
64 }
65 
66 template <bool isPureInteger>
ConvertToColor(const GLuint * params)67 ColorGeneric ConvertToColor(const GLuint *params)
68 {
69     if (isPureInteger)
70     {
71         return ColorGeneric(ColorUI(params[0], params[1], params[2], params[3]));
72     }
73     else
74     {
75         UNREACHABLE();
76         return ColorGeneric(ColorF());
77     }
78 }
79 
80 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLfloat * outParams)81 void ConvertFromColor(const ColorGeneric &color, GLfloat *outParams)
82 {
83     if (isPureInteger)
84     {
85         UNREACHABLE();
86     }
87     else
88     {
89         ASSERT(color.type == ColorGeneric::Type::Float);
90         color.colorF.writeData(outParams);
91     }
92 }
93 
94 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLint * outParams)95 void ConvertFromColor(const ColorGeneric &color, GLint *outParams)
96 {
97     if (isPureInteger)
98     {
99         ASSERT(color.type == ColorGeneric::Type::Int);
100         outParams[0] = color.colorI.red;
101         outParams[1] = color.colorI.green;
102         outParams[2] = color.colorI.blue;
103         outParams[3] = color.colorI.alpha;
104     }
105     else
106     {
107         ASSERT(color.type == ColorGeneric::Type::Float);
108         outParams[0] = floatToNormalized<GLint>(color.colorF.red);
109         outParams[1] = floatToNormalized<GLint>(color.colorF.green);
110         outParams[2] = floatToNormalized<GLint>(color.colorF.blue);
111         outParams[3] = floatToNormalized<GLint>(color.colorF.alpha);
112     }
113 }
114 
115 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLuint * outParams)116 void ConvertFromColor(const ColorGeneric &color, GLuint *outParams)
117 {
118     if (isPureInteger)
119     {
120         ASSERT(color.type == ColorGeneric::Type::UInt);
121         outParams[0] = color.colorUI.red;
122         outParams[1] = color.colorUI.green;
123         outParams[2] = color.colorUI.blue;
124         outParams[3] = color.colorUI.alpha;
125     }
126     else
127     {
128         UNREACHABLE();
129     }
130 }
131 
132 template <typename ParamType>
QueryTexLevelParameterBase(const Texture * texture,TextureTarget target,GLint level,GLenum pname,ParamType * params)133 void QueryTexLevelParameterBase(const Texture *texture,
134                                 TextureTarget target,
135                                 GLint level,
136                                 GLenum pname,
137                                 ParamType *params)
138 {
139     ASSERT(texture != nullptr);
140     const InternalFormat *info = texture->getTextureState().getImageDesc(target, level).format.info;
141 
142     switch (pname)
143     {
144         case GL_TEXTURE_RED_TYPE:
145             *params = CastFromGLintStateValue<ParamType>(
146                 pname, info->redBits ? info->componentType : GL_NONE);
147             break;
148         case GL_TEXTURE_GREEN_TYPE:
149             *params = CastFromGLintStateValue<ParamType>(
150                 pname, info->greenBits ? info->componentType : GL_NONE);
151             break;
152         case GL_TEXTURE_BLUE_TYPE:
153             *params = CastFromGLintStateValue<ParamType>(
154                 pname, info->blueBits ? info->componentType : GL_NONE);
155             break;
156         case GL_TEXTURE_ALPHA_TYPE:
157             *params = CastFromGLintStateValue<ParamType>(
158                 pname, info->alphaBits ? info->componentType : GL_NONE);
159             break;
160         case GL_TEXTURE_DEPTH_TYPE:
161             *params = CastFromGLintStateValue<ParamType>(
162                 pname, info->depthBits ? info->componentType : GL_NONE);
163             break;
164         case GL_TEXTURE_RED_SIZE:
165             *params = CastFromGLintStateValue<ParamType>(pname, info->redBits);
166             break;
167         case GL_TEXTURE_GREEN_SIZE:
168             *params = CastFromGLintStateValue<ParamType>(pname, info->greenBits);
169             break;
170         case GL_TEXTURE_BLUE_SIZE:
171             *params = CastFromGLintStateValue<ParamType>(pname, info->blueBits);
172             break;
173         case GL_TEXTURE_ALPHA_SIZE:
174             *params = CastFromGLintStateValue<ParamType>(pname, info->alphaBits);
175             break;
176         case GL_TEXTURE_DEPTH_SIZE:
177             *params = CastFromGLintStateValue<ParamType>(pname, info->depthBits);
178             break;
179         case GL_TEXTURE_STENCIL_SIZE:
180             *params = CastFromGLintStateValue<ParamType>(pname, info->stencilBits);
181             break;
182         case GL_TEXTURE_SHARED_SIZE:
183             *params = CastFromGLintStateValue<ParamType>(pname, info->sharedBits);
184             break;
185         case GL_TEXTURE_INTERNAL_FORMAT:
186             *params = CastFromGLintStateValue<ParamType>(
187                 pname, info->internalFormat ? info->internalFormat : GL_RGBA);
188             break;
189         case GL_TEXTURE_WIDTH:
190             *params = CastFromGLintStateValue<ParamType>(
191                 pname, static_cast<uint32_t>(texture->getWidth(target, level)));
192             break;
193         case GL_TEXTURE_HEIGHT:
194             *params = CastFromGLintStateValue<ParamType>(
195                 pname, static_cast<uint32_t>(texture->getHeight(target, level)));
196             break;
197         case GL_TEXTURE_DEPTH:
198             *params = CastFromGLintStateValue<ParamType>(
199                 pname, static_cast<uint32_t>(texture->getDepth(target, level)));
200             break;
201         case GL_TEXTURE_SAMPLES:
202             *params = CastFromStateValue<ParamType>(pname, texture->getSamples(target, level));
203             break;
204         case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
205             *params = CastFromStateValue<ParamType>(
206                 pname, static_cast<GLint>(texture->getFixedSampleLocations(target, level)));
207             break;
208         case GL_TEXTURE_COMPRESSED:
209             *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(info->compressed));
210             break;
211         case GL_MEMORY_SIZE_ANGLE:
212             *params =
213                 CastFromStateValue<ParamType>(pname, texture->getLevelMemorySize(target, level));
214             break;
215         default:
216             UNREACHABLE();
217             break;
218     }
219 }
220 
221 // This function is needed to handle fixed_point data.
222 // It can be used when some pname need special conversion from int/float/bool to fixed_point.
223 template <bool isGLfixed, typename QueryT, typename ParamType>
CastFromSpecialValue(GLenum pname,const ParamType param)224 QueryT CastFromSpecialValue(GLenum pname, const ParamType param)
225 {
226     if (isGLfixed)
227     {
228         return static_cast<QueryT>(ConvertFloatToFixed(CastFromStateValue<GLfloat>(pname, param)));
229     }
230     else
231     {
232         return CastFromStateValue<QueryT>(pname, param);
233     }
234 }
235 
236 template <bool isPureInteger, bool isGLfixed, typename ParamType>
QueryTexParameterBase(const Context * context,const Texture * texture,GLenum pname,ParamType * params)237 void QueryTexParameterBase(const Context *context,
238                            const Texture *texture,
239                            GLenum pname,
240                            ParamType *params)
241 {
242     ASSERT(texture != nullptr);
243 
244     switch (pname)
245     {
246         case GL_TEXTURE_MAG_FILTER:
247             *params = CastFromGLintStateValue<ParamType>(pname, texture->getMagFilter());
248             break;
249         case GL_TEXTURE_MIN_FILTER:
250             *params = CastFromGLintStateValue<ParamType>(pname, texture->getMinFilter());
251             break;
252         case GL_TEXTURE_WRAP_S:
253             *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapS());
254             break;
255         case GL_TEXTURE_WRAP_T:
256             *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapT());
257             break;
258         case GL_TEXTURE_WRAP_R:
259             *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapR());
260             break;
261         case GL_TEXTURE_IMMUTABLE_FORMAT:
262             *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableFormat());
263             break;
264         case GL_TEXTURE_IMMUTABLE_LEVELS:
265             *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableLevels());
266             break;
267         case GL_TEXTURE_USAGE_ANGLE:
268             *params = CastFromGLintStateValue<ParamType>(pname, texture->getUsage());
269             break;
270         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
271             *params =
272                 CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxAnisotropy());
273             break;
274         case GL_TEXTURE_SWIZZLE_R:
275             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleRed());
276             break;
277         case GL_TEXTURE_SWIZZLE_G:
278             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleGreen());
279             break;
280         case GL_TEXTURE_SWIZZLE_B:
281             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleBlue());
282             break;
283         case GL_TEXTURE_SWIZZLE_A:
284             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleAlpha());
285             break;
286         case GL_TEXTURE_BASE_LEVEL:
287             *params = CastFromGLintStateValue<ParamType>(pname, texture->getBaseLevel());
288             break;
289         case GL_TEXTURE_MAX_LEVEL:
290             *params = CastFromGLintStateValue<ParamType>(pname, texture->getMaxLevel());
291             break;
292         case GL_TEXTURE_MIN_LOD:
293             *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMinLod());
294             break;
295         case GL_TEXTURE_MAX_LOD:
296             *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxLod());
297             break;
298         case GL_TEXTURE_COMPARE_MODE:
299             *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareMode());
300             break;
301         case GL_TEXTURE_COMPARE_FUNC:
302             *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareFunc());
303             break;
304         case GL_TEXTURE_SRGB_DECODE_EXT:
305             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBDecode());
306             break;
307         case GL_DEPTH_STENCIL_TEXTURE_MODE:
308             *params =
309                 CastFromGLintStateValue<ParamType>(pname, texture->getDepthStencilTextureMode());
310             break;
311         case GL_TEXTURE_CROP_RECT_OES:
312         {
313             const gl::Rectangle &crop = texture->getCrop();
314             params[0]                 = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.x);
315             params[1]                 = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.y);
316             params[2] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.width);
317             params[3] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.height);
318             break;
319         }
320         case GL_GENERATE_MIPMAP:
321             *params = CastFromGLintStateValue<ParamType>(pname, texture->getGenerateMipmapHint());
322             break;
323         case GL_MEMORY_SIZE_ANGLE:
324             *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMemorySize());
325             break;
326         case GL_TEXTURE_BORDER_COLOR:
327             ConvertFromColor<isPureInteger>(texture->getBorderColor(), params);
328             break;
329         case GL_TEXTURE_NATIVE_ID_ANGLE:
330             *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getNativeID());
331             break;
332         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
333             *params = CastFromGLintStateValue<ParamType>(
334                 pname, texture->getImplementationColorReadFormat(context));
335             break;
336         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
337             *params = CastFromGLintStateValue<ParamType>(
338                 pname, texture->getImplementationColorReadType(context));
339             break;
340         case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
341             *params =
342                 CastFromGLintStateValue<ParamType>(pname, GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE);
343             break;
344         default:
345             UNREACHABLE();
346             break;
347     }
348 }
349 
350 // this function is needed to handle OES_FIXED_POINT.
351 // Some pname values can take in GLfixed values and may need to be converted
352 template <bool isGLfixed, typename ReturnType, typename ParamType>
ConvertTexParam(GLenum pname,const ParamType param)353 ReturnType ConvertTexParam(GLenum pname, const ParamType param)
354 {
355     if (isGLfixed)
356     {
357         return CastQueryValueTo<ReturnType>(pname,
358                                             ConvertFixedToFloat(static_cast<GLfixed>(param)));
359     }
360     else
361     {
362         return CastQueryValueTo<ReturnType>(pname, param);
363     }
364 }
365 
366 template <bool isPureInteger, bool isGLfixed, typename ParamType>
SetTexParameterBase(Context * context,Texture * texture,GLenum pname,const ParamType * params)367 void SetTexParameterBase(Context *context, Texture *texture, GLenum pname, const ParamType *params)
368 {
369     ASSERT(texture != nullptr);
370 
371     switch (pname)
372     {
373         case GL_TEXTURE_WRAP_S:
374             texture->setWrapS(context, ConvertToGLenum(pname, params[0]));
375             break;
376         case GL_TEXTURE_WRAP_T:
377             texture->setWrapT(context, ConvertToGLenum(pname, params[0]));
378             break;
379         case GL_TEXTURE_WRAP_R:
380             texture->setWrapR(context, ConvertToGLenum(pname, params[0]));
381             break;
382         case GL_TEXTURE_MIN_FILTER:
383             texture->setMinFilter(context, ConvertToGLenum(pname, params[0]));
384             break;
385         case GL_TEXTURE_MAG_FILTER:
386             texture->setMagFilter(context, ConvertToGLenum(pname, params[0]));
387             break;
388         case GL_TEXTURE_USAGE_ANGLE:
389             texture->setUsage(context, ConvertToGLenum(pname, params[0]));
390             break;
391         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
392             texture->setMaxAnisotropy(context,
393                                       ConvertTexParam<isGLfixed, GLfloat>(pname, params[0]));
394             break;
395         case GL_TEXTURE_COMPARE_MODE:
396             texture->setCompareMode(context, ConvertToGLenum(pname, params[0]));
397             break;
398         case GL_TEXTURE_COMPARE_FUNC:
399             texture->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
400             break;
401         case GL_TEXTURE_SWIZZLE_R:
402             texture->setSwizzleRed(context, ConvertToGLenum(pname, params[0]));
403             break;
404         case GL_TEXTURE_SWIZZLE_G:
405             texture->setSwizzleGreen(context, ConvertToGLenum(pname, params[0]));
406             break;
407         case GL_TEXTURE_SWIZZLE_B:
408             texture->setSwizzleBlue(context, ConvertToGLenum(pname, params[0]));
409             break;
410         case GL_TEXTURE_SWIZZLE_A:
411             texture->setSwizzleAlpha(context, ConvertToGLenum(pname, params[0]));
412             break;
413         case GL_TEXTURE_BASE_LEVEL:
414         {
415             (void)(texture->setBaseLevel(
416                 context, clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0]))));
417             break;
418         }
419         case GL_TEXTURE_MAX_LEVEL:
420             texture->setMaxLevel(context,
421                                  clampCast<GLuint>(CastQueryValueTo<GLint>(pname, params[0])));
422             break;
423         case GL_TEXTURE_MIN_LOD:
424             texture->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
425             break;
426         case GL_TEXTURE_MAX_LOD:
427             texture->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
428             break;
429         case GL_DEPTH_STENCIL_TEXTURE_MODE:
430             texture->setDepthStencilTextureMode(context, ConvertToGLenum(pname, params[0]));
431             break;
432         case GL_TEXTURE_SRGB_DECODE_EXT:
433             texture->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
434             break;
435         case GL_TEXTURE_CROP_RECT_OES:
436             texture->setCrop(gl::Rectangle(ConvertTexParam<isGLfixed, GLint>(pname, params[0]),
437                                            ConvertTexParam<isGLfixed, GLint>(pname, params[1]),
438                                            ConvertTexParam<isGLfixed, GLint>(pname, params[2]),
439                                            ConvertTexParam<isGLfixed, GLint>(pname, params[3])));
440             break;
441         case GL_GENERATE_MIPMAP:
442             texture->setGenerateMipmapHint(ConvertToGLenum(params[0]));
443             break;
444         case GL_TEXTURE_BORDER_COLOR:
445             texture->setBorderColor(context, ConvertToColor<isPureInteger>(params));
446             break;
447         default:
448             UNREACHABLE();
449             break;
450     }
451 }
452 
453 template <bool isPureInteger, typename ParamType>
QuerySamplerParameterBase(const Sampler * sampler,GLenum pname,ParamType * params)454 void QuerySamplerParameterBase(const Sampler *sampler, GLenum pname, ParamType *params)
455 {
456     switch (pname)
457     {
458         case GL_TEXTURE_MIN_FILTER:
459             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMinFilter());
460             break;
461         case GL_TEXTURE_MAG_FILTER:
462             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getMagFilter());
463             break;
464         case GL_TEXTURE_WRAP_S:
465             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapS());
466             break;
467         case GL_TEXTURE_WRAP_T:
468             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapT());
469             break;
470         case GL_TEXTURE_WRAP_R:
471             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getWrapR());
472             break;
473         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
474             *params = CastFromStateValue<ParamType>(pname, sampler->getMaxAnisotropy());
475             break;
476         case GL_TEXTURE_MIN_LOD:
477             *params = CastFromStateValue<ParamType>(pname, sampler->getMinLod());
478             break;
479         case GL_TEXTURE_MAX_LOD:
480             *params = CastFromStateValue<ParamType>(pname, sampler->getMaxLod());
481             break;
482         case GL_TEXTURE_COMPARE_MODE:
483             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareMode());
484             break;
485         case GL_TEXTURE_COMPARE_FUNC:
486             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getCompareFunc());
487             break;
488         case GL_TEXTURE_SRGB_DECODE_EXT:
489             *params = CastFromGLintStateValue<ParamType>(pname, sampler->getSRGBDecode());
490             break;
491         case GL_TEXTURE_BORDER_COLOR:
492             ConvertFromColor<isPureInteger>(sampler->getBorderColor(), params);
493             break;
494         default:
495             UNREACHABLE();
496             break;
497     }
498 }
499 
500 template <bool isPureInteger, typename ParamType>
SetSamplerParameterBase(Context * context,Sampler * sampler,GLenum pname,const ParamType * params)501 void SetSamplerParameterBase(Context *context,
502                              Sampler *sampler,
503                              GLenum pname,
504                              const ParamType *params)
505 {
506     switch (pname)
507     {
508         case GL_TEXTURE_WRAP_S:
509             sampler->setWrapS(context, ConvertToGLenum(pname, params[0]));
510             break;
511         case GL_TEXTURE_WRAP_T:
512             sampler->setWrapT(context, ConvertToGLenum(pname, params[0]));
513             break;
514         case GL_TEXTURE_WRAP_R:
515             sampler->setWrapR(context, ConvertToGLenum(pname, params[0]));
516             break;
517         case GL_TEXTURE_MIN_FILTER:
518             sampler->setMinFilter(context, ConvertToGLenum(pname, params[0]));
519             break;
520         case GL_TEXTURE_MAG_FILTER:
521             sampler->setMagFilter(context, ConvertToGLenum(pname, params[0]));
522             break;
523         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
524             sampler->setMaxAnisotropy(context, CastQueryValueTo<GLfloat>(pname, params[0]));
525             break;
526         case GL_TEXTURE_COMPARE_MODE:
527             sampler->setCompareMode(context, ConvertToGLenum(pname, params[0]));
528             break;
529         case GL_TEXTURE_COMPARE_FUNC:
530             sampler->setCompareFunc(context, ConvertToGLenum(pname, params[0]));
531             break;
532         case GL_TEXTURE_MIN_LOD:
533             sampler->setMinLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
534             break;
535         case GL_TEXTURE_MAX_LOD:
536             sampler->setMaxLod(context, CastQueryValueTo<GLfloat>(pname, params[0]));
537             break;
538         case GL_TEXTURE_SRGB_DECODE_EXT:
539             sampler->setSRGBDecode(context, ConvertToGLenum(pname, params[0]));
540             break;
541         case GL_TEXTURE_BORDER_COLOR:
542             sampler->setBorderColor(context, ConvertToColor<isPureInteger>(params));
543             break;
544         default:
545             UNREACHABLE();
546             break;
547     }
548 
549     sampler->onStateChange(angle::SubjectMessage::ContentsChanged);
550 }
551 
552 // Warning: you should ensure binding really matches attrib.bindingIndex before using this function.
553 template <typename ParamType, typename CurrentDataType, size_t CurrentValueCount>
QueryVertexAttribBase(const VertexAttribute & attrib,const VertexBinding & binding,const CurrentDataType (& currentValueData)[CurrentValueCount],GLenum pname,ParamType * params)554 void QueryVertexAttribBase(const VertexAttribute &attrib,
555                            const VertexBinding &binding,
556                            const CurrentDataType (&currentValueData)[CurrentValueCount],
557                            GLenum pname,
558                            ParamType *params)
559 {
560     switch (pname)
561     {
562         case GL_CURRENT_VERTEX_ATTRIB:
563             for (size_t i = 0; i < CurrentValueCount; ++i)
564             {
565                 params[i] = CastFromStateValue<ParamType>(pname, currentValueData[i]);
566             }
567             break;
568         case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
569             *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.enabled));
570             break;
571         case GL_VERTEX_ATTRIB_ARRAY_SIZE:
572             *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->channelCount);
573             break;
574         case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
575             *params = CastFromGLintStateValue<ParamType>(pname, attrib.vertexAttribArrayStride);
576             break;
577         case GL_VERTEX_ATTRIB_ARRAY_TYPE:
578             *params = CastFromGLintStateValue<ParamType>(
579                 pname, gl::ToGLenum(attrib.format->vertexAttribType));
580             break;
581         case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
582             *params =
583                 CastFromStateValue<ParamType>(pname, static_cast<GLint>(attrib.format->isNorm()));
584             break;
585         case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
586             *params = CastFromGLintStateValue<ParamType>(pname, binding.getBuffer().id().value);
587             break;
588         case GL_VERTEX_ATTRIB_ARRAY_DIVISOR:
589             *params = CastFromStateValue<ParamType>(pname, binding.getDivisor());
590             break;
591         case GL_VERTEX_ATTRIB_ARRAY_INTEGER:
592             *params = CastFromGLintStateValue<ParamType>(pname, attrib.format->isPureInt());
593             break;
594         case GL_VERTEX_ATTRIB_BINDING:
595             *params = CastFromGLintStateValue<ParamType>(pname, attrib.bindingIndex);
596             break;
597         case GL_VERTEX_ATTRIB_RELATIVE_OFFSET:
598             *params = CastFromGLintStateValue<ParamType>(pname, attrib.relativeOffset);
599             break;
600         default:
601             UNREACHABLE();
602             break;
603     }
604 }
605 
606 template <typename ParamType>
QueryBufferParameterBase(const Buffer * buffer,GLenum pname,ParamType * params)607 void QueryBufferParameterBase(const Buffer *buffer, GLenum pname, ParamType *params)
608 {
609     ASSERT(buffer != nullptr);
610 
611     switch (pname)
612     {
613         case GL_BUFFER_USAGE:
614             *params = CastFromGLintStateValue<ParamType>(pname, ToGLenum(buffer->getUsage()));
615             break;
616         case GL_BUFFER_SIZE:
617             *params = CastFromStateValue<ParamType>(pname, buffer->getSize());
618             break;
619         case GL_BUFFER_ACCESS_FLAGS:
620             *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccessFlags());
621             break;
622         case GL_BUFFER_ACCESS_OES:
623             *params = CastFromGLintStateValue<ParamType>(pname, buffer->getAccess());
624             break;
625         case GL_BUFFER_MAPPED:
626             *params = CastFromStateValue<ParamType>(pname, buffer->isMapped());
627             break;
628         case GL_BUFFER_MAP_OFFSET:
629             *params = CastFromStateValue<ParamType>(pname, buffer->getMapOffset());
630             break;
631         case GL_BUFFER_MAP_LENGTH:
632             *params = CastFromStateValue<ParamType>(pname, buffer->getMapLength());
633             break;
634         case GL_MEMORY_SIZE_ANGLE:
635             *params = CastFromStateValue<ParamType>(pname, buffer->getMemorySize());
636             break;
637         default:
638             UNREACHABLE();
639             break;
640     }
641 }
642 
GetCommonVariableProperty(const sh::ShaderVariable & var,GLenum prop)643 GLint GetCommonVariableProperty(const sh::ShaderVariable &var, GLenum prop)
644 {
645     switch (prop)
646     {
647         case GL_TYPE:
648             return clampCast<GLint>(var.type);
649 
650         case GL_ARRAY_SIZE:
651             // Queryable variables are guaranteed not to be arrays of arrays or arrays of structs,
652             // see GLES 3.1 spec section 7.3.1.1 page 77.
653             return clampCast<GLint>(var.getBasicTypeElementCount());
654 
655         case GL_NAME_LENGTH:
656             // ES31 spec p84: This counts the terminating null char.
657             return clampCast<GLint>(var.name.size() + 1u);
658 
659         default:
660             UNREACHABLE();
661             return GL_INVALID_VALUE;
662     }
663 }
664 
GetInputResourceProperty(const Program * program,GLuint index,GLenum prop)665 GLint GetInputResourceProperty(const Program *program, GLuint index, GLenum prop)
666 {
667     const sh::ShaderVariable &variable = program->getInputResource(index);
668 
669     switch (prop)
670     {
671         case GL_TYPE:
672         case GL_ARRAY_SIZE:
673             return GetCommonVariableProperty(variable, prop);
674 
675         case GL_NAME_LENGTH:
676             return clampCast<GLint>(program->getInputResourceName(index).size() + 1u);
677 
678         case GL_LOCATION:
679             return variable.location;
680 
681         // The query is targeted at the set of active input variables used by the first shader stage
682         // of program. If program contains multiple shader stages then input variables from any
683         // stage other than the first will not be enumerated. Since we found the variable to get
684         // this far, we know it exists in the first attached shader stage.
685         case GL_REFERENCED_BY_VERTEX_SHADER:
686             return program->getState().getFirstAttachedShaderStageType() == ShaderType::Vertex;
687         case GL_REFERENCED_BY_FRAGMENT_SHADER:
688             return program->getState().getFirstAttachedShaderStageType() == ShaderType::Fragment;
689         case GL_REFERENCED_BY_COMPUTE_SHADER:
690             return program->getState().getFirstAttachedShaderStageType() == ShaderType::Compute;
691         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
692             return program->getState().getFirstAttachedShaderStageType() == ShaderType::Geometry;
693 
694         default:
695             UNREACHABLE();
696             return GL_INVALID_VALUE;
697     }
698 }
699 
GetOutputResourceProperty(const Program * program,GLuint index,const GLenum prop)700 GLint GetOutputResourceProperty(const Program *program, GLuint index, const GLenum prop)
701 {
702     const sh::ShaderVariable &outputVariable = program->getOutputResource(index);
703 
704     switch (prop)
705     {
706         case GL_TYPE:
707         case GL_ARRAY_SIZE:
708             return GetCommonVariableProperty(outputVariable, prop);
709 
710         case GL_NAME_LENGTH:
711             return clampCast<GLint>(program->getOutputResourceName(index).size() + 1u);
712 
713         case GL_LOCATION:
714             return outputVariable.location;
715 
716         case GL_LOCATION_INDEX_EXT:
717             // EXT_blend_func_extended
718             if (program->getState().getLastAttachedShaderStageType() == gl::ShaderType::Fragment)
719             {
720                 return program->getFragDataIndex(outputVariable.name);
721             }
722             return GL_INVALID_INDEX;
723 
724         // The set of active user-defined outputs from the final shader stage in this program. If
725         // the final stage is a Fragment Shader, then this represents the fragment outputs that get
726         // written to individual color buffers. If the program only contains a Compute Shader, then
727         // there are no user-defined outputs.
728         case GL_REFERENCED_BY_VERTEX_SHADER:
729             return program->getState().getLastAttachedShaderStageType() == ShaderType::Vertex;
730         case GL_REFERENCED_BY_FRAGMENT_SHADER:
731             return program->getState().getLastAttachedShaderStageType() == ShaderType::Fragment;
732         case GL_REFERENCED_BY_COMPUTE_SHADER:
733             return program->getState().getLastAttachedShaderStageType() == ShaderType::Compute;
734         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
735             return program->getState().getLastAttachedShaderStageType() == ShaderType::Geometry;
736 
737         default:
738             UNREACHABLE();
739             return GL_INVALID_VALUE;
740     }
741 }
742 
GetTransformFeedbackVaryingResourceProperty(const Program * program,GLuint index,const GLenum prop)743 GLint GetTransformFeedbackVaryingResourceProperty(const Program *program,
744                                                   GLuint index,
745                                                   const GLenum prop)
746 {
747     const auto &tfVariable = program->getTransformFeedbackVaryingResource(index);
748     switch (prop)
749     {
750         case GL_TYPE:
751             return clampCast<GLint>(tfVariable.type);
752 
753         case GL_ARRAY_SIZE:
754             return clampCast<GLint>(tfVariable.size());
755 
756         case GL_NAME_LENGTH:
757             return clampCast<GLint>(tfVariable.nameWithArrayIndex().size() + 1);
758 
759         default:
760             UNREACHABLE();
761             return GL_INVALID_VALUE;
762     }
763 }
764 
QueryProgramInterfaceActiveResources(const Program * program,GLenum programInterface)765 GLint QueryProgramInterfaceActiveResources(const Program *program, GLenum programInterface)
766 {
767     switch (programInterface)
768     {
769         case GL_PROGRAM_INPUT:
770             return clampCast<GLint>(program->getState().getProgramInputs().size());
771 
772         case GL_PROGRAM_OUTPUT:
773             return clampCast<GLint>(program->getState().getOutputVariables().size());
774 
775         case GL_UNIFORM:
776             return clampCast<GLint>(program->getState().getUniforms().size());
777 
778         case GL_UNIFORM_BLOCK:
779             return clampCast<GLint>(program->getState().getUniformBlocks().size());
780 
781         case GL_ATOMIC_COUNTER_BUFFER:
782             return clampCast<GLint>(program->getState().getAtomicCounterBuffers().size());
783 
784         case GL_BUFFER_VARIABLE:
785             return clampCast<GLint>(program->getState().getBufferVariables().size());
786 
787         case GL_SHADER_STORAGE_BLOCK:
788             return clampCast<GLint>(program->getState().getShaderStorageBlocks().size());
789 
790         case GL_TRANSFORM_FEEDBACK_VARYING:
791             return clampCast<GLint>(program->getTransformFeedbackVaryingCount());
792 
793         default:
794             UNREACHABLE();
795             return 0;
796     }
797 }
798 
799 template <typename T, typename M>
FindMaxSize(const std::vector<T> & resources,M member)800 GLint FindMaxSize(const std::vector<T> &resources, M member)
801 {
802     GLint max = 0;
803     for (const T &resource : resources)
804     {
805         max = std::max(max, clampCast<GLint>((resource.*member).size()));
806     }
807     return max;
808 }
809 
QueryProgramInterfaceMaxNameLength(const Program * program,GLenum programInterface)810 GLint QueryProgramInterfaceMaxNameLength(const Program *program, GLenum programInterface)
811 {
812     GLint maxNameLength = 0;
813     switch (programInterface)
814     {
815         case GL_PROGRAM_INPUT:
816             maxNameLength = program->getInputResourceMaxNameSize();
817             break;
818 
819         case GL_PROGRAM_OUTPUT:
820             maxNameLength = program->getOutputResourceMaxNameSize();
821             break;
822 
823         case GL_UNIFORM:
824             maxNameLength = FindMaxSize(program->getState().getUniforms(), &LinkedUniform::name);
825             break;
826 
827         case GL_UNIFORM_BLOCK:
828             return program->getActiveUniformBlockMaxNameLength();
829 
830         case GL_BUFFER_VARIABLE:
831             maxNameLength =
832                 FindMaxSize(program->getState().getBufferVariables(), &BufferVariable::name);
833             break;
834 
835         case GL_SHADER_STORAGE_BLOCK:
836             return program->getActiveShaderStorageBlockMaxNameLength();
837 
838         case GL_TRANSFORM_FEEDBACK_VARYING:
839             return clampCast<GLint>(program->getTransformFeedbackVaryingMaxLength());
840 
841         default:
842             UNREACHABLE();
843             return 0;
844     }
845     // This length includes an extra character for the null terminator.
846     return (maxNameLength == 0 ? 0 : maxNameLength + 1);
847 }
848 
QueryProgramInterfaceMaxNumActiveVariables(const Program * program,GLenum programInterface)849 GLint QueryProgramInterfaceMaxNumActiveVariables(const Program *program, GLenum programInterface)
850 {
851     switch (programInterface)
852     {
853         case GL_UNIFORM_BLOCK:
854             return FindMaxSize(program->getState().getUniformBlocks(),
855                                &InterfaceBlock::memberIndexes);
856         case GL_ATOMIC_COUNTER_BUFFER:
857             return FindMaxSize(program->getState().getAtomicCounterBuffers(),
858                                &AtomicCounterBuffer::memberIndexes);
859 
860         case GL_SHADER_STORAGE_BLOCK:
861             return FindMaxSize(program->getState().getShaderStorageBlocks(),
862                                &InterfaceBlock::memberIndexes);
863 
864         default:
865             UNREACHABLE();
866             return 0;
867     }
868 }
869 
GetUniformPropertyEnum(GLenum prop)870 GLenum GetUniformPropertyEnum(GLenum prop)
871 {
872     switch (prop)
873     {
874         case GL_UNIFORM_TYPE:
875             return GL_TYPE;
876         case GL_UNIFORM_SIZE:
877             return GL_ARRAY_SIZE;
878         case GL_UNIFORM_NAME_LENGTH:
879             return GL_NAME_LENGTH;
880         case GL_UNIFORM_BLOCK_INDEX:
881             return GL_BLOCK_INDEX;
882         case GL_UNIFORM_OFFSET:
883             return GL_OFFSET;
884         case GL_UNIFORM_ARRAY_STRIDE:
885             return GL_ARRAY_STRIDE;
886         case GL_UNIFORM_MATRIX_STRIDE:
887             return GL_MATRIX_STRIDE;
888         case GL_UNIFORM_IS_ROW_MAJOR:
889             return GL_IS_ROW_MAJOR;
890 
891         default:
892             return prop;
893     }
894 }
895 
GetUniformBlockPropertyEnum(GLenum prop)896 GLenum GetUniformBlockPropertyEnum(GLenum prop)
897 {
898     switch (prop)
899     {
900         case GL_UNIFORM_BLOCK_BINDING:
901             return GL_BUFFER_BINDING;
902 
903         case GL_UNIFORM_BLOCK_DATA_SIZE:
904             return GL_BUFFER_DATA_SIZE;
905 
906         case GL_UNIFORM_BLOCK_NAME_LENGTH:
907             return GL_NAME_LENGTH;
908 
909         case GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS:
910             return GL_NUM_ACTIVE_VARIABLES;
911 
912         case GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES:
913             return GL_ACTIVE_VARIABLES;
914 
915         case GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER:
916             return GL_REFERENCED_BY_VERTEX_SHADER;
917 
918         case GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER:
919             return GL_REFERENCED_BY_FRAGMENT_SHADER;
920 
921         default:
922             return prop;
923     }
924 }
925 
GetShaderVariableBufferResourceProperty(const ShaderVariableBuffer & buffer,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)926 void GetShaderVariableBufferResourceProperty(const ShaderVariableBuffer &buffer,
927                                              GLenum pname,
928                                              GLint *params,
929                                              GLsizei bufSize,
930                                              GLsizei *outputPosition)
931 
932 {
933     switch (pname)
934     {
935         case GL_BUFFER_BINDING:
936             params[(*outputPosition)++] = buffer.binding;
937             break;
938         case GL_BUFFER_DATA_SIZE:
939             params[(*outputPosition)++] = clampCast<GLint>(buffer.dataSize);
940             break;
941         case GL_NUM_ACTIVE_VARIABLES:
942             params[(*outputPosition)++] = buffer.numActiveVariables();
943             break;
944         case GL_ACTIVE_VARIABLES:
945             for (size_t memberIndex = 0;
946                  memberIndex < buffer.memberIndexes.size() && *outputPosition < bufSize;
947                  ++memberIndex)
948             {
949                 params[(*outputPosition)++] = clampCast<GLint>(buffer.memberIndexes[memberIndex]);
950             }
951             break;
952         case GL_REFERENCED_BY_VERTEX_SHADER:
953             params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Vertex));
954             break;
955         case GL_REFERENCED_BY_FRAGMENT_SHADER:
956             params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Fragment));
957             break;
958         case GL_REFERENCED_BY_COMPUTE_SHADER:
959             params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Compute));
960             break;
961         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
962             params[(*outputPosition)++] = static_cast<GLint>(buffer.isActive(ShaderType::Geometry));
963             break;
964         default:
965             UNREACHABLE();
966             break;
967     }
968 }
969 
GetInterfaceBlockResourceProperty(const InterfaceBlock & block,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)970 void GetInterfaceBlockResourceProperty(const InterfaceBlock &block,
971                                        GLenum pname,
972                                        GLint *params,
973                                        GLsizei bufSize,
974                                        GLsizei *outputPosition)
975 {
976     if (pname == GL_NAME_LENGTH)
977     {
978         params[(*outputPosition)++] = clampCast<GLint>(block.nameWithArrayIndex().size() + 1);
979         return;
980     }
981     GetShaderVariableBufferResourceProperty(block, pname, params, bufSize, outputPosition);
982 }
983 
GetUniformBlockResourceProperty(const Program * program,GLuint blockIndex,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)984 void GetUniformBlockResourceProperty(const Program *program,
985                                      GLuint blockIndex,
986                                      GLenum pname,
987                                      GLint *params,
988                                      GLsizei bufSize,
989                                      GLsizei *outputPosition)
990 
991 {
992     ASSERT(*outputPosition < bufSize);
993     const auto &block = program->getUniformBlockByIndex(blockIndex);
994     GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
995 }
996 
GetShaderStorageBlockResourceProperty(const Program * program,GLuint blockIndex,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)997 void GetShaderStorageBlockResourceProperty(const Program *program,
998                                            GLuint blockIndex,
999                                            GLenum pname,
1000                                            GLint *params,
1001                                            GLsizei bufSize,
1002                                            GLsizei *outputPosition)
1003 
1004 {
1005     ASSERT(*outputPosition < bufSize);
1006     const auto &block = program->getShaderStorageBlockByIndex(blockIndex);
1007     GetInterfaceBlockResourceProperty(block, pname, params, bufSize, outputPosition);
1008 }
1009 
GetAtomicCounterBufferResourceProperty(const Program * program,GLuint index,GLenum pname,GLint * params,GLsizei bufSize,GLsizei * outputPosition)1010 void GetAtomicCounterBufferResourceProperty(const Program *program,
1011                                             GLuint index,
1012                                             GLenum pname,
1013                                             GLint *params,
1014                                             GLsizei bufSize,
1015                                             GLsizei *outputPosition)
1016 
1017 {
1018     ASSERT(*outputPosition < bufSize);
1019     const auto &buffer = program->getState().getAtomicCounterBuffers()[index];
1020     GetShaderVariableBufferResourceProperty(buffer, pname, params, bufSize, outputPosition);
1021 }
1022 
IsTextureEnvEnumParameter(TextureEnvParameter pname)1023 bool IsTextureEnvEnumParameter(TextureEnvParameter pname)
1024 {
1025     switch (pname)
1026     {
1027         case TextureEnvParameter::Mode:
1028         case TextureEnvParameter::CombineRgb:
1029         case TextureEnvParameter::CombineAlpha:
1030         case TextureEnvParameter::Src0Rgb:
1031         case TextureEnvParameter::Src1Rgb:
1032         case TextureEnvParameter::Src2Rgb:
1033         case TextureEnvParameter::Src0Alpha:
1034         case TextureEnvParameter::Src1Alpha:
1035         case TextureEnvParameter::Src2Alpha:
1036         case TextureEnvParameter::Op0Rgb:
1037         case TextureEnvParameter::Op1Rgb:
1038         case TextureEnvParameter::Op2Rgb:
1039         case TextureEnvParameter::Op0Alpha:
1040         case TextureEnvParameter::Op1Alpha:
1041         case TextureEnvParameter::Op2Alpha:
1042         case TextureEnvParameter::PointCoordReplace:
1043             return true;
1044         default:
1045             return false;
1046     }
1047 }
1048 
1049 }  // namespace
1050 
QueryFramebufferAttachmentParameteriv(const Context * context,const Framebuffer * framebuffer,GLenum attachment,GLenum pname,GLint * params)1051 void QueryFramebufferAttachmentParameteriv(const Context *context,
1052                                            const Framebuffer *framebuffer,
1053                                            GLenum attachment,
1054                                            GLenum pname,
1055                                            GLint *params)
1056 {
1057     ASSERT(framebuffer);
1058 
1059     const FramebufferAttachment *attachmentObject = framebuffer->getAttachment(context, attachment);
1060 
1061     if (attachmentObject == nullptr)
1062     {
1063         // ES 2.0.25 spec pg 127 states that if the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE
1064         // is NONE, then querying any other pname will generate INVALID_ENUM.
1065 
1066         // ES 3.0.2 spec pg 235 states that if the attachment type is none,
1067         // GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero and be an
1068         // INVALID_OPERATION for all other pnames
1069 
1070         switch (pname)
1071         {
1072             case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
1073                 *params = GL_NONE;
1074                 break;
1075 
1076             case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
1077                 *params = 0;
1078                 break;
1079 
1080             default:
1081                 UNREACHABLE();
1082                 break;
1083         }
1084 
1085         return;
1086     }
1087 
1088     switch (pname)
1089     {
1090         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
1091             *params = attachmentObject->type();
1092             break;
1093 
1094         case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
1095             *params = attachmentObject->id();
1096             break;
1097 
1098         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
1099             *params = attachmentObject->mipLevel();
1100             break;
1101 
1102         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
1103         {
1104             TextureTarget face = attachmentObject->cubeMapFace();
1105             if (face != TextureTarget::InvalidEnum)
1106             {
1107                 *params = ToGLenum(attachmentObject->cubeMapFace());
1108             }
1109             else
1110             {
1111                 // This happens when the attachment isn't a texture cube map face
1112                 *params = GL_NONE;
1113             }
1114         }
1115         break;
1116 
1117         case GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
1118             *params = attachmentObject->getRedSize();
1119             break;
1120 
1121         case GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
1122             *params = attachmentObject->getGreenSize();
1123             break;
1124 
1125         case GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
1126             *params = attachmentObject->getBlueSize();
1127             break;
1128 
1129         case GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
1130             *params = attachmentObject->getAlphaSize();
1131             break;
1132 
1133         case GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
1134             *params = attachmentObject->getDepthSize();
1135             break;
1136 
1137         case GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
1138             *params = attachmentObject->getStencilSize();
1139             break;
1140 
1141         case GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
1142             *params = attachmentObject->getComponentType();
1143             break;
1144 
1145         case GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
1146             *params = attachmentObject->getColorEncoding();
1147             break;
1148 
1149         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
1150             *params = attachmentObject->layer();
1151             break;
1152 
1153         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_NUM_VIEWS_OVR:
1154             *params = attachmentObject->getNumViews();
1155             break;
1156 
1157         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_BASE_VIEW_INDEX_OVR:
1158             *params = attachmentObject->getBaseViewIndex();
1159             break;
1160 
1161         case GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT:
1162             *params = attachmentObject->isLayered();
1163             break;
1164 
1165         case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT:
1166             if (attachmentObject->type() == GL_TEXTURE)
1167             {
1168                 *params = attachmentObject->getSamples();
1169             }
1170             else
1171             {
1172                 *params = 0;
1173             }
1174             break;
1175 
1176         default:
1177             UNREACHABLE();
1178             break;
1179     }
1180 }
1181 
QueryBufferParameteriv(const Buffer * buffer,GLenum pname,GLint * params)1182 void QueryBufferParameteriv(const Buffer *buffer, GLenum pname, GLint *params)
1183 {
1184     QueryBufferParameterBase(buffer, pname, params);
1185 }
1186 
QueryBufferParameteri64v(const Buffer * buffer,GLenum pname,GLint64 * params)1187 void QueryBufferParameteri64v(const Buffer *buffer, GLenum pname, GLint64 *params)
1188 {
1189     QueryBufferParameterBase(buffer, pname, params);
1190 }
1191 
QueryBufferPointerv(const Buffer * buffer,GLenum pname,void ** params)1192 void QueryBufferPointerv(const Buffer *buffer, GLenum pname, void **params)
1193 {
1194     switch (pname)
1195     {
1196         case GL_BUFFER_MAP_POINTER:
1197             *params = buffer->getMapPointer();
1198             break;
1199 
1200         default:
1201             UNREACHABLE();
1202             break;
1203     }
1204 }
1205 
QueryProgramiv(Context * context,const Program * program,GLenum pname,GLint * params)1206 void QueryProgramiv(Context *context, const Program *program, GLenum pname, GLint *params)
1207 {
1208     ASSERT(program != nullptr || pname == GL_COMPLETION_STATUS_KHR);
1209 
1210     switch (pname)
1211     {
1212         case GL_DELETE_STATUS:
1213             *params = program->isFlaggedForDeletion();
1214             return;
1215         case GL_LINK_STATUS:
1216             *params = program->isLinked();
1217             return;
1218         case GL_COMPLETION_STATUS_KHR:
1219             if (context->isContextLost())
1220             {
1221                 *params = GL_TRUE;
1222             }
1223             else
1224             {
1225                 *params = program->isLinking() ? GL_FALSE : GL_TRUE;
1226             }
1227             return;
1228         case GL_VALIDATE_STATUS:
1229             *params = program->isValidated();
1230             return;
1231         case GL_INFO_LOG_LENGTH:
1232             *params = program->getExecutable().getInfoLogLength();
1233             return;
1234         case GL_ATTACHED_SHADERS:
1235             *params = program->getAttachedShadersCount();
1236             return;
1237         case GL_ACTIVE_ATTRIBUTES:
1238             *params = program->getActiveAttributeCount();
1239             return;
1240         case GL_ACTIVE_ATTRIBUTE_MAX_LENGTH:
1241             *params = program->getActiveAttributeMaxLength();
1242             return;
1243         case GL_ACTIVE_UNIFORMS:
1244             *params = program->getActiveUniformCount();
1245             return;
1246         case GL_ACTIVE_UNIFORM_MAX_LENGTH:
1247             *params = program->getActiveUniformMaxLength();
1248             return;
1249         case GL_PROGRAM_BINARY_LENGTH_OES:
1250             *params = context->getCaps().programBinaryFormats.empty()
1251                           ? 0
1252                           : program->getBinaryLength(context);
1253             return;
1254         case GL_ACTIVE_UNIFORM_BLOCKS:
1255             *params = program->getActiveUniformBlockCount();
1256             return;
1257         case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH:
1258             *params = program->getActiveUniformBlockMaxNameLength();
1259             break;
1260         case GL_TRANSFORM_FEEDBACK_BUFFER_MODE:
1261             *params = program->getTransformFeedbackBufferMode();
1262             break;
1263         case GL_TRANSFORM_FEEDBACK_VARYINGS:
1264             *params = clampCast<GLint>(program->getTransformFeedbackVaryingCount());
1265             break;
1266         case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH:
1267             *params = program->getTransformFeedbackVaryingMaxLength();
1268             break;
1269         case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
1270             *params = program->getBinaryRetrievableHint();
1271             break;
1272         case GL_PROGRAM_SEPARABLE:
1273             // From es31cSeparateShaderObjsTests.cpp:
1274             // ProgramParameteri PROGRAM_SEPARABLE
1275             // NOTE: The query for PROGRAM_SEPARABLE must query latched
1276             //       state. In other words, the state of the binary after
1277             //       it was linked. So in the tests below, the queries
1278             //       should return the default state GL_FALSE since the
1279             //       program has no linked binary.
1280             *params = program->isSeparable() && program->isLinked();
1281             break;
1282         case GL_COMPUTE_WORK_GROUP_SIZE:
1283         {
1284             const sh::WorkGroupSize &localSize = program->getComputeShaderLocalSize();
1285             params[0]                          = localSize[0];
1286             params[1]                          = localSize[1];
1287             params[2]                          = localSize[2];
1288         }
1289         break;
1290         case GL_ACTIVE_ATOMIC_COUNTER_BUFFERS:
1291             *params = program->getActiveAtomicCounterBufferCount();
1292             break;
1293         case GL_GEOMETRY_LINKED_INPUT_TYPE_EXT:
1294             *params = ToGLenum(program->getGeometryShaderInputPrimitiveType());
1295             break;
1296         case GL_GEOMETRY_LINKED_OUTPUT_TYPE_EXT:
1297             *params = ToGLenum(program->getGeometryShaderOutputPrimitiveType());
1298             break;
1299         case GL_GEOMETRY_LINKED_VERTICES_OUT_EXT:
1300             *params = program->getGeometryShaderMaxVertices();
1301             break;
1302         case GL_GEOMETRY_SHADER_INVOCATIONS_EXT:
1303             *params = program->getGeometryShaderInvocations();
1304             break;
1305         default:
1306             UNREACHABLE();
1307             break;
1308     }
1309 }
1310 
QueryRenderbufferiv(const Context * context,const Renderbuffer * renderbuffer,GLenum pname,GLint * params)1311 void QueryRenderbufferiv(const Context *context,
1312                          const Renderbuffer *renderbuffer,
1313                          GLenum pname,
1314                          GLint *params)
1315 {
1316     ASSERT(renderbuffer != nullptr);
1317 
1318     switch (pname)
1319     {
1320         case GL_RENDERBUFFER_WIDTH:
1321             *params = renderbuffer->getWidth();
1322             break;
1323         case GL_RENDERBUFFER_HEIGHT:
1324             *params = renderbuffer->getHeight();
1325             break;
1326         case GL_RENDERBUFFER_INTERNAL_FORMAT:
1327             // Special case the WebGL 1 DEPTH_STENCIL format.
1328             if (context->isWebGL1() &&
1329                 renderbuffer->getFormat().info->internalFormat == GL_DEPTH24_STENCIL8)
1330             {
1331                 *params = GL_DEPTH_STENCIL;
1332             }
1333             else
1334             {
1335                 *params = renderbuffer->getFormat().info->internalFormat;
1336             }
1337             break;
1338         case GL_RENDERBUFFER_RED_SIZE:
1339             *params = renderbuffer->getRedSize();
1340             break;
1341         case GL_RENDERBUFFER_GREEN_SIZE:
1342             *params = renderbuffer->getGreenSize();
1343             break;
1344         case GL_RENDERBUFFER_BLUE_SIZE:
1345             *params = renderbuffer->getBlueSize();
1346             break;
1347         case GL_RENDERBUFFER_ALPHA_SIZE:
1348             *params = renderbuffer->getAlphaSize();
1349             break;
1350         case GL_RENDERBUFFER_DEPTH_SIZE:
1351             *params = renderbuffer->getDepthSize();
1352             break;
1353         case GL_RENDERBUFFER_STENCIL_SIZE:
1354             *params = renderbuffer->getStencilSize();
1355             break;
1356         case GL_RENDERBUFFER_SAMPLES_ANGLE:
1357             *params = renderbuffer->getSamples();
1358             break;
1359         case GL_MEMORY_SIZE_ANGLE:
1360             *params = renderbuffer->getMemorySize();
1361             break;
1362         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1363             *params = static_cast<GLint>(renderbuffer->getImplementationColorReadFormat(context));
1364             break;
1365         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1366             *params = static_cast<GLint>(renderbuffer->getImplementationColorReadType(context));
1367             break;
1368         default:
1369             UNREACHABLE();
1370             break;
1371     }
1372 }
1373 
QueryShaderiv(const Context * context,Shader * shader,GLenum pname,GLint * params)1374 void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params)
1375 {
1376     ASSERT(shader != nullptr || pname == GL_COMPLETION_STATUS_KHR);
1377 
1378     switch (pname)
1379     {
1380         case GL_SHADER_TYPE:
1381             *params = static_cast<GLint>(ToGLenum(shader->getType()));
1382             return;
1383         case GL_DELETE_STATUS:
1384             *params = shader->isFlaggedForDeletion();
1385             return;
1386         case GL_COMPILE_STATUS:
1387             *params = shader->isCompiled() ? GL_TRUE : GL_FALSE;
1388             return;
1389         case GL_COMPLETION_STATUS_KHR:
1390             if (context->isContextLost())
1391             {
1392                 *params = GL_TRUE;
1393             }
1394             else
1395             {
1396                 *params = shader->isCompleted() ? GL_TRUE : GL_FALSE;
1397             }
1398             return;
1399         case GL_INFO_LOG_LENGTH:
1400             *params = shader->getInfoLogLength();
1401             return;
1402         case GL_SHADER_SOURCE_LENGTH:
1403             *params = shader->getSourceLength();
1404             return;
1405         case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
1406             *params = shader->getTranslatedSourceWithDebugInfoLength();
1407             return;
1408         default:
1409             UNREACHABLE();
1410             break;
1411     }
1412 }
1413 
QueryTexLevelParameterfv(const Texture * texture,TextureTarget target,GLint level,GLenum pname,GLfloat * params)1414 void QueryTexLevelParameterfv(const Texture *texture,
1415                               TextureTarget target,
1416                               GLint level,
1417                               GLenum pname,
1418                               GLfloat *params)
1419 {
1420     QueryTexLevelParameterBase(texture, target, level, pname, params);
1421 }
1422 
QueryTexLevelParameteriv(const Texture * texture,TextureTarget target,GLint level,GLenum pname,GLint * params)1423 void QueryTexLevelParameteriv(const Texture *texture,
1424                               TextureTarget target,
1425                               GLint level,
1426                               GLenum pname,
1427                               GLint *params)
1428 {
1429     QueryTexLevelParameterBase(texture, target, level, pname, params);
1430 }
1431 
QueryTexParameterfv(const Context * context,const Texture * texture,GLenum pname,GLfloat * params)1432 void QueryTexParameterfv(const Context *context,
1433                          const Texture *texture,
1434                          GLenum pname,
1435                          GLfloat *params)
1436 {
1437     QueryTexParameterBase<false, false>(context, texture, pname, params);
1438 }
1439 
QueryTexParameterxv(const Context * context,const Texture * texture,GLenum pname,GLfixed * params)1440 void QueryTexParameterxv(const Context *context,
1441                          const Texture *texture,
1442                          GLenum pname,
1443                          GLfixed *params)
1444 {
1445     QueryTexParameterBase<false, true>(context, texture, pname, params);
1446 }
1447 
QueryTexParameteriv(const Context * context,const Texture * texture,GLenum pname,GLint * params)1448 void QueryTexParameteriv(const Context *context,
1449                          const Texture *texture,
1450                          GLenum pname,
1451                          GLint *params)
1452 {
1453     QueryTexParameterBase<false, false>(context, texture, pname, params);
1454 }
1455 
QueryTexParameterIiv(const Context * context,const Texture * texture,GLenum pname,GLint * params)1456 void QueryTexParameterIiv(const Context *context,
1457                           const Texture *texture,
1458                           GLenum pname,
1459                           GLint *params)
1460 {
1461     QueryTexParameterBase<true, false>(context, texture, pname, params);
1462 }
1463 
QueryTexParameterIuiv(const Context * context,const Texture * texture,GLenum pname,GLuint * params)1464 void QueryTexParameterIuiv(const Context *context,
1465                            const Texture *texture,
1466                            GLenum pname,
1467                            GLuint *params)
1468 {
1469     QueryTexParameterBase<true, false>(context, texture, pname, params);
1470 }
1471 
QuerySamplerParameterfv(const Sampler * sampler,GLenum pname,GLfloat * params)1472 void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params)
1473 {
1474     QuerySamplerParameterBase<false>(sampler, pname, params);
1475 }
1476 
QuerySamplerParameteriv(const Sampler * sampler,GLenum pname,GLint * params)1477 void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params)
1478 {
1479     QuerySamplerParameterBase<false>(sampler, pname, params);
1480 }
1481 
QuerySamplerParameterIiv(const Sampler * sampler,GLenum pname,GLint * params)1482 void QuerySamplerParameterIiv(const Sampler *sampler, GLenum pname, GLint *params)
1483 {
1484     QuerySamplerParameterBase<true>(sampler, pname, params);
1485 }
1486 
QuerySamplerParameterIuiv(const Sampler * sampler,GLenum pname,GLuint * params)1487 void QuerySamplerParameterIuiv(const Sampler *sampler, GLenum pname, GLuint *params)
1488 {
1489     QuerySamplerParameterBase<true>(sampler, pname, params);
1490 }
1491 
QueryVertexAttribfv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLfloat * params)1492 void QueryVertexAttribfv(const VertexAttribute &attrib,
1493                          const VertexBinding &binding,
1494                          const VertexAttribCurrentValueData &currentValueData,
1495                          GLenum pname,
1496                          GLfloat *params)
1497 {
1498     QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
1499 }
1500 
QueryVertexAttribiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLint * params)1501 void QueryVertexAttribiv(const VertexAttribute &attrib,
1502                          const VertexBinding &binding,
1503                          const VertexAttribCurrentValueData &currentValueData,
1504                          GLenum pname,
1505                          GLint *params)
1506 {
1507     QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
1508 }
1509 
QueryVertexAttribPointerv(const VertexAttribute & attrib,GLenum pname,void ** pointer)1510 void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer)
1511 {
1512     switch (pname)
1513     {
1514         case GL_VERTEX_ATTRIB_ARRAY_POINTER:
1515             *pointer = const_cast<void *>(attrib.pointer);
1516             break;
1517 
1518         default:
1519             UNREACHABLE();
1520             break;
1521     }
1522 }
1523 
QueryVertexAttribIiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLint * params)1524 void QueryVertexAttribIiv(const VertexAttribute &attrib,
1525                           const VertexBinding &binding,
1526                           const VertexAttribCurrentValueData &currentValueData,
1527                           GLenum pname,
1528                           GLint *params)
1529 {
1530     QueryVertexAttribBase(attrib, binding, currentValueData.Values.IntValues, pname, params);
1531 }
1532 
QueryVertexAttribIuiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLuint * params)1533 void QueryVertexAttribIuiv(const VertexAttribute &attrib,
1534                            const VertexBinding &binding,
1535                            const VertexAttribCurrentValueData &currentValueData,
1536                            GLenum pname,
1537                            GLuint *params)
1538 {
1539     QueryVertexAttribBase(attrib, binding, currentValueData.Values.UnsignedIntValues, pname,
1540                           params);
1541 }
1542 
QueryActiveUniformBlockiv(const Program * program,GLuint uniformBlockIndex,GLenum pname,GLint * params)1543 void QueryActiveUniformBlockiv(const Program *program,
1544                                GLuint uniformBlockIndex,
1545                                GLenum pname,
1546                                GLint *params)
1547 {
1548     GLenum prop = GetUniformBlockPropertyEnum(pname);
1549     QueryProgramResourceiv(program, GL_UNIFORM_BLOCK, uniformBlockIndex, 1, &prop,
1550                            std::numeric_limits<GLsizei>::max(), nullptr, params);
1551 }
1552 
QueryInternalFormativ(const TextureCaps & format,GLenum pname,GLsizei bufSize,GLint * params)1553 void QueryInternalFormativ(const TextureCaps &format, GLenum pname, GLsizei bufSize, GLint *params)
1554 {
1555     switch (pname)
1556     {
1557         case GL_NUM_SAMPLE_COUNTS:
1558             if (bufSize != 0)
1559             {
1560                 *params = clampCast<GLint>(format.sampleCounts.size());
1561             }
1562             break;
1563 
1564         case GL_SAMPLES:
1565         {
1566             size_t returnCount   = std::min<size_t>(bufSize, format.sampleCounts.size());
1567             auto sampleReverseIt = format.sampleCounts.rbegin();
1568             for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex)
1569             {
1570                 params[sampleIndex] = *sampleReverseIt++;
1571             }
1572         }
1573         break;
1574 
1575         default:
1576             UNREACHABLE();
1577             break;
1578     }
1579 }
1580 
QueryFramebufferParameteriv(const Framebuffer * framebuffer,GLenum pname,GLint * params)1581 void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params)
1582 {
1583     ASSERT(framebuffer);
1584 
1585     switch (pname)
1586     {
1587         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1588             *params = framebuffer->getDefaultWidth();
1589             break;
1590         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1591             *params = framebuffer->getDefaultHeight();
1592             break;
1593         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1594             *params = framebuffer->getDefaultSamples();
1595             break;
1596         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1597             *params = ConvertToGLBoolean(framebuffer->getDefaultFixedSampleLocations());
1598             break;
1599         case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1600             *params = framebuffer->getDefaultLayers();
1601             break;
1602         default:
1603             UNREACHABLE();
1604             break;
1605     }
1606 }
1607 
QuerySynciv(const Context * context,const Sync * sync,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)1608 angle::Result QuerySynciv(const Context *context,
1609                           const Sync *sync,
1610                           GLenum pname,
1611                           GLsizei bufSize,
1612                           GLsizei *length,
1613                           GLint *values)
1614 {
1615     ASSERT(sync != nullptr || pname == GL_SYNC_STATUS);
1616 
1617     // All queries return one value, exit early if the buffer can't fit anything.
1618     if (bufSize < 1)
1619     {
1620         if (length != nullptr)
1621         {
1622             *length = 0;
1623         }
1624         return angle::Result::Continue;
1625     }
1626 
1627     switch (pname)
1628     {
1629         case GL_OBJECT_TYPE:
1630             *values = clampCast<GLint>(GL_SYNC_FENCE);
1631             break;
1632         case GL_SYNC_CONDITION:
1633             *values = clampCast<GLint>(sync->getCondition());
1634             break;
1635         case GL_SYNC_FLAGS:
1636             *values = clampCast<GLint>(sync->getFlags());
1637             break;
1638         case GL_SYNC_STATUS:
1639             if (context->isContextLost())
1640             {
1641                 *values = GL_SIGNALED;
1642             }
1643             else
1644             {
1645                 ANGLE_TRY(sync->getStatus(context, values));
1646             }
1647             break;
1648 
1649         default:
1650             UNREACHABLE();
1651             break;
1652     }
1653 
1654     if (length != nullptr)
1655     {
1656         *length = 1;
1657     }
1658 
1659     return angle::Result::Continue;
1660 }
1661 
SetTexParameterx(Context * context,Texture * texture,GLenum pname,GLfixed param)1662 void SetTexParameterx(Context *context, Texture *texture, GLenum pname, GLfixed param)
1663 {
1664     SetTexParameterBase<false, true>(context, texture, pname, &param);
1665 }
1666 
SetTexParameterxv(Context * context,Texture * texture,GLenum pname,const GLfixed * params)1667 void SetTexParameterxv(Context *context, Texture *texture, GLenum pname, const GLfixed *params)
1668 {
1669     SetTexParameterBase<false, true>(context, texture, pname, params);
1670 }
1671 
SetTexParameterf(Context * context,Texture * texture,GLenum pname,GLfloat param)1672 void SetTexParameterf(Context *context, Texture *texture, GLenum pname, GLfloat param)
1673 {
1674     SetTexParameterBase<false, false>(context, texture, pname, &param);
1675 }
1676 
SetTexParameterfv(Context * context,Texture * texture,GLenum pname,const GLfloat * params)1677 void SetTexParameterfv(Context *context, Texture *texture, GLenum pname, const GLfloat *params)
1678 {
1679     SetTexParameterBase<false, false>(context, texture, pname, params);
1680 }
1681 
SetTexParameteri(Context * context,Texture * texture,GLenum pname,GLint param)1682 void SetTexParameteri(Context *context, Texture *texture, GLenum pname, GLint param)
1683 {
1684     SetTexParameterBase<false, false>(context, texture, pname, &param);
1685 }
1686 
SetTexParameteriv(Context * context,Texture * texture,GLenum pname,const GLint * params)1687 void SetTexParameteriv(Context *context, Texture *texture, GLenum pname, const GLint *params)
1688 {
1689     SetTexParameterBase<false, false>(context, texture, pname, params);
1690 }
1691 
SetTexParameterIiv(Context * context,Texture * texture,GLenum pname,const GLint * params)1692 void SetTexParameterIiv(Context *context, Texture *texture, GLenum pname, const GLint *params)
1693 {
1694     SetTexParameterBase<true, false>(context, texture, pname, params);
1695 }
1696 
SetTexParameterIuiv(Context * context,Texture * texture,GLenum pname,const GLuint * params)1697 void SetTexParameterIuiv(Context *context, Texture *texture, GLenum pname, const GLuint *params)
1698 {
1699     SetTexParameterBase<true, false>(context, texture, pname, params);
1700 }
1701 
SetSamplerParameterf(Context * context,Sampler * sampler,GLenum pname,GLfloat param)1702 void SetSamplerParameterf(Context *context, Sampler *sampler, GLenum pname, GLfloat param)
1703 {
1704     SetSamplerParameterBase<false>(context, sampler, pname, &param);
1705 }
1706 
SetSamplerParameterfv(Context * context,Sampler * sampler,GLenum pname,const GLfloat * params)1707 void SetSamplerParameterfv(Context *context, Sampler *sampler, GLenum pname, const GLfloat *params)
1708 {
1709     SetSamplerParameterBase<false>(context, sampler, pname, params);
1710 }
1711 
SetSamplerParameteri(Context * context,Sampler * sampler,GLenum pname,GLint param)1712 void SetSamplerParameteri(Context *context, Sampler *sampler, GLenum pname, GLint param)
1713 {
1714     SetSamplerParameterBase<false>(context, sampler, pname, &param);
1715 }
1716 
SetSamplerParameteriv(Context * context,Sampler * sampler,GLenum pname,const GLint * params)1717 void SetSamplerParameteriv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
1718 {
1719     SetSamplerParameterBase<false>(context, sampler, pname, params);
1720 }
1721 
SetSamplerParameterIiv(Context * context,Sampler * sampler,GLenum pname,const GLint * params)1722 void SetSamplerParameterIiv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
1723 {
1724     SetSamplerParameterBase<true>(context, sampler, pname, params);
1725 }
1726 
SetSamplerParameterIuiv(Context * context,Sampler * sampler,GLenum pname,const GLuint * params)1727 void SetSamplerParameterIuiv(Context *context, Sampler *sampler, GLenum pname, const GLuint *params)
1728 {
1729     SetSamplerParameterBase<true>(context, sampler, pname, params);
1730 }
1731 
SetFramebufferParameteri(const Context * context,Framebuffer * framebuffer,GLenum pname,GLint param)1732 void SetFramebufferParameteri(const Context *context,
1733                               Framebuffer *framebuffer,
1734                               GLenum pname,
1735                               GLint param)
1736 {
1737     ASSERT(framebuffer);
1738 
1739     switch (pname)
1740     {
1741         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1742             framebuffer->setDefaultWidth(context, param);
1743             break;
1744         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1745             framebuffer->setDefaultHeight(context, param);
1746             break;
1747         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1748             framebuffer->setDefaultSamples(context, param);
1749             break;
1750         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1751             framebuffer->setDefaultFixedSampleLocations(context, ConvertToBool(param));
1752             break;
1753         case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1754             framebuffer->setDefaultLayers(param);
1755             break;
1756         default:
1757             UNREACHABLE();
1758             break;
1759     }
1760 }
1761 
SetProgramParameteri(Program * program,GLenum pname,GLint value)1762 void SetProgramParameteri(Program *program, GLenum pname, GLint value)
1763 {
1764     ASSERT(program);
1765 
1766     switch (pname)
1767     {
1768         case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
1769             program->setBinaryRetrievableHint(ConvertToBool(value));
1770             break;
1771         case GL_PROGRAM_SEPARABLE:
1772             program->setSeparable(ConvertToBool(value));
1773             break;
1774         default:
1775             UNREACHABLE();
1776             break;
1777     }
1778 }
1779 
GetUniformResourceProperty(const Program * program,GLuint index,const GLenum prop)1780 GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop)
1781 {
1782     const auto &uniform = program->getUniformByIndex(index);
1783     GLenum resourceProp = GetUniformPropertyEnum(prop);
1784     switch (resourceProp)
1785     {
1786         case GL_TYPE:
1787         case GL_ARRAY_SIZE:
1788         case GL_NAME_LENGTH:
1789             return GetCommonVariableProperty(uniform, resourceProp);
1790 
1791         case GL_LOCATION:
1792             return program->getUniformLocation(uniform.name).value;
1793 
1794         case GL_BLOCK_INDEX:
1795             return (uniform.isAtomicCounter() ? -1 : uniform.bufferIndex);
1796 
1797         case GL_OFFSET:
1798             return uniform.blockInfo.offset;
1799 
1800         case GL_ARRAY_STRIDE:
1801             return uniform.blockInfo.arrayStride;
1802 
1803         case GL_MATRIX_STRIDE:
1804             return uniform.blockInfo.matrixStride;
1805 
1806         case GL_IS_ROW_MAJOR:
1807             return static_cast<GLint>(uniform.blockInfo.isRowMajorMatrix);
1808 
1809         case GL_REFERENCED_BY_VERTEX_SHADER:
1810             return uniform.isActive(ShaderType::Vertex);
1811 
1812         case GL_REFERENCED_BY_FRAGMENT_SHADER:
1813             return uniform.isActive(ShaderType::Fragment);
1814 
1815         case GL_REFERENCED_BY_COMPUTE_SHADER:
1816             return uniform.isActive(ShaderType::Compute);
1817 
1818         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
1819             return uniform.isActive(ShaderType::Geometry);
1820 
1821         case GL_ATOMIC_COUNTER_BUFFER_INDEX:
1822             return (uniform.isAtomicCounter() ? uniform.bufferIndex : -1);
1823 
1824         default:
1825             UNREACHABLE();
1826             return 0;
1827     }
1828 }
1829 
GetBufferVariableResourceProperty(const Program * program,GLuint index,const GLenum prop)1830 GLint GetBufferVariableResourceProperty(const Program *program, GLuint index, const GLenum prop)
1831 {
1832     const BufferVariable &bufferVariable = program->getBufferVariableByIndex(index);
1833     switch (prop)
1834     {
1835         case GL_TYPE:
1836         case GL_ARRAY_SIZE:
1837         case GL_NAME_LENGTH:
1838             return GetCommonVariableProperty(bufferVariable, prop);
1839 
1840         case GL_BLOCK_INDEX:
1841             return bufferVariable.bufferIndex;
1842 
1843         case GL_OFFSET:
1844             return bufferVariable.blockInfo.offset;
1845 
1846         case GL_ARRAY_STRIDE:
1847             return bufferVariable.blockInfo.arrayStride;
1848 
1849         case GL_MATRIX_STRIDE:
1850             return bufferVariable.blockInfo.matrixStride;
1851 
1852         case GL_IS_ROW_MAJOR:
1853             return static_cast<GLint>(bufferVariable.blockInfo.isRowMajorMatrix);
1854 
1855         case GL_REFERENCED_BY_VERTEX_SHADER:
1856             return bufferVariable.isActive(ShaderType::Vertex);
1857 
1858         case GL_REFERENCED_BY_FRAGMENT_SHADER:
1859             return bufferVariable.isActive(ShaderType::Fragment);
1860 
1861         case GL_REFERENCED_BY_COMPUTE_SHADER:
1862             return bufferVariable.isActive(ShaderType::Compute);
1863 
1864         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
1865             return bufferVariable.isActive(ShaderType::Geometry);
1866 
1867         case GL_TOP_LEVEL_ARRAY_SIZE:
1868             return bufferVariable.topLevelArraySize;
1869 
1870         case GL_TOP_LEVEL_ARRAY_STRIDE:
1871             return bufferVariable.blockInfo.topLevelArrayStride;
1872 
1873         default:
1874             UNREACHABLE();
1875             return 0;
1876     }
1877 }
1878 
QueryProgramResourceIndex(const Program * program,GLenum programInterface,const GLchar * name)1879 GLuint QueryProgramResourceIndex(const Program *program,
1880                                  GLenum programInterface,
1881                                  const GLchar *name)
1882 {
1883     switch (programInterface)
1884     {
1885         case GL_PROGRAM_INPUT:
1886             return program->getInputResourceIndex(name);
1887 
1888         case GL_PROGRAM_OUTPUT:
1889             return program->getOutputResourceIndex(name);
1890 
1891         case GL_UNIFORM:
1892             return program->getState().getUniformIndexFromName(name);
1893 
1894         case GL_BUFFER_VARIABLE:
1895             return program->getState().getBufferVariableIndexFromName(name);
1896 
1897         case GL_SHADER_STORAGE_BLOCK:
1898             return program->getShaderStorageBlockIndex(name);
1899 
1900         case GL_UNIFORM_BLOCK:
1901             return program->getUniformBlockIndex(name);
1902 
1903         case GL_TRANSFORM_FEEDBACK_VARYING:
1904             return program->getTransformFeedbackVaryingResourceIndex(name);
1905 
1906         default:
1907             UNREACHABLE();
1908             return GL_INVALID_INDEX;
1909     }
1910 }
1911 
QueryProgramResourceName(const Program * program,GLenum programInterface,GLuint index,GLsizei bufSize,GLsizei * length,GLchar * name)1912 void QueryProgramResourceName(const Program *program,
1913                               GLenum programInterface,
1914                               GLuint index,
1915                               GLsizei bufSize,
1916                               GLsizei *length,
1917                               GLchar *name)
1918 {
1919     switch (programInterface)
1920     {
1921         case GL_PROGRAM_INPUT:
1922             program->getInputResourceName(index, bufSize, length, name);
1923             break;
1924 
1925         case GL_PROGRAM_OUTPUT:
1926             program->getOutputResourceName(index, bufSize, length, name);
1927             break;
1928 
1929         case GL_UNIFORM:
1930             program->getUniformResourceName(index, bufSize, length, name);
1931             break;
1932 
1933         case GL_BUFFER_VARIABLE:
1934             program->getBufferVariableResourceName(index, bufSize, length, name);
1935             break;
1936 
1937         case GL_SHADER_STORAGE_BLOCK:
1938             program->getActiveShaderStorageBlockName(index, bufSize, length, name);
1939             break;
1940 
1941         case GL_UNIFORM_BLOCK:
1942             program->getActiveUniformBlockName(index, bufSize, length, name);
1943             break;
1944 
1945         case GL_TRANSFORM_FEEDBACK_VARYING:
1946             program->getTransformFeedbackVarying(index, bufSize, length, nullptr, nullptr, name);
1947             break;
1948 
1949         default:
1950             UNREACHABLE();
1951     }
1952 }
1953 
QueryProgramResourceLocation(const Program * program,GLenum programInterface,const GLchar * name)1954 GLint QueryProgramResourceLocation(const Program *program,
1955                                    GLenum programInterface,
1956                                    const GLchar *name)
1957 {
1958     switch (programInterface)
1959     {
1960         case GL_PROGRAM_INPUT:
1961             return program->getInputResourceLocation(name);
1962 
1963         case GL_PROGRAM_OUTPUT:
1964             return program->getOutputResourceLocation(name);
1965 
1966         case GL_UNIFORM:
1967             return program->getUniformLocation(name).value;
1968 
1969         default:
1970             UNREACHABLE();
1971             return -1;
1972     }
1973 }
1974 
QueryProgramResourceiv(const Program * program,GLenum programInterface,GLuint index,GLsizei propCount,const GLenum * props,GLsizei bufSize,GLsizei * length,GLint * params)1975 void QueryProgramResourceiv(const Program *program,
1976                             GLenum programInterface,
1977                             GLuint index,
1978                             GLsizei propCount,
1979                             const GLenum *props,
1980                             GLsizei bufSize,
1981                             GLsizei *length,
1982                             GLint *params)
1983 {
1984     if (!program->isLinked())
1985     {
1986         return;
1987     }
1988 
1989     if (length != nullptr)
1990     {
1991         *length = 0;
1992     }
1993 
1994     if (bufSize == 0)
1995     {
1996         // No room to write the results
1997         return;
1998     }
1999 
2000     GLsizei pos = 0;
2001     for (GLsizei i = 0; i < propCount; i++)
2002     {
2003         switch (programInterface)
2004         {
2005             case GL_PROGRAM_INPUT:
2006                 params[i] = GetInputResourceProperty(program, index, props[i]);
2007                 ++pos;
2008                 break;
2009 
2010             case GL_PROGRAM_OUTPUT:
2011                 params[i] = GetOutputResourceProperty(program, index, props[i]);
2012                 ++pos;
2013                 break;
2014 
2015             case GL_UNIFORM:
2016                 params[i] = GetUniformResourceProperty(program, index, props[i]);
2017                 ++pos;
2018                 break;
2019 
2020             case GL_BUFFER_VARIABLE:
2021                 params[i] = GetBufferVariableResourceProperty(program, index, props[i]);
2022                 ++pos;
2023                 break;
2024 
2025             case GL_UNIFORM_BLOCK:
2026                 GetUniformBlockResourceProperty(program, index, props[i], params, bufSize, &pos);
2027                 break;
2028 
2029             case GL_SHADER_STORAGE_BLOCK:
2030                 GetShaderStorageBlockResourceProperty(program, index, props[i], params, bufSize,
2031                                                       &pos);
2032                 break;
2033 
2034             case GL_ATOMIC_COUNTER_BUFFER:
2035                 GetAtomicCounterBufferResourceProperty(program, index, props[i], params, bufSize,
2036                                                        &pos);
2037                 break;
2038 
2039             case GL_TRANSFORM_FEEDBACK_VARYING:
2040                 params[i] = GetTransformFeedbackVaryingResourceProperty(program, index, props[i]);
2041                 ++pos;
2042                 break;
2043 
2044             default:
2045                 UNREACHABLE();
2046                 params[i] = GL_INVALID_VALUE;
2047         }
2048         if (pos == bufSize)
2049         {
2050             // Most properties return one value, but GL_ACTIVE_VARIABLES returns an array of values.
2051             // This checks not to break buffer bounds for such case.
2052             break;
2053         }
2054     }
2055 
2056     if (length != nullptr)
2057     {
2058         *length = pos;
2059     }
2060 }
2061 
QueryProgramInterfaceiv(const Program * program,GLenum programInterface,GLenum pname,GLint * params)2062 void QueryProgramInterfaceiv(const Program *program,
2063                              GLenum programInterface,
2064                              GLenum pname,
2065                              GLint *params)
2066 {
2067     switch (pname)
2068     {
2069         case GL_ACTIVE_RESOURCES:
2070             *params = QueryProgramInterfaceActiveResources(program, programInterface);
2071             break;
2072 
2073         case GL_MAX_NAME_LENGTH:
2074             *params = QueryProgramInterfaceMaxNameLength(program, programInterface);
2075             break;
2076 
2077         case GL_MAX_NUM_ACTIVE_VARIABLES:
2078             *params = QueryProgramInterfaceMaxNumActiveVariables(program, programInterface);
2079             break;
2080 
2081         default:
2082             UNREACHABLE();
2083     }
2084 }
2085 
SetMemoryObjectParameteriv(const Context * context,MemoryObject * memoryObject,GLenum pname,const GLint * params)2086 angle::Result SetMemoryObjectParameteriv(const Context *context,
2087                                          MemoryObject *memoryObject,
2088                                          GLenum pname,
2089                                          const GLint *params)
2090 {
2091     switch (pname)
2092     {
2093         case GL_DEDICATED_MEMORY_OBJECT_EXT:
2094             ANGLE_TRY(memoryObject->setDedicatedMemory(context, ConvertToBool(params[0])));
2095             break;
2096 
2097         default:
2098             UNREACHABLE();
2099     }
2100 
2101     return angle::Result::Continue;
2102 }
2103 
QueryMemoryObjectParameteriv(const MemoryObject * memoryObject,GLenum pname,GLint * params)2104 void QueryMemoryObjectParameteriv(const MemoryObject *memoryObject, GLenum pname, GLint *params)
2105 {
2106     switch (pname)
2107     {
2108         case GL_DEDICATED_MEMORY_OBJECT_EXT:
2109             *params = memoryObject->isDedicatedMemory();
2110             break;
2111 
2112         default:
2113             UNREACHABLE();
2114     }
2115 }
2116 
ParamToVertexArrayType(GLenum param)2117 ClientVertexArrayType ParamToVertexArrayType(GLenum param)
2118 {
2119     switch (param)
2120     {
2121         case GL_VERTEX_ARRAY:
2122         case GL_VERTEX_ARRAY_BUFFER_BINDING:
2123         case GL_VERTEX_ARRAY_STRIDE:
2124         case GL_VERTEX_ARRAY_SIZE:
2125         case GL_VERTEX_ARRAY_TYPE:
2126         case GL_VERTEX_ARRAY_POINTER:
2127             return ClientVertexArrayType::Vertex;
2128         case GL_NORMAL_ARRAY:
2129         case GL_NORMAL_ARRAY_BUFFER_BINDING:
2130         case GL_NORMAL_ARRAY_STRIDE:
2131         case GL_NORMAL_ARRAY_TYPE:
2132         case GL_NORMAL_ARRAY_POINTER:
2133             return ClientVertexArrayType::Normal;
2134         case GL_COLOR_ARRAY:
2135         case GL_COLOR_ARRAY_BUFFER_BINDING:
2136         case GL_COLOR_ARRAY_STRIDE:
2137         case GL_COLOR_ARRAY_SIZE:
2138         case GL_COLOR_ARRAY_TYPE:
2139         case GL_COLOR_ARRAY_POINTER:
2140             return ClientVertexArrayType::Color;
2141         case GL_POINT_SIZE_ARRAY_OES:
2142         case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
2143         case GL_POINT_SIZE_ARRAY_STRIDE_OES:
2144         case GL_POINT_SIZE_ARRAY_TYPE_OES:
2145         case GL_POINT_SIZE_ARRAY_POINTER_OES:
2146             return ClientVertexArrayType::PointSize;
2147         case GL_TEXTURE_COORD_ARRAY:
2148         case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
2149         case GL_TEXTURE_COORD_ARRAY_STRIDE:
2150         case GL_TEXTURE_COORD_ARRAY_SIZE:
2151         case GL_TEXTURE_COORD_ARRAY_TYPE:
2152         case GL_TEXTURE_COORD_ARRAY_POINTER:
2153             return ClientVertexArrayType::TextureCoord;
2154         default:
2155             UNREACHABLE();
2156             return ClientVertexArrayType::InvalidEnum;
2157     }
2158 }
2159 
SetLightModelParameters(GLES1State * state,GLenum pname,const GLfloat * params)2160 void SetLightModelParameters(GLES1State *state, GLenum pname, const GLfloat *params)
2161 {
2162     LightModelParameters &lightModel = state->lightModelParameters();
2163 
2164     switch (pname)
2165     {
2166         case GL_LIGHT_MODEL_AMBIENT:
2167             lightModel.color = ColorF::fromData(params);
2168             break;
2169         case GL_LIGHT_MODEL_TWO_SIDE:
2170             lightModel.twoSided = *params == 1.0f ? true : false;
2171             break;
2172         default:
2173             break;
2174     }
2175 }
2176 
GetLightModelParameters(const GLES1State * state,GLenum pname,GLfloat * params)2177 void GetLightModelParameters(const GLES1State *state, GLenum pname, GLfloat *params)
2178 {
2179     const LightModelParameters &lightModel = state->lightModelParameters();
2180 
2181     switch (pname)
2182     {
2183         case GL_LIGHT_MODEL_TWO_SIDE:
2184             *params = lightModel.twoSided ? 1.0f : 0.0f;
2185             break;
2186         case GL_LIGHT_MODEL_AMBIENT:
2187             lightModel.color.writeData(params);
2188             break;
2189         default:
2190             break;
2191     }
2192 }
2193 
IsLightModelTwoSided(const GLES1State * state)2194 bool IsLightModelTwoSided(const GLES1State *state)
2195 {
2196     return state->lightModelParameters().twoSided;
2197 }
2198 
SetLightParameters(GLES1State * state,GLenum light,LightParameter pname,const GLfloat * params)2199 void SetLightParameters(GLES1State *state,
2200                         GLenum light,
2201                         LightParameter pname,
2202                         const GLfloat *params)
2203 {
2204     uint32_t lightIndex = light - GL_LIGHT0;
2205 
2206     LightParameters &lightParams = state->lightParameters(lightIndex);
2207 
2208     switch (pname)
2209     {
2210         case LightParameter::Ambient:
2211             lightParams.ambient = ColorF::fromData(params);
2212             break;
2213         case LightParameter::Diffuse:
2214             lightParams.diffuse = ColorF::fromData(params);
2215             break;
2216         case LightParameter::Specular:
2217             lightParams.specular = ColorF::fromData(params);
2218             break;
2219         case LightParameter::Position:
2220         {
2221             angle::Mat4 mv = state->getModelviewMatrix();
2222             angle::Vector4 transformedPos =
2223                 mv.product(angle::Vector4(params[0], params[1], params[2], params[3]));
2224             lightParams.position[0] = transformedPos[0];
2225             lightParams.position[1] = transformedPos[1];
2226             lightParams.position[2] = transformedPos[2];
2227             lightParams.position[3] = transformedPos[3];
2228         }
2229         break;
2230         case LightParameter::SpotDirection:
2231         {
2232             angle::Mat4 mv = state->getModelviewMatrix();
2233             angle::Vector4 transformedPos =
2234                 mv.product(angle::Vector4(params[0], params[1], params[2], 0.0f));
2235             lightParams.direction[0] = transformedPos[0];
2236             lightParams.direction[1] = transformedPos[1];
2237             lightParams.direction[2] = transformedPos[2];
2238         }
2239         break;
2240         case LightParameter::SpotExponent:
2241             lightParams.spotlightExponent = *params;
2242             break;
2243         case LightParameter::SpotCutoff:
2244             lightParams.spotlightCutoffAngle = *params;
2245             break;
2246         case LightParameter::ConstantAttenuation:
2247             lightParams.attenuationConst = *params;
2248             break;
2249         case LightParameter::LinearAttenuation:
2250             lightParams.attenuationLinear = *params;
2251             break;
2252         case LightParameter::QuadraticAttenuation:
2253             lightParams.attenuationQuadratic = *params;
2254             break;
2255         default:
2256             return;
2257     }
2258 }
2259 
GetLightParameters(const GLES1State * state,GLenum light,LightParameter pname,GLfloat * params)2260 void GetLightParameters(const GLES1State *state,
2261                         GLenum light,
2262                         LightParameter pname,
2263                         GLfloat *params)
2264 {
2265     uint32_t lightIndex                = light - GL_LIGHT0;
2266     const LightParameters &lightParams = state->lightParameters(lightIndex);
2267 
2268     switch (pname)
2269     {
2270         case LightParameter::Ambient:
2271             lightParams.ambient.writeData(params);
2272             break;
2273         case LightParameter::Diffuse:
2274             lightParams.diffuse.writeData(params);
2275             break;
2276         case LightParameter::Specular:
2277             lightParams.specular.writeData(params);
2278             break;
2279         case LightParameter::Position:
2280             memcpy(params, lightParams.position.data(), 4 * sizeof(GLfloat));
2281             break;
2282         case LightParameter::SpotDirection:
2283             memcpy(params, lightParams.direction.data(), 3 * sizeof(GLfloat));
2284             break;
2285         case LightParameter::SpotExponent:
2286             *params = lightParams.spotlightExponent;
2287             break;
2288         case LightParameter::SpotCutoff:
2289             *params = lightParams.spotlightCutoffAngle;
2290             break;
2291         case LightParameter::ConstantAttenuation:
2292             *params = lightParams.attenuationConst;
2293             break;
2294         case LightParameter::LinearAttenuation:
2295             *params = lightParams.attenuationLinear;
2296             break;
2297         case LightParameter::QuadraticAttenuation:
2298             *params = lightParams.attenuationQuadratic;
2299             break;
2300         default:
2301             break;
2302     }
2303 }
2304 
SetMaterialParameters(GLES1State * state,GLenum face,MaterialParameter pname,const GLfloat * params)2305 void SetMaterialParameters(GLES1State *state,
2306                            GLenum face,
2307                            MaterialParameter pname,
2308                            const GLfloat *params)
2309 {
2310     MaterialParameters &material = state->materialParameters();
2311     switch (pname)
2312     {
2313         case MaterialParameter::Ambient:
2314             material.ambient = ColorF::fromData(params);
2315             break;
2316         case MaterialParameter::Diffuse:
2317             material.diffuse = ColorF::fromData(params);
2318             break;
2319         case MaterialParameter::AmbientAndDiffuse:
2320             material.ambient = ColorF::fromData(params);
2321             material.diffuse = ColorF::fromData(params);
2322             break;
2323         case MaterialParameter::Specular:
2324             material.specular = ColorF::fromData(params);
2325             break;
2326         case MaterialParameter::Emission:
2327             material.emissive = ColorF::fromData(params);
2328             break;
2329         case MaterialParameter::Shininess:
2330             material.specularExponent = *params;
2331             break;
2332         default:
2333             return;
2334     }
2335 }
2336 
GetMaterialParameters(const GLES1State * state,GLenum face,MaterialParameter pname,GLfloat * params)2337 void GetMaterialParameters(const GLES1State *state,
2338                            GLenum face,
2339                            MaterialParameter pname,
2340                            GLfloat *params)
2341 {
2342     const ColorF &currentColor         = state->getCurrentColor();
2343     const MaterialParameters &material = state->materialParameters();
2344     const bool colorMaterialEnabled    = state->isColorMaterialEnabled();
2345 
2346     switch (pname)
2347     {
2348         case MaterialParameter::Ambient:
2349             if (colorMaterialEnabled)
2350             {
2351                 currentColor.writeData(params);
2352             }
2353             else
2354             {
2355                 material.ambient.writeData(params);
2356             }
2357             break;
2358         case MaterialParameter::Diffuse:
2359             if (colorMaterialEnabled)
2360             {
2361                 currentColor.writeData(params);
2362             }
2363             else
2364             {
2365                 material.diffuse.writeData(params);
2366             }
2367             break;
2368         case MaterialParameter::Specular:
2369             material.specular.writeData(params);
2370             break;
2371         case MaterialParameter::Emission:
2372             material.emissive.writeData(params);
2373             break;
2374         case MaterialParameter::Shininess:
2375             *params = material.specularExponent;
2376             break;
2377         default:
2378             return;
2379     }
2380 }
2381 
GetLightModelParameterCount(GLenum pname)2382 unsigned int GetLightModelParameterCount(GLenum pname)
2383 {
2384     switch (pname)
2385     {
2386         case GL_LIGHT_MODEL_AMBIENT:
2387             return 4;
2388         case GL_LIGHT_MODEL_TWO_SIDE:
2389             return 1;
2390         default:
2391             return 0;
2392     }
2393 }
2394 
GetLightParameterCount(LightParameter pname)2395 unsigned int GetLightParameterCount(LightParameter pname)
2396 {
2397     switch (pname)
2398     {
2399         case LightParameter::Ambient:
2400         case LightParameter::Diffuse:
2401         case LightParameter::Specular:
2402         case LightParameter::Position:
2403             return 4;
2404         case LightParameter::SpotDirection:
2405             return 3;
2406         case LightParameter::SpotExponent:
2407         case LightParameter::SpotCutoff:
2408         case LightParameter::ConstantAttenuation:
2409         case LightParameter::LinearAttenuation:
2410         case LightParameter::QuadraticAttenuation:
2411             return 1;
2412         default:
2413             return 0;
2414     }
2415 }
2416 
GetMaterialParameterCount(MaterialParameter pname)2417 unsigned int GetMaterialParameterCount(MaterialParameter pname)
2418 {
2419     switch (pname)
2420     {
2421         case MaterialParameter::Ambient:
2422         case MaterialParameter::Diffuse:
2423         case MaterialParameter::Specular:
2424         case MaterialParameter::Emission:
2425             return 4;
2426         case MaterialParameter::Shininess:
2427             return 1;
2428         default:
2429             return 0;
2430     }
2431 }
2432 
SetFogParameters(GLES1State * state,GLenum pname,const GLfloat * params)2433 void SetFogParameters(GLES1State *state, GLenum pname, const GLfloat *params)
2434 {
2435     FogParameters &fog = state->fogParameters();
2436     switch (pname)
2437     {
2438         case GL_FOG_MODE:
2439             fog.mode = FromGLenum<FogMode>(static_cast<GLenum>(params[0]));
2440             break;
2441         case GL_FOG_DENSITY:
2442             fog.density = params[0];
2443             break;
2444         case GL_FOG_START:
2445             fog.start = params[0];
2446             break;
2447         case GL_FOG_END:
2448             fog.end = params[0];
2449             break;
2450         case GL_FOG_COLOR:
2451             fog.color = ColorF::fromData(params);
2452             break;
2453         default:
2454             return;
2455     }
2456 }
2457 
GetFogParameters(const GLES1State * state,GLenum pname,GLfloat * params)2458 void GetFogParameters(const GLES1State *state, GLenum pname, GLfloat *params)
2459 {
2460     const FogParameters &fog = state->fogParameters();
2461     switch (pname)
2462     {
2463         case GL_FOG_MODE:
2464             params[0] = static_cast<GLfloat>(ToGLenum(fog.mode));
2465             break;
2466         case GL_FOG_DENSITY:
2467             params[0] = fog.density;
2468             break;
2469         case GL_FOG_START:
2470             params[0] = fog.start;
2471             break;
2472         case GL_FOG_END:
2473             params[0] = fog.end;
2474             break;
2475         case GL_FOG_COLOR:
2476             fog.color.writeData(params);
2477             break;
2478         default:
2479             return;
2480     }
2481 }
2482 
GetFogParameterCount(GLenum pname)2483 unsigned int GetFogParameterCount(GLenum pname)
2484 {
2485     switch (pname)
2486     {
2487         case GL_FOG_MODE:
2488         case GL_FOG_DENSITY:
2489         case GL_FOG_START:
2490         case GL_FOG_END:
2491             return 1;
2492         case GL_FOG_COLOR:
2493             return 4;
2494         default:
2495             return 0;
2496     }
2497 }
2498 
GetTextureEnvParameterCount(TextureEnvParameter pname)2499 unsigned int GetTextureEnvParameterCount(TextureEnvParameter pname)
2500 {
2501     switch (pname)
2502     {
2503         case TextureEnvParameter::Mode:
2504         case TextureEnvParameter::CombineRgb:
2505         case TextureEnvParameter::CombineAlpha:
2506         case TextureEnvParameter::Src0Rgb:
2507         case TextureEnvParameter::Src1Rgb:
2508         case TextureEnvParameter::Src2Rgb:
2509         case TextureEnvParameter::Src0Alpha:
2510         case TextureEnvParameter::Src1Alpha:
2511         case TextureEnvParameter::Src2Alpha:
2512         case TextureEnvParameter::Op0Rgb:
2513         case TextureEnvParameter::Op1Rgb:
2514         case TextureEnvParameter::Op2Rgb:
2515         case TextureEnvParameter::Op0Alpha:
2516         case TextureEnvParameter::Op1Alpha:
2517         case TextureEnvParameter::Op2Alpha:
2518         case TextureEnvParameter::RgbScale:
2519         case TextureEnvParameter::AlphaScale:
2520         case TextureEnvParameter::PointCoordReplace:
2521             return 1;
2522         case TextureEnvParameter::Color:
2523             return 4;
2524         default:
2525             return 0;
2526     }
2527 }
2528 
ConvertTextureEnvFromInt(TextureEnvParameter pname,const GLint * input,GLfloat * output)2529 void ConvertTextureEnvFromInt(TextureEnvParameter pname, const GLint *input, GLfloat *output)
2530 {
2531     if (IsTextureEnvEnumParameter(pname))
2532     {
2533         ConvertGLenumValue(input[0], output);
2534         return;
2535     }
2536 
2537     switch (pname)
2538     {
2539         case TextureEnvParameter::RgbScale:
2540         case TextureEnvParameter::AlphaScale:
2541             output[0] = static_cast<GLfloat>(input[0]);
2542             break;
2543         case TextureEnvParameter::Color:
2544             for (int i = 0; i < 4; i++)
2545             {
2546                 output[i] = input[i] / 255.0f;
2547             }
2548             break;
2549         default:
2550             UNREACHABLE();
2551             break;
2552     }
2553 }
2554 
ConvertTextureEnvFromFixed(TextureEnvParameter pname,const GLfixed * input,GLfloat * output)2555 void ConvertTextureEnvFromFixed(TextureEnvParameter pname, const GLfixed *input, GLfloat *output)
2556 {
2557     if (IsTextureEnvEnumParameter(pname))
2558     {
2559         ConvertGLenumValue(input[0], output);
2560         return;
2561     }
2562 
2563     switch (pname)
2564     {
2565         case TextureEnvParameter::RgbScale:
2566         case TextureEnvParameter::AlphaScale:
2567             output[0] = ConvertFixedToFloat(input[0]);
2568             break;
2569         case TextureEnvParameter::Color:
2570             for (int i = 0; i < 4; i++)
2571             {
2572                 output[i] = ConvertFixedToFloat(input[i]);
2573             }
2574             break;
2575         default:
2576             UNREACHABLE();
2577             break;
2578     }
2579 }
2580 
ConvertTextureEnvToInt(TextureEnvParameter pname,const GLfloat * input,GLint * output)2581 void ConvertTextureEnvToInt(TextureEnvParameter pname, const GLfloat *input, GLint *output)
2582 {
2583     if (IsTextureEnvEnumParameter(pname))
2584     {
2585         ConvertGLenumValue(input[0], output);
2586         return;
2587     }
2588 
2589     switch (pname)
2590     {
2591         case TextureEnvParameter::RgbScale:
2592         case TextureEnvParameter::AlphaScale:
2593             output[0] = static_cast<GLint>(input[0]);
2594             break;
2595         case TextureEnvParameter::Color:
2596             for (int i = 0; i < 4; i++)
2597             {
2598                 output[i] = static_cast<GLint>(input[i] * 255.0f);
2599             }
2600             break;
2601         default:
2602             UNREACHABLE();
2603             break;
2604     }
2605 }
2606 
ConvertTextureEnvToFixed(TextureEnvParameter pname,const GLfloat * input,GLfixed * output)2607 void ConvertTextureEnvToFixed(TextureEnvParameter pname, const GLfloat *input, GLfixed *output)
2608 {
2609     if (IsTextureEnvEnumParameter(pname))
2610     {
2611         ConvertGLenumValue(input[0], output);
2612         return;
2613     }
2614 
2615     switch (pname)
2616     {
2617         case TextureEnvParameter::RgbScale:
2618         case TextureEnvParameter::AlphaScale:
2619             output[0] = ConvertFloatToFixed(input[0]);
2620             break;
2621         case TextureEnvParameter::Color:
2622             for (int i = 0; i < 4; i++)
2623             {
2624                 output[i] = ConvertFloatToFixed(input[i]);
2625             }
2626             break;
2627         default:
2628             UNREACHABLE();
2629             break;
2630     }
2631 }
2632 
SetTextureEnv(unsigned int unit,GLES1State * state,TextureEnvTarget target,TextureEnvParameter pname,const GLfloat * params)2633 void SetTextureEnv(unsigned int unit,
2634                    GLES1State *state,
2635                    TextureEnvTarget target,
2636                    TextureEnvParameter pname,
2637                    const GLfloat *params)
2638 {
2639     TextureEnvironmentParameters &env = state->textureEnvironment(unit);
2640     GLenum asEnum                     = ConvertToGLenum(params[0]);
2641 
2642     switch (target)
2643     {
2644         case TextureEnvTarget::Env:
2645             switch (pname)
2646             {
2647                 case TextureEnvParameter::Mode:
2648                     env.mode = FromGLenum<TextureEnvMode>(asEnum);
2649                     break;
2650                 case TextureEnvParameter::CombineRgb:
2651                     env.combineRgb = FromGLenum<TextureCombine>(asEnum);
2652                     break;
2653                 case TextureEnvParameter::CombineAlpha:
2654                     env.combineAlpha = FromGLenum<TextureCombine>(asEnum);
2655                     break;
2656                 case TextureEnvParameter::Src0Rgb:
2657                     env.src0Rgb = FromGLenum<TextureSrc>(asEnum);
2658                     break;
2659                 case TextureEnvParameter::Src1Rgb:
2660                     env.src1Rgb = FromGLenum<TextureSrc>(asEnum);
2661                     break;
2662                 case TextureEnvParameter::Src2Rgb:
2663                     env.src2Rgb = FromGLenum<TextureSrc>(asEnum);
2664                     break;
2665                 case TextureEnvParameter::Src0Alpha:
2666                     env.src0Alpha = FromGLenum<TextureSrc>(asEnum);
2667                     break;
2668                 case TextureEnvParameter::Src1Alpha:
2669                     env.src1Alpha = FromGLenum<TextureSrc>(asEnum);
2670                     break;
2671                 case TextureEnvParameter::Src2Alpha:
2672                     env.src2Alpha = FromGLenum<TextureSrc>(asEnum);
2673                     break;
2674                 case TextureEnvParameter::Op0Rgb:
2675                     env.op0Rgb = FromGLenum<TextureOp>(asEnum);
2676                     break;
2677                 case TextureEnvParameter::Op1Rgb:
2678                     env.op1Rgb = FromGLenum<TextureOp>(asEnum);
2679                     break;
2680                 case TextureEnvParameter::Op2Rgb:
2681                     env.op2Rgb = FromGLenum<TextureOp>(asEnum);
2682                     break;
2683                 case TextureEnvParameter::Op0Alpha:
2684                     env.op0Alpha = FromGLenum<TextureOp>(asEnum);
2685                     break;
2686                 case TextureEnvParameter::Op1Alpha:
2687                     env.op1Alpha = FromGLenum<TextureOp>(asEnum);
2688                     break;
2689                 case TextureEnvParameter::Op2Alpha:
2690                     env.op2Alpha = FromGLenum<TextureOp>(asEnum);
2691                     break;
2692                 case TextureEnvParameter::Color:
2693                     env.color = ColorF::fromData(params);
2694                     break;
2695                 case TextureEnvParameter::RgbScale:
2696                     env.rgbScale = params[0];
2697                     break;
2698                 case TextureEnvParameter::AlphaScale:
2699                     env.alphaScale = params[0];
2700                     break;
2701                 default:
2702                     UNREACHABLE();
2703                     break;
2704             }
2705             break;
2706         case TextureEnvTarget::PointSprite:
2707             switch (pname)
2708             {
2709                 case TextureEnvParameter::PointCoordReplace:
2710                     env.pointSpriteCoordReplace = static_cast<bool>(params[0]);
2711                     break;
2712                 default:
2713                     UNREACHABLE();
2714                     break;
2715             }
2716             break;
2717         default:
2718             UNREACHABLE();
2719             break;
2720     }
2721 }
2722 
GetTextureEnv(unsigned int unit,const GLES1State * state,TextureEnvTarget target,TextureEnvParameter pname,GLfloat * params)2723 void GetTextureEnv(unsigned int unit,
2724                    const GLES1State *state,
2725                    TextureEnvTarget target,
2726                    TextureEnvParameter pname,
2727                    GLfloat *params)
2728 {
2729     const TextureEnvironmentParameters &env = state->textureEnvironment(unit);
2730 
2731     switch (target)
2732     {
2733         case TextureEnvTarget::Env:
2734             switch (pname)
2735             {
2736                 case TextureEnvParameter::Mode:
2737                     ConvertPackedEnum(env.mode, params);
2738                     break;
2739                 case TextureEnvParameter::CombineRgb:
2740                     ConvertPackedEnum(env.combineRgb, params);
2741                     break;
2742                 case TextureEnvParameter::CombineAlpha:
2743                     ConvertPackedEnum(env.combineAlpha, params);
2744                     break;
2745                 case TextureEnvParameter::Src0Rgb:
2746                     ConvertPackedEnum(env.src0Rgb, params);
2747                     break;
2748                 case TextureEnvParameter::Src1Rgb:
2749                     ConvertPackedEnum(env.src1Rgb, params);
2750                     break;
2751                 case TextureEnvParameter::Src2Rgb:
2752                     ConvertPackedEnum(env.src2Rgb, params);
2753                     break;
2754                 case TextureEnvParameter::Src0Alpha:
2755                     ConvertPackedEnum(env.src0Alpha, params);
2756                     break;
2757                 case TextureEnvParameter::Src1Alpha:
2758                     ConvertPackedEnum(env.src1Alpha, params);
2759                     break;
2760                 case TextureEnvParameter::Src2Alpha:
2761                     ConvertPackedEnum(env.src2Alpha, params);
2762                     break;
2763                 case TextureEnvParameter::Op0Rgb:
2764                     ConvertPackedEnum(env.op0Rgb, params);
2765                     break;
2766                 case TextureEnvParameter::Op1Rgb:
2767                     ConvertPackedEnum(env.op1Rgb, params);
2768                     break;
2769                 case TextureEnvParameter::Op2Rgb:
2770                     ConvertPackedEnum(env.op2Rgb, params);
2771                     break;
2772                 case TextureEnvParameter::Op0Alpha:
2773                     ConvertPackedEnum(env.op0Alpha, params);
2774                     break;
2775                 case TextureEnvParameter::Op1Alpha:
2776                     ConvertPackedEnum(env.op1Alpha, params);
2777                     break;
2778                 case TextureEnvParameter::Op2Alpha:
2779                     ConvertPackedEnum(env.op2Alpha, params);
2780                     break;
2781                 case TextureEnvParameter::Color:
2782                     env.color.writeData(params);
2783                     break;
2784                 case TextureEnvParameter::RgbScale:
2785                     *params = env.rgbScale;
2786                     break;
2787                 case TextureEnvParameter::AlphaScale:
2788                     *params = env.alphaScale;
2789                     break;
2790                 default:
2791                     UNREACHABLE();
2792                     break;
2793             }
2794             break;
2795         case TextureEnvTarget::PointSprite:
2796             switch (pname)
2797             {
2798                 case TextureEnvParameter::PointCoordReplace:
2799                     *params = static_cast<GLfloat>(env.pointSpriteCoordReplace);
2800                     break;
2801                 default:
2802                     UNREACHABLE();
2803                     break;
2804             }
2805             break;
2806         default:
2807             UNREACHABLE();
2808             break;
2809     }
2810 }
2811 
GetPointParameterCount(PointParameter pname)2812 unsigned int GetPointParameterCount(PointParameter pname)
2813 {
2814     switch (pname)
2815     {
2816         case PointParameter::PointSizeMin:
2817         case PointParameter::PointSizeMax:
2818         case PointParameter::PointFadeThresholdSize:
2819             return 1;
2820         case PointParameter::PointDistanceAttenuation:
2821             return 3;
2822         default:
2823             return 0;
2824     }
2825 }
2826 
SetPointParameter(GLES1State * state,PointParameter pname,const GLfloat * params)2827 void SetPointParameter(GLES1State *state, PointParameter pname, const GLfloat *params)
2828 {
2829 
2830     PointParameters &pointParams = state->pointParameters();
2831 
2832     switch (pname)
2833     {
2834         case PointParameter::PointSizeMin:
2835             pointParams.pointSizeMin = params[0];
2836             break;
2837         case PointParameter::PointSizeMax:
2838             pointParams.pointSizeMax = params[0];
2839             break;
2840         case PointParameter::PointFadeThresholdSize:
2841             pointParams.pointFadeThresholdSize = params[0];
2842             break;
2843         case PointParameter::PointDistanceAttenuation:
2844             for (unsigned int i = 0; i < 3; i++)
2845             {
2846                 pointParams.pointDistanceAttenuation[i] = params[i];
2847             }
2848             break;
2849         default:
2850             UNREACHABLE();
2851     }
2852 }
2853 
GetPointParameter(const GLES1State * state,PointParameter pname,GLfloat * params)2854 void GetPointParameter(const GLES1State *state, PointParameter pname, GLfloat *params)
2855 {
2856     const PointParameters &pointParams = state->pointParameters();
2857 
2858     switch (pname)
2859     {
2860         case PointParameter::PointSizeMin:
2861             params[0] = pointParams.pointSizeMin;
2862             break;
2863         case PointParameter::PointSizeMax:
2864             params[0] = pointParams.pointSizeMax;
2865             break;
2866         case PointParameter::PointFadeThresholdSize:
2867             params[0] = pointParams.pointFadeThresholdSize;
2868             break;
2869         case PointParameter::PointDistanceAttenuation:
2870             for (unsigned int i = 0; i < 3; i++)
2871             {
2872                 params[i] = pointParams.pointDistanceAttenuation[i];
2873             }
2874             break;
2875         default:
2876             UNREACHABLE();
2877     }
2878 }
2879 
SetPointSize(GLES1State * state,GLfloat size)2880 void SetPointSize(GLES1State *state, GLfloat size)
2881 {
2882     PointParameters &params = state->pointParameters();
2883     params.pointSize        = size;
2884 }
2885 
GetPointSize(const GLES1State * state,GLfloat * sizeOut)2886 void GetPointSize(const GLES1State *state, GLfloat *sizeOut)
2887 {
2888     const PointParameters &params = state->pointParameters();
2889     *sizeOut                      = params.pointSize;
2890 }
2891 
GetTexParameterCount(GLenum pname)2892 unsigned int GetTexParameterCount(GLenum pname)
2893 {
2894     switch (pname)
2895     {
2896         case GL_TEXTURE_CROP_RECT_OES:
2897         case GL_TEXTURE_BORDER_COLOR:
2898             return 4;
2899         case GL_TEXTURE_MAG_FILTER:
2900         case GL_TEXTURE_MIN_FILTER:
2901         case GL_TEXTURE_WRAP_S:
2902         case GL_TEXTURE_WRAP_T:
2903         case GL_TEXTURE_USAGE_ANGLE:
2904         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
2905         case GL_TEXTURE_IMMUTABLE_FORMAT:
2906         case GL_TEXTURE_WRAP_R:
2907         case GL_TEXTURE_IMMUTABLE_LEVELS:
2908         case GL_TEXTURE_SWIZZLE_R:
2909         case GL_TEXTURE_SWIZZLE_G:
2910         case GL_TEXTURE_SWIZZLE_B:
2911         case GL_TEXTURE_SWIZZLE_A:
2912         case GL_TEXTURE_BASE_LEVEL:
2913         case GL_TEXTURE_MAX_LEVEL:
2914         case GL_TEXTURE_MIN_LOD:
2915         case GL_TEXTURE_MAX_LOD:
2916         case GL_TEXTURE_COMPARE_MODE:
2917         case GL_TEXTURE_COMPARE_FUNC:
2918         case GL_TEXTURE_SRGB_DECODE_EXT:
2919         case GL_DEPTH_STENCIL_TEXTURE_MODE:
2920         case GL_TEXTURE_NATIVE_ID_ANGLE:
2921             return 1;
2922         default:
2923             return 0;
2924     }
2925 }
2926 
GetQueryParameterInfo(const State & glState,GLenum pname,GLenum * type,unsigned int * numParams)2927 bool GetQueryParameterInfo(const State &glState,
2928                            GLenum pname,
2929                            GLenum *type,
2930                            unsigned int *numParams)
2931 {
2932     const Caps &caps             = glState.getCaps();
2933     const Extensions &extensions = glState.getExtensions();
2934     GLint clientMajorVersion     = glState.getClientMajorVersion();
2935 
2936     // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
2937     // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
2938     // to the fact that it is stored internally as a float, and so would require conversion
2939     // if returned from Context::getIntegerv. Since this conversion is already implemented
2940     // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
2941     // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
2942     // application.
2943     switch (pname)
2944     {
2945         case GL_COMPRESSED_TEXTURE_FORMATS:
2946         {
2947             *type      = GL_INT;
2948             *numParams = static_cast<unsigned int>(caps.compressedTextureFormats.size());
2949             return true;
2950         }
2951         case GL_SHADER_BINARY_FORMATS:
2952         {
2953             *type      = GL_INT;
2954             *numParams = static_cast<unsigned int>(caps.shaderBinaryFormats.size());
2955             return true;
2956         }
2957 
2958         case GL_MAX_VERTEX_ATTRIBS:
2959         case GL_MAX_VERTEX_UNIFORM_VECTORS:
2960         case GL_MAX_VARYING_VECTORS:
2961         case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
2962         case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
2963         case GL_MAX_TEXTURE_IMAGE_UNITS:
2964         case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
2965         case GL_MAX_RENDERBUFFER_SIZE:
2966         case GL_NUM_SHADER_BINARY_FORMATS:
2967         case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
2968         case GL_ARRAY_BUFFER_BINDING:
2969         case GL_FRAMEBUFFER_BINDING:  // GL_FRAMEBUFFER_BINDING now equivalent to
2970                                       // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE
2971         case GL_RENDERBUFFER_BINDING:
2972         case GL_CURRENT_PROGRAM:
2973         case GL_PACK_ALIGNMENT:
2974         case GL_UNPACK_ALIGNMENT:
2975         case GL_GENERATE_MIPMAP_HINT:
2976         case GL_RED_BITS:
2977         case GL_GREEN_BITS:
2978         case GL_BLUE_BITS:
2979         case GL_ALPHA_BITS:
2980         case GL_DEPTH_BITS:
2981         case GL_STENCIL_BITS:
2982         case GL_ELEMENT_ARRAY_BUFFER_BINDING:
2983         case GL_CULL_FACE_MODE:
2984         case GL_FRONT_FACE:
2985         case GL_ACTIVE_TEXTURE:
2986         case GL_STENCIL_FUNC:
2987         case GL_STENCIL_VALUE_MASK:
2988         case GL_STENCIL_REF:
2989         case GL_STENCIL_FAIL:
2990         case GL_STENCIL_PASS_DEPTH_FAIL:
2991         case GL_STENCIL_PASS_DEPTH_PASS:
2992         case GL_STENCIL_BACK_FUNC:
2993         case GL_STENCIL_BACK_VALUE_MASK:
2994         case GL_STENCIL_BACK_REF:
2995         case GL_STENCIL_BACK_FAIL:
2996         case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
2997         case GL_STENCIL_BACK_PASS_DEPTH_PASS:
2998         case GL_DEPTH_FUNC:
2999         case GL_BLEND_SRC_RGB:
3000         case GL_BLEND_SRC_ALPHA:
3001         case GL_BLEND_DST_RGB:
3002         case GL_BLEND_DST_ALPHA:
3003         case GL_BLEND_EQUATION_RGB:
3004         case GL_BLEND_EQUATION_ALPHA:
3005         case GL_STENCIL_WRITEMASK:
3006         case GL_STENCIL_BACK_WRITEMASK:
3007         case GL_STENCIL_CLEAR_VALUE:
3008         case GL_SUBPIXEL_BITS:
3009         case GL_MAX_TEXTURE_SIZE:
3010         case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
3011         case GL_SAMPLE_BUFFERS:
3012         case GL_SAMPLES:
3013         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
3014         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
3015         case GL_TEXTURE_BINDING_2D:
3016         case GL_TEXTURE_BINDING_CUBE_MAP:
3017         case GL_RESET_NOTIFICATION_STRATEGY_EXT:
3018         {
3019             *type      = GL_INT;
3020             *numParams = 1;
3021             return true;
3022         }
3023         case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
3024         {
3025             if (!extensions.packReverseRowOrder)
3026             {
3027                 return false;
3028             }
3029             *type      = GL_INT;
3030             *numParams = 1;
3031             return true;
3032         }
3033         case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
3034         case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
3035         {
3036             if (!extensions.textureRectangle)
3037             {
3038                 return false;
3039             }
3040             *type      = GL_INT;
3041             *numParams = 1;
3042             return true;
3043         }
3044         case GL_MAX_DRAW_BUFFERS_EXT:
3045         case GL_MAX_COLOR_ATTACHMENTS_EXT:
3046         {
3047             if ((clientMajorVersion < 3) && !extensions.drawBuffers)
3048             {
3049                 return false;
3050             }
3051             *type      = GL_INT;
3052             *numParams = 1;
3053             return true;
3054         }
3055         case GL_MAX_VIEWPORT_DIMS:
3056         {
3057             *type      = GL_INT;
3058             *numParams = 2;
3059             return true;
3060         }
3061         case GL_VIEWPORT:
3062         case GL_SCISSOR_BOX:
3063         {
3064             *type      = GL_INT;
3065             *numParams = 4;
3066             return true;
3067         }
3068         case GL_SHADER_COMPILER:
3069         case GL_SAMPLE_COVERAGE_INVERT:
3070         case GL_DEPTH_WRITEMASK:
3071         case GL_CULL_FACE:                 // CULL_FACE through DITHER are natural to IsEnabled,
3072         case GL_POLYGON_OFFSET_FILL:       // but can be retrieved through the Get{Type}v queries.
3073         case GL_SAMPLE_ALPHA_TO_COVERAGE:  // For this purpose, they are treated here as
3074                                            // bool-natural
3075         case GL_SAMPLE_COVERAGE:
3076         case GL_SCISSOR_TEST:
3077         case GL_STENCIL_TEST:
3078         case GL_DEPTH_TEST:
3079         case GL_BLEND:
3080         case GL_DITHER:
3081         case GL_CONTEXT_ROBUST_ACCESS_EXT:
3082         {
3083             *type      = GL_BOOL;
3084             *numParams = 1;
3085             return true;
3086         }
3087         case GL_COLOR_WRITEMASK:
3088         {
3089             *type      = GL_BOOL;
3090             *numParams = 4;
3091             return true;
3092         }
3093         case GL_POLYGON_OFFSET_FACTOR:
3094         case GL_POLYGON_OFFSET_UNITS:
3095         case GL_SAMPLE_COVERAGE_VALUE:
3096         case GL_DEPTH_CLEAR_VALUE:
3097         case GL_LINE_WIDTH:
3098         {
3099             *type      = GL_FLOAT;
3100             *numParams = 1;
3101             return true;
3102         }
3103         case GL_ALIASED_LINE_WIDTH_RANGE:
3104         case GL_ALIASED_POINT_SIZE_RANGE:
3105         case GL_DEPTH_RANGE:
3106         {
3107             *type      = GL_FLOAT;
3108             *numParams = 2;
3109             return true;
3110         }
3111         case GL_COLOR_CLEAR_VALUE:
3112         case GL_BLEND_COLOR:
3113         {
3114             *type      = GL_FLOAT;
3115             *numParams = 4;
3116             return true;
3117         }
3118         case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
3119             if (!extensions.textureFilterAnisotropic)
3120             {
3121                 return false;
3122             }
3123             *type      = GL_FLOAT;
3124             *numParams = 1;
3125             return true;
3126         case GL_TIMESTAMP_EXT:
3127             if (!extensions.disjointTimerQuery)
3128             {
3129                 return false;
3130             }
3131             *type      = GL_INT_64_ANGLEX;
3132             *numParams = 1;
3133             return true;
3134         case GL_GPU_DISJOINT_EXT:
3135             if (!extensions.disjointTimerQuery)
3136             {
3137                 return false;
3138             }
3139             *type      = GL_INT;
3140             *numParams = 1;
3141             return true;
3142         case GL_COVERAGE_MODULATION_CHROMIUM:
3143             if (!extensions.framebufferMixedSamples)
3144             {
3145                 return false;
3146             }
3147             *type      = GL_INT;
3148             *numParams = 1;
3149             return true;
3150         case GL_TEXTURE_BINDING_EXTERNAL_OES:
3151             if (!extensions.eglStreamConsumerExternalNV && !extensions.eglImageExternalOES)
3152             {
3153                 return false;
3154             }
3155             *type      = GL_INT;
3156             *numParams = 1;
3157             return true;
3158     }
3159 
3160     if (glState.getClientType() == EGL_OPENGL_API)
3161     {
3162         switch (pname)
3163         {
3164             case GL_CONTEXT_FLAGS:
3165             case GL_CONTEXT_PROFILE_MASK:
3166             {
3167                 *type      = GL_INT;
3168                 *numParams = 1;
3169                 return true;
3170             }
3171         }
3172     }
3173 
3174     if (extensions.debug)
3175     {
3176         switch (pname)
3177         {
3178             case GL_DEBUG_LOGGED_MESSAGES:
3179             case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
3180             case GL_DEBUG_GROUP_STACK_DEPTH:
3181             case GL_MAX_DEBUG_MESSAGE_LENGTH:
3182             case GL_MAX_DEBUG_LOGGED_MESSAGES:
3183             case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
3184             case GL_MAX_LABEL_LENGTH:
3185                 *type      = GL_INT;
3186                 *numParams = 1;
3187                 return true;
3188 
3189             case GL_DEBUG_OUTPUT_SYNCHRONOUS:
3190             case GL_DEBUG_OUTPUT:
3191                 *type      = GL_BOOL;
3192                 *numParams = 1;
3193                 return true;
3194         }
3195     }
3196 
3197     if (extensions.multisampleCompatibility)
3198     {
3199         switch (pname)
3200         {
3201             case GL_MULTISAMPLE_EXT:
3202             case GL_SAMPLE_ALPHA_TO_ONE_EXT:
3203                 *type      = GL_BOOL;
3204                 *numParams = 1;
3205                 return true;
3206         }
3207     }
3208 
3209     if (extensions.bindGeneratesResource)
3210     {
3211         switch (pname)
3212         {
3213             case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
3214                 *type      = GL_BOOL;
3215                 *numParams = 1;
3216                 return true;
3217         }
3218     }
3219 
3220     if (extensions.clientArrays)
3221     {
3222         switch (pname)
3223         {
3224             case GL_CLIENT_ARRAYS_ANGLE:
3225                 *type      = GL_BOOL;
3226                 *numParams = 1;
3227                 return true;
3228         }
3229     }
3230 
3231     if (extensions.sRGBWriteControl)
3232     {
3233         switch (pname)
3234         {
3235             case GL_FRAMEBUFFER_SRGB_EXT:
3236                 *type      = GL_BOOL;
3237                 *numParams = 1;
3238                 return true;
3239         }
3240     }
3241 
3242     if (extensions.robustResourceInitialization && pname == GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE)
3243     {
3244         *type      = GL_BOOL;
3245         *numParams = 1;
3246         return true;
3247     }
3248 
3249     if (extensions.programCacheControl && pname == GL_PROGRAM_CACHE_ENABLED_ANGLE)
3250     {
3251         *type      = GL_BOOL;
3252         *numParams = 1;
3253         return true;
3254     }
3255 
3256     if (extensions.parallelShaderCompile && pname == GL_MAX_SHADER_COMPILER_THREADS_KHR)
3257     {
3258         *type      = GL_INT;
3259         *numParams = 1;
3260         return true;
3261     }
3262 
3263     if (extensions.blendFuncExtended && pname == GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT)
3264     {
3265         *type      = GL_INT;
3266         *numParams = 1;
3267         return true;
3268     }
3269 
3270     // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
3271     switch (pname)
3272     {
3273         // GL_DRAW_FRAMEBUFFER_BINDING_ANGLE equivalent to FRAMEBUFFER_BINDING
3274         case GL_READ_FRAMEBUFFER_BINDING_ANGLE:
3275             if ((clientMajorVersion < 3) && !extensions.framebufferBlit)
3276             {
3277                 return false;
3278             }
3279             *type      = GL_INT;
3280             *numParams = 1;
3281             return true;
3282 
3283         case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
3284             if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES)
3285             {
3286                 return false;
3287             }
3288             *type      = GL_INT;
3289             *numParams = 1;
3290             return true;
3291 
3292         case GL_PROGRAM_BINARY_FORMATS_OES:
3293             if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES)
3294             {
3295                 return false;
3296             }
3297             *type      = GL_INT;
3298             *numParams = static_cast<unsigned int>(caps.programBinaryFormats.size());
3299             return true;
3300 
3301         case GL_PACK_ROW_LENGTH:
3302         case GL_PACK_SKIP_ROWS:
3303         case GL_PACK_SKIP_PIXELS:
3304             if ((clientMajorVersion < 3) && !extensions.packSubimage)
3305             {
3306                 return false;
3307             }
3308             *type      = GL_INT;
3309             *numParams = 1;
3310             return true;
3311         case GL_UNPACK_ROW_LENGTH:
3312         case GL_UNPACK_SKIP_ROWS:
3313         case GL_UNPACK_SKIP_PIXELS:
3314             if ((clientMajorVersion < 3) && !extensions.unpackSubimage)
3315             {
3316                 return false;
3317             }
3318             *type      = GL_INT;
3319             *numParams = 1;
3320             return true;
3321         case GL_VERTEX_ARRAY_BINDING:
3322             if ((clientMajorVersion < 3) && !extensions.vertexArrayObjectOES)
3323             {
3324                 return false;
3325             }
3326             *type      = GL_INT;
3327             *numParams = 1;
3328             return true;
3329         case GL_PIXEL_PACK_BUFFER_BINDING:
3330         case GL_PIXEL_UNPACK_BUFFER_BINDING:
3331             if ((clientMajorVersion < 3) && !extensions.pixelBufferObjectNV)
3332             {
3333                 return false;
3334             }
3335             *type      = GL_INT;
3336             *numParams = 1;
3337             return true;
3338         case GL_MAX_SAMPLES:
3339         {
3340             static_assert(GL_MAX_SAMPLES_ANGLE == GL_MAX_SAMPLES,
3341                           "GL_MAX_SAMPLES_ANGLE not equal to GL_MAX_SAMPLES");
3342             if ((clientMajorVersion < 3) &&
3343                 !(extensions.framebufferMultisample || extensions.multisampledRenderToTexture))
3344             {
3345                 return false;
3346             }
3347             *type      = GL_INT;
3348             *numParams = 1;
3349             return true;
3350 
3351             case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
3352                 if ((clientMajorVersion < 3) && !extensions.standardDerivativesOES)
3353                 {
3354                     return false;
3355                 }
3356                 *type      = GL_INT;
3357                 *numParams = 1;
3358                 return true;
3359         }
3360         case GL_TEXTURE_BINDING_3D:
3361             if ((clientMajorVersion < 3) && !extensions.texture3DOES)
3362             {
3363                 return false;
3364             }
3365             *type      = GL_INT;
3366             *numParams = 1;
3367             return true;
3368         case GL_MAX_3D_TEXTURE_SIZE:
3369             if ((clientMajorVersion < 3) && !extensions.texture3DOES)
3370             {
3371                 return false;
3372             }
3373             *type      = GL_INT;
3374             *numParams = 1;
3375             return true;
3376     }
3377 
3378     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
3379     {
3380         if ((glState.getClientVersion() < Version(3, 0)) && !extensions.drawBuffers)
3381         {
3382             return false;
3383         }
3384         *type      = GL_INT;
3385         *numParams = 1;
3386         return true;
3387     }
3388 
3389     if ((extensions.multiview2 || extensions.multiview) && pname == GL_MAX_VIEWS_OVR)
3390     {
3391         *type      = GL_INT;
3392         *numParams = 1;
3393         return true;
3394     }
3395 
3396     if (glState.getClientVersion() < Version(2, 0))
3397     {
3398         switch (pname)
3399         {
3400             case GL_ALPHA_TEST_FUNC:
3401             case GL_CLIENT_ACTIVE_TEXTURE:
3402             case GL_MATRIX_MODE:
3403             case GL_MAX_TEXTURE_UNITS:
3404             case GL_MAX_MODELVIEW_STACK_DEPTH:
3405             case GL_MAX_PROJECTION_STACK_DEPTH:
3406             case GL_MAX_TEXTURE_STACK_DEPTH:
3407             case GL_MAX_LIGHTS:
3408             case GL_MAX_CLIP_PLANES:
3409             case GL_VERTEX_ARRAY_STRIDE:
3410             case GL_NORMAL_ARRAY_STRIDE:
3411             case GL_COLOR_ARRAY_STRIDE:
3412             case GL_TEXTURE_COORD_ARRAY_STRIDE:
3413             case GL_VERTEX_ARRAY_SIZE:
3414             case GL_COLOR_ARRAY_SIZE:
3415             case GL_TEXTURE_COORD_ARRAY_SIZE:
3416             case GL_VERTEX_ARRAY_TYPE:
3417             case GL_NORMAL_ARRAY_TYPE:
3418             case GL_COLOR_ARRAY_TYPE:
3419             case GL_TEXTURE_COORD_ARRAY_TYPE:
3420             case GL_VERTEX_ARRAY_BUFFER_BINDING:
3421             case GL_NORMAL_ARRAY_BUFFER_BINDING:
3422             case GL_COLOR_ARRAY_BUFFER_BINDING:
3423             case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
3424             case GL_POINT_SIZE_ARRAY_STRIDE_OES:
3425             case GL_POINT_SIZE_ARRAY_TYPE_OES:
3426             case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
3427             case GL_SHADE_MODEL:
3428             case GL_MODELVIEW_STACK_DEPTH:
3429             case GL_PROJECTION_STACK_DEPTH:
3430             case GL_TEXTURE_STACK_DEPTH:
3431             case GL_LOGIC_OP_MODE:
3432             case GL_BLEND_SRC:
3433             case GL_BLEND_DST:
3434             case GL_PERSPECTIVE_CORRECTION_HINT:
3435             case GL_POINT_SMOOTH_HINT:
3436             case GL_LINE_SMOOTH_HINT:
3437             case GL_FOG_HINT:
3438                 *type      = GL_INT;
3439                 *numParams = 1;
3440                 return true;
3441             case GL_ALPHA_TEST_REF:
3442             case GL_FOG_DENSITY:
3443             case GL_FOG_START:
3444             case GL_FOG_END:
3445             case GL_FOG_MODE:
3446             case GL_POINT_SIZE:
3447             case GL_POINT_SIZE_MIN:
3448             case GL_POINT_SIZE_MAX:
3449             case GL_POINT_FADE_THRESHOLD_SIZE:
3450                 *type      = GL_FLOAT;
3451                 *numParams = 1;
3452                 return true;
3453             case GL_SMOOTH_POINT_SIZE_RANGE:
3454             case GL_SMOOTH_LINE_WIDTH_RANGE:
3455                 *type      = GL_FLOAT;
3456                 *numParams = 2;
3457                 return true;
3458             case GL_CURRENT_COLOR:
3459             case GL_CURRENT_TEXTURE_COORDS:
3460             case GL_LIGHT_MODEL_AMBIENT:
3461             case GL_FOG_COLOR:
3462                 *type      = GL_FLOAT;
3463                 *numParams = 4;
3464                 return true;
3465             case GL_CURRENT_NORMAL:
3466             case GL_POINT_DISTANCE_ATTENUATION:
3467                 *type      = GL_FLOAT;
3468                 *numParams = 3;
3469                 return true;
3470             case GL_MODELVIEW_MATRIX:
3471             case GL_PROJECTION_MATRIX:
3472             case GL_TEXTURE_MATRIX:
3473                 *type      = GL_FLOAT;
3474                 *numParams = 16;
3475                 return true;
3476             case GL_LIGHT_MODEL_TWO_SIDE:
3477                 *type      = GL_BOOL;
3478                 *numParams = 1;
3479                 return true;
3480         }
3481     }
3482 
3483     if (glState.getClientVersion() < Version(3, 0))
3484     {
3485         return false;
3486     }
3487 
3488     // Check for ES3.0+ parameter names
3489     switch (pname)
3490     {
3491         case GL_MAX_UNIFORM_BUFFER_BINDINGS:
3492         case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
3493         case GL_UNIFORM_BUFFER_BINDING:
3494         case GL_TRANSFORM_FEEDBACK_BINDING:
3495         case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
3496         case GL_COPY_READ_BUFFER_BINDING:
3497         case GL_COPY_WRITE_BUFFER_BINDING:
3498         case GL_SAMPLER_BINDING:
3499         case GL_READ_BUFFER:
3500         case GL_TEXTURE_BINDING_3D:
3501         case GL_TEXTURE_BINDING_2D_ARRAY:
3502         case GL_MAX_ARRAY_TEXTURE_LAYERS:
3503         case GL_MAX_VERTEX_UNIFORM_BLOCKS:
3504         case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
3505         case GL_MAX_COMBINED_UNIFORM_BLOCKS:
3506         case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
3507         case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
3508         case GL_MAX_VARYING_COMPONENTS:
3509         case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
3510         case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
3511         case GL_MIN_PROGRAM_TEXEL_OFFSET:
3512         case GL_MAX_PROGRAM_TEXEL_OFFSET:
3513         case GL_NUM_EXTENSIONS:
3514         case GL_MAJOR_VERSION:
3515         case GL_MINOR_VERSION:
3516         case GL_MAX_ELEMENTS_INDICES:
3517         case GL_MAX_ELEMENTS_VERTICES:
3518         case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
3519         case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
3520         case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
3521         case GL_UNPACK_IMAGE_HEIGHT:
3522         case GL_UNPACK_SKIP_IMAGES:
3523         {
3524             *type      = GL_INT;
3525             *numParams = 1;
3526             return true;
3527         }
3528 
3529         case GL_MAX_ELEMENT_INDEX:
3530         case GL_MAX_UNIFORM_BLOCK_SIZE:
3531         case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
3532         case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
3533         case GL_MAX_SERVER_WAIT_TIMEOUT:
3534         {
3535             *type      = GL_INT_64_ANGLEX;
3536             *numParams = 1;
3537             return true;
3538         }
3539 
3540         case GL_TRANSFORM_FEEDBACK_ACTIVE:
3541         case GL_TRANSFORM_FEEDBACK_PAUSED:
3542         case GL_PRIMITIVE_RESTART_FIXED_INDEX:
3543         case GL_RASTERIZER_DISCARD:
3544         {
3545             *type      = GL_BOOL;
3546             *numParams = 1;
3547             return true;
3548         }
3549 
3550         case GL_MAX_TEXTURE_LOD_BIAS:
3551         {
3552             *type      = GL_FLOAT;
3553             *numParams = 1;
3554             return true;
3555         }
3556     }
3557 
3558     if (extensions.requestExtension)
3559     {
3560         switch (pname)
3561         {
3562             case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE:
3563                 *type      = GL_INT;
3564                 *numParams = 1;
3565                 return true;
3566         }
3567     }
3568 
3569     if (extensions.textureMultisample)
3570     {
3571         switch (pname)
3572         {
3573             case GL_MAX_COLOR_TEXTURE_SAMPLES_ANGLE:
3574             case GL_MAX_INTEGER_SAMPLES_ANGLE:
3575             case GL_MAX_DEPTH_TEXTURE_SAMPLES_ANGLE:
3576             case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ANGLE:
3577             case GL_MAX_SAMPLE_MASK_WORDS:
3578                 *type      = GL_INT;
3579                 *numParams = 1;
3580                 return true;
3581         }
3582     }
3583 
3584     if (glState.getClientVersion() < Version(3, 1))
3585     {
3586         return false;
3587     }
3588 
3589     // Check for ES3.1+ parameter names
3590     switch (pname)
3591     {
3592         case GL_ATOMIC_COUNTER_BUFFER_BINDING:
3593         case GL_DRAW_INDIRECT_BUFFER_BINDING:
3594         case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
3595         case GL_MAX_FRAMEBUFFER_WIDTH:
3596         case GL_MAX_FRAMEBUFFER_HEIGHT:
3597         case GL_MAX_FRAMEBUFFER_SAMPLES:
3598         case GL_MAX_SAMPLE_MASK_WORDS:
3599         case GL_MAX_COLOR_TEXTURE_SAMPLES:
3600         case GL_MAX_DEPTH_TEXTURE_SAMPLES:
3601         case GL_MAX_INTEGER_SAMPLES:
3602         case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
3603         case GL_MAX_VERTEX_ATTRIB_BINDINGS:
3604         case GL_MAX_VERTEX_ATTRIB_STRIDE:
3605         case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
3606         case GL_MAX_VERTEX_ATOMIC_COUNTERS:
3607         case GL_MAX_VERTEX_IMAGE_UNIFORMS:
3608         case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
3609         case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
3610         case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
3611         case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
3612         case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
3613         case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
3614         case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
3615         case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
3616         case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
3617         case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
3618         case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
3619         case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
3620         case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
3621         case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
3622         case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
3623         case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
3624         case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
3625         case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
3626         case GL_MAX_UNIFORM_LOCATIONS:
3627         case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
3628         case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
3629         case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
3630         case GL_MAX_COMBINED_ATOMIC_COUNTERS:
3631         case GL_MAX_IMAGE_UNITS:
3632         case GL_MAX_COMBINED_IMAGE_UNIFORMS:
3633         case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
3634         case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
3635         case GL_SHADER_STORAGE_BUFFER_BINDING:
3636         case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
3637         case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
3638         case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
3639         case GL_PROGRAM_PIPELINE_BINDING:
3640             *type      = GL_INT;
3641             *numParams = 1;
3642             return true;
3643         case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
3644             *type      = GL_INT_64_ANGLEX;
3645             *numParams = 1;
3646             return true;
3647         case GL_SAMPLE_MASK:
3648             *type      = GL_BOOL;
3649             *numParams = 1;
3650             return true;
3651     }
3652 
3653     if (extensions.geometryShader)
3654     {
3655         switch (pname)
3656         {
3657             case GL_MAX_FRAMEBUFFER_LAYERS_EXT:
3658             case GL_LAYER_PROVOKING_VERTEX_EXT:
3659             case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT:
3660             case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT:
3661             case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT:
3662             case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT:
3663             case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT:
3664             case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT:
3665             case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT:
3666             case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT:
3667             case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT:
3668             case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT:
3669             case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT:
3670             case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT:
3671             case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT:
3672                 *type      = GL_INT;
3673                 *numParams = 1;
3674                 return true;
3675         }
3676     }
3677 
3678     return false;
3679 }
3680 
QueryProgramPipelineiv(const Context * context,ProgramPipeline * programPipeline,GLenum pname,GLint * params)3681 void QueryProgramPipelineiv(const Context *context,
3682                             ProgramPipeline *programPipeline,
3683                             GLenum pname,
3684                             GLint *params)
3685 {
3686     if (!params)
3687     {
3688         // Can't write the result anywhere, so just return immediately.
3689         return;
3690     }
3691 
3692     switch (pname)
3693     {
3694         case GL_ACTIVE_PROGRAM:
3695         {
3696             // the name of the active program object of the program pipeline object is returned in
3697             // params
3698             *params = 0;
3699             if (programPipeline)
3700             {
3701                 const Program *program = programPipeline->getActiveShaderProgram();
3702                 if (program)
3703                 {
3704                     *params = program->id().value;
3705                 }
3706             }
3707             break;
3708         }
3709 
3710         case GL_VERTEX_SHADER:
3711         {
3712             // the name of the current program object for the vertex shader type of the program
3713             // pipeline object is returned in params
3714             *params = 0;
3715             if (programPipeline)
3716             {
3717                 const Program *program = programPipeline->getShaderProgram(ShaderType::Vertex);
3718                 if (program)
3719                 {
3720                     *params = program->id().value;
3721                 }
3722             }
3723             break;
3724         }
3725 
3726         case GL_FRAGMENT_SHADER:
3727         {
3728             // the name of the current program object for the fragment shader type of the program
3729             // pipeline object is returned in params
3730             *params = 0;
3731             if (programPipeline)
3732             {
3733                 const Program *program = programPipeline->getShaderProgram(ShaderType::Fragment);
3734                 if (program)
3735                 {
3736                     *params = program->id().value;
3737                 }
3738             }
3739             break;
3740         }
3741 
3742         case GL_COMPUTE_SHADER:
3743         {
3744             // the name of the current program object for the compute shader type of the program
3745             // pipeline object is returned in params
3746             *params = 0;
3747             if (programPipeline)
3748             {
3749                 const Program *program = programPipeline->getShaderProgram(ShaderType::Compute);
3750                 if (program)
3751                 {
3752                     *params = program->id().value;
3753                 }
3754             }
3755             break;
3756         }
3757 
3758         case GL_INFO_LOG_LENGTH:
3759         {
3760             // the length of the info log, including the null terminator, is returned in params. If
3761             // there is no info log, zero is returned.
3762             *params = 0;
3763             if (programPipeline)
3764             {
3765                 *params = programPipeline->getExecutable().getInfoLogLength();
3766             }
3767             break;
3768         }
3769 
3770         case GL_VALIDATE_STATUS:
3771         {
3772             // the validation status of pipeline, as determined by glValidateProgramPipeline, is
3773             // returned in params
3774             *params = 0;
3775             if (programPipeline)
3776             {
3777                 *params = programPipeline->isValid();
3778             }
3779             break;
3780         }
3781 
3782         default:
3783             break;
3784     }
3785 }
3786 
3787 }  // namespace gl
3788 
3789 namespace egl
3790 {
3791 
QueryConfigAttrib(const Config * config,EGLint attribute,EGLint * value)3792 void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value)
3793 {
3794     ASSERT(config != nullptr);
3795     switch (attribute)
3796     {
3797         case EGL_BUFFER_SIZE:
3798             *value = config->bufferSize;
3799             break;
3800         case EGL_ALPHA_SIZE:
3801             *value = config->alphaSize;
3802             break;
3803         case EGL_BLUE_SIZE:
3804             *value = config->blueSize;
3805             break;
3806         case EGL_GREEN_SIZE:
3807             *value = config->greenSize;
3808             break;
3809         case EGL_RED_SIZE:
3810             *value = config->redSize;
3811             break;
3812         case EGL_DEPTH_SIZE:
3813             *value = config->depthSize;
3814             break;
3815         case EGL_STENCIL_SIZE:
3816             *value = config->stencilSize;
3817             break;
3818         case EGL_CONFIG_CAVEAT:
3819             *value = config->configCaveat;
3820             break;
3821         case EGL_CONFIG_ID:
3822             *value = config->configID;
3823             break;
3824         case EGL_LEVEL:
3825             *value = config->level;
3826             break;
3827         case EGL_NATIVE_RENDERABLE:
3828             *value = config->nativeRenderable;
3829             break;
3830         case EGL_NATIVE_VISUAL_ID:
3831             *value = config->nativeVisualID;
3832             break;
3833         case EGL_NATIVE_VISUAL_TYPE:
3834             *value = config->nativeVisualType;
3835             break;
3836         case EGL_SAMPLES:
3837             *value = config->samples;
3838             break;
3839         case EGL_SAMPLE_BUFFERS:
3840             *value = config->sampleBuffers;
3841             break;
3842         case EGL_SURFACE_TYPE:
3843             *value = config->surfaceType;
3844             break;
3845         case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
3846             *value = config->bindToTextureTarget;
3847             break;
3848         case EGL_TRANSPARENT_TYPE:
3849             *value = config->transparentType;
3850             break;
3851         case EGL_TRANSPARENT_BLUE_VALUE:
3852             *value = config->transparentBlueValue;
3853             break;
3854         case EGL_TRANSPARENT_GREEN_VALUE:
3855             *value = config->transparentGreenValue;
3856             break;
3857         case EGL_TRANSPARENT_RED_VALUE:
3858             *value = config->transparentRedValue;
3859             break;
3860         case EGL_BIND_TO_TEXTURE_RGB:
3861             *value = config->bindToTextureRGB;
3862             break;
3863         case EGL_BIND_TO_TEXTURE_RGBA:
3864             *value = config->bindToTextureRGBA;
3865             break;
3866         case EGL_MIN_SWAP_INTERVAL:
3867             *value = config->minSwapInterval;
3868             break;
3869         case EGL_MAX_SWAP_INTERVAL:
3870             *value = config->maxSwapInterval;
3871             break;
3872         case EGL_LUMINANCE_SIZE:
3873             *value = config->luminanceSize;
3874             break;
3875         case EGL_ALPHA_MASK_SIZE:
3876             *value = config->alphaMaskSize;
3877             break;
3878         case EGL_COLOR_BUFFER_TYPE:
3879             *value = config->colorBufferType;
3880             break;
3881         case EGL_RENDERABLE_TYPE:
3882             *value = config->renderableType;
3883             break;
3884         case EGL_MATCH_NATIVE_PIXMAP:
3885             *value = false;
3886             UNIMPLEMENTED();
3887             break;
3888         case EGL_CONFORMANT:
3889             *value = config->conformant;
3890             break;
3891         case EGL_MAX_PBUFFER_WIDTH:
3892             *value = config->maxPBufferWidth;
3893             break;
3894         case EGL_MAX_PBUFFER_HEIGHT:
3895             *value = config->maxPBufferHeight;
3896             break;
3897         case EGL_MAX_PBUFFER_PIXELS:
3898             *value = config->maxPBufferPixels;
3899             break;
3900         case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
3901             *value = config->optimalOrientation;
3902             break;
3903         case EGL_COLOR_COMPONENT_TYPE_EXT:
3904             *value = config->colorComponentType;
3905             break;
3906         case EGL_RECORDABLE_ANDROID:
3907             *value = config->recordable;
3908             break;
3909         case EGL_FRAMEBUFFER_TARGET_ANDROID:
3910             *value = config->framebufferTarget;
3911             break;
3912         default:
3913             UNREACHABLE();
3914             break;
3915     }
3916 }
3917 
QueryContextAttrib(const gl::Context * context,EGLint attribute,EGLint * value)3918 void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value)
3919 {
3920     switch (attribute)
3921     {
3922         case EGL_CONFIG_ID:
3923             if (context->getConfig() != EGL_NO_CONFIG_KHR)
3924             {
3925                 *value = context->getConfig()->configID;
3926             }
3927             else
3928             {
3929                 *value = 0;
3930             }
3931             break;
3932         case EGL_CONTEXT_CLIENT_TYPE:
3933             *value = context->getClientType();
3934             break;
3935         case EGL_CONTEXT_CLIENT_VERSION:
3936             *value = context->getClientMajorVersion();
3937             break;
3938         case EGL_RENDER_BUFFER:
3939             *value = context->getRenderBuffer();
3940             break;
3941         case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
3942             *value = context->isRobustResourceInitEnabled();
3943             break;
3944         case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
3945             *value = static_cast<EGLint>(context->getContextPriority());
3946             break;
3947         default:
3948             UNREACHABLE();
3949             break;
3950     }
3951 }
3952 
QuerySurfaceAttrib(const Surface * surface,EGLint attribute,EGLint * value)3953 void QuerySurfaceAttrib(const Surface *surface, EGLint attribute, EGLint *value)
3954 {
3955     switch (attribute)
3956     {
3957         case EGL_GL_COLORSPACE:
3958             *value = surface->getGLColorspace();
3959             break;
3960         case EGL_VG_ALPHA_FORMAT:
3961             *value = surface->getVGAlphaFormat();
3962             break;
3963         case EGL_VG_COLORSPACE:
3964             *value = surface->getVGColorspace();
3965             break;
3966         case EGL_CONFIG_ID:
3967             *value = surface->getConfig()->configID;
3968             break;
3969         case EGL_HEIGHT:
3970             *value = surface->getHeight();
3971             break;
3972         case EGL_HORIZONTAL_RESOLUTION:
3973             *value = surface->getHorizontalResolution();
3974             break;
3975         case EGL_LARGEST_PBUFFER:
3976             // The EGL spec states that value is not written if the surface is not a pbuffer
3977             if (surface->getType() == EGL_PBUFFER_BIT)
3978             {
3979                 *value = surface->getLargestPbuffer();
3980             }
3981             break;
3982         case EGL_MIPMAP_TEXTURE:
3983             // The EGL spec states that value is not written if the surface is not a pbuffer
3984             if (surface->getType() == EGL_PBUFFER_BIT)
3985             {
3986                 *value = surface->getMipmapTexture();
3987             }
3988             break;
3989         case EGL_MIPMAP_LEVEL:
3990             // The EGL spec states that value is not written if the surface is not a pbuffer
3991             if (surface->getType() == EGL_PBUFFER_BIT)
3992             {
3993                 *value = surface->getMipmapLevel();
3994             }
3995             break;
3996         case EGL_MULTISAMPLE_RESOLVE:
3997             *value = surface->getMultisampleResolve();
3998             break;
3999         case EGL_PIXEL_ASPECT_RATIO:
4000             *value = surface->getPixelAspectRatio();
4001             break;
4002         case EGL_RENDER_BUFFER:
4003             *value = surface->getRenderBuffer();
4004             break;
4005         case EGL_SWAP_BEHAVIOR:
4006             *value = surface->getSwapBehavior();
4007             break;
4008         case EGL_TEXTURE_FORMAT:
4009             // The EGL spec states that value is not written if the surface is not a pbuffer
4010             if (surface->getType() == EGL_PBUFFER_BIT)
4011             {
4012                 *value = ToEGLenum(surface->getTextureFormat());
4013             }
4014             break;
4015         case EGL_TEXTURE_TARGET:
4016             // The EGL spec states that value is not written if the surface is not a pbuffer
4017             if (surface->getType() == EGL_PBUFFER_BIT)
4018             {
4019                 *value = surface->getTextureTarget();
4020             }
4021             break;
4022         case EGL_VERTICAL_RESOLUTION:
4023             *value = surface->getVerticalResolution();
4024             break;
4025         case EGL_WIDTH:
4026             *value = surface->getWidth();
4027             break;
4028         case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
4029             *value = surface->isPostSubBufferSupported();
4030             break;
4031         case EGL_FIXED_SIZE_ANGLE:
4032             *value = surface->isFixedSize();
4033             break;
4034         case EGL_FLEXIBLE_SURFACE_COMPATIBILITY_SUPPORTED_ANGLE:
4035             *value = surface->flexibleSurfaceCompatibilityRequested();
4036             break;
4037         case EGL_SURFACE_ORIENTATION_ANGLE:
4038             *value = surface->getOrientation();
4039             break;
4040         case EGL_DIRECT_COMPOSITION_ANGLE:
4041             *value = surface->directComposition();
4042             break;
4043         case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
4044             *value = surface->isRobustResourceInitEnabled();
4045             break;
4046         case EGL_TIMESTAMPS_ANDROID:
4047             *value = surface->isTimestampsEnabled();
4048             break;
4049         default:
4050             UNREACHABLE();
4051             break;
4052     }
4053 }
4054 
SetSurfaceAttrib(Surface * surface,EGLint attribute,EGLint value)4055 void SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value)
4056 {
4057     switch (attribute)
4058     {
4059         case EGL_MIPMAP_LEVEL:
4060             surface->setMipmapLevel(value);
4061             break;
4062         case EGL_MULTISAMPLE_RESOLVE:
4063             surface->setMultisampleResolve(value);
4064             break;
4065         case EGL_SWAP_BEHAVIOR:
4066             surface->setSwapBehavior(value);
4067             break;
4068         case EGL_WIDTH:
4069             surface->setFixedWidth(value);
4070             break;
4071         case EGL_HEIGHT:
4072             surface->setFixedHeight(value);
4073             break;
4074         case EGL_TIMESTAMPS_ANDROID:
4075             surface->setTimestampsEnabled(value != EGL_FALSE);
4076             break;
4077         default:
4078             UNREACHABLE();
4079             break;
4080     }
4081 }
4082 
GetSyncAttrib(Display * display,Sync * sync,EGLint attribute,EGLint * value)4083 Error GetSyncAttrib(Display *display, Sync *sync, EGLint attribute, EGLint *value)
4084 {
4085     switch (attribute)
4086     {
4087         case EGL_SYNC_TYPE_KHR:
4088             *value = sync->getType();
4089             return NoError();
4090 
4091         case EGL_SYNC_STATUS_KHR:
4092             return sync->getStatus(display, value);
4093 
4094         case EGL_SYNC_CONDITION_KHR:
4095             *value = sync->getCondition();
4096             return NoError();
4097 
4098         default:
4099             break;
4100     }
4101 
4102     UNREACHABLE();
4103     return NoError();
4104 }
4105 }  // namespace egl
4106