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