• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2016 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 
7 // queryutils.cpp: Utilities for querying values from GL objects
8 
9 #include "libANGLE/queryutils.h"
10 
11 #include <algorithm>
12 
13 #include "common/utilities.h"
14 
15 #include "libANGLE/Buffer.h"
16 #include "libANGLE/Config.h"
17 #include "libANGLE/Context.h"
18 #include "libANGLE/Display.h"
19 #include "libANGLE/EGLSync.h"
20 #include "libANGLE/Fence.h"
21 #include "libANGLE/Framebuffer.h"
22 #include "libANGLE/GLES1State.h"
23 #include "libANGLE/MemoryObject.h"
24 #include "libANGLE/Program.h"
25 #include "libANGLE/Renderbuffer.h"
26 #include "libANGLE/Sampler.h"
27 #include "libANGLE/Shader.h"
28 #include "libANGLE/Surface.h"
29 #include "libANGLE/Texture.h"
30 #include "libANGLE/Uniform.h"
31 #include "libANGLE/VertexAttribute.h"
32 #include "libANGLE/queryconversions.h"
33 
34 namespace gl
35 {
36 
37 namespace
38 {
39 
40 template <bool isPureInteger>
ConvertToColor(const GLfloat * params)41 ColorGeneric ConvertToColor(const GLfloat *params)
42 {
43     if (isPureInteger)
44     {
45         UNREACHABLE();
46         return ColorGeneric(ColorI());
47     }
48     else
49     {
50         return ColorGeneric(ColorF::fromData(params));
51     }
52 }
53 
54 template <bool isPureInteger>
ConvertToColor(const GLint * params)55 ColorGeneric ConvertToColor(const GLint *params)
56 {
57     if (isPureInteger)
58     {
59         return ColorGeneric(ColorI(params[0], params[1], params[2], params[3]));
60     }
61     else
62     {
63         return ColorGeneric(ColorF(normalizedToFloat(params[0]), normalizedToFloat(params[1]),
64                                    normalizedToFloat(params[2]), normalizedToFloat(params[3])));
65     }
66 }
67 
68 template <bool isPureInteger>
ConvertToColor(const GLuint * params)69 ColorGeneric ConvertToColor(const GLuint *params)
70 {
71     if (isPureInteger)
72     {
73         return ColorGeneric(ColorUI(params[0], params[1], params[2], params[3]));
74     }
75     else
76     {
77         UNREACHABLE();
78         return ColorGeneric(ColorF());
79     }
80 }
81 
82 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLfloat * outParams)83 void ConvertFromColor(const ColorGeneric &color, GLfloat *outParams)
84 {
85     if (isPureInteger)
86     {
87         UNREACHABLE();
88     }
89     else
90     {
91         color.colorF.writeData(outParams);
92     }
93 }
94 
95 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLint * outParams)96 void ConvertFromColor(const ColorGeneric &color, GLint *outParams)
97 {
98     if (isPureInteger)
99     {
100         outParams[0] = color.colorI.red;
101         outParams[1] = color.colorI.green;
102         outParams[2] = color.colorI.blue;
103         outParams[3] = color.colorI.alpha;
104     }
105     else
106     {
107         outParams[0] = floatToNormalized<GLint>(color.colorF.red);
108         outParams[1] = floatToNormalized<GLint>(color.colorF.green);
109         outParams[2] = floatToNormalized<GLint>(color.colorF.blue);
110         outParams[3] = floatToNormalized<GLint>(color.colorF.alpha);
111     }
112 }
113 
114 template <bool isPureInteger>
ConvertFromColor(const ColorGeneric & color,GLuint * outParams)115 void ConvertFromColor(const ColorGeneric &color, GLuint *outParams)
116 {
117     if (isPureInteger)
118     {
119         constexpr unsigned int kMinValue = 0;
120 
121         outParams[0] = std::max(color.colorUI.red, kMinValue);
122         outParams[1] = std::max(color.colorUI.green, kMinValue);
123         outParams[2] = std::max(color.colorUI.blue, kMinValue);
124         outParams[3] = std::max(color.colorUI.alpha, kMinValue);
125     }
126     else
127     {
128         UNREACHABLE();
129     }
130 }
131 
132 template <typename ParamType>
QueryTexLevelParameterBase(const Texture * texture,TextureTarget target,GLint level,GLenum pname,ParamType * params)133 void QueryTexLevelParameterBase(const Texture *texture,
134                                 TextureTarget target,
135                                 GLint level,
136                                 GLenum pname,
137                                 ParamType *params)
138 {
139     ASSERT(texture != nullptr);
140     const InternalFormat *info = texture->getTextureState().getImageDesc(target, level).format.info;
141 
142     switch (pname)
143     {
144         case GL_TEXTURE_RED_TYPE:
145             *params = CastFromGLintStateValue<ParamType>(
146                 pname, info->redBits ? info->componentType : GL_NONE);
147             break;
148         case GL_TEXTURE_GREEN_TYPE:
149             *params = CastFromGLintStateValue<ParamType>(
150                 pname, info->greenBits ? info->componentType : GL_NONE);
151             break;
152         case GL_TEXTURE_BLUE_TYPE:
153             *params = CastFromGLintStateValue<ParamType>(
154                 pname, info->blueBits ? info->componentType : GL_NONE);
155             break;
156         case GL_TEXTURE_ALPHA_TYPE:
157             *params = CastFromGLintStateValue<ParamType>(
158                 pname, info->alphaBits ? info->componentType : GL_NONE);
159             break;
160         case GL_TEXTURE_DEPTH_TYPE:
161             *params = CastFromGLintStateValue<ParamType>(
162                 pname, info->depthBits ? info->componentType : GL_NONE);
163             break;
164         case GL_TEXTURE_RED_SIZE:
165             *params = CastFromGLintStateValue<ParamType>(pname, info->redBits);
166             break;
167         case GL_TEXTURE_GREEN_SIZE:
168             *params = CastFromGLintStateValue<ParamType>(pname, info->greenBits);
169             break;
170         case GL_TEXTURE_BLUE_SIZE:
171             *params = CastFromGLintStateValue<ParamType>(pname, info->blueBits);
172             break;
173         case GL_TEXTURE_ALPHA_SIZE:
174             *params = CastFromGLintStateValue<ParamType>(pname, info->alphaBits);
175             break;
176         case GL_TEXTURE_DEPTH_SIZE:
177             *params = CastFromGLintStateValue<ParamType>(pname, info->depthBits);
178             break;
179         case GL_TEXTURE_STENCIL_SIZE:
180             *params = CastFromGLintStateValue<ParamType>(pname, info->stencilBits);
181             break;
182         case GL_TEXTURE_SHARED_SIZE:
183             *params = CastFromGLintStateValue<ParamType>(pname, info->sharedBits);
184             break;
185         case GL_TEXTURE_INTERNAL_FORMAT:
186             *params = CastFromGLintStateValue<ParamType>(
187                 pname, info->internalFormat ? info->internalFormat : GL_RGBA);
188             break;
189         case GL_TEXTURE_WIDTH:
190             *params = CastFromGLintStateValue<ParamType>(
191                 pname, static_cast<uint32_t>(texture->getWidth(target, level)));
192             break;
193         case GL_TEXTURE_HEIGHT:
194             *params = CastFromGLintStateValue<ParamType>(
195                 pname, static_cast<uint32_t>(texture->getHeight(target, level)));
196             break;
197         case GL_TEXTURE_DEPTH:
198             *params = CastFromGLintStateValue<ParamType>(
199                 pname, static_cast<uint32_t>(texture->getDepth(target, level)));
200             break;
201         case GL_TEXTURE_SAMPLES:
202             *params = CastFromStateValue<ParamType>(pname, texture->getSamples(target, level));
203             break;
204         case GL_TEXTURE_FIXED_SAMPLE_LOCATIONS:
205             *params = CastFromStateValue<ParamType>(
206                 pname, static_cast<GLint>(texture->getFixedSampleLocations(target, level)));
207             break;
208         case GL_TEXTURE_COMPRESSED:
209             *params = CastFromStateValue<ParamType>(pname, static_cast<GLint>(info->compressed));
210             break;
211         case GL_MEMORY_SIZE_ANGLE:
212             *params =
213                 CastFromStateValue<ParamType>(pname, texture->getLevelMemorySize(target, level));
214             break;
215         case GL_RESOURCE_INITIALIZED_ANGLE:
216             *params = CastFromGLintStateValue<ParamType>(
217                 pname, texture->initState(GL_NONE, ImageIndex::MakeFromTarget(target, level)) ==
218                            InitState::Initialized);
219             break;
220         case GL_TEXTURE_BUFFER_DATA_STORE_BINDING:
221             *params = CastFromStateValue<ParamType>(
222                 pname, static_cast<GLint>(texture->getBuffer().id().value));
223             break;
224         case GL_TEXTURE_BUFFER_OFFSET:
225             *params = CastFromStateValue<ParamType>(
226                 pname, static_cast<GLint>(texture->getBuffer().getOffset()));
227             break;
228         case GL_TEXTURE_BUFFER_SIZE:
229             *params = CastFromStateValue<ParamType>(
230                 pname, static_cast<GLint>(GetBoundBufferAvailableSize(texture->getBuffer())));
231             break;
232         default:
233             UNREACHABLE();
234             break;
235     }
236 }
237 
238 // This function is needed to handle fixed_point data.
239 // It can be used when some pname need special conversion from int/float/bool to fixed_point.
240 template <bool isGLfixed, typename QueryT, typename ParamType>
CastFromSpecialValue(GLenum pname,const ParamType param)241 QueryT CastFromSpecialValue(GLenum pname, const ParamType param)
242 {
243     if (isGLfixed)
244     {
245         return static_cast<QueryT>(ConvertFloatToFixed(CastFromStateValue<GLfloat>(pname, param)));
246     }
247     else
248     {
249         return CastFromStateValue<QueryT>(pname, param);
250     }
251 }
252 
253 template <bool isPureInteger, bool isGLfixed, typename ParamType>
QueryTexParameterBase(const Context * context,const Texture * texture,GLenum pname,ParamType * params)254 void QueryTexParameterBase(const Context *context,
255                            const Texture *texture,
256                            GLenum pname,
257                            ParamType *params)
258 {
259     ASSERT(texture != nullptr);
260 
261     switch (pname)
262     {
263         case GL_TEXTURE_MAG_FILTER:
264             *params = CastFromGLintStateValue<ParamType>(pname, texture->getMagFilter());
265             break;
266         case GL_TEXTURE_MIN_FILTER:
267             *params = CastFromGLintStateValue<ParamType>(pname, texture->getMinFilter());
268             break;
269         case GL_TEXTURE_WRAP_S:
270             *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapS());
271             break;
272         case GL_TEXTURE_WRAP_T:
273             *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapT());
274             break;
275         case GL_TEXTURE_WRAP_R:
276             *params = CastFromGLintStateValue<ParamType>(pname, texture->getWrapR());
277             break;
278         case GL_TEXTURE_IMMUTABLE_FORMAT:
279             *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableFormat());
280             break;
281         case GL_TEXTURE_IMMUTABLE_LEVELS:
282             *params = CastFromGLintStateValue<ParamType>(pname, texture->getImmutableLevels());
283             break;
284         case GL_TEXTURE_USAGE_ANGLE:
285             *params = CastFromGLintStateValue<ParamType>(pname, texture->getUsage());
286             break;
287         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
288             *params =
289                 CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxAnisotropy());
290             break;
291         case GL_TEXTURE_SWIZZLE_R:
292             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleRed());
293             break;
294         case GL_TEXTURE_SWIZZLE_G:
295             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleGreen());
296             break;
297         case GL_TEXTURE_SWIZZLE_B:
298             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleBlue());
299             break;
300         case GL_TEXTURE_SWIZZLE_A:
301             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSwizzleAlpha());
302             break;
303         case GL_TEXTURE_BASE_LEVEL:
304             *params = CastFromGLintStateValue<ParamType>(pname, texture->getBaseLevel());
305             break;
306         case GL_TEXTURE_MAX_LEVEL:
307             *params = CastFromGLintStateValue<ParamType>(pname, texture->getMaxLevel());
308             break;
309         case GL_TEXTURE_MIN_LOD:
310             *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMinLod());
311             break;
312         case GL_TEXTURE_MAX_LOD:
313             *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMaxLod());
314             break;
315         case GL_TEXTURE_COMPARE_MODE:
316             *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareMode());
317             break;
318         case GL_TEXTURE_COMPARE_FUNC:
319             *params = CastFromGLintStateValue<ParamType>(pname, texture->getCompareFunc());
320             break;
321         case GL_TEXTURE_SRGB_DECODE_EXT:
322             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBDecode());
323             break;
324         case GL_TEXTURE_FORMAT_SRGB_OVERRIDE_EXT:
325             *params = CastFromGLintStateValue<ParamType>(pname, texture->getSRGBOverride());
326             break;
327         case GL_DEPTH_STENCIL_TEXTURE_MODE:
328             *params =
329                 CastFromGLintStateValue<ParamType>(pname, texture->getDepthStencilTextureMode());
330             break;
331         case GL_TEXTURE_CROP_RECT_OES:
332         {
333             const gl::Rectangle &crop = texture->getCrop();
334             params[0]                 = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.x);
335             params[1]                 = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.y);
336             params[2] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.width);
337             params[3] = CastFromSpecialValue<isGLfixed, ParamType>(pname, crop.height);
338             break;
339         }
340         case GL_GENERATE_MIPMAP:
341             *params = CastFromGLintStateValue<ParamType>(pname, texture->getGenerateMipmapHint());
342             break;
343         case GL_MEMORY_SIZE_ANGLE:
344             *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getMemorySize());
345             break;
346         case GL_TEXTURE_BORDER_COLOR:
347             ConvertFromColor<isPureInteger>(texture->getBorderColor(), params);
348             break;
349         case GL_TEXTURE_NATIVE_ID_ANGLE:
350             *params = CastFromSpecialValue<isGLfixed, ParamType>(pname, texture->getNativeID());
351             break;
352         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
353             *params = CastFromGLintStateValue<ParamType>(
354                 pname, texture->getImplementationColorReadFormat(context));
355             break;
356         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
357             *params = CastFromGLintStateValue<ParamType>(
358                 pname, texture->getImplementationColorReadType(context));
359             break;
360         case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE:
361             *params =
362                 CastFromGLintStateValue<ParamType>(pname, GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE);
363             break;
364         case GL_RESOURCE_INITIALIZED_ANGLE:
365             *params = CastFromGLintStateValue<ParamType>(
366                 pname, texture->initState() == InitState::Initialized);
367             break;
368         case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
369             *params = CastFromGLintStateValue<ParamType>(
370                 pname, texture->getRequiredTextureImageUnits(context));
371             break;
372         case GL_TEXTURE_PROTECTED_EXT:
373             *params = CastFromGLintStateValue<ParamType>(pname, texture->hasProtectedContent());
374             break;
375         case GL_TEXTURE_TILING_EXT:
376             *params = CastFromGLintStateValue<ParamType>(pname, texture->getTilingMode());
377             break;
378         case GL_TEXTURE_FOVEATED_FEATURE_BITS_QCOM:
379             *params = CastFromGLintStateValue<ParamType>(pname, texture->getFoveatedFeatureBits());
380             break;
381         case GL_TEXTURE_FOVEATED_FEATURE_QUERY_QCOM:
382             *params =
383                 CastFromGLintStateValue<ParamType>(pname, texture->getSupportedFoveationFeatures());
384             break;
385         case GL_TEXTURE_FOVEATED_MIN_PIXEL_DENSITY_QCOM:
386             *params = CastFromGLintStateValue<ParamType>(pname, texture->getMinPixelDensity());
387             break;
388         case GL_TEXTURE_FOVEATED_NUM_FOCAL_POINTS_QUERY_QCOM:
389             *params = CastFromGLintStateValue<ParamType>(pname, texture->getNumFocalPoints());
390             break;
391         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 == GL_NONE)
1517                               ? GL_RGBA4
1518                               : renderbuffer->getFormat().info->internalFormat;
1519             }
1520             break;
1521         case GL_RENDERBUFFER_RED_SIZE:
1522             *params = renderbuffer->getRedSize();
1523             break;
1524         case GL_RENDERBUFFER_GREEN_SIZE:
1525             *params = renderbuffer->getGreenSize();
1526             break;
1527         case GL_RENDERBUFFER_BLUE_SIZE:
1528             *params = renderbuffer->getBlueSize();
1529             break;
1530         case GL_RENDERBUFFER_ALPHA_SIZE:
1531             *params = renderbuffer->getAlphaSize();
1532             break;
1533         case GL_RENDERBUFFER_DEPTH_SIZE:
1534             *params = renderbuffer->getDepthSize();
1535             break;
1536         case GL_RENDERBUFFER_STENCIL_SIZE:
1537             *params = renderbuffer->getStencilSize();
1538             break;
1539         case GL_RENDERBUFFER_SAMPLES_ANGLE:
1540             *params = renderbuffer->getState().getSamples();
1541             break;
1542         case GL_MEMORY_SIZE_ANGLE:
1543             *params = renderbuffer->getMemorySize();
1544             break;
1545         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
1546             *params = static_cast<GLint>(renderbuffer->getImplementationColorReadFormat(context));
1547             break;
1548         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
1549             *params = static_cast<GLint>(renderbuffer->getImplementationColorReadType(context));
1550             break;
1551         case GL_RESOURCE_INITIALIZED_ANGLE:
1552             *params = (renderbuffer->initState(GL_NONE, ImageIndex()) == InitState::Initialized);
1553             break;
1554         default:
1555             UNREACHABLE();
1556             break;
1557     }
1558 }
1559 
QueryShaderiv(const Context * context,Shader * shader,GLenum pname,GLint * params)1560 void QueryShaderiv(const Context *context, Shader *shader, GLenum pname, GLint *params)
1561 {
1562     ASSERT(shader != nullptr || pname == GL_COMPLETION_STATUS_KHR);
1563 
1564     switch (pname)
1565     {
1566         case GL_SHADER_TYPE:
1567             *params = static_cast<GLint>(ToGLenum(shader->getType()));
1568             return;
1569         case GL_DELETE_STATUS:
1570             *params = shader->isFlaggedForDeletion();
1571             return;
1572         case GL_COMPILE_STATUS:
1573             *params = shader->isCompiled(context) ? GL_TRUE : GL_FALSE;
1574             return;
1575         case GL_COMPLETION_STATUS_KHR:
1576             if (context->isContextLost())
1577             {
1578                 *params = GL_TRUE;
1579             }
1580             else
1581             {
1582                 *params = shader->isCompleted() ? GL_TRUE : GL_FALSE;
1583             }
1584             return;
1585         case GL_INFO_LOG_LENGTH:
1586             *params = shader->getInfoLogLength(context);
1587             return;
1588         case GL_SHADER_SOURCE_LENGTH:
1589             *params = shader->getSourceLength();
1590             return;
1591         case GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE:
1592             *params = shader->getTranslatedSourceWithDebugInfoLength(context);
1593             return;
1594         default:
1595             UNREACHABLE();
1596             break;
1597     }
1598 }
1599 
QueryTexLevelParameterfv(const Texture * texture,TextureTarget target,GLint level,GLenum pname,GLfloat * params)1600 void QueryTexLevelParameterfv(const Texture *texture,
1601                               TextureTarget target,
1602                               GLint level,
1603                               GLenum pname,
1604                               GLfloat *params)
1605 {
1606     QueryTexLevelParameterBase(texture, target, level, pname, params);
1607 }
1608 
QueryTexLevelParameteriv(const Texture * texture,TextureTarget target,GLint level,GLenum pname,GLint * params)1609 void QueryTexLevelParameteriv(const Texture *texture,
1610                               TextureTarget target,
1611                               GLint level,
1612                               GLenum pname,
1613                               GLint *params)
1614 {
1615     QueryTexLevelParameterBase(texture, target, level, pname, params);
1616 }
1617 
QueryTexParameterfv(const Context * context,const Texture * texture,GLenum pname,GLfloat * params)1618 void QueryTexParameterfv(const Context *context,
1619                          const Texture *texture,
1620                          GLenum pname,
1621                          GLfloat *params)
1622 {
1623     QueryTexParameterBase<false, false>(context, texture, pname, params);
1624 }
1625 
QueryTexParameterxv(const Context * context,const Texture * texture,GLenum pname,GLfixed * params)1626 void QueryTexParameterxv(const Context *context,
1627                          const Texture *texture,
1628                          GLenum pname,
1629                          GLfixed *params)
1630 {
1631     QueryTexParameterBase<false, true>(context, texture, pname, params);
1632 }
1633 
QueryTexParameteriv(const Context * context,const Texture * texture,GLenum pname,GLint * params)1634 void QueryTexParameteriv(const Context *context,
1635                          const Texture *texture,
1636                          GLenum pname,
1637                          GLint *params)
1638 {
1639     QueryTexParameterBase<false, false>(context, texture, pname, params);
1640 }
1641 
QueryTexParameterIiv(const Context * context,const Texture * texture,GLenum pname,GLint * params)1642 void QueryTexParameterIiv(const Context *context,
1643                           const Texture *texture,
1644                           GLenum pname,
1645                           GLint *params)
1646 {
1647     QueryTexParameterBase<true, false>(context, texture, pname, params);
1648 }
1649 
QueryTexParameterIuiv(const Context * context,const Texture * texture,GLenum pname,GLuint * params)1650 void QueryTexParameterIuiv(const Context *context,
1651                            const Texture *texture,
1652                            GLenum pname,
1653                            GLuint *params)
1654 {
1655     QueryTexParameterBase<true, false>(context, texture, pname, params);
1656 }
1657 
QuerySamplerParameterfv(const Sampler * sampler,GLenum pname,GLfloat * params)1658 void QuerySamplerParameterfv(const Sampler *sampler, GLenum pname, GLfloat *params)
1659 {
1660     QuerySamplerParameterBase<false>(sampler, pname, params);
1661 }
1662 
QuerySamplerParameteriv(const Sampler * sampler,GLenum pname,GLint * params)1663 void QuerySamplerParameteriv(const Sampler *sampler, GLenum pname, GLint *params)
1664 {
1665     QuerySamplerParameterBase<false>(sampler, pname, params);
1666 }
1667 
QuerySamplerParameterIiv(const Sampler * sampler,GLenum pname,GLint * params)1668 void QuerySamplerParameterIiv(const Sampler *sampler, GLenum pname, GLint *params)
1669 {
1670     QuerySamplerParameterBase<true>(sampler, pname, params);
1671 }
1672 
QuerySamplerParameterIuiv(const Sampler * sampler,GLenum pname,GLuint * params)1673 void QuerySamplerParameterIuiv(const Sampler *sampler, GLenum pname, GLuint *params)
1674 {
1675     QuerySamplerParameterBase<true>(sampler, pname, params);
1676 }
1677 
QueryVertexAttribfv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLfloat * params)1678 void QueryVertexAttribfv(const VertexAttribute &attrib,
1679                          const VertexBinding &binding,
1680                          const VertexAttribCurrentValueData &currentValueData,
1681                          GLenum pname,
1682                          GLfloat *params)
1683 {
1684     QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
1685 }
1686 
QueryVertexAttribiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLint * params)1687 void QueryVertexAttribiv(const VertexAttribute &attrib,
1688                          const VertexBinding &binding,
1689                          const VertexAttribCurrentValueData &currentValueData,
1690                          GLenum pname,
1691                          GLint *params)
1692 {
1693     QueryVertexAttribBase(attrib, binding, currentValueData.Values.FloatValues, pname, params);
1694 }
1695 
QueryVertexAttribPointerv(const VertexAttribute & attrib,GLenum pname,void ** pointer)1696 void QueryVertexAttribPointerv(const VertexAttribute &attrib, GLenum pname, void **pointer)
1697 {
1698     switch (pname)
1699     {
1700         case GL_VERTEX_ATTRIB_ARRAY_POINTER:
1701             *pointer = const_cast<void *>(attrib.pointer);
1702             break;
1703 
1704         default:
1705             UNREACHABLE();
1706             break;
1707     }
1708 }
1709 
QueryVertexAttribIiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLint * params)1710 void QueryVertexAttribIiv(const VertexAttribute &attrib,
1711                           const VertexBinding &binding,
1712                           const VertexAttribCurrentValueData &currentValueData,
1713                           GLenum pname,
1714                           GLint *params)
1715 {
1716     QueryVertexAttribBase(attrib, binding, currentValueData.Values.IntValues, pname, params);
1717 }
1718 
QueryVertexAttribIuiv(const VertexAttribute & attrib,const VertexBinding & binding,const VertexAttribCurrentValueData & currentValueData,GLenum pname,GLuint * params)1719 void QueryVertexAttribIuiv(const VertexAttribute &attrib,
1720                            const VertexBinding &binding,
1721                            const VertexAttribCurrentValueData &currentValueData,
1722                            GLenum pname,
1723                            GLuint *params)
1724 {
1725     QueryVertexAttribBase(attrib, binding, currentValueData.Values.UnsignedIntValues, pname,
1726                           params);
1727 }
1728 
QueryActiveUniformBlockiv(const Program * program,UniformBlockIndex uniformBlockIndex,GLenum pname,GLint * params)1729 void QueryActiveUniformBlockiv(const Program *program,
1730                                UniformBlockIndex uniformBlockIndex,
1731                                GLenum pname,
1732                                GLint *params)
1733 {
1734     GLenum prop = GetUniformBlockPropertyEnum(pname);
1735     QueryProgramResourceiv(program, GL_UNIFORM_BLOCK, uniformBlockIndex, 1, &prop,
1736                            std::numeric_limits<GLsizei>::max(), nullptr, params);
1737 }
1738 
QueryInternalFormativ(const Context * context,const Texture * texture,GLenum internalformat,const TextureCaps & format,GLenum pname,GLsizei bufSize,GLint * params)1739 void QueryInternalFormativ(const Context *context,
1740                            const Texture *texture,
1741                            GLenum internalformat,
1742                            const TextureCaps &format,
1743                            GLenum pname,
1744                            GLsizei bufSize,
1745                            GLint *params)
1746 {
1747     switch (pname)
1748     {
1749         case GL_NUM_SAMPLE_COUNTS:
1750             if (bufSize != 0)
1751             {
1752                 *params = clampCast<GLint>(format.sampleCounts.size());
1753             }
1754             break;
1755 
1756         case GL_SAMPLES:
1757         {
1758             size_t returnCount   = std::min<size_t>(bufSize, format.sampleCounts.size());
1759             auto sampleReverseIt = format.sampleCounts.rbegin();
1760             for (size_t sampleIndex = 0; sampleIndex < returnCount; ++sampleIndex)
1761             {
1762                 params[sampleIndex] = *sampleReverseIt++;
1763             }
1764         }
1765         break;
1766 
1767         case GL_NUM_SURFACE_COMPRESSION_FIXED_RATES_EXT:
1768             if (texture != nullptr)
1769             {
1770                 *params = texture->getFormatSupportedCompressionRates(context, internalformat,
1771                                                                       bufSize, nullptr);
1772             }
1773             break;
1774 
1775         case GL_SURFACE_COMPRESSION_EXT:
1776             if (texture != nullptr)
1777             {
1778                 texture->getFormatSupportedCompressionRates(context, internalformat, bufSize,
1779                                                             params);
1780             }
1781             break;
1782 
1783         default:
1784             UNREACHABLE();
1785             break;
1786     }
1787 }
1788 
QueryFramebufferParameteriv(const Framebuffer * framebuffer,GLenum pname,GLint * params)1789 void QueryFramebufferParameteriv(const Framebuffer *framebuffer, GLenum pname, GLint *params)
1790 {
1791     ASSERT(framebuffer);
1792 
1793     switch (pname)
1794     {
1795         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1796             *params = framebuffer->getDefaultWidth();
1797             break;
1798         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1799             *params = framebuffer->getDefaultHeight();
1800             break;
1801         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1802             *params = framebuffer->getDefaultSamples();
1803             break;
1804         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1805             *params = ConvertToGLBoolean(framebuffer->getDefaultFixedSampleLocations());
1806             break;
1807         case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1808             *params = framebuffer->getDefaultLayers();
1809             break;
1810         case GL_FRAMEBUFFER_FLIP_Y_MESA:
1811             *params = ConvertToGLBoolean(framebuffer->getFlipY());
1812             break;
1813         default:
1814             UNREACHABLE();
1815             break;
1816     }
1817 }
1818 
QuerySynciv(const Context * context,const Sync * sync,GLenum pname,GLsizei bufSize,GLsizei * length,GLint * values)1819 angle::Result QuerySynciv(const Context *context,
1820                           const Sync *sync,
1821                           GLenum pname,
1822                           GLsizei bufSize,
1823                           GLsizei *length,
1824                           GLint *values)
1825 {
1826     ASSERT(sync != nullptr || pname == GL_SYNC_STATUS);
1827 
1828     // All queries return one value, exit early if the buffer can't fit anything.
1829     if (bufSize < 1)
1830     {
1831         if (length != nullptr)
1832         {
1833             *length = 0;
1834         }
1835         return angle::Result::Continue;
1836     }
1837 
1838     switch (pname)
1839     {
1840         case GL_OBJECT_TYPE:
1841             *values = clampCast<GLint>(GL_SYNC_FENCE);
1842             break;
1843         case GL_SYNC_CONDITION:
1844             *values = clampCast<GLint>(sync->getCondition());
1845             break;
1846         case GL_SYNC_FLAGS:
1847             *values = clampCast<GLint>(sync->getFlags());
1848             break;
1849         case GL_SYNC_STATUS:
1850             if (context->isContextLost())
1851             {
1852                 *values = GL_SIGNALED;
1853             }
1854             else
1855             {
1856                 ANGLE_TRY(sync->getStatus(context, values));
1857             }
1858             break;
1859 
1860         default:
1861             UNREACHABLE();
1862             break;
1863     }
1864 
1865     if (length != nullptr)
1866     {
1867         *length = 1;
1868     }
1869 
1870     return angle::Result::Continue;
1871 }
1872 
SetTexParameterx(Context * context,Texture * texture,GLenum pname,GLfixed param)1873 void SetTexParameterx(Context *context, Texture *texture, GLenum pname, GLfixed param)
1874 {
1875     SetTexParameterBase<false, true>(context, texture, pname, &param);
1876 }
1877 
SetTexParameterxv(Context * context,Texture * texture,GLenum pname,const GLfixed * params)1878 void SetTexParameterxv(Context *context, Texture *texture, GLenum pname, const GLfixed *params)
1879 {
1880     SetTexParameterBase<false, true>(context, texture, pname, params);
1881 }
1882 
SetTexParameterf(Context * context,Texture * texture,GLenum pname,GLfloat param)1883 void SetTexParameterf(Context *context, Texture *texture, GLenum pname, GLfloat param)
1884 {
1885     SetTexParameterBase<false, false>(context, texture, pname, &param);
1886 }
1887 
SetTexParameterfv(Context * context,Texture * texture,GLenum pname,const GLfloat * params)1888 void SetTexParameterfv(Context *context, Texture *texture, GLenum pname, const GLfloat *params)
1889 {
1890     SetTexParameterBase<false, false>(context, texture, pname, params);
1891 }
1892 
SetTexParameteri(Context * context,Texture * texture,GLenum pname,GLint param)1893 void SetTexParameteri(Context *context, Texture *texture, GLenum pname, GLint param)
1894 {
1895     SetTexParameterBase<false, false>(context, texture, pname, &param);
1896 }
1897 
SetTexParameteriv(Context * context,Texture * texture,GLenum pname,const GLint * params)1898 void SetTexParameteriv(Context *context, Texture *texture, GLenum pname, const GLint *params)
1899 {
1900     SetTexParameterBase<false, false>(context, texture, pname, params);
1901 }
1902 
SetTexParameterIiv(Context * context,Texture * texture,GLenum pname,const GLint * params)1903 void SetTexParameterIiv(Context *context, Texture *texture, GLenum pname, const GLint *params)
1904 {
1905     SetTexParameterBase<true, false>(context, texture, pname, params);
1906 }
1907 
SetTexParameterIuiv(Context * context,Texture * texture,GLenum pname,const GLuint * params)1908 void SetTexParameterIuiv(Context *context, Texture *texture, GLenum pname, const GLuint *params)
1909 {
1910     SetTexParameterBase<true, false>(context, texture, pname, params);
1911 }
1912 
SetSamplerParameterf(Context * context,Sampler * sampler,GLenum pname,GLfloat param)1913 void SetSamplerParameterf(Context *context, Sampler *sampler, GLenum pname, GLfloat param)
1914 {
1915     SetSamplerParameterBase<false>(context, sampler, pname, &param);
1916 }
1917 
SetSamplerParameterfv(Context * context,Sampler * sampler,GLenum pname,const GLfloat * params)1918 void SetSamplerParameterfv(Context *context, Sampler *sampler, GLenum pname, const GLfloat *params)
1919 {
1920     SetSamplerParameterBase<false>(context, sampler, pname, params);
1921 }
1922 
SetSamplerParameteri(Context * context,Sampler * sampler,GLenum pname,GLint param)1923 void SetSamplerParameteri(Context *context, Sampler *sampler, GLenum pname, GLint param)
1924 {
1925     SetSamplerParameterBase<false>(context, sampler, pname, &param);
1926 }
1927 
SetSamplerParameteriv(Context * context,Sampler * sampler,GLenum pname,const GLint * params)1928 void SetSamplerParameteriv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
1929 {
1930     SetSamplerParameterBase<false>(context, sampler, pname, params);
1931 }
1932 
SetSamplerParameterIiv(Context * context,Sampler * sampler,GLenum pname,const GLint * params)1933 void SetSamplerParameterIiv(Context *context, Sampler *sampler, GLenum pname, const GLint *params)
1934 {
1935     SetSamplerParameterBase<true>(context, sampler, pname, params);
1936 }
1937 
SetSamplerParameterIuiv(Context * context,Sampler * sampler,GLenum pname,const GLuint * params)1938 void SetSamplerParameterIuiv(Context *context, Sampler *sampler, GLenum pname, const GLuint *params)
1939 {
1940     SetSamplerParameterBase<true>(context, sampler, pname, params);
1941 }
1942 
SetFramebufferParameteri(const Context * context,Framebuffer * framebuffer,GLenum pname,GLint param)1943 void SetFramebufferParameteri(const Context *context,
1944                               Framebuffer *framebuffer,
1945                               GLenum pname,
1946                               GLint param)
1947 {
1948     ASSERT(framebuffer);
1949 
1950     switch (pname)
1951     {
1952         case GL_FRAMEBUFFER_DEFAULT_WIDTH:
1953             framebuffer->setDefaultWidth(context, param);
1954             break;
1955         case GL_FRAMEBUFFER_DEFAULT_HEIGHT:
1956             framebuffer->setDefaultHeight(context, param);
1957             break;
1958         case GL_FRAMEBUFFER_DEFAULT_SAMPLES:
1959             framebuffer->setDefaultSamples(context, param);
1960             break;
1961         case GL_FRAMEBUFFER_DEFAULT_FIXED_SAMPLE_LOCATIONS:
1962             framebuffer->setDefaultFixedSampleLocations(context, ConvertToBool(param));
1963             break;
1964         case GL_FRAMEBUFFER_DEFAULT_LAYERS_EXT:
1965             framebuffer->setDefaultLayers(param);
1966             break;
1967         case GL_FRAMEBUFFER_FLIP_Y_MESA:
1968             framebuffer->setFlipY(ConvertToBool(param));
1969             break;
1970         default:
1971             UNREACHABLE();
1972             break;
1973     }
1974 }
1975 
SetProgramParameteri(const Context * context,Program * program,GLenum pname,GLint value)1976 void SetProgramParameteri(const Context *context, Program *program, GLenum pname, GLint value)
1977 {
1978     ASSERT(program);
1979 
1980     switch (pname)
1981     {
1982         case GL_PROGRAM_BINARY_RETRIEVABLE_HINT:
1983             program->setBinaryRetrievableHint(ConvertToBool(value));
1984             break;
1985         case GL_PROGRAM_SEPARABLE:
1986             program->setSeparable(context, ConvertToBool(value));
1987             break;
1988         default:
1989             UNREACHABLE();
1990             break;
1991     }
1992 }
1993 
GetUniformResourceProperty(const Program * program,GLuint index,const GLenum prop)1994 GLint GetUniformResourceProperty(const Program *program, GLuint index, const GLenum prop)
1995 {
1996     const ProgramExecutable &executable = program->getExecutable();
1997     const LinkedUniform &uniform        = executable.getUniformByIndex(index);
1998 
1999     GLenum resourceProp = GetUniformPropertyEnum(prop);
2000     switch (resourceProp)
2001     {
2002         case GL_TYPE:
2003             return clampCast<GLint>(uniform.getType());
2004 
2005         case GL_ARRAY_SIZE:
2006             return clampCast<GLint>(uniform.getBasicTypeElementCount());
2007 
2008         case GL_NAME_LENGTH:
2009             return clampCast<GLint>(executable.getUniformNameByIndex(index).size() + 1u);
2010 
2011         case GL_LOCATION:
2012             return executable.getUniformLocation(executable.getUniformNameByIndex(index)).value;
2013 
2014         case GL_BLOCK_INDEX:
2015             return (uniform.isAtomicCounter() ? -1 : uniform.getBufferIndex());
2016 
2017         case GL_OFFSET:
2018             return uniform.pod.flagBits.isBlock ? uniform.pod.blockOffset : -1;
2019 
2020         case GL_ARRAY_STRIDE:
2021             return uniform.pod.flagBits.isBlock ? uniform.pod.blockArrayStride : -1;
2022 
2023         case GL_MATRIX_STRIDE:
2024             return uniform.pod.flagBits.isBlock ? uniform.pod.blockMatrixStride : -1;
2025 
2026         case GL_IS_ROW_MAJOR:
2027             return uniform.pod.flagBits.blockIsRowMajorMatrix ? 1 : 0;
2028 
2029         case GL_REFERENCED_BY_VERTEX_SHADER:
2030             return uniform.isActive(ShaderType::Vertex);
2031 
2032         case GL_REFERENCED_BY_FRAGMENT_SHADER:
2033             return uniform.isActive(ShaderType::Fragment);
2034 
2035         case GL_REFERENCED_BY_COMPUTE_SHADER:
2036             return uniform.isActive(ShaderType::Compute);
2037 
2038         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
2039             return uniform.isActive(ShaderType::Geometry);
2040 
2041         case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
2042             return uniform.isActive(ShaderType::TessControl);
2043 
2044         case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
2045             return uniform.isActive(ShaderType::TessEvaluation);
2046 
2047         case GL_ATOMIC_COUNTER_BUFFER_INDEX:
2048             return (uniform.isAtomicCounter() ? uniform.getBufferIndex() : -1);
2049 
2050         default:
2051             UNREACHABLE();
2052             return 0;
2053     }
2054 }
2055 
GetBufferVariableResourceProperty(const Program * program,GLuint index,const GLenum prop)2056 GLint GetBufferVariableResourceProperty(const Program *program, GLuint index, const GLenum prop)
2057 {
2058     const ProgramExecutable &executable  = program->getExecutable();
2059     const BufferVariable &bufferVariable = executable.getBufferVariableByIndex(index);
2060 
2061     switch (prop)
2062     {
2063         case GL_TYPE:
2064         case GL_ARRAY_SIZE:
2065         case GL_NAME_LENGTH:
2066             return GetCommonVariableProperty(bufferVariable, prop);
2067 
2068         case GL_BLOCK_INDEX:
2069             return bufferVariable.pod.bufferIndex;
2070 
2071         case GL_OFFSET:
2072             return bufferVariable.pod.blockInfo.offset;
2073 
2074         case GL_ARRAY_STRIDE:
2075             return bufferVariable.pod.blockInfo.arrayStride;
2076 
2077         case GL_MATRIX_STRIDE:
2078             return bufferVariable.pod.blockInfo.matrixStride;
2079 
2080         case GL_IS_ROW_MAJOR:
2081             return static_cast<GLint>(bufferVariable.pod.blockInfo.isRowMajorMatrix);
2082 
2083         case GL_REFERENCED_BY_VERTEX_SHADER:
2084             return bufferVariable.isActive(ShaderType::Vertex);
2085 
2086         case GL_REFERENCED_BY_FRAGMENT_SHADER:
2087             return bufferVariable.isActive(ShaderType::Fragment);
2088 
2089         case GL_REFERENCED_BY_COMPUTE_SHADER:
2090             return bufferVariable.isActive(ShaderType::Compute);
2091 
2092         case GL_REFERENCED_BY_GEOMETRY_SHADER_EXT:
2093             return bufferVariable.isActive(ShaderType::Geometry);
2094 
2095         case GL_REFERENCED_BY_TESS_CONTROL_SHADER_EXT:
2096             return bufferVariable.isActive(ShaderType::TessControl);
2097 
2098         case GL_REFERENCED_BY_TESS_EVALUATION_SHADER_EXT:
2099             return bufferVariable.isActive(ShaderType::TessEvaluation);
2100 
2101         case GL_TOP_LEVEL_ARRAY_SIZE:
2102             return bufferVariable.pod.topLevelArraySize;
2103 
2104         case GL_TOP_LEVEL_ARRAY_STRIDE:
2105             return bufferVariable.pod.blockInfo.topLevelArrayStride;
2106 
2107         default:
2108             UNREACHABLE();
2109             return 0;
2110     }
2111 }
2112 
QueryProgramResourceIndex(const Program * program,GLenum programInterface,const GLchar * name)2113 GLuint QueryProgramResourceIndex(const Program *program,
2114                                  GLenum programInterface,
2115                                  const GLchar *name)
2116 {
2117     const ProgramExecutable &executable = program->getExecutable();
2118 
2119     switch (programInterface)
2120     {
2121         case GL_PROGRAM_INPUT:
2122             return executable.getInputResourceIndex(name);
2123 
2124         case GL_PROGRAM_OUTPUT:
2125             return executable.getOutputResourceIndex(name);
2126 
2127         case GL_UNIFORM:
2128             return executable.getUniformIndexFromName(name);
2129 
2130         case GL_BUFFER_VARIABLE:
2131             return executable.getBufferVariableIndexFromName(name);
2132 
2133         case GL_SHADER_STORAGE_BLOCK:
2134             return executable.getShaderStorageBlockIndex(name);
2135 
2136         case GL_UNIFORM_BLOCK:
2137             return executable.getUniformBlockIndex(name);
2138 
2139         case GL_TRANSFORM_FEEDBACK_VARYING:
2140             return executable.getTransformFeedbackVaryingResourceIndex(name);
2141 
2142         default:
2143             UNREACHABLE();
2144             return GL_INVALID_INDEX;
2145     }
2146 }
2147 
QueryProgramResourceName(const Context * context,const Program * program,GLenum programInterface,GLuint index,GLsizei bufSize,GLsizei * length,GLchar * name)2148 void QueryProgramResourceName(const Context *context,
2149                               const Program *program,
2150                               GLenum programInterface,
2151                               GLuint index,
2152                               GLsizei bufSize,
2153                               GLsizei *length,
2154                               GLchar *name)
2155 {
2156     const ProgramExecutable &executable = program->getExecutable();
2157 
2158     switch (programInterface)
2159     {
2160         case GL_PROGRAM_INPUT:
2161             executable.getInputResourceName(index, bufSize, length, name);
2162             break;
2163 
2164         case GL_PROGRAM_OUTPUT:
2165             executable.getOutputResourceName(index, bufSize, length, name);
2166             break;
2167 
2168         case GL_UNIFORM:
2169             executable.getUniformResourceName(index, bufSize, length, name);
2170             break;
2171 
2172         case GL_BUFFER_VARIABLE:
2173             executable.getBufferVariableResourceName(index, bufSize, length, name);
2174             break;
2175 
2176         case GL_SHADER_STORAGE_BLOCK:
2177             executable.getActiveShaderStorageBlockName(index, bufSize, length, name);
2178             break;
2179 
2180         case GL_UNIFORM_BLOCK:
2181             executable.getActiveUniformBlockName(context, {index}, bufSize, length, name);
2182             break;
2183 
2184         case GL_TRANSFORM_FEEDBACK_VARYING:
2185             executable.getTransformFeedbackVarying(index, bufSize, length, nullptr, nullptr, name);
2186             break;
2187 
2188         default:
2189             UNREACHABLE();
2190     }
2191 }
2192 
QueryProgramResourceLocation(const Program * program,GLenum programInterface,const GLchar * name)2193 GLint QueryProgramResourceLocation(const Program *program,
2194                                    GLenum programInterface,
2195                                    const GLchar *name)
2196 {
2197     const ProgramExecutable &executable = program->getExecutable();
2198 
2199     switch (programInterface)
2200     {
2201         case GL_PROGRAM_INPUT:
2202             return executable.getInputResourceLocation(name);
2203 
2204         case GL_PROGRAM_OUTPUT:
2205             return executable.getOutputResourceLocation(name);
2206 
2207         case GL_UNIFORM:
2208             return executable.getUniformLocation(name).value;
2209 
2210         default:
2211             UNREACHABLE();
2212             return -1;
2213     }
2214 }
2215 
QueryProgramResourceiv(const Program * program,GLenum programInterface,UniformBlockIndex index,GLsizei propCount,const GLenum * props,GLsizei bufSize,GLsizei * length,GLint * params)2216 void QueryProgramResourceiv(const Program *program,
2217                             GLenum programInterface,
2218                             UniformBlockIndex index,
2219                             GLsizei propCount,
2220                             const GLenum *props,
2221                             GLsizei bufSize,
2222                             GLsizei *length,
2223                             GLint *params)
2224 {
2225     if (!program->isLinked())
2226     {
2227         return;
2228     }
2229 
2230     if (length != nullptr)
2231     {
2232         *length = 0;
2233     }
2234 
2235     if (bufSize == 0)
2236     {
2237         // No room to write the results
2238         return;
2239     }
2240 
2241     GLsizei pos = 0;
2242     for (GLsizei i = 0; i < propCount; i++)
2243     {
2244         switch (programInterface)
2245         {
2246             case GL_PROGRAM_INPUT:
2247                 params[i] = GetInputResourceProperty(program, index.value, props[i]);
2248                 ++pos;
2249                 break;
2250 
2251             case GL_PROGRAM_OUTPUT:
2252                 params[i] = GetOutputResourceProperty(program, index.value, props[i]);
2253                 ++pos;
2254                 break;
2255 
2256             case GL_UNIFORM:
2257                 params[i] = GetUniformResourceProperty(program, index.value, props[i]);
2258                 ++pos;
2259                 break;
2260 
2261             case GL_BUFFER_VARIABLE:
2262                 params[i] = GetBufferVariableResourceProperty(program, index.value, props[i]);
2263                 ++pos;
2264                 break;
2265 
2266             case GL_UNIFORM_BLOCK:
2267                 GetUniformBlockResourceProperty(program, index.value, props[i], params, bufSize,
2268                                                 &pos);
2269                 break;
2270 
2271             case GL_SHADER_STORAGE_BLOCK:
2272                 GetShaderStorageBlockResourceProperty(program, index.value, props[i], params,
2273                                                       bufSize, &pos);
2274                 break;
2275 
2276             case GL_ATOMIC_COUNTER_BUFFER:
2277                 GetAtomicCounterBufferResourceProperty(program, index.value, props[i], params,
2278                                                        bufSize, &pos);
2279                 break;
2280 
2281             case GL_TRANSFORM_FEEDBACK_VARYING:
2282                 params[i] =
2283                     GetTransformFeedbackVaryingResourceProperty(program, index.value, props[i]);
2284                 ++pos;
2285                 break;
2286 
2287             default:
2288                 UNREACHABLE();
2289                 params[i] = GL_INVALID_VALUE;
2290         }
2291         if (pos == bufSize)
2292         {
2293             // Most properties return one value, but GL_ACTIVE_VARIABLES returns an array of values.
2294             // This checks not to break buffer bounds for such case.
2295             break;
2296         }
2297     }
2298 
2299     if (length != nullptr)
2300     {
2301         *length = pos;
2302     }
2303 }
2304 
QueryProgramInterfaceiv(const Program * program,GLenum programInterface,GLenum pname,GLint * params)2305 void QueryProgramInterfaceiv(const Program *program,
2306                              GLenum programInterface,
2307                              GLenum pname,
2308                              GLint *params)
2309 {
2310     switch (pname)
2311     {
2312         case GL_ACTIVE_RESOURCES:
2313             *params = QueryProgramInterfaceActiveResources(program, programInterface);
2314             break;
2315 
2316         case GL_MAX_NAME_LENGTH:
2317             *params = QueryProgramInterfaceMaxNameLength(program, programInterface);
2318             break;
2319 
2320         case GL_MAX_NUM_ACTIVE_VARIABLES:
2321             *params = QueryProgramInterfaceMaxNumActiveVariables(program, programInterface);
2322             break;
2323 
2324         default:
2325             UNREACHABLE();
2326     }
2327 }
2328 
SetMemoryObjectParameteriv(const Context * context,MemoryObject * memoryObject,GLenum pname,const GLint * params)2329 angle::Result SetMemoryObjectParameteriv(const Context *context,
2330                                          MemoryObject *memoryObject,
2331                                          GLenum pname,
2332                                          const GLint *params)
2333 {
2334     switch (pname)
2335     {
2336         case GL_DEDICATED_MEMORY_OBJECT_EXT:
2337             ANGLE_TRY(memoryObject->setDedicatedMemory(context, ConvertToBool(params[0])));
2338             break;
2339 
2340         case GL_PROTECTED_MEMORY_OBJECT_EXT:
2341             ANGLE_TRY(memoryObject->setProtectedMemory(context, ConvertToBool(params[0])));
2342             break;
2343 
2344         default:
2345             UNREACHABLE();
2346     }
2347 
2348     return angle::Result::Continue;
2349 }
2350 
QueryMemoryObjectParameteriv(const MemoryObject * memoryObject,GLenum pname,GLint * params)2351 void QueryMemoryObjectParameteriv(const MemoryObject *memoryObject, GLenum pname, GLint *params)
2352 {
2353     switch (pname)
2354     {
2355         case GL_DEDICATED_MEMORY_OBJECT_EXT:
2356             *params = memoryObject->isDedicatedMemory();
2357             break;
2358 
2359         case GL_PROTECTED_MEMORY_OBJECT_EXT:
2360             *params = memoryObject->isProtectedMemory();
2361             break;
2362 
2363         default:
2364             UNREACHABLE();
2365     }
2366 }
2367 
ParamToVertexArrayType(GLenum param)2368 ClientVertexArrayType ParamToVertexArrayType(GLenum param)
2369 {
2370     switch (param)
2371     {
2372         case GL_VERTEX_ARRAY:
2373         case GL_VERTEX_ARRAY_BUFFER_BINDING:
2374         case GL_VERTEX_ARRAY_STRIDE:
2375         case GL_VERTEX_ARRAY_SIZE:
2376         case GL_VERTEX_ARRAY_TYPE:
2377         case GL_VERTEX_ARRAY_POINTER:
2378             return ClientVertexArrayType::Vertex;
2379         case GL_NORMAL_ARRAY:
2380         case GL_NORMAL_ARRAY_BUFFER_BINDING:
2381         case GL_NORMAL_ARRAY_STRIDE:
2382         case GL_NORMAL_ARRAY_TYPE:
2383         case GL_NORMAL_ARRAY_POINTER:
2384             return ClientVertexArrayType::Normal;
2385         case GL_COLOR_ARRAY:
2386         case GL_COLOR_ARRAY_BUFFER_BINDING:
2387         case GL_COLOR_ARRAY_STRIDE:
2388         case GL_COLOR_ARRAY_SIZE:
2389         case GL_COLOR_ARRAY_TYPE:
2390         case GL_COLOR_ARRAY_POINTER:
2391             return ClientVertexArrayType::Color;
2392         case GL_POINT_SIZE_ARRAY_OES:
2393         case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
2394         case GL_POINT_SIZE_ARRAY_STRIDE_OES:
2395         case GL_POINT_SIZE_ARRAY_TYPE_OES:
2396         case GL_POINT_SIZE_ARRAY_POINTER_OES:
2397             return ClientVertexArrayType::PointSize;
2398         case GL_TEXTURE_COORD_ARRAY:
2399         case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
2400         case GL_TEXTURE_COORD_ARRAY_STRIDE:
2401         case GL_TEXTURE_COORD_ARRAY_SIZE:
2402         case GL_TEXTURE_COORD_ARRAY_TYPE:
2403         case GL_TEXTURE_COORD_ARRAY_POINTER:
2404             return ClientVertexArrayType::TextureCoord;
2405         default:
2406             UNREACHABLE();
2407             return ClientVertexArrayType::InvalidEnum;
2408     }
2409 }
2410 
SetLightModelParameters(GLES1State * state,GLenum pname,const GLfloat * params)2411 void SetLightModelParameters(GLES1State *state, GLenum pname, const GLfloat *params)
2412 {
2413     LightModelParameters &lightModel = state->lightModelParameters();
2414 
2415     switch (pname)
2416     {
2417         case GL_LIGHT_MODEL_AMBIENT:
2418             lightModel.color = ColorF::fromData(params);
2419             break;
2420         case GL_LIGHT_MODEL_TWO_SIDE:
2421             lightModel.twoSided = *params == 1.0f ? true : false;
2422             break;
2423         default:
2424             break;
2425     }
2426 }
2427 
GetLightModelParameters(const GLES1State * state,GLenum pname,GLfloat * params)2428 void GetLightModelParameters(const GLES1State *state, GLenum pname, GLfloat *params)
2429 {
2430     const LightModelParameters &lightModel = state->lightModelParameters();
2431 
2432     switch (pname)
2433     {
2434         case GL_LIGHT_MODEL_TWO_SIDE:
2435             *params = lightModel.twoSided ? 1.0f : 0.0f;
2436             break;
2437         case GL_LIGHT_MODEL_AMBIENT:
2438             lightModel.color.writeData(params);
2439             break;
2440         default:
2441             break;
2442     }
2443 }
2444 
IsLightModelTwoSided(const GLES1State * state)2445 bool IsLightModelTwoSided(const GLES1State *state)
2446 {
2447     return state->lightModelParameters().twoSided;
2448 }
2449 
SetLightParameters(GLES1State * state,GLenum light,LightParameter pname,const GLfloat * params)2450 void SetLightParameters(GLES1State *state,
2451                         GLenum light,
2452                         LightParameter pname,
2453                         const GLfloat *params)
2454 {
2455     uint32_t lightIndex = light - GL_LIGHT0;
2456 
2457     LightParameters &lightParams = state->lightParameters(lightIndex);
2458 
2459     switch (pname)
2460     {
2461         case LightParameter::Ambient:
2462             lightParams.ambient = ColorF::fromData(params);
2463             break;
2464         case LightParameter::Diffuse:
2465             lightParams.diffuse = ColorF::fromData(params);
2466             break;
2467         case LightParameter::Specular:
2468             lightParams.specular = ColorF::fromData(params);
2469             break;
2470         case LightParameter::Position:
2471         {
2472             angle::Mat4 mv = state->getModelviewMatrix();
2473             angle::Vector4 transformedPos =
2474                 mv.product(angle::Vector4(params[0], params[1], params[2], params[3]));
2475             lightParams.position[0] = transformedPos[0];
2476             lightParams.position[1] = transformedPos[1];
2477             lightParams.position[2] = transformedPos[2];
2478             lightParams.position[3] = transformedPos[3];
2479         }
2480         break;
2481         case LightParameter::SpotDirection:
2482         {
2483             angle::Mat4 mv = state->getModelviewMatrix();
2484             angle::Vector4 transformedPos =
2485                 mv.product(angle::Vector4(params[0], params[1], params[2], 0.0f));
2486             lightParams.direction[0] = transformedPos[0];
2487             lightParams.direction[1] = transformedPos[1];
2488             lightParams.direction[2] = transformedPos[2];
2489         }
2490         break;
2491         case LightParameter::SpotExponent:
2492             lightParams.spotlightExponent = *params;
2493             break;
2494         case LightParameter::SpotCutoff:
2495             lightParams.spotlightCutoffAngle = *params;
2496             break;
2497         case LightParameter::ConstantAttenuation:
2498             lightParams.attenuationConst = *params;
2499             break;
2500         case LightParameter::LinearAttenuation:
2501             lightParams.attenuationLinear = *params;
2502             break;
2503         case LightParameter::QuadraticAttenuation:
2504             lightParams.attenuationQuadratic = *params;
2505             break;
2506         default:
2507             return;
2508     }
2509 }
2510 
GetLightParameters(const GLES1State * state,GLenum light,LightParameter pname,GLfloat * params)2511 void GetLightParameters(const GLES1State *state,
2512                         GLenum light,
2513                         LightParameter pname,
2514                         GLfloat *params)
2515 {
2516     uint32_t lightIndex                = light - GL_LIGHT0;
2517     const LightParameters &lightParams = state->lightParameters(lightIndex);
2518 
2519     switch (pname)
2520     {
2521         case LightParameter::Ambient:
2522             lightParams.ambient.writeData(params);
2523             break;
2524         case LightParameter::Diffuse:
2525             lightParams.diffuse.writeData(params);
2526             break;
2527         case LightParameter::Specular:
2528             lightParams.specular.writeData(params);
2529             break;
2530         case LightParameter::Position:
2531             memcpy(params, lightParams.position.data(), 4 * sizeof(GLfloat));
2532             break;
2533         case LightParameter::SpotDirection:
2534             memcpy(params, lightParams.direction.data(), 3 * sizeof(GLfloat));
2535             break;
2536         case LightParameter::SpotExponent:
2537             *params = lightParams.spotlightExponent;
2538             break;
2539         case LightParameter::SpotCutoff:
2540             *params = lightParams.spotlightCutoffAngle;
2541             break;
2542         case LightParameter::ConstantAttenuation:
2543             *params = lightParams.attenuationConst;
2544             break;
2545         case LightParameter::LinearAttenuation:
2546             *params = lightParams.attenuationLinear;
2547             break;
2548         case LightParameter::QuadraticAttenuation:
2549             *params = lightParams.attenuationQuadratic;
2550             break;
2551         default:
2552             break;
2553     }
2554 }
2555 
SetMaterialParameters(GLES1State * state,GLenum face,MaterialParameter pname,const GLfloat * params)2556 void SetMaterialParameters(GLES1State *state,
2557                            GLenum face,
2558                            MaterialParameter pname,
2559                            const GLfloat *params)
2560 {
2561     // Note: Ambient and diffuse colors are inherited from glColor when COLOR_MATERIAL is enabled,
2562     // and can only be modified by this function if that is disabled:
2563     //
2564     // > the replaced values remain until changed by either sending a new color or by setting a
2565     // > new material value when COLOR_MATERIAL is not currently enabled, to override that
2566     // particular value.
2567 
2568     MaterialParameters &material = state->materialParameters();
2569     switch (pname)
2570     {
2571         case MaterialParameter::Ambient:
2572             if (!state->isColorMaterialEnabled())
2573             {
2574                 material.ambient = ColorF::fromData(params);
2575             }
2576             break;
2577         case MaterialParameter::Diffuse:
2578             if (!state->isColorMaterialEnabled())
2579             {
2580                 material.diffuse = ColorF::fromData(params);
2581             }
2582             break;
2583         case MaterialParameter::AmbientAndDiffuse:
2584             if (!state->isColorMaterialEnabled())
2585             {
2586                 material.ambient = ColorF::fromData(params);
2587                 material.diffuse = ColorF::fromData(params);
2588             }
2589             break;
2590         case MaterialParameter::Specular:
2591             material.specular = ColorF::fromData(params);
2592             break;
2593         case MaterialParameter::Emission:
2594             material.emissive = ColorF::fromData(params);
2595             break;
2596         case MaterialParameter::Shininess:
2597             material.specularExponent = *params;
2598             break;
2599         default:
2600             return;
2601     }
2602 }
2603 
GetMaterialParameters(const GLES1State * state,GLenum face,MaterialParameter pname,GLfloat * params)2604 void GetMaterialParameters(const GLES1State *state,
2605                            GLenum face,
2606                            MaterialParameter pname,
2607                            GLfloat *params)
2608 {
2609     const ColorF &currentColor         = state->getCurrentColor();
2610     const MaterialParameters &material = state->materialParameters();
2611     const bool colorMaterialEnabled    = state->isColorMaterialEnabled();
2612 
2613     switch (pname)
2614     {
2615         case MaterialParameter::Ambient:
2616             if (colorMaterialEnabled)
2617             {
2618                 currentColor.writeData(params);
2619             }
2620             else
2621             {
2622                 material.ambient.writeData(params);
2623             }
2624             break;
2625         case MaterialParameter::Diffuse:
2626             if (colorMaterialEnabled)
2627             {
2628                 currentColor.writeData(params);
2629             }
2630             else
2631             {
2632                 material.diffuse.writeData(params);
2633             }
2634             break;
2635         case MaterialParameter::Specular:
2636             material.specular.writeData(params);
2637             break;
2638         case MaterialParameter::Emission:
2639             material.emissive.writeData(params);
2640             break;
2641         case MaterialParameter::Shininess:
2642             *params = material.specularExponent;
2643             break;
2644         default:
2645             return;
2646     }
2647 }
2648 
GetLightModelParameterCount(GLenum pname)2649 unsigned int GetLightModelParameterCount(GLenum pname)
2650 {
2651     switch (pname)
2652     {
2653         case GL_LIGHT_MODEL_AMBIENT:
2654             return 4;
2655         case GL_LIGHT_MODEL_TWO_SIDE:
2656             return 1;
2657         default:
2658             UNREACHABLE();
2659             return 0;
2660     }
2661 }
2662 
GetLightParameterCount(LightParameter pname)2663 unsigned int GetLightParameterCount(LightParameter pname)
2664 {
2665     switch (pname)
2666     {
2667         case LightParameter::Ambient:
2668         case LightParameter::Diffuse:
2669         case LightParameter::AmbientAndDiffuse:
2670         case LightParameter::Specular:
2671         case LightParameter::Position:
2672             return 4;
2673         case LightParameter::SpotDirection:
2674             return 3;
2675         case LightParameter::SpotExponent:
2676         case LightParameter::SpotCutoff:
2677         case LightParameter::ConstantAttenuation:
2678         case LightParameter::LinearAttenuation:
2679         case LightParameter::QuadraticAttenuation:
2680             return 1;
2681         default:
2682             UNREACHABLE();
2683             return 0;
2684     }
2685 }
2686 
GetMaterialParameterCount(MaterialParameter pname)2687 unsigned int GetMaterialParameterCount(MaterialParameter pname)
2688 {
2689     switch (pname)
2690     {
2691         case MaterialParameter::Ambient:
2692         case MaterialParameter::Diffuse:
2693         case MaterialParameter::AmbientAndDiffuse:
2694         case MaterialParameter::Specular:
2695         case MaterialParameter::Emission:
2696             return 4;
2697         case MaterialParameter::Shininess:
2698             return 1;
2699         default:
2700             UNREACHABLE();
2701             return 0;
2702     }
2703 }
2704 
SetFogParameters(GLES1State * state,GLenum pname,const GLfloat * params)2705 void SetFogParameters(GLES1State *state, GLenum pname, const GLfloat *params)
2706 {
2707     FogParameters &fog = state->fogParameters();
2708     switch (pname)
2709     {
2710         case GL_FOG_MODE:
2711             fog.mode = FromGLenum<FogMode>(static_cast<GLenum>(params[0]));
2712             break;
2713         case GL_FOG_DENSITY:
2714             fog.density = params[0];
2715             break;
2716         case GL_FOG_START:
2717             fog.start = params[0];
2718             break;
2719         case GL_FOG_END:
2720             fog.end = params[0];
2721             break;
2722         case GL_FOG_COLOR:
2723             fog.color = ColorF::fromData(params);
2724             break;
2725         default:
2726             return;
2727     }
2728 }
2729 
GetFogParameters(const GLES1State * state,GLenum pname,GLfloat * params)2730 void GetFogParameters(const GLES1State *state, GLenum pname, GLfloat *params)
2731 {
2732     const FogParameters &fog = state->fogParameters();
2733     switch (pname)
2734     {
2735         case GL_FOG_MODE:
2736             params[0] = static_cast<GLfloat>(ToGLenum(fog.mode));
2737             break;
2738         case GL_FOG_DENSITY:
2739             params[0] = fog.density;
2740             break;
2741         case GL_FOG_START:
2742             params[0] = fog.start;
2743             break;
2744         case GL_FOG_END:
2745             params[0] = fog.end;
2746             break;
2747         case GL_FOG_COLOR:
2748             fog.color.writeData(params);
2749             break;
2750         default:
2751             return;
2752     }
2753 }
2754 
GetFogParameterCount(GLenum pname)2755 unsigned int GetFogParameterCount(GLenum pname)
2756 {
2757     switch (pname)
2758     {
2759         case GL_FOG_MODE:
2760         case GL_FOG_DENSITY:
2761         case GL_FOG_START:
2762         case GL_FOG_END:
2763             return 1;
2764         case GL_FOG_COLOR:
2765             return 4;
2766         default:
2767             return 0;
2768     }
2769 }
2770 
GetTextureEnvParameterCount(TextureEnvParameter pname)2771 unsigned int GetTextureEnvParameterCount(TextureEnvParameter pname)
2772 {
2773     switch (pname)
2774     {
2775         case TextureEnvParameter::Mode:
2776         case TextureEnvParameter::CombineRgb:
2777         case TextureEnvParameter::CombineAlpha:
2778         case TextureEnvParameter::Src0Rgb:
2779         case TextureEnvParameter::Src1Rgb:
2780         case TextureEnvParameter::Src2Rgb:
2781         case TextureEnvParameter::Src0Alpha:
2782         case TextureEnvParameter::Src1Alpha:
2783         case TextureEnvParameter::Src2Alpha:
2784         case TextureEnvParameter::Op0Rgb:
2785         case TextureEnvParameter::Op1Rgb:
2786         case TextureEnvParameter::Op2Rgb:
2787         case TextureEnvParameter::Op0Alpha:
2788         case TextureEnvParameter::Op1Alpha:
2789         case TextureEnvParameter::Op2Alpha:
2790         case TextureEnvParameter::RgbScale:
2791         case TextureEnvParameter::AlphaScale:
2792         case TextureEnvParameter::PointCoordReplace:
2793             return 1;
2794         case TextureEnvParameter::Color:
2795             return 4;
2796         default:
2797             return 0;
2798     }
2799 }
2800 
ConvertTextureEnvFromInt(TextureEnvParameter pname,const GLint * input,GLfloat * output)2801 void ConvertTextureEnvFromInt(TextureEnvParameter pname, const GLint *input, GLfloat *output)
2802 {
2803     if (IsTextureEnvEnumParameter(pname))
2804     {
2805         ConvertGLenumValue(input[0], output);
2806         return;
2807     }
2808 
2809     switch (pname)
2810     {
2811         case TextureEnvParameter::RgbScale:
2812         case TextureEnvParameter::AlphaScale:
2813             output[0] = static_cast<GLfloat>(input[0]);
2814             break;
2815         case TextureEnvParameter::Color:
2816             for (int i = 0; i < 4; i++)
2817             {
2818                 output[i] = input[i] / 255.0f;
2819             }
2820             break;
2821         default:
2822             UNREACHABLE();
2823             break;
2824     }
2825 }
2826 
ConvertTextureEnvFromFixed(TextureEnvParameter pname,const GLfixed * input,GLfloat * output)2827 void ConvertTextureEnvFromFixed(TextureEnvParameter pname, const GLfixed *input, GLfloat *output)
2828 {
2829     if (IsTextureEnvEnumParameter(pname))
2830     {
2831         ConvertGLenumValue(input[0], output);
2832         return;
2833     }
2834 
2835     switch (pname)
2836     {
2837         case TextureEnvParameter::RgbScale:
2838         case TextureEnvParameter::AlphaScale:
2839             output[0] = ConvertFixedToFloat(input[0]);
2840             break;
2841         case TextureEnvParameter::Color:
2842             for (int i = 0; i < 4; i++)
2843             {
2844                 output[i] = ConvertFixedToFloat(input[i]);
2845             }
2846             break;
2847         default:
2848             UNREACHABLE();
2849             break;
2850     }
2851 }
2852 
ConvertTextureEnvToInt(TextureEnvParameter pname,const GLfloat * input,GLint * output)2853 void ConvertTextureEnvToInt(TextureEnvParameter pname, const GLfloat *input, GLint *output)
2854 {
2855     if (IsTextureEnvEnumParameter(pname))
2856     {
2857         ConvertGLenumValue(input[0], output);
2858         return;
2859     }
2860 
2861     switch (pname)
2862     {
2863         case TextureEnvParameter::RgbScale:
2864         case TextureEnvParameter::AlphaScale:
2865             output[0] = static_cast<GLint>(input[0]);
2866             break;
2867         case TextureEnvParameter::Color:
2868             for (int i = 0; i < 4; i++)
2869             {
2870                 output[i] = static_cast<GLint>(input[i] * 255.0f);
2871             }
2872             break;
2873         default:
2874             UNREACHABLE();
2875             break;
2876     }
2877 }
2878 
ConvertTextureEnvToFixed(TextureEnvParameter pname,const GLfloat * input,GLfixed * output)2879 void ConvertTextureEnvToFixed(TextureEnvParameter pname, const GLfloat *input, GLfixed *output)
2880 {
2881     if (IsTextureEnvEnumParameter(pname))
2882     {
2883         ConvertGLenumValue(input[0], output);
2884         return;
2885     }
2886 
2887     switch (pname)
2888     {
2889         case TextureEnvParameter::RgbScale:
2890         case TextureEnvParameter::AlphaScale:
2891             output[0] = ConvertFloatToFixed(input[0]);
2892             break;
2893         case TextureEnvParameter::Color:
2894             for (int i = 0; i < 4; i++)
2895             {
2896                 output[i] = ConvertFloatToFixed(input[i]);
2897             }
2898             break;
2899         default:
2900             UNREACHABLE();
2901             break;
2902     }
2903 }
2904 
SetTextureEnv(unsigned int unit,GLES1State * state,TextureEnvTarget target,TextureEnvParameter pname,const GLfloat * params)2905 void SetTextureEnv(unsigned int unit,
2906                    GLES1State *state,
2907                    TextureEnvTarget target,
2908                    TextureEnvParameter pname,
2909                    const GLfloat *params)
2910 {
2911     TextureEnvironmentParameters &env = state->textureEnvironment(unit);
2912     GLenum asEnum                     = ConvertToGLenum(params[0]);
2913 
2914     switch (target)
2915     {
2916         case TextureEnvTarget::Env:
2917             switch (pname)
2918             {
2919                 case TextureEnvParameter::Mode:
2920                     env.mode = FromGLenum<TextureEnvMode>(asEnum);
2921                     break;
2922                 case TextureEnvParameter::CombineRgb:
2923                     env.combineRgb = FromGLenum<TextureCombine>(asEnum);
2924                     break;
2925                 case TextureEnvParameter::CombineAlpha:
2926                     env.combineAlpha = FromGLenum<TextureCombine>(asEnum);
2927                     break;
2928                 case TextureEnvParameter::Src0Rgb:
2929                     env.src0Rgb = FromGLenum<TextureSrc>(asEnum);
2930                     break;
2931                 case TextureEnvParameter::Src1Rgb:
2932                     env.src1Rgb = FromGLenum<TextureSrc>(asEnum);
2933                     break;
2934                 case TextureEnvParameter::Src2Rgb:
2935                     env.src2Rgb = FromGLenum<TextureSrc>(asEnum);
2936                     break;
2937                 case TextureEnvParameter::Src0Alpha:
2938                     env.src0Alpha = FromGLenum<TextureSrc>(asEnum);
2939                     break;
2940                 case TextureEnvParameter::Src1Alpha:
2941                     env.src1Alpha = FromGLenum<TextureSrc>(asEnum);
2942                     break;
2943                 case TextureEnvParameter::Src2Alpha:
2944                     env.src2Alpha = FromGLenum<TextureSrc>(asEnum);
2945                     break;
2946                 case TextureEnvParameter::Op0Rgb:
2947                     env.op0Rgb = FromGLenum<TextureOp>(asEnum);
2948                     break;
2949                 case TextureEnvParameter::Op1Rgb:
2950                     env.op1Rgb = FromGLenum<TextureOp>(asEnum);
2951                     break;
2952                 case TextureEnvParameter::Op2Rgb:
2953                     env.op2Rgb = FromGLenum<TextureOp>(asEnum);
2954                     break;
2955                 case TextureEnvParameter::Op0Alpha:
2956                     env.op0Alpha = FromGLenum<TextureOp>(asEnum);
2957                     break;
2958                 case TextureEnvParameter::Op1Alpha:
2959                     env.op1Alpha = FromGLenum<TextureOp>(asEnum);
2960                     break;
2961                 case TextureEnvParameter::Op2Alpha:
2962                     env.op2Alpha = FromGLenum<TextureOp>(asEnum);
2963                     break;
2964                 case TextureEnvParameter::Color:
2965                     env.color = ColorF::fromData(params);
2966                     break;
2967                 case TextureEnvParameter::RgbScale:
2968                     env.rgbScale = params[0];
2969                     break;
2970                 case TextureEnvParameter::AlphaScale:
2971                     env.alphaScale = params[0];
2972                     break;
2973                 default:
2974                     UNREACHABLE();
2975                     break;
2976             }
2977             break;
2978         case TextureEnvTarget::PointSprite:
2979             switch (pname)
2980             {
2981                 case TextureEnvParameter::PointCoordReplace:
2982                     env.pointSpriteCoordReplace = static_cast<bool>(params[0]);
2983                     break;
2984                 default:
2985                     UNREACHABLE();
2986                     break;
2987             }
2988             break;
2989         default:
2990             UNREACHABLE();
2991             break;
2992     }
2993 }
2994 
GetTextureEnv(unsigned int unit,const GLES1State * state,TextureEnvTarget target,TextureEnvParameter pname,GLfloat * params)2995 void GetTextureEnv(unsigned int unit,
2996                    const GLES1State *state,
2997                    TextureEnvTarget target,
2998                    TextureEnvParameter pname,
2999                    GLfloat *params)
3000 {
3001     const TextureEnvironmentParameters &env = state->textureEnvironment(unit);
3002 
3003     switch (target)
3004     {
3005         case TextureEnvTarget::Env:
3006             switch (pname)
3007             {
3008                 case TextureEnvParameter::Mode:
3009                     ConvertPackedEnum(env.mode, params);
3010                     break;
3011                 case TextureEnvParameter::CombineRgb:
3012                     ConvertPackedEnum(env.combineRgb, params);
3013                     break;
3014                 case TextureEnvParameter::CombineAlpha:
3015                     ConvertPackedEnum(env.combineAlpha, params);
3016                     break;
3017                 case TextureEnvParameter::Src0Rgb:
3018                     ConvertPackedEnum(env.src0Rgb, params);
3019                     break;
3020                 case TextureEnvParameter::Src1Rgb:
3021                     ConvertPackedEnum(env.src1Rgb, params);
3022                     break;
3023                 case TextureEnvParameter::Src2Rgb:
3024                     ConvertPackedEnum(env.src2Rgb, params);
3025                     break;
3026                 case TextureEnvParameter::Src0Alpha:
3027                     ConvertPackedEnum(env.src0Alpha, params);
3028                     break;
3029                 case TextureEnvParameter::Src1Alpha:
3030                     ConvertPackedEnum(env.src1Alpha, params);
3031                     break;
3032                 case TextureEnvParameter::Src2Alpha:
3033                     ConvertPackedEnum(env.src2Alpha, params);
3034                     break;
3035                 case TextureEnvParameter::Op0Rgb:
3036                     ConvertPackedEnum(env.op0Rgb, params);
3037                     break;
3038                 case TextureEnvParameter::Op1Rgb:
3039                     ConvertPackedEnum(env.op1Rgb, params);
3040                     break;
3041                 case TextureEnvParameter::Op2Rgb:
3042                     ConvertPackedEnum(env.op2Rgb, params);
3043                     break;
3044                 case TextureEnvParameter::Op0Alpha:
3045                     ConvertPackedEnum(env.op0Alpha, params);
3046                     break;
3047                 case TextureEnvParameter::Op1Alpha:
3048                     ConvertPackedEnum(env.op1Alpha, params);
3049                     break;
3050                 case TextureEnvParameter::Op2Alpha:
3051                     ConvertPackedEnum(env.op2Alpha, params);
3052                     break;
3053                 case TextureEnvParameter::Color:
3054                     env.color.writeData(params);
3055                     break;
3056                 case TextureEnvParameter::RgbScale:
3057                     *params = env.rgbScale;
3058                     break;
3059                 case TextureEnvParameter::AlphaScale:
3060                     *params = env.alphaScale;
3061                     break;
3062                 default:
3063                     UNREACHABLE();
3064                     break;
3065             }
3066             break;
3067         case TextureEnvTarget::PointSprite:
3068             switch (pname)
3069             {
3070                 case TextureEnvParameter::PointCoordReplace:
3071                     *params = static_cast<GLfloat>(env.pointSpriteCoordReplace);
3072                     break;
3073                 default:
3074                     UNREACHABLE();
3075                     break;
3076             }
3077             break;
3078         default:
3079             UNREACHABLE();
3080             break;
3081     }
3082 }
3083 
GetPointParameterCount(PointParameter pname)3084 unsigned int GetPointParameterCount(PointParameter pname)
3085 {
3086     switch (pname)
3087     {
3088         case PointParameter::PointSizeMin:
3089         case PointParameter::PointSizeMax:
3090         case PointParameter::PointFadeThresholdSize:
3091             return 1;
3092         case PointParameter::PointDistanceAttenuation:
3093             return 3;
3094         default:
3095             return 0;
3096     }
3097 }
3098 
SetPointParameter(GLES1State * state,PointParameter pname,const GLfloat * params)3099 void SetPointParameter(GLES1State *state, PointParameter pname, const GLfloat *params)
3100 {
3101 
3102     PointParameters &pointParams = state->pointParameters();
3103 
3104     switch (pname)
3105     {
3106         case PointParameter::PointSizeMin:
3107             pointParams.pointSizeMin = params[0];
3108             break;
3109         case PointParameter::PointSizeMax:
3110             pointParams.pointSizeMax = params[0];
3111             break;
3112         case PointParameter::PointFadeThresholdSize:
3113             pointParams.pointFadeThresholdSize = params[0];
3114             break;
3115         case PointParameter::PointDistanceAttenuation:
3116             for (unsigned int i = 0; i < 3; i++)
3117             {
3118                 pointParams.pointDistanceAttenuation[i] = params[i];
3119             }
3120             break;
3121         default:
3122             UNREACHABLE();
3123     }
3124 }
3125 
GetPointParameter(const GLES1State * state,PointParameter pname,GLfloat * params)3126 void GetPointParameter(const GLES1State *state, PointParameter pname, GLfloat *params)
3127 {
3128     const PointParameters &pointParams = state->pointParameters();
3129 
3130     switch (pname)
3131     {
3132         case PointParameter::PointSizeMin:
3133             params[0] = pointParams.pointSizeMin;
3134             break;
3135         case PointParameter::PointSizeMax:
3136             params[0] = pointParams.pointSizeMax;
3137             break;
3138         case PointParameter::PointFadeThresholdSize:
3139             params[0] = pointParams.pointFadeThresholdSize;
3140             break;
3141         case PointParameter::PointDistanceAttenuation:
3142             for (unsigned int i = 0; i < 3; i++)
3143             {
3144                 params[i] = pointParams.pointDistanceAttenuation[i];
3145             }
3146             break;
3147         default:
3148             UNREACHABLE();
3149     }
3150 }
3151 
SetPointSize(GLES1State * state,GLfloat size)3152 void SetPointSize(GLES1State *state, GLfloat size)
3153 {
3154     PointParameters &params = state->pointParameters();
3155     params.pointSize        = size;
3156 }
3157 
GetPointSize(const GLES1State * state,GLfloat * sizeOut)3158 void GetPointSize(const GLES1State *state, GLfloat *sizeOut)
3159 {
3160     const PointParameters &params = state->pointParameters();
3161     *sizeOut                      = params.pointSize;
3162 }
3163 
GetTexParameterCount(GLenum pname)3164 unsigned int GetTexParameterCount(GLenum pname)
3165 {
3166     switch (pname)
3167     {
3168         case GL_TEXTURE_CROP_RECT_OES:
3169         case GL_TEXTURE_BORDER_COLOR:
3170             return 4;
3171         case GL_TEXTURE_MAG_FILTER:
3172         case GL_TEXTURE_MIN_FILTER:
3173         case GL_TEXTURE_WRAP_S:
3174         case GL_TEXTURE_WRAP_T:
3175         case GL_TEXTURE_USAGE_ANGLE:
3176         case GL_TEXTURE_MAX_ANISOTROPY_EXT:
3177         case GL_TEXTURE_IMMUTABLE_FORMAT:
3178         case GL_TEXTURE_WRAP_R:
3179         case GL_TEXTURE_IMMUTABLE_LEVELS:
3180         case GL_TEXTURE_SWIZZLE_R:
3181         case GL_TEXTURE_SWIZZLE_G:
3182         case GL_TEXTURE_SWIZZLE_B:
3183         case GL_TEXTURE_SWIZZLE_A:
3184         case GL_TEXTURE_BASE_LEVEL:
3185         case GL_TEXTURE_MAX_LEVEL:
3186         case GL_TEXTURE_MIN_LOD:
3187         case GL_TEXTURE_MAX_LOD:
3188         case GL_TEXTURE_COMPARE_MODE:
3189         case GL_TEXTURE_COMPARE_FUNC:
3190         case GL_TEXTURE_SRGB_DECODE_EXT:
3191         case GL_DEPTH_STENCIL_TEXTURE_MODE:
3192         case GL_TEXTURE_NATIVE_ID_ANGLE:
3193         case GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES:
3194         case GL_RENDERABILITY_VALIDATION_ANGLE:
3195             return 1;
3196         default:
3197             return 0;
3198     }
3199 }
3200 
GetQueryParameterInfo(const State & glState,GLenum pname,GLenum * type,unsigned int * numParams)3201 bool GetQueryParameterInfo(const State &glState,
3202                            GLenum pname,
3203                            GLenum *type,
3204                            unsigned int *numParams)
3205 {
3206     const Caps &caps             = glState.getCaps();
3207     const Extensions &extensions = glState.getExtensions();
3208     GLint clientMajorVersion     = glState.getClientMajorVersion();
3209 
3210     // Please note: the query type returned for DEPTH_CLEAR_VALUE in this implementation
3211     // is FLOAT rather than INT, as would be suggested by the GL ES 2.0 spec. This is due
3212     // to the fact that it is stored internally as a float, and so would require conversion
3213     // if returned from Context::getIntegerv. Since this conversion is already implemented
3214     // in the case that one calls glGetIntegerv to retrieve a float-typed state variable, we
3215     // place DEPTH_CLEAR_VALUE with the floats. This should make no difference to the calling
3216     // application.
3217     switch (pname)
3218     {
3219         case GL_COMPRESSED_TEXTURE_FORMATS:
3220         {
3221             *type      = GL_INT;
3222             *numParams = static_cast<unsigned int>(caps.compressedTextureFormats.size());
3223             return true;
3224         }
3225         case GL_SHADER_BINARY_FORMATS:
3226         {
3227             *type      = GL_INT;
3228             *numParams = static_cast<unsigned int>(caps.shaderBinaryFormats.size());
3229             return true;
3230         }
3231 
3232         case GL_MAX_VERTEX_ATTRIBS:
3233         case GL_MAX_VERTEX_UNIFORM_VECTORS:
3234         case GL_MAX_VARYING_VECTORS:
3235         case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
3236         case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
3237         case GL_MAX_TEXTURE_IMAGE_UNITS:
3238         case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
3239         case GL_MAX_RENDERBUFFER_SIZE:
3240         case GL_NUM_SHADER_BINARY_FORMATS:
3241         case GL_NUM_COMPRESSED_TEXTURE_FORMATS:
3242         case GL_ARRAY_BUFFER_BINDING:
3243         case GL_FRAMEBUFFER_BINDING:  // GL_FRAMEBUFFER_BINDING now equivalent to
3244                                       // GL_DRAW_FRAMEBUFFER_BINDING
3245         case GL_RENDERBUFFER_BINDING:
3246         case GL_CURRENT_PROGRAM:
3247         case GL_PACK_ALIGNMENT:
3248         case GL_UNPACK_ALIGNMENT:
3249         case GL_GENERATE_MIPMAP_HINT:
3250         case GL_RED_BITS:
3251         case GL_GREEN_BITS:
3252         case GL_BLUE_BITS:
3253         case GL_ALPHA_BITS:
3254         case GL_DEPTH_BITS:
3255         case GL_STENCIL_BITS:
3256         case GL_ELEMENT_ARRAY_BUFFER_BINDING:
3257         case GL_CULL_FACE_MODE:
3258         case GL_FRONT_FACE:
3259         case GL_ACTIVE_TEXTURE:
3260         case GL_STENCIL_FUNC:
3261         case GL_STENCIL_VALUE_MASK:
3262         case GL_STENCIL_REF:
3263         case GL_STENCIL_FAIL:
3264         case GL_STENCIL_PASS_DEPTH_FAIL:
3265         case GL_STENCIL_PASS_DEPTH_PASS:
3266         case GL_STENCIL_BACK_FUNC:
3267         case GL_STENCIL_BACK_VALUE_MASK:
3268         case GL_STENCIL_BACK_REF:
3269         case GL_STENCIL_BACK_FAIL:
3270         case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
3271         case GL_STENCIL_BACK_PASS_DEPTH_PASS:
3272         case GL_DEPTH_FUNC:
3273         case GL_BLEND_SRC_RGB:
3274         case GL_BLEND_SRC_ALPHA:
3275         case GL_BLEND_DST_RGB:
3276         case GL_BLEND_DST_ALPHA:
3277         case GL_BLEND_EQUATION_RGB:
3278         case GL_BLEND_EQUATION_ALPHA:
3279         case GL_STENCIL_WRITEMASK:
3280         case GL_STENCIL_BACK_WRITEMASK:
3281         case GL_STENCIL_CLEAR_VALUE:
3282         case GL_SUBPIXEL_BITS:
3283         case GL_MAX_TEXTURE_SIZE:
3284         case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
3285         case GL_SAMPLE_BUFFERS:
3286         case GL_SAMPLES:
3287         case GL_IMPLEMENTATION_COLOR_READ_TYPE:
3288         case GL_IMPLEMENTATION_COLOR_READ_FORMAT:
3289         case GL_TEXTURE_BINDING_2D:
3290         case GL_TEXTURE_BINDING_CUBE_MAP:
3291         case GL_RESET_NOTIFICATION_STRATEGY_EXT:
3292         case GL_QUERY_COUNTER_BITS_EXT:
3293         {
3294             *type      = GL_INT;
3295             *numParams = 1;
3296             return true;
3297         }
3298         case GL_PACK_REVERSE_ROW_ORDER_ANGLE:
3299         {
3300             if (!extensions.packReverseRowOrderANGLE)
3301             {
3302                 return false;
3303             }
3304             *type      = GL_INT;
3305             *numParams = 1;
3306             return true;
3307         }
3308         case GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE:
3309         case GL_TEXTURE_BINDING_RECTANGLE_ANGLE:
3310         {
3311             if (!extensions.textureRectangleANGLE)
3312             {
3313                 return false;
3314             }
3315             *type      = GL_INT;
3316             *numParams = 1;
3317             return true;
3318         }
3319         case GL_MAX_DRAW_BUFFERS_EXT:
3320         case GL_MAX_COLOR_ATTACHMENTS_EXT:
3321         {
3322             if ((clientMajorVersion < 3) && !extensions.drawBuffersEXT)
3323             {
3324                 return false;
3325             }
3326             *type      = GL_INT;
3327             *numParams = 1;
3328             return true;
3329         }
3330         case GL_BLEND_ADVANCED_COHERENT_KHR:
3331         {
3332             if (clientMajorVersion < 2 || !extensions.blendEquationAdvancedCoherentKHR)
3333             {
3334                 return false;
3335             }
3336             *type      = GL_INT;
3337             *numParams = 1;
3338             return true;
3339         }
3340         case GL_MAX_VIEWPORT_DIMS:
3341         {
3342             *type      = GL_INT;
3343             *numParams = 2;
3344             return true;
3345         }
3346         case GL_VIEWPORT:
3347         case GL_SCISSOR_BOX:
3348         {
3349             *type      = GL_INT;
3350             *numParams = 4;
3351             return true;
3352         }
3353         case GL_SHADER_COMPILER:
3354         case GL_SAMPLE_COVERAGE_INVERT:
3355         case GL_DEPTH_WRITEMASK:
3356         case GL_CULL_FACE:                 // CULL_FACE through DITHER are natural to IsEnabled,
3357         case GL_POLYGON_OFFSET_FILL:       // but can be retrieved through the Get{Type}v queries.
3358         case GL_SAMPLE_ALPHA_TO_COVERAGE:  // For this purpose, they are treated here as
3359                                            // bool-natural
3360         case GL_SAMPLE_COVERAGE:
3361         case GL_SCISSOR_TEST:
3362         case GL_STENCIL_TEST:
3363         case GL_DEPTH_TEST:
3364         case GL_BLEND:
3365         case GL_DITHER:
3366         case GL_CONTEXT_ROBUST_ACCESS_EXT:
3367         {
3368             *type      = GL_BOOL;
3369             *numParams = 1;
3370             return true;
3371         }
3372         case GL_POLYGON_OFFSET_POINT_NV:
3373         {
3374             if (!extensions.polygonModeNV)
3375             {
3376                 return false;
3377             }
3378             *type      = GL_BOOL;
3379             *numParams = 1;
3380             return true;
3381         }
3382         case GL_POLYGON_OFFSET_LINE_NV:  // = GL_POLYGON_OFFSET_LINE_ANGLE
3383         {
3384             if (!extensions.polygonModeAny())
3385             {
3386                 return false;
3387             }
3388             *type      = GL_BOOL;
3389             *numParams = 1;
3390             return true;
3391         }
3392         case GL_DEPTH_CLAMP_EXT:
3393         {
3394             if (!extensions.depthClampEXT)
3395             {
3396                 return false;
3397             }
3398             *type      = GL_BOOL;
3399             *numParams = 1;
3400             return true;
3401         }
3402         case GL_COLOR_LOGIC_OP:
3403         {
3404             if (clientMajorVersion == 1)
3405             {
3406                 // Handle logicOp in GLES1 through GLES1 state management.
3407                 break;
3408             }
3409 
3410             if (!extensions.logicOpANGLE)
3411             {
3412                 return false;
3413             }
3414             *type      = GL_BOOL;
3415             *numParams = 1;
3416             return true;
3417         }
3418         case GL_COLOR_WRITEMASK:
3419         {
3420             *type      = GL_BOOL;
3421             *numParams = 4;
3422             return true;
3423         }
3424         case GL_POLYGON_OFFSET_FACTOR:
3425         case GL_POLYGON_OFFSET_UNITS:
3426         case GL_SAMPLE_COVERAGE_VALUE:
3427         case GL_DEPTH_CLEAR_VALUE:
3428         case GL_MULTISAMPLE_LINE_WIDTH_GRANULARITY:
3429         case GL_LINE_WIDTH:
3430         {
3431             *type      = GL_FLOAT;
3432             *numParams = 1;
3433             return true;
3434         }
3435         case GL_POLYGON_OFFSET_CLAMP_EXT:
3436             if (!extensions.polygonOffsetClampEXT)
3437             {
3438                 return false;
3439             }
3440             *type      = GL_FLOAT;
3441             *numParams = 1;
3442             return true;
3443         case GL_ALIASED_LINE_WIDTH_RANGE:
3444         case GL_MULTISAMPLE_LINE_WIDTH_RANGE:
3445         case GL_ALIASED_POINT_SIZE_RANGE:
3446         case GL_DEPTH_RANGE:
3447         {
3448             *type      = GL_FLOAT;
3449             *numParams = 2;
3450             return true;
3451         }
3452         case GL_COLOR_CLEAR_VALUE:
3453         case GL_BLEND_COLOR:
3454         {
3455             *type      = GL_FLOAT;
3456             *numParams = 4;
3457             return true;
3458         }
3459         case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT:
3460             if (!extensions.textureFilterAnisotropicEXT)
3461             {
3462                 return false;
3463             }
3464             *type      = GL_FLOAT;
3465             *numParams = 1;
3466             return true;
3467         case GL_TIMESTAMP_EXT:
3468             if (!extensions.disjointTimerQueryEXT)
3469             {
3470                 return false;
3471             }
3472             *type      = GL_INT_64_ANGLEX;
3473             *numParams = 1;
3474             return true;
3475         case GL_GPU_DISJOINT_EXT:
3476             if (!extensions.disjointTimerQueryEXT)
3477             {
3478                 return false;
3479             }
3480             *type      = GL_INT;
3481             *numParams = 1;
3482             return true;
3483         case GL_COVERAGE_MODULATION_CHROMIUM:
3484             if (!extensions.framebufferMixedSamplesCHROMIUM)
3485             {
3486                 return false;
3487             }
3488             *type      = GL_INT;
3489             *numParams = 1;
3490             return true;
3491         case GL_TEXTURE_BINDING_EXTERNAL_OES:
3492             if (!extensions.EGLStreamConsumerExternalNV && !extensions.EGLImageExternalOES)
3493             {
3494                 return false;
3495             }
3496             *type      = GL_INT;
3497             *numParams = 1;
3498             return true;
3499         case GL_MAX_CLIP_DISTANCES_EXT:  // case GL_MAX_CLIP_PLANES
3500         case GL_CLIP_DISTANCE0_EXT:
3501         case GL_CLIP_DISTANCE1_EXT:
3502         case GL_CLIP_DISTANCE2_EXT:
3503         case GL_CLIP_DISTANCE3_EXT:
3504         case GL_CLIP_DISTANCE4_EXT:
3505         case GL_CLIP_DISTANCE5_EXT:
3506         case GL_CLIP_DISTANCE6_EXT:
3507         case GL_CLIP_DISTANCE7_EXT:
3508             if (clientMajorVersion < 2)
3509             {
3510                 break;
3511             }
3512             if (!extensions.clipDistanceAPPLE && !extensions.clipCullDistanceAny())
3513             {
3514                 // NOTE(hqle): if client version is 1. GL_MAX_CLIP_DISTANCES_EXT is equal
3515                 // to GL_MAX_CLIP_PLANES which is a valid enum.
3516                 return false;
3517             }
3518             *type      = (pname == GL_MAX_CLIP_DISTANCES_EXT) ? GL_INT : GL_BOOL;
3519             *numParams = 1;
3520             return true;
3521         case GL_MAX_CULL_DISTANCES_EXT:
3522         case GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT:
3523             if (!extensions.clipCullDistanceAny())
3524             {
3525                 return false;
3526             }
3527             *type      = GL_INT;
3528             *numParams = 1;
3529             return true;
3530         case GL_CLIP_ORIGIN_EXT:
3531         case GL_CLIP_DEPTH_MODE_EXT:
3532             if (!extensions.clipControlEXT)
3533             {
3534                 return false;
3535             }
3536             *type      = GL_INT;
3537             *numParams = 1;
3538             return true;
3539         case GL_POLYGON_MODE_NV:  // = GL_POLYGON_MODE_ANGLE
3540         {
3541             if (!extensions.polygonModeAny())
3542             {
3543                 return false;
3544             }
3545             *type      = GL_INT;
3546             *numParams = 1;
3547             return true;
3548         }
3549         case GL_PRIMITIVE_BOUNDING_BOX:
3550             if (!extensions.primitiveBoundingBoxAny())
3551             {
3552                 return false;
3553             }
3554             *type      = GL_FLOAT;
3555             *numParams = 8;
3556             return true;
3557         case GL_SHADING_RATE_QCOM:
3558             if (!extensions.shadingRateQCOM)
3559             {
3560                 return false;
3561             }
3562             *type      = GL_INT;
3563             *numParams = 1;
3564             return true;
3565     }
3566 
3567     if (glState.getClientVersion() >= Version(3, 2))
3568     {
3569         switch (pname)
3570         {
3571             case GL_CONTEXT_FLAGS:
3572             {
3573                 *type      = GL_INT;
3574                 *numParams = 1;
3575                 return true;
3576             }
3577         }
3578     }
3579 
3580     if (extensions.debugKHR)
3581     {
3582         switch (pname)
3583         {
3584             case GL_DEBUG_LOGGED_MESSAGES:
3585             case GL_DEBUG_NEXT_LOGGED_MESSAGE_LENGTH:
3586             case GL_DEBUG_GROUP_STACK_DEPTH:
3587             case GL_MAX_DEBUG_MESSAGE_LENGTH:
3588             case GL_MAX_DEBUG_LOGGED_MESSAGES:
3589             case GL_MAX_DEBUG_GROUP_STACK_DEPTH:
3590             case GL_MAX_LABEL_LENGTH:
3591                 *type      = GL_INT;
3592                 *numParams = 1;
3593                 return true;
3594 
3595             case GL_DEBUG_OUTPUT_SYNCHRONOUS:
3596             case GL_DEBUG_OUTPUT:
3597                 *type      = GL_BOOL;
3598                 *numParams = 1;
3599                 return true;
3600         }
3601     }
3602 
3603     if (extensions.multisampleCompatibilityEXT)
3604     {
3605         switch (pname)
3606         {
3607             case GL_MULTISAMPLE_EXT:
3608             case GL_SAMPLE_ALPHA_TO_ONE_EXT:
3609                 *type      = GL_BOOL;
3610                 *numParams = 1;
3611                 return true;
3612         }
3613     }
3614 
3615     if (extensions.bindGeneratesResourceCHROMIUM)
3616     {
3617         switch (pname)
3618         {
3619             case GL_BIND_GENERATES_RESOURCE_CHROMIUM:
3620                 *type      = GL_BOOL;
3621                 *numParams = 1;
3622                 return true;
3623         }
3624     }
3625 
3626     if (extensions.clientArraysANGLE)
3627     {
3628         switch (pname)
3629         {
3630             case GL_CLIENT_ARRAYS_ANGLE:
3631                 *type      = GL_BOOL;
3632                 *numParams = 1;
3633                 return true;
3634         }
3635     }
3636 
3637     if (extensions.sRGBWriteControlEXT)
3638     {
3639         switch (pname)
3640         {
3641             case GL_FRAMEBUFFER_SRGB_EXT:
3642                 *type      = GL_BOOL;
3643                 *numParams = 1;
3644                 return true;
3645         }
3646     }
3647 
3648     if (extensions.robustResourceInitializationANGLE &&
3649         pname == GL_ROBUST_RESOURCE_INITIALIZATION_ANGLE)
3650     {
3651         *type      = GL_BOOL;
3652         *numParams = 1;
3653         return true;
3654     }
3655 
3656     if (extensions.programCacheControlANGLE && pname == GL_PROGRAM_CACHE_ENABLED_ANGLE)
3657     {
3658         *type      = GL_BOOL;
3659         *numParams = 1;
3660         return true;
3661     }
3662 
3663     if (extensions.parallelShaderCompileKHR && pname == GL_MAX_SHADER_COMPILER_THREADS_KHR)
3664     {
3665         *type      = GL_INT;
3666         *numParams = 1;
3667         return true;
3668     }
3669 
3670     if (extensions.blendFuncExtendedEXT && pname == GL_MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT)
3671     {
3672         *type      = GL_INT;
3673         *numParams = 1;
3674         return true;
3675     }
3676 
3677     if (extensions.robustFragmentShaderOutputANGLE &&
3678         pname == GL_ROBUST_FRAGMENT_SHADER_OUTPUT_ANGLE)
3679     {
3680         *type      = GL_BOOL;
3681         *numParams = 1;
3682         return true;
3683     }
3684 
3685     // Check for ES3.0+ parameter names which are also exposed as ES2 extensions
3686     switch (pname)
3687     {
3688         // GL_DRAW_FRAMEBUFFER_BINDING equivalent to GL_FRAMEBUFFER_BINDING
3689         case GL_READ_FRAMEBUFFER_BINDING:
3690             if ((clientMajorVersion < 3) && !extensions.framebufferBlitAny())
3691             {
3692                 return false;
3693             }
3694             *type      = GL_INT;
3695             *numParams = 1;
3696             return true;
3697 
3698         case GL_NUM_PROGRAM_BINARY_FORMATS_OES:
3699             if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES)
3700             {
3701                 return false;
3702             }
3703             *type      = GL_INT;
3704             *numParams = 1;
3705             return true;
3706 
3707         case GL_PROGRAM_BINARY_FORMATS_OES:
3708             if ((clientMajorVersion < 3) && !extensions.getProgramBinaryOES)
3709             {
3710                 return false;
3711             }
3712             *type      = GL_INT;
3713             *numParams = static_cast<unsigned int>(caps.programBinaryFormats.size());
3714             return true;
3715 
3716         case GL_PACK_ROW_LENGTH:
3717         case GL_PACK_SKIP_ROWS:
3718         case GL_PACK_SKIP_PIXELS:
3719             if ((clientMajorVersion < 3) && !extensions.packSubimageNV)
3720             {
3721                 return false;
3722             }
3723             *type      = GL_INT;
3724             *numParams = 1;
3725             return true;
3726         case GL_UNPACK_ROW_LENGTH:
3727         case GL_UNPACK_SKIP_ROWS:
3728         case GL_UNPACK_SKIP_PIXELS:
3729             if ((clientMajorVersion < 3) && !extensions.unpackSubimageEXT)
3730             {
3731                 return false;
3732             }
3733             *type      = GL_INT;
3734             *numParams = 1;
3735             return true;
3736         case GL_VERTEX_ARRAY_BINDING:
3737             if ((clientMajorVersion < 3) && !extensions.vertexArrayObjectOES)
3738             {
3739                 return false;
3740             }
3741             *type      = GL_INT;
3742             *numParams = 1;
3743             return true;
3744         case GL_PIXEL_PACK_BUFFER_BINDING:
3745         case GL_PIXEL_UNPACK_BUFFER_BINDING:
3746             if ((clientMajorVersion < 3) && !extensions.pixelBufferObjectNV)
3747             {
3748                 return false;
3749             }
3750             *type      = GL_INT;
3751             *numParams = 1;
3752             return true;
3753         case GL_MAX_SAMPLES:
3754             static_assert(GL_MAX_SAMPLES_ANGLE == GL_MAX_SAMPLES,
3755                           "GL_MAX_SAMPLES_ANGLE not equal to GL_MAX_SAMPLES");
3756             if ((clientMajorVersion < 3) && !(extensions.framebufferMultisampleANGLE ||
3757                                               extensions.multisampledRenderToTextureEXT))
3758             {
3759                 return false;
3760             }
3761             *type      = GL_INT;
3762             *numParams = 1;
3763             return true;
3764         case GL_FRAGMENT_SHADER_DERIVATIVE_HINT:
3765             if ((clientMajorVersion < 3) && !extensions.standardDerivativesOES)
3766             {
3767                 return false;
3768             }
3769             *type      = GL_INT;
3770             *numParams = 1;
3771             return true;
3772         case GL_TEXTURE_BINDING_3D:
3773             if ((clientMajorVersion < 3) && !extensions.texture3DOES)
3774             {
3775                 return false;
3776             }
3777             *type      = GL_INT;
3778             *numParams = 1;
3779             return true;
3780         case GL_MAX_3D_TEXTURE_SIZE:
3781             if ((clientMajorVersion < 3) && !extensions.texture3DOES)
3782             {
3783                 return false;
3784             }
3785             *type      = GL_INT;
3786             *numParams = 1;
3787             return true;
3788     }
3789 
3790     if (pname >= GL_DRAW_BUFFER0_EXT && pname <= GL_DRAW_BUFFER15_EXT)
3791     {
3792         if ((glState.getClientVersion() < Version(3, 0)) && !extensions.drawBuffersEXT)
3793         {
3794             return false;
3795         }
3796         *type      = GL_INT;
3797         *numParams = 1;
3798         return true;
3799     }
3800 
3801     if ((extensions.multiview2OVR || extensions.multiviewOVR) && pname == GL_MAX_VIEWS_OVR)
3802     {
3803         *type      = GL_INT;
3804         *numParams = 1;
3805         return true;
3806     }
3807 
3808     if (extensions.provokingVertexANGLE && pname == GL_PROVOKING_VERTEX_ANGLE)
3809     {
3810         *type      = GL_INT;
3811         *numParams = 1;
3812         return true;
3813     }
3814 
3815     if (extensions.shaderFramebufferFetchARM &&
3816         (pname == GL_FETCH_PER_SAMPLE_ARM || pname == GL_FRAGMENT_SHADER_FRAMEBUFFER_FETCH_MRT_ARM))
3817     {
3818         *type      = GL_BOOL;
3819         *numParams = 1;
3820         return true;
3821     }
3822 
3823     if (glState.getClientVersion() < Version(2, 0))
3824     {
3825         switch (pname)
3826         {
3827             case GL_ALPHA_TEST_FUNC:
3828             case GL_CLIENT_ACTIVE_TEXTURE:
3829             case GL_MATRIX_MODE:
3830             case GL_MAX_TEXTURE_UNITS:
3831             case GL_MAX_MODELVIEW_STACK_DEPTH:
3832             case GL_MAX_PROJECTION_STACK_DEPTH:
3833             case GL_MAX_TEXTURE_STACK_DEPTH:
3834             case GL_MAX_LIGHTS:
3835             case GL_MAX_CLIP_PLANES:
3836             case GL_VERTEX_ARRAY_STRIDE:
3837             case GL_NORMAL_ARRAY_STRIDE:
3838             case GL_COLOR_ARRAY_STRIDE:
3839             case GL_TEXTURE_COORD_ARRAY_STRIDE:
3840             case GL_VERTEX_ARRAY_SIZE:
3841             case GL_COLOR_ARRAY_SIZE:
3842             case GL_TEXTURE_COORD_ARRAY_SIZE:
3843             case GL_VERTEX_ARRAY_TYPE:
3844             case GL_NORMAL_ARRAY_TYPE:
3845             case GL_COLOR_ARRAY_TYPE:
3846             case GL_TEXTURE_COORD_ARRAY_TYPE:
3847             case GL_VERTEX_ARRAY_BUFFER_BINDING:
3848             case GL_NORMAL_ARRAY_BUFFER_BINDING:
3849             case GL_COLOR_ARRAY_BUFFER_BINDING:
3850             case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING:
3851             case GL_POINT_SIZE_ARRAY_STRIDE_OES:
3852             case GL_POINT_SIZE_ARRAY_TYPE_OES:
3853             case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES:
3854             case GL_SHADE_MODEL:
3855             case GL_MODELVIEW_STACK_DEPTH:
3856             case GL_PROJECTION_STACK_DEPTH:
3857             case GL_TEXTURE_STACK_DEPTH:
3858             case GL_LOGIC_OP_MODE:
3859             case GL_BLEND_SRC:
3860             case GL_BLEND_DST:
3861             case GL_PERSPECTIVE_CORRECTION_HINT:
3862             case GL_POINT_SMOOTH_HINT:
3863             case GL_LINE_SMOOTH_HINT:
3864             case GL_FOG_HINT:
3865                 *type      = GL_INT;
3866                 *numParams = 1;
3867                 return true;
3868             case GL_ALPHA_TEST_REF:
3869             case GL_FOG_DENSITY:
3870             case GL_FOG_START:
3871             case GL_FOG_END:
3872             case GL_FOG_MODE:
3873             case GL_POINT_SIZE:
3874             case GL_POINT_SIZE_MIN:
3875             case GL_POINT_SIZE_MAX:
3876             case GL_POINT_FADE_THRESHOLD_SIZE:
3877                 *type      = GL_FLOAT;
3878                 *numParams = 1;
3879                 return true;
3880             case GL_SMOOTH_POINT_SIZE_RANGE:
3881             case GL_SMOOTH_LINE_WIDTH_RANGE:
3882                 *type      = GL_FLOAT;
3883                 *numParams = 2;
3884                 return true;
3885             case GL_CURRENT_COLOR:
3886             case GL_CURRENT_TEXTURE_COORDS:
3887             case GL_LIGHT_MODEL_AMBIENT:
3888             case GL_FOG_COLOR:
3889                 *type      = GL_FLOAT;
3890                 *numParams = 4;
3891                 return true;
3892             case GL_CURRENT_NORMAL:
3893             case GL_POINT_DISTANCE_ATTENUATION:
3894                 *type      = GL_FLOAT;
3895                 *numParams = 3;
3896                 return true;
3897             case GL_MODELVIEW_MATRIX:
3898             case GL_PROJECTION_MATRIX:
3899             case GL_TEXTURE_MATRIX:
3900                 *type      = GL_FLOAT;
3901                 *numParams = 16;
3902                 return true;
3903             case GL_ALPHA_TEST:
3904             case GL_CLIP_PLANE0:
3905             case GL_CLIP_PLANE1:
3906             case GL_CLIP_PLANE2:
3907             case GL_CLIP_PLANE3:
3908             case GL_CLIP_PLANE4:
3909             case GL_CLIP_PLANE5:
3910             case GL_COLOR_ARRAY:
3911             case GL_COLOR_LOGIC_OP:
3912             case GL_COLOR_MATERIAL:
3913             case GL_FOG:
3914             case GL_LIGHT_MODEL_TWO_SIDE:
3915             case GL_LIGHT0:
3916             case GL_LIGHT1:
3917             case GL_LIGHT2:
3918             case GL_LIGHT3:
3919             case GL_LIGHT4:
3920             case GL_LIGHT5:
3921             case GL_LIGHT6:
3922             case GL_LIGHT7:
3923             case GL_LIGHTING:
3924             case GL_LINE_SMOOTH:
3925             case GL_NORMAL_ARRAY:
3926             case GL_NORMALIZE:
3927             case GL_POINT_SIZE_ARRAY_OES:
3928             case GL_POINT_SMOOTH:
3929             case GL_POINT_SPRITE_OES:
3930             case GL_RESCALE_NORMAL:
3931             case GL_TEXTURE_2D:
3932             case GL_TEXTURE_CUBE_MAP:
3933             case GL_TEXTURE_COORD_ARRAY:
3934             case GL_VERTEX_ARRAY:
3935                 *type      = GL_BOOL;
3936                 *numParams = 1;
3937                 return true;
3938         }
3939     }
3940 
3941     if (glState.getClientVersion() < Version(3, 0))
3942     {
3943         return false;
3944     }
3945 
3946     // Check for ES3.0+ parameter names
3947     switch (pname)
3948     {
3949         case GL_MAX_UNIFORM_BUFFER_BINDINGS:
3950         case GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT:
3951         case GL_UNIFORM_BUFFER_BINDING:
3952         case GL_TRANSFORM_FEEDBACK_BINDING:
3953         case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
3954         case GL_COPY_READ_BUFFER_BINDING:
3955         case GL_COPY_WRITE_BUFFER_BINDING:
3956         case GL_SAMPLER_BINDING:
3957         case GL_READ_BUFFER:
3958         case GL_TEXTURE_BINDING_3D:
3959         case GL_TEXTURE_BINDING_2D_ARRAY:
3960         case GL_MAX_ARRAY_TEXTURE_LAYERS:
3961         case GL_MAX_VERTEX_UNIFORM_BLOCKS:
3962         case GL_MAX_FRAGMENT_UNIFORM_BLOCKS:
3963         case GL_MAX_COMBINED_UNIFORM_BLOCKS:
3964         case GL_MAX_VERTEX_OUTPUT_COMPONENTS:
3965         case GL_MAX_FRAGMENT_INPUT_COMPONENTS:
3966         case GL_MAX_VARYING_COMPONENTS:
3967         case GL_MAX_VERTEX_UNIFORM_COMPONENTS:
3968         case GL_MAX_FRAGMENT_UNIFORM_COMPONENTS:
3969         case GL_MIN_PROGRAM_TEXEL_OFFSET:
3970         case GL_MAX_PROGRAM_TEXEL_OFFSET:
3971         case GL_NUM_EXTENSIONS:
3972         case GL_MAJOR_VERSION:
3973         case GL_MINOR_VERSION:
3974         case GL_MAX_ELEMENTS_INDICES:
3975         case GL_MAX_ELEMENTS_VERTICES:
3976         case GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS:
3977         case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS:
3978         case GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS:
3979         case GL_UNPACK_IMAGE_HEIGHT:
3980         case GL_UNPACK_SKIP_IMAGES:
3981         {
3982             *type      = GL_INT;
3983             *numParams = 1;
3984             return true;
3985         }
3986 
3987         case GL_MAX_ELEMENT_INDEX:
3988         case GL_MAX_UNIFORM_BLOCK_SIZE:
3989         case GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS:
3990         case GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS:
3991         case GL_MAX_SERVER_WAIT_TIMEOUT:
3992         {
3993             *type      = GL_INT_64_ANGLEX;
3994             *numParams = 1;
3995             return true;
3996         }
3997 
3998         case GL_TRANSFORM_FEEDBACK_ACTIVE:
3999         case GL_TRANSFORM_FEEDBACK_PAUSED:
4000         case GL_PRIMITIVE_RESTART_FIXED_INDEX:
4001         case GL_RASTERIZER_DISCARD:
4002         {
4003             *type      = GL_BOOL;
4004             *numParams = 1;
4005             return true;
4006         }
4007 
4008         case GL_MAX_TEXTURE_LOD_BIAS:
4009         {
4010             *type      = GL_FLOAT;
4011             *numParams = 1;
4012             return true;
4013         }
4014     }
4015 
4016     if (extensions.shaderMultisampleInterpolationOES)
4017     {
4018         switch (pname)
4019         {
4020             case GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES:
4021             case GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES:
4022             {
4023                 *type      = GL_FLOAT;
4024                 *numParams = 1;
4025                 return true;
4026             }
4027             case GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES:
4028             {
4029                 *type      = GL_INT;
4030                 *numParams = 1;
4031                 return true;
4032             }
4033         }
4034     }
4035 
4036     if (extensions.requestExtensionANGLE)
4037     {
4038         switch (pname)
4039         {
4040             case GL_NUM_REQUESTABLE_EXTENSIONS_ANGLE:
4041                 *type      = GL_INT;
4042                 *numParams = 1;
4043                 return true;
4044         }
4045     }
4046 
4047     if (glState.getClientVersion() >= Version(3, 1) || extensions.textureMultisampleANGLE)
4048     {
4049         static_assert(GL_SAMPLE_MASK_ANGLE == GL_SAMPLE_MASK);
4050         static_assert(GL_MAX_SAMPLE_MASK_WORDS_ANGLE == GL_MAX_SAMPLE_MASK_WORDS);
4051         static_assert(GL_MAX_COLOR_TEXTURE_SAMPLES_ANGLE == GL_MAX_COLOR_TEXTURE_SAMPLES);
4052         static_assert(GL_MAX_DEPTH_TEXTURE_SAMPLES_ANGLE == GL_MAX_DEPTH_TEXTURE_SAMPLES);
4053         static_assert(GL_MAX_INTEGER_SAMPLES_ANGLE == GL_MAX_INTEGER_SAMPLES);
4054         static_assert(GL_TEXTURE_BINDING_2D_MULTISAMPLE_ANGLE == GL_TEXTURE_BINDING_2D_MULTISAMPLE);
4055 
4056         switch (pname)
4057         {
4058             case GL_SAMPLE_MASK:
4059                 *type      = GL_BOOL;
4060                 *numParams = 1;
4061                 return true;
4062             case GL_MAX_SAMPLE_MASK_WORDS:
4063             case GL_MAX_COLOR_TEXTURE_SAMPLES:
4064             case GL_MAX_DEPTH_TEXTURE_SAMPLES:
4065             case GL_MAX_INTEGER_SAMPLES:
4066             case GL_TEXTURE_BINDING_2D_MULTISAMPLE:
4067                 *type      = GL_INT;
4068                 *numParams = 1;
4069                 return true;
4070         }
4071     }
4072 
4073     if (extensions.textureCubeMapArrayAny())
4074     {
4075         switch (pname)
4076         {
4077             case GL_TEXTURE_BINDING_CUBE_MAP_ARRAY:
4078                 *type      = GL_INT;
4079                 *numParams = 1;
4080                 return true;
4081         }
4082     }
4083 
4084     if (extensions.textureBufferAny())
4085     {
4086         switch (pname)
4087         {
4088             case GL_TEXTURE_BUFFER_BINDING:
4089             case GL_TEXTURE_BINDING_BUFFER:
4090             case GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT:
4091             case GL_MAX_TEXTURE_BUFFER_SIZE:
4092                 *type      = GL_INT;
4093                 *numParams = 1;
4094                 return true;
4095         }
4096     }
4097 
4098     if (extensions.shaderPixelLocalStorageANGLE)
4099     {
4100         switch (pname)
4101         {
4102             case GL_MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE:
4103             case GL_MAX_COMBINED_DRAW_BUFFERS_AND_PIXEL_LOCAL_STORAGE_PLANES_ANGLE:
4104             case GL_PIXEL_LOCAL_STORAGE_ACTIVE_PLANES_ANGLE:
4105                 *type      = GL_INT;
4106                 *numParams = 1;
4107                 return true;
4108         }
4109     }
4110 
4111     if (glState.getClientVersion() >= Version(3, 2) ||
4112         extensions.textureStorageMultisample2dArrayOES)
4113     {
4114         switch (pname)
4115         {
4116             case GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY:
4117                 *type      = GL_INT;
4118                 *numParams = 1;
4119                 return true;
4120         }
4121     }
4122 
4123     if (glState.getClientVersion() < Version(3, 1))
4124     {
4125         return false;
4126     }
4127 
4128     // Check for ES3.1+ parameter names
4129     switch (pname)
4130     {
4131         case GL_ATOMIC_COUNTER_BUFFER_BINDING:
4132         case GL_DRAW_INDIRECT_BUFFER_BINDING:
4133         case GL_DISPATCH_INDIRECT_BUFFER_BINDING:
4134         case GL_MAX_FRAMEBUFFER_WIDTH:
4135         case GL_MAX_FRAMEBUFFER_HEIGHT:
4136         case GL_MAX_FRAMEBUFFER_SAMPLES:
4137         case GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET:
4138         case GL_MAX_VERTEX_ATTRIB_BINDINGS:
4139         case GL_MAX_VERTEX_ATTRIB_STRIDE:
4140         case GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS:
4141         case GL_MAX_VERTEX_ATOMIC_COUNTERS:
4142         case GL_MAX_VERTEX_IMAGE_UNIFORMS:
4143         case GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS:
4144         case GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS:
4145         case GL_MAX_FRAGMENT_ATOMIC_COUNTERS:
4146         case GL_MAX_FRAGMENT_IMAGE_UNIFORMS:
4147         case GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS:
4148         case GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET:
4149         case GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET:
4150         case GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS:
4151         case GL_MAX_COMPUTE_UNIFORM_BLOCKS:
4152         case GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS:
4153         case GL_MAX_COMPUTE_SHARED_MEMORY_SIZE:
4154         case GL_MAX_COMPUTE_UNIFORM_COMPONENTS:
4155         case GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS:
4156         case GL_MAX_COMPUTE_ATOMIC_COUNTERS:
4157         case GL_MAX_COMPUTE_IMAGE_UNIFORMS:
4158         case GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS:
4159         case GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS:
4160         case GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES:
4161         case GL_MAX_UNIFORM_LOCATIONS:
4162         case GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS:
4163         case GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE:
4164         case GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS:
4165         case GL_MAX_COMBINED_ATOMIC_COUNTERS:
4166         case GL_MAX_IMAGE_UNITS:
4167         case GL_MAX_COMBINED_IMAGE_UNIFORMS:
4168         case GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS:
4169         case GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS:
4170         case GL_SHADER_STORAGE_BUFFER_BINDING:
4171         case GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT:
4172         case GL_PROGRAM_PIPELINE_BINDING:
4173             *type      = GL_INT;
4174             *numParams = 1;
4175             return true;
4176         case GL_MAX_SHADER_STORAGE_BLOCK_SIZE:
4177             *type      = GL_INT_64_ANGLEX;
4178             *numParams = 1;
4179             return true;
4180         case GL_SAMPLE_SHADING:
4181             *type      = GL_BOOL;
4182             *numParams = 1;
4183             return true;
4184         case GL_MIN_SAMPLE_SHADING_VALUE:
4185             *type      = GL_FLOAT;
4186             *numParams = 1;
4187             return true;
4188     }
4189 
4190     if (extensions.geometryShaderAny())
4191     {
4192         switch (pname)
4193         {
4194             case GL_MAX_FRAMEBUFFER_LAYERS_EXT:
4195             case GL_LAYER_PROVOKING_VERTEX_EXT:
4196             case GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT:
4197             case GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT:
4198             case GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT:
4199             case GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT:
4200             case GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT:
4201             case GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT:
4202             case GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT:
4203             case GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT:
4204             case GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT:
4205             case GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT:
4206             case GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT:
4207             case GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT:
4208             case GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT:
4209                 *type      = GL_INT;
4210                 *numParams = 1;
4211                 return true;
4212         }
4213     }
4214 
4215     if (extensions.tessellationShaderAny())
4216     {
4217         switch (pname)
4218         {
4219             case GL_PRIMITIVE_RESTART_FOR_PATCHES_SUPPORTED:
4220                 *type      = GL_BOOL;
4221                 *numParams = 1;
4222                 return true;
4223             case GL_PATCH_VERTICES:
4224             case GL_MAX_PATCH_VERTICES_EXT:
4225             case GL_MAX_TESS_GEN_LEVEL_EXT:
4226             case GL_MAX_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
4227             case GL_MAX_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
4228             case GL_MAX_TESS_CONTROL_TEXTURE_IMAGE_UNITS_EXT:
4229             case GL_MAX_TESS_EVALUATION_TEXTURE_IMAGE_UNITS_EXT:
4230             case GL_MAX_TESS_CONTROL_OUTPUT_COMPONENTS_EXT:
4231             case GL_MAX_TESS_PATCH_COMPONENTS_EXT:
4232             case GL_MAX_TESS_CONTROL_TOTAL_OUTPUT_COMPONENTS_EXT:
4233             case GL_MAX_TESS_EVALUATION_OUTPUT_COMPONENTS_EXT:
4234             case GL_MAX_TESS_CONTROL_UNIFORM_BLOCKS_EXT:
4235             case GL_MAX_TESS_EVALUATION_UNIFORM_BLOCKS_EXT:
4236             case GL_MAX_TESS_CONTROL_INPUT_COMPONENTS_EXT:
4237             case GL_MAX_TESS_EVALUATION_INPUT_COMPONENTS_EXT:
4238             case GL_MAX_COMBINED_TESS_CONTROL_UNIFORM_COMPONENTS_EXT:
4239             case GL_MAX_COMBINED_TESS_EVALUATION_UNIFORM_COMPONENTS_EXT:
4240             case GL_MAX_TESS_CONTROL_ATOMIC_COUNTER_BUFFERS_EXT:
4241             case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTER_BUFFERS_EXT:
4242             case GL_MAX_TESS_CONTROL_ATOMIC_COUNTERS_EXT:
4243             case GL_MAX_TESS_EVALUATION_ATOMIC_COUNTERS_EXT:
4244             case GL_MAX_TESS_CONTROL_IMAGE_UNIFORMS_EXT:
4245             case GL_MAX_TESS_EVALUATION_IMAGE_UNIFORMS_EXT:
4246             case GL_MAX_TESS_CONTROL_SHADER_STORAGE_BLOCKS_EXT:
4247             case GL_MAX_TESS_EVALUATION_SHADER_STORAGE_BLOCKS_EXT:
4248                 *type      = GL_INT;
4249                 *numParams = 1;
4250                 return true;
4251         }
4252     }
4253 
4254     return false;
4255 }
4256 
GetIndexedQueryParameterInfo(const State & glState,GLenum target,GLenum * type,unsigned int * numParams)4257 bool GetIndexedQueryParameterInfo(const State &glState,
4258                                   GLenum target,
4259                                   GLenum *type,
4260                                   unsigned int *numParams)
4261 {
4262     const Extensions &extensions = glState.getExtensions();
4263     const Version &clientVersion = glState.getClientVersion();
4264 
4265     ASSERT(clientVersion >= ES_3_0);
4266 
4267     switch (target)
4268     {
4269         case GL_TRANSFORM_FEEDBACK_BUFFER_BINDING:
4270         case GL_UNIFORM_BUFFER_BINDING:
4271         {
4272             *type      = GL_INT;
4273             *numParams = 1;
4274             return true;
4275         }
4276         case GL_TRANSFORM_FEEDBACK_BUFFER_START:
4277         case GL_TRANSFORM_FEEDBACK_BUFFER_SIZE:
4278         case GL_UNIFORM_BUFFER_START:
4279         case GL_UNIFORM_BUFFER_SIZE:
4280         {
4281             *type      = GL_INT_64_ANGLEX;
4282             *numParams = 1;
4283             return true;
4284         }
4285     }
4286 
4287     if (clientVersion >= ES_3_1 || extensions.textureMultisampleANGLE)
4288     {
4289         static_assert(GL_SAMPLE_MASK_VALUE_ANGLE == GL_SAMPLE_MASK_VALUE);
4290         switch (target)
4291         {
4292             case GL_SAMPLE_MASK_VALUE:
4293             {
4294                 *type      = GL_INT;
4295                 *numParams = 1;
4296                 return true;
4297             }
4298         }
4299     }
4300 
4301     if (clientVersion >= ES_3_2 || extensions.drawBuffersIndexedAny())
4302     {
4303         switch (target)
4304         {
4305             case GL_BLEND_SRC_RGB:
4306             case GL_BLEND_SRC_ALPHA:
4307             case GL_BLEND_DST_RGB:
4308             case GL_BLEND_DST_ALPHA:
4309             case GL_BLEND_EQUATION_RGB:
4310             case GL_BLEND_EQUATION_ALPHA:
4311             {
4312                 *type      = GL_INT;
4313                 *numParams = 1;
4314                 return true;
4315             }
4316             case GL_COLOR_WRITEMASK:
4317             {
4318                 *type      = GL_BOOL;
4319                 *numParams = 4;
4320                 return true;
4321             }
4322         }
4323     }
4324 
4325     if (clientVersion < ES_3_1)
4326     {
4327         return false;
4328     }
4329 
4330     switch (target)
4331     {
4332         case GL_IMAGE_BINDING_LAYERED:
4333         {
4334             *type      = GL_BOOL;
4335             *numParams = 1;
4336             return true;
4337         }
4338         case GL_MAX_COMPUTE_WORK_GROUP_COUNT:
4339         case GL_MAX_COMPUTE_WORK_GROUP_SIZE:
4340         case GL_ATOMIC_COUNTER_BUFFER_BINDING:
4341         case GL_SHADER_STORAGE_BUFFER_BINDING:
4342         case GL_VERTEX_BINDING_BUFFER:
4343         case GL_VERTEX_BINDING_DIVISOR:
4344         case GL_VERTEX_BINDING_OFFSET:
4345         case GL_VERTEX_BINDING_STRIDE:
4346         case GL_IMAGE_BINDING_NAME:
4347         case GL_IMAGE_BINDING_LEVEL:
4348         case GL_IMAGE_BINDING_LAYER:
4349         case GL_IMAGE_BINDING_ACCESS:
4350         case GL_IMAGE_BINDING_FORMAT:
4351         {
4352             *type      = GL_INT;
4353             *numParams = 1;
4354             return true;
4355         }
4356         case GL_ATOMIC_COUNTER_BUFFER_START:
4357         case GL_ATOMIC_COUNTER_BUFFER_SIZE:
4358         case GL_SHADER_STORAGE_BUFFER_START:
4359         case GL_SHADER_STORAGE_BUFFER_SIZE:
4360         {
4361             *type      = GL_INT_64_ANGLEX;
4362             *numParams = 1;
4363             return true;
4364         }
4365     }
4366 
4367     return false;
4368 }
4369 
QueryProgramPipelineiv(const Context * context,ProgramPipeline * programPipeline,GLenum pname,GLint * params)4370 void QueryProgramPipelineiv(const Context *context,
4371                             ProgramPipeline *programPipeline,
4372                             GLenum pname,
4373                             GLint *params)
4374 {
4375     if (!params)
4376     {
4377         // Can't write the result anywhere, so just return immediately.
4378         return;
4379     }
4380 
4381     switch (pname)
4382     {
4383         case GL_ACTIVE_PROGRAM:
4384         {
4385             // the name of the active program object of the program pipeline object is returned in
4386             // params
4387             *params = 0;
4388             if (programPipeline)
4389             {
4390                 const Program *program = programPipeline->getActiveShaderProgram();
4391                 if (program)
4392                 {
4393                     *params = program->id().value;
4394                 }
4395             }
4396             break;
4397         }
4398 
4399         case GL_VERTEX_SHADER:
4400         {
4401             // the name of the current program object for the vertex shader type of the program
4402             // pipeline object is returned in params
4403             GetShaderProgramId(programPipeline, ShaderType::Vertex, params);
4404             break;
4405         }
4406 
4407         case GL_FRAGMENT_SHADER:
4408         {
4409             // the name of the current program object for the fragment shader type of the program
4410             // pipeline object is returned in params
4411             GetShaderProgramId(programPipeline, ShaderType::Fragment, params);
4412             break;
4413         }
4414 
4415         case GL_TESS_CONTROL_SHADER:
4416         {
4417             // the name of the current program object for the tessellation control shader type of
4418             // the program pipeline object is returned in params
4419             GetShaderProgramId(programPipeline, ShaderType::TessControl, params);
4420             break;
4421         }
4422 
4423         case GL_TESS_EVALUATION_SHADER:
4424         {
4425             // the name of the current program object for the tessellation evaluation shader type of
4426             // the program pipeline object is returned in params
4427             GetShaderProgramId(programPipeline, ShaderType::TessEvaluation, params);
4428             break;
4429         }
4430 
4431         case GL_COMPUTE_SHADER:
4432         {
4433             // the name of the current program object for the compute shader type of the program
4434             // pipeline object is returned in params
4435             GetShaderProgramId(programPipeline, ShaderType::Compute, params);
4436             break;
4437         }
4438 
4439         case GL_GEOMETRY_SHADER:
4440         {
4441             // the name of the current program object for the geometry shader type of the program
4442             // pipeline object is returned in params
4443             GetShaderProgramId(programPipeline, ShaderType::Geometry, params);
4444             break;
4445         }
4446 
4447         case GL_INFO_LOG_LENGTH:
4448         {
4449             // the length of the info log, including the null terminator, is returned in params. If
4450             // there is no info log, zero is returned.
4451             *params = 0;
4452             if (programPipeline)
4453             {
4454                 *params = programPipeline->getInfoLogLength();
4455             }
4456             break;
4457         }
4458 
4459         case GL_VALIDATE_STATUS:
4460         {
4461             // the validation status of pipeline, as determined by glValidateProgramPipeline, is
4462             // returned in params
4463             *params = 0;
4464             if (programPipeline)
4465             {
4466                 *params = programPipeline->isValid();
4467             }
4468             break;
4469         }
4470 
4471         default:
4472             break;
4473     }
4474 }
4475 
4476 }  // namespace gl
4477 
4478 namespace egl
4479 {
4480 
QueryConfigAttrib(const Config * config,EGLint attribute,EGLint * value)4481 void QueryConfigAttrib(const Config *config, EGLint attribute, EGLint *value)
4482 {
4483     ASSERT(config != nullptr);
4484     switch (attribute)
4485     {
4486         case EGL_BUFFER_SIZE:
4487             *value = config->bufferSize;
4488             break;
4489         case EGL_ALPHA_SIZE:
4490             *value = config->alphaSize;
4491             break;
4492         case EGL_BLUE_SIZE:
4493             *value = config->blueSize;
4494             break;
4495         case EGL_GREEN_SIZE:
4496             *value = config->greenSize;
4497             break;
4498         case EGL_RED_SIZE:
4499             *value = config->redSize;
4500             break;
4501         case EGL_DEPTH_SIZE:
4502             *value = config->depthSize;
4503             break;
4504         case EGL_STENCIL_SIZE:
4505             *value = config->stencilSize;
4506             break;
4507         case EGL_CONFIG_CAVEAT:
4508             *value = config->configCaveat;
4509             break;
4510         case EGL_CONFIG_ID:
4511             *value = config->configID;
4512             break;
4513         case EGL_LEVEL:
4514             *value = config->level;
4515             break;
4516         case EGL_NATIVE_RENDERABLE:
4517             *value = config->nativeRenderable;
4518             break;
4519         case EGL_NATIVE_VISUAL_ID:
4520             *value = config->nativeVisualID;
4521             break;
4522         case EGL_NATIVE_VISUAL_TYPE:
4523             *value = config->nativeVisualType;
4524             break;
4525         case EGL_SAMPLES:
4526             *value = config->samples;
4527             break;
4528         case EGL_SAMPLE_BUFFERS:
4529             *value = config->sampleBuffers;
4530             break;
4531         case EGL_SURFACE_TYPE:
4532             *value = config->surfaceType;
4533             break;
4534         case EGL_BIND_TO_TEXTURE_TARGET_ANGLE:
4535             *value = config->bindToTextureTarget;
4536             break;
4537         case EGL_TRANSPARENT_TYPE:
4538             *value = config->transparentType;
4539             break;
4540         case EGL_TRANSPARENT_BLUE_VALUE:
4541             *value = config->transparentBlueValue;
4542             break;
4543         case EGL_TRANSPARENT_GREEN_VALUE:
4544             *value = config->transparentGreenValue;
4545             break;
4546         case EGL_TRANSPARENT_RED_VALUE:
4547             *value = config->transparentRedValue;
4548             break;
4549         case EGL_BIND_TO_TEXTURE_RGB:
4550             *value = config->bindToTextureRGB;
4551             break;
4552         case EGL_BIND_TO_TEXTURE_RGBA:
4553             *value = config->bindToTextureRGBA;
4554             break;
4555         case EGL_MIN_SWAP_INTERVAL:
4556             *value = config->minSwapInterval;
4557             break;
4558         case EGL_MAX_SWAP_INTERVAL:
4559             *value = config->maxSwapInterval;
4560             break;
4561         case EGL_LUMINANCE_SIZE:
4562             *value = config->luminanceSize;
4563             break;
4564         case EGL_ALPHA_MASK_SIZE:
4565             *value = config->alphaMaskSize;
4566             break;
4567         case EGL_COLOR_BUFFER_TYPE:
4568             *value = config->colorBufferType;
4569             break;
4570         case EGL_RENDERABLE_TYPE:
4571             *value = config->renderableType;
4572             break;
4573         case EGL_MATCH_NATIVE_PIXMAP:
4574             *value = false;
4575             UNIMPLEMENTED();
4576             break;
4577         case EGL_CONFORMANT:
4578             *value = config->conformant;
4579             break;
4580         case EGL_MAX_PBUFFER_WIDTH:
4581             *value = config->maxPBufferWidth;
4582             break;
4583         case EGL_MAX_PBUFFER_HEIGHT:
4584             *value = config->maxPBufferHeight;
4585             break;
4586         case EGL_MAX_PBUFFER_PIXELS:
4587             *value = config->maxPBufferPixels;
4588             break;
4589         case EGL_OPTIMAL_SURFACE_ORIENTATION_ANGLE:
4590             *value = config->optimalOrientation;
4591             break;
4592         case EGL_COLOR_COMPONENT_TYPE_EXT:
4593             *value = config->colorComponentType;
4594             break;
4595         case EGL_RECORDABLE_ANDROID:
4596             *value = config->recordable;
4597             break;
4598         case EGL_FRAMEBUFFER_TARGET_ANDROID:
4599             *value = config->framebufferTarget;
4600             break;
4601         case EGL_MATCH_FORMAT_KHR:
4602             *value = config->matchFormat;
4603             break;
4604         default:
4605             UNREACHABLE();
4606             break;
4607     }
4608 }
4609 
QueryContextAttrib(const gl::Context * context,EGLint attribute,EGLint * value)4610 void QueryContextAttrib(const gl::Context *context, EGLint attribute, EGLint *value)
4611 {
4612     switch (attribute)
4613     {
4614         case EGL_CONFIG_ID:
4615             if (context->getConfig() != EGL_NO_CONFIG_KHR)
4616             {
4617                 *value = context->getConfig()->configID;
4618             }
4619             else
4620             {
4621                 *value = 0;
4622             }
4623             break;
4624         case EGL_CONTEXT_CLIENT_TYPE:
4625             *value = EGL_OPENGL_ES_API;
4626             break;
4627         case EGL_CONTEXT_MAJOR_VERSION:
4628             static_assert(EGL_CONTEXT_MAJOR_VERSION == EGL_CONTEXT_CLIENT_VERSION);
4629             *value = context->getClientMajorVersion();
4630             break;
4631         case EGL_CONTEXT_MINOR_VERSION:
4632             *value = context->getClientMinorVersion();
4633             break;
4634         case EGL_RENDER_BUFFER:
4635             *value = context->getRenderBuffer();
4636             break;
4637         case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
4638             *value = context->isRobustResourceInitEnabled();
4639             break;
4640         case EGL_CONTEXT_PRIORITY_LEVEL_IMG:
4641             *value = static_cast<EGLint>(context->getContextPriority());
4642             break;
4643         case EGL_PROTECTED_CONTENT_EXT:
4644             *value = context->getState().hasProtectedContent();
4645             break;
4646         case EGL_CONTEXT_MEMORY_USAGE_ANGLE:
4647         {
4648             uint64_t memory = context->getMemoryUsage();
4649             value[0]        = static_cast<GLint>(memory & 0xffffffff);
4650             value[1]        = static_cast<GLint>(memory >> 32);
4651         }
4652         break;
4653         default:
4654             UNREACHABLE();
4655             break;
4656     }
4657 }
4658 
QuerySurfaceAttrib(const Display * display,const gl::Context * context,Surface * surface,EGLint attribute,EGLint * value)4659 egl::Error QuerySurfaceAttrib(const Display *display,
4660                               const gl::Context *context,
4661                               Surface *surface,
4662                               EGLint attribute,
4663                               EGLint *value)
4664 {
4665     switch (attribute)
4666     {
4667         case EGL_GL_COLORSPACE:
4668             *value = surface->getGLColorspace();
4669             break;
4670         case EGL_VG_ALPHA_FORMAT:
4671             *value = surface->getVGAlphaFormat();
4672             break;
4673         case EGL_VG_COLORSPACE:
4674             *value = surface->getVGColorspace();
4675             break;
4676         case EGL_CONFIG_ID:
4677             *value = surface->getConfig()->configID;
4678             break;
4679         case EGL_HEIGHT:
4680             ANGLE_TRY(surface->getUserHeight(display, value));
4681             break;
4682         case EGL_HORIZONTAL_RESOLUTION:
4683             *value = surface->getHorizontalResolution();
4684             break;
4685         case EGL_LARGEST_PBUFFER:
4686             // The EGL spec states that value is not written if the surface is not a pbuffer
4687             if (surface->getType() == EGL_PBUFFER_BIT)
4688             {
4689                 *value = surface->getLargestPbuffer();
4690             }
4691             break;
4692         case EGL_MIPMAP_TEXTURE:
4693             // The EGL spec states that value is not written if the surface is not a pbuffer
4694             if (surface->getType() == EGL_PBUFFER_BIT)
4695             {
4696                 *value = surface->getMipmapTexture();
4697             }
4698             break;
4699         case EGL_MIPMAP_LEVEL:
4700             // The EGL spec states that value is not written if the surface is not a pbuffer
4701             if (surface->getType() == EGL_PBUFFER_BIT)
4702             {
4703                 *value = surface->getMipmapLevel();
4704             }
4705             break;
4706         case EGL_MULTISAMPLE_RESOLVE:
4707             *value = surface->getMultisampleResolve();
4708             break;
4709         case EGL_PIXEL_ASPECT_RATIO:
4710             *value = surface->getPixelAspectRatio();
4711             break;
4712         case EGL_RENDER_BUFFER:
4713             if (surface->getType() == EGL_WINDOW_BIT)
4714             {
4715                 *value = surface->getRequestedRenderBuffer();
4716             }
4717             else
4718             {
4719                 *value = surface->getRenderBuffer();
4720             }
4721             break;
4722         case EGL_SWAP_BEHAVIOR:
4723             *value = surface->getSwapBehavior();
4724             break;
4725         case EGL_TEXTURE_FORMAT:
4726             // The EGL spec states that value is not written if the surface is not a pbuffer
4727             if (surface->getType() == EGL_PBUFFER_BIT)
4728             {
4729                 *value = ToEGLenum(surface->getTextureFormat());
4730             }
4731             break;
4732         case EGL_TEXTURE_TARGET:
4733             // The EGL spec states that value is not written if the surface is not a pbuffer
4734             if (surface->getType() == EGL_PBUFFER_BIT)
4735             {
4736                 *value = surface->getTextureTarget();
4737             }
4738             break;
4739         case EGL_VERTICAL_RESOLUTION:
4740             *value = surface->getVerticalResolution();
4741             break;
4742         case EGL_WIDTH:
4743             ANGLE_TRY(surface->getUserWidth(display, value));
4744             break;
4745         case EGL_POST_SUB_BUFFER_SUPPORTED_NV:
4746             *value = surface->isPostSubBufferSupported();
4747             break;
4748         case EGL_FIXED_SIZE_ANGLE:
4749             *value = surface->isFixedSize();
4750             break;
4751         case EGL_SURFACE_ORIENTATION_ANGLE:
4752             *value = surface->getOrientation();
4753             break;
4754         case EGL_DIRECT_COMPOSITION_ANGLE:
4755             *value = surface->directComposition();
4756             break;
4757         case EGL_ROBUST_RESOURCE_INITIALIZATION_ANGLE:
4758             *value = surface->isRobustResourceInitEnabled();
4759             break;
4760         case EGL_TIMESTAMPS_ANDROID:
4761             *value = surface->isTimestampsEnabled();
4762             break;
4763         case EGL_BUFFER_AGE_EXT:
4764             ANGLE_TRY(surface->getBufferAge(context, value));
4765             break;
4766         case EGL_BITMAP_PITCH_KHR:
4767             *value = surface->getBitmapPitch();
4768             break;
4769         case EGL_BITMAP_ORIGIN_KHR:
4770             *value = surface->getBitmapOrigin();
4771             break;
4772         case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
4773             *value = surface->getRedOffset();
4774             break;
4775         case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
4776             *value = surface->getGreenOffset();
4777             break;
4778         case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
4779             *value = surface->getBlueOffset();
4780             break;
4781         case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
4782             *value = surface->getAlphaOffset();
4783             break;
4784         case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
4785             *value = surface->getLuminanceOffset();
4786             break;
4787         case EGL_BITMAP_PIXEL_SIZE_KHR:
4788             *value = surface->getBitmapPixelSize();
4789             break;
4790         case EGL_PROTECTED_CONTENT_EXT:
4791             *value = surface->hasProtectedContent();
4792             break;
4793         case EGL_SURFACE_COMPRESSION_EXT:
4794             *value = surface->getCompressionRate(display);
4795             break;
4796         default:
4797             UNREACHABLE();
4798             break;
4799     }
4800     return NoError();
4801 }
4802 
QuerySurfaceAttrib64KHR(const Display * display,const gl::Context * context,Surface * surface,EGLint attribute,EGLAttribKHR * value)4803 egl::Error QuerySurfaceAttrib64KHR(const Display *display,
4804                                    const gl::Context *context,
4805                                    Surface *surface,
4806                                    EGLint attribute,
4807                                    EGLAttribKHR *value)
4808 {
4809     switch (attribute)
4810     {
4811         case EGL_BITMAP_PITCH_KHR:
4812             *value = static_cast<EGLAttribKHR>(surface->getBitmapPitch());
4813             break;
4814         case EGL_BITMAP_ORIGIN_KHR:
4815             *value = static_cast<EGLAttribKHR>(surface->getBitmapOrigin());
4816             break;
4817         case EGL_BITMAP_PIXEL_RED_OFFSET_KHR:
4818             *value = static_cast<EGLAttribKHR>(surface->getRedOffset());
4819             break;
4820         case EGL_BITMAP_PIXEL_GREEN_OFFSET_KHR:
4821             *value = static_cast<EGLAttribKHR>(surface->getGreenOffset());
4822             break;
4823         case EGL_BITMAP_PIXEL_BLUE_OFFSET_KHR:
4824             *value = static_cast<EGLAttribKHR>(surface->getBlueOffset());
4825             break;
4826         case EGL_BITMAP_PIXEL_ALPHA_OFFSET_KHR:
4827             *value = static_cast<EGLAttribKHR>(surface->getAlphaOffset());
4828             break;
4829         case EGL_BITMAP_PIXEL_LUMINANCE_OFFSET_KHR:
4830             *value = static_cast<EGLAttribKHR>(surface->getLuminanceOffset());
4831             break;
4832         case EGL_BITMAP_PIXEL_SIZE_KHR:
4833             *value = static_cast<EGLAttribKHR>(surface->getBitmapPixelSize());
4834             break;
4835         case EGL_BITMAP_POINTER_KHR:
4836             *value = surface->getBitmapPointer();
4837             break;
4838         default:
4839         {
4840             EGLint intValue = 0;
4841             ANGLE_TRY(QuerySurfaceAttrib(display, context, surface, attribute, &intValue));
4842             *value = static_cast<EGLAttribKHR>(intValue);
4843         }
4844         break;
4845     }
4846     return NoError();
4847 }
4848 
SetSurfaceAttrib(Surface * surface,EGLint attribute,EGLint value)4849 egl::Error SetSurfaceAttrib(Surface *surface, EGLint attribute, EGLint value)
4850 {
4851     switch (attribute)
4852     {
4853         case EGL_MIPMAP_LEVEL:
4854             surface->setMipmapLevel(value);
4855             break;
4856         case EGL_MULTISAMPLE_RESOLVE:
4857             surface->setMultisampleResolve(value);
4858             break;
4859         case EGL_SWAP_BEHAVIOR:
4860             surface->setSwapBehavior(value);
4861             break;
4862         case EGL_WIDTH:
4863             surface->setFixedWidth(value);
4864             break;
4865         case EGL_HEIGHT:
4866             surface->setFixedHeight(value);
4867             break;
4868         case EGL_TIMESTAMPS_ANDROID:
4869             surface->setTimestampsEnabled(value != EGL_FALSE);
4870             break;
4871         case EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID:
4872             return surface->setAutoRefreshEnabled(value != EGL_FALSE);
4873         case EGL_RENDER_BUFFER:
4874             surface->setRequestedRenderBuffer(value);
4875             break;
4876         default:
4877             UNREACHABLE();
4878             break;
4879     }
4880     return NoError();
4881 }
4882 
GetSyncAttrib(Display * display,SyncID sync,EGLint attribute,EGLint * value)4883 Error GetSyncAttrib(Display *display, SyncID sync, EGLint attribute, EGLint *value)
4884 {
4885     const egl::Sync *syncObj = display->getSync(sync);
4886     switch (attribute)
4887     {
4888         case EGL_SYNC_TYPE_KHR:
4889             *value = syncObj->getType();
4890             return NoError();
4891 
4892         case EGL_SYNC_STATUS_KHR:
4893             return syncObj->getStatus(display, value);
4894 
4895         case EGL_SYNC_CONDITION_KHR:
4896             *value = syncObj->getCondition();
4897             return NoError();
4898 
4899         default:
4900             break;
4901     }
4902 
4903     UNREACHABLE();
4904     return NoError();
4905 }
4906 }  // namespace egl
4907