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