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