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