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