• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2012 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 // renderergl_utils.cpp: Conversion functions and other utility routines
8 // specific to the OpenGL renderer.
9 
10 #include "libANGLE/renderer/gl/renderergl_utils.h"
11 
12 #include <limits>
13 
14 #include "common/mathutil.h"
15 #include "common/platform.h"
16 #include "libANGLE/Buffer.h"
17 #include "libANGLE/Caps.h"
18 #include "libANGLE/Context.h"
19 #include "libANGLE/formatutils.h"
20 #include "libANGLE/queryconversions.h"
21 #include "libANGLE/renderer/gl/ContextGL.h"
22 #include "libANGLE/renderer/gl/FenceNVGL.h"
23 #include "libANGLE/renderer/gl/FunctionsGL.h"
24 #include "libANGLE/renderer/gl/QueryGL.h"
25 #include "libANGLE/renderer/gl/formatutilsgl.h"
26 #include "platform/FeaturesGL.h"
27 #include "platform/FrontendFeatures.h"
28 
29 #include <EGL/eglext.h>
30 #include <algorithm>
31 #include <sstream>
32 
33 using angle::CheckedNumeric;
34 
35 namespace rx
36 {
GetVendorID(const FunctionsGL * functions)37 VendorID GetVendorID(const FunctionsGL *functions)
38 {
39     std::string nativeVendorString(reinterpret_cast<const char *>(functions->getString(GL_VENDOR)));
40     if (nativeVendorString.find("Intel") != std::string::npos)
41     {
42         return VENDOR_ID_INTEL;
43     }
44     else if (nativeVendorString.find("NVIDIA") != std::string::npos)
45     {
46         return VENDOR_ID_NVIDIA;
47     }
48     else if (nativeVendorString.find("ATI") != std::string::npos ||
49              nativeVendorString.find("AMD") != std::string::npos)
50     {
51         return VENDOR_ID_AMD;
52     }
53     else if (nativeVendorString.find("Qualcomm") != std::string::npos)
54     {
55         return VENDOR_ID_QUALCOMM;
56     }
57     else
58     {
59         return VENDOR_ID_UNKNOWN;
60     }
61 }
62 
GetDeviceID(const FunctionsGL * functions)63 uint32_t GetDeviceID(const FunctionsGL *functions)
64 {
65     std::string nativeRendererString(
66         reinterpret_cast<const char *>(functions->getString(GL_RENDERER)));
67     constexpr std::pair<const char *, uint32_t> kKnownDeviceIDs[] = {
68         {"Adreno (TM) 418", ANDROID_DEVICE_ID_NEXUS5X},
69         {"Adreno (TM) 530", ANDROID_DEVICE_ID_PIXEL1XL},
70         {"Adreno (TM) 540", ANDROID_DEVICE_ID_PIXEL2},
71     };
72 
73     for (const auto &knownDeviceID : kKnownDeviceIDs)
74     {
75         if (nativeRendererString.find(knownDeviceID.first) != std::string::npos)
76         {
77             return knownDeviceID.second;
78         }
79     }
80 
81     return 0;
82 }
83 
84 namespace nativegl_gl
85 {
86 
MeetsRequirements(const FunctionsGL * functions,const nativegl::SupportRequirement & requirements)87 static bool MeetsRequirements(const FunctionsGL *functions,
88                               const nativegl::SupportRequirement &requirements)
89 {
90     bool hasRequiredExtensions = false;
91     for (const std::vector<std::string> &exts : requirements.requiredExtensions)
92     {
93         bool hasAllExtensionsInSet = true;
94         for (const std::string &extension : exts)
95         {
96             if (!functions->hasExtension(extension))
97             {
98                 hasAllExtensionsInSet = false;
99                 break;
100             }
101         }
102         if (hasAllExtensionsInSet)
103         {
104             hasRequiredExtensions = true;
105             break;
106         }
107     }
108     if (!requirements.requiredExtensions.empty() && !hasRequiredExtensions)
109     {
110         return false;
111     }
112 
113     if (functions->version >= requirements.version)
114     {
115         return true;
116     }
117     else if (!requirements.versionExtensions.empty())
118     {
119         for (const std::string &extension : requirements.versionExtensions)
120         {
121             if (!functions->hasExtension(extension))
122             {
123                 return false;
124             }
125         }
126         return true;
127     }
128     else
129     {
130         return false;
131     }
132 }
133 
CheckSizedInternalFormatTextureRenderability(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)134 static bool CheckSizedInternalFormatTextureRenderability(const FunctionsGL *functions,
135                                                          const angle::FeaturesGL &features,
136                                                          GLenum internalFormat)
137 {
138     const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
139     ASSERT(formatInfo.sized);
140 
141     // Query the current texture so it can be rebound afterwards
142     GLint oldTextureBinding = 0;
143     functions->getIntegerv(GL_TEXTURE_BINDING_2D, &oldTextureBinding);
144 
145     // Create a small texture with the same format and type that gl::Texture would use
146     GLuint texture = 0;
147     functions->genTextures(1, &texture);
148     functions->bindTexture(GL_TEXTURE_2D, texture);
149 
150     // Nearest filter needed for framebuffer completeness on some drivers.
151     functions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
152 
153     nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
154         functions, features, formatInfo.internalFormat, formatInfo.format, formatInfo.type);
155     constexpr GLsizei kTextureSize = 16;
156     functions->texImage2D(GL_TEXTURE_2D, 0, texImageFormat.internalFormat, kTextureSize,
157                           kTextureSize, 0, texImageFormat.format, texImageFormat.type, nullptr);
158 
159     // Query the current framebuffer so it can be rebound afterwards
160     GLint oldFramebufferBinding = 0;
161     functions->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding);
162 
163     // Bind the texture to the framebuffer and check renderability
164     GLuint fbo = 0;
165     functions->genFramebuffers(1, &fbo);
166     functions->bindFramebuffer(GL_FRAMEBUFFER, fbo);
167     functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,
168                                     0);
169 
170     bool supported = functions->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
171 
172     // Delete the framebuffer and restore the previous binding
173     functions->deleteFramebuffers(1, &fbo);
174     functions->bindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(oldFramebufferBinding));
175 
176     // Delete the texture and restore the previous binding
177     functions->deleteTextures(1, &texture);
178     functions->bindTexture(GL_TEXTURE_2D, static_cast<GLuint>(oldTextureBinding));
179 
180     return supported;
181 }
182 
CheckInternalFormatRenderbufferRenderability(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)183 static bool CheckInternalFormatRenderbufferRenderability(const FunctionsGL *functions,
184                                                          const angle::FeaturesGL &features,
185                                                          GLenum internalFormat)
186 {
187     const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
188     ASSERT(formatInfo.sized);
189 
190     // Query the current renderbuffer so it can be rebound afterwards
191     GLint oldRenderbufferBinding = 0;
192     functions->getIntegerv(GL_RENDERBUFFER_BINDING, &oldRenderbufferBinding);
193 
194     // Create a small renderbuffer with the same format and type that gl::Renderbuffer would use
195     GLuint renderbuffer = 0;
196     functions->genRenderbuffers(1, &renderbuffer);
197     functions->bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
198 
199     nativegl::RenderbufferFormat renderbufferFormat =
200         nativegl::GetRenderbufferFormat(functions, features, formatInfo.internalFormat);
201     constexpr GLsizei kRenderbufferSize = 16;
202     functions->renderbufferStorage(GL_RENDERBUFFER, renderbufferFormat.internalFormat,
203                                    kRenderbufferSize, kRenderbufferSize);
204 
205     // Query the current framebuffer so it can be rebound afterwards
206     GLint oldFramebufferBinding = 0;
207     functions->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding);
208 
209     // Bind the texture to the framebuffer and check renderability
210     GLuint fbo = 0;
211     functions->genFramebuffers(1, &fbo);
212     functions->bindFramebuffer(GL_FRAMEBUFFER, fbo);
213     functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
214                                        renderbuffer);
215 
216     bool supported = functions->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
217 
218     // Delete the framebuffer and restore the previous binding
219     functions->deleteFramebuffers(1, &fbo);
220     functions->bindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(oldFramebufferBinding));
221 
222     // Delete the renderbuffer and restore the previous binding
223     functions->deleteRenderbuffers(1, &renderbuffer);
224     functions->bindRenderbuffer(GL_RENDERBUFFER, static_cast<GLuint>(oldRenderbufferBinding));
225 
226     return supported;
227 }
228 
GenerateTextureFormatCaps(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)229 static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions,
230                                                  const angle::FeaturesGL &features,
231                                                  GLenum internalFormat)
232 {
233     ASSERT(functions->getError() == GL_NO_ERROR);
234 
235     gl::TextureCaps textureCaps;
236 
237     const nativegl::InternalFormat &formatInfo =
238         nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
239     textureCaps.texturable = MeetsRequirements(functions, formatInfo.texture);
240     textureCaps.filterable =
241         textureCaps.texturable && MeetsRequirements(functions, formatInfo.filter);
242     textureCaps.textureAttachment = MeetsRequirements(functions, formatInfo.textureAttachment);
243     textureCaps.renderbuffer      = MeetsRequirements(functions, formatInfo.renderbuffer);
244 
245     // Do extra renderability validation for some formats.
246     // We require GL_RGBA16F is renderable to expose EXT_color_buffer_half_float but we can't know
247     // if the format is supported unless we try to create a framebuffer.
248     if (internalFormat == GL_RGBA16F)
249     {
250         if (textureCaps.textureAttachment)
251         {
252             textureCaps.textureAttachment =
253                 CheckSizedInternalFormatTextureRenderability(functions, features, internalFormat);
254         }
255         if (textureCaps.renderbuffer)
256         {
257             textureCaps.renderbuffer =
258                 CheckInternalFormatRenderbufferRenderability(functions, features, internalFormat);
259         }
260     }
261 
262     // glGetInternalformativ is not available until version 4.2 but may be available through the 3.0
263     // extension GL_ARB_internalformat_query
264     if (textureCaps.renderbuffer && functions->getInternalformativ)
265     {
266         GLenum queryInternalFormat = internalFormat;
267 
268         if (internalFormat == GL_BGRA8_EXT)
269         {
270             // Querying GL_NUM_SAMPLE_COUNTS for GL_BGRA8_EXT generates an INVALID_ENUM on some
271             // drivers.  It seems however that allocating a multisampled renderbuffer of this format
272             // succeeds. To avoid breaking multisampling for this format, query the supported sample
273             // counts for GL_RGBA8 instead.
274             queryInternalFormat = GL_RGBA8;
275         }
276 
277         GLint numSamples = 0;
278         functions->getInternalformativ(GL_RENDERBUFFER, queryInternalFormat, GL_NUM_SAMPLE_COUNTS,
279                                        1, &numSamples);
280 
281         if (numSamples > 0)
282         {
283             std::vector<GLint> samples(numSamples);
284             functions->getInternalformativ(GL_RENDERBUFFER, queryInternalFormat, GL_SAMPLES,
285                                            static_cast<GLsizei>(samples.size()), &samples[0]);
286 
287             if (internalFormat == GL_STENCIL_INDEX8)
288             {
289                 // The query below does generates an error with STENCIL_INDEX8 on NVIDIA driver
290                 // 382.33. So for now we assume that the same sampling modes are conformant for
291                 // STENCIL_INDEX8 as for DEPTH24_STENCIL8. Clean this up once the driver is fixed.
292                 // http://anglebug.com/2059
293                 queryInternalFormat = GL_DEPTH24_STENCIL8;
294             }
295             for (size_t sampleIndex = 0; sampleIndex < samples.size(); sampleIndex++)
296             {
297                 if (features.limitMaxMSAASamplesTo4.enabled && samples[sampleIndex] > 4)
298                 {
299                     continue;
300                 }
301 
302                 // Some NVIDIA drivers expose multisampling modes implemented as a combination of
303                 // multisampling and supersampling. These are non-conformant and should not be
304                 // exposed through ANGLE. Query which formats are conformant from the driver if
305                 // supported.
306                 GLint conformant = GL_TRUE;
307                 if (functions->getInternalformatSampleivNV)
308                 {
309                     ASSERT(functions->getError() == GL_NO_ERROR);
310                     functions->getInternalformatSampleivNV(GL_RENDERBUFFER, queryInternalFormat,
311                                                            samples[sampleIndex], GL_CONFORMANT_NV,
312                                                            1, &conformant);
313                     // getInternalFormatSampleivNV does not work for all formats on NVIDIA Shield TV
314                     // drivers. Assume that formats with large sample counts are non-conformant in
315                     // case the query generates an error.
316                     if (functions->getError() != GL_NO_ERROR)
317                     {
318                         conformant = (samples[sampleIndex] <= 8) ? GL_TRUE : GL_FALSE;
319                     }
320                 }
321                 if (conformant == GL_TRUE)
322                 {
323                     textureCaps.sampleCounts.insert(samples[sampleIndex]);
324                 }
325             }
326         }
327     }
328 
329     ASSERT(functions->getError() == GL_NO_ERROR);
330     return textureCaps;
331 }
332 
QuerySingleGLInt(const FunctionsGL * functions,GLenum name)333 static GLint QuerySingleGLInt(const FunctionsGL *functions, GLenum name)
334 {
335     GLint result = 0;
336     functions->getIntegerv(name, &result);
337     return result;
338 }
339 
QuerySingleIndexGLInt(const FunctionsGL * functions,GLenum name,GLuint index)340 static GLint QuerySingleIndexGLInt(const FunctionsGL *functions, GLenum name, GLuint index)
341 {
342     GLint result;
343     functions->getIntegeri_v(name, index, &result);
344     return result;
345 }
346 
QueryGLIntRange(const FunctionsGL * functions,GLenum name,size_t index)347 static GLint QueryGLIntRange(const FunctionsGL *functions, GLenum name, size_t index)
348 {
349     GLint result[2] = {};
350     functions->getIntegerv(name, result);
351     return result[index];
352 }
353 
QuerySingleGLInt64(const FunctionsGL * functions,GLenum name)354 static GLint64 QuerySingleGLInt64(const FunctionsGL *functions, GLenum name)
355 {
356     // Fall back to 32-bit int if 64-bit query is not available. This can become relevant for some
357     // caps that are defined as 64-bit values in core spec, but were introduced earlier in
358     // extensions as 32-bit. Triggered in some cases by RenderDoc's emulated OpenGL driver.
359     if (!functions->getInteger64v)
360     {
361         GLint result = 0;
362         functions->getIntegerv(name, &result);
363         return static_cast<GLint64>(result);
364     }
365     else
366     {
367         GLint64 result = 0;
368         functions->getInteger64v(name, &result);
369         return result;
370     }
371 }
372 
QuerySingleGLFloat(const FunctionsGL * functions,GLenum name)373 static GLfloat QuerySingleGLFloat(const FunctionsGL *functions, GLenum name)
374 {
375     GLfloat result = 0.0f;
376     functions->getFloatv(name, &result);
377     return result;
378 }
379 
QueryGLFloatRange(const FunctionsGL * functions,GLenum name,size_t index)380 static GLfloat QueryGLFloatRange(const FunctionsGL *functions, GLenum name, size_t index)
381 {
382     GLfloat result[2] = {};
383     functions->getFloatv(name, result);
384     return result[index];
385 }
386 
QueryTypePrecision(const FunctionsGL * functions,GLenum shaderType,GLenum precisionType)387 static gl::TypePrecision QueryTypePrecision(const FunctionsGL *functions,
388                                             GLenum shaderType,
389                                             GLenum precisionType)
390 {
391     gl::TypePrecision precision;
392     functions->getShaderPrecisionFormat(shaderType, precisionType, precision.range.data(),
393                                         &precision.precision);
394     return precision;
395 }
396 
QueryQueryValue(const FunctionsGL * functions,GLenum target,GLenum name)397 static GLint QueryQueryValue(const FunctionsGL *functions, GLenum target, GLenum name)
398 {
399     GLint result;
400     functions->getQueryiv(target, name, &result);
401     return result;
402 }
403 
LimitVersion(gl::Version * curVersion,const gl::Version & maxVersion)404 static void LimitVersion(gl::Version *curVersion, const gl::Version &maxVersion)
405 {
406     if (*curVersion >= maxVersion)
407     {
408         *curVersion = maxVersion;
409     }
410 }
411 
CapCombinedLimitToESShaders(GLuint * combinedLimit,gl::ShaderMap<GLuint> & perShaderLimit)412 void CapCombinedLimitToESShaders(GLuint *combinedLimit, gl::ShaderMap<GLuint> &perShaderLimit)
413 {
414     GLuint combinedESLimit = 0;
415     for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
416     {
417         combinedESLimit += perShaderLimit[shaderType];
418     }
419 
420     *combinedLimit = std::min(*combinedLimit, combinedESLimit);
421 }
422 
GenerateCaps(const FunctionsGL * functions,const angle::FeaturesGL & features,gl::Caps * caps,gl::TextureCapsMap * textureCapsMap,gl::Extensions * extensions,gl::Version * maxSupportedESVersion,MultiviewImplementationTypeGL * multiviewImplementationType)423 void GenerateCaps(const FunctionsGL *functions,
424                   const angle::FeaturesGL &features,
425                   gl::Caps *caps,
426                   gl::TextureCapsMap *textureCapsMap,
427                   gl::Extensions *extensions,
428                   gl::Version *maxSupportedESVersion,
429                   MultiviewImplementationTypeGL *multiviewImplementationType)
430 {
431     // Texture format support checks
432     const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
433     for (GLenum internalFormat : allFormats)
434     {
435         gl::TextureCaps textureCaps =
436             GenerateTextureFormatCaps(functions, features, internalFormat);
437         textureCapsMap->insert(internalFormat, textureCaps);
438 
439         if (gl::GetSizedInternalFormatInfo(internalFormat).compressed)
440         {
441             caps->compressedTextureFormats.push_back(internalFormat);
442         }
443     }
444 
445     // Start by assuming ES3.1 support and work down
446     *maxSupportedESVersion = gl::Version(3, 1);
447 
448     // Table 6.28, implementation dependent values
449     if (functions->isAtLeastGL(gl::Version(4, 3)) ||
450         functions->hasGLExtension("GL_ARB_ES3_compatibility") ||
451         functions->isAtLeastGLES(gl::Version(3, 0)))
452     {
453         caps->maxElementIndex = QuerySingleGLInt64(functions, GL_MAX_ELEMENT_INDEX);
454 
455         // Work around the null driver limitations.
456         if (caps->maxElementIndex == 0)
457         {
458             caps->maxElementIndex = 0xFFFF;
459         }
460     }
461     else
462     {
463         // Doesn't affect ES3 support, can use a pre-defined limit
464         caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
465     }
466 
467     GLint textureSizeLimit = std::numeric_limits<GLint>::max();
468     if (features.limitMaxTextureSizeTo4096.enabled)
469     {
470         textureSizeLimit = 4096;
471     }
472 
473     GLint max3dArrayTextureSizeLimit = std::numeric_limits<GLint>::max();
474     if (features.limitMax3dArrayTextureSizeTo1024.enabled)
475     {
476         max3dArrayTextureSizeLimit = 1024;
477     }
478 
479     if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)) ||
480         functions->hasGLESExtension("GL_OES_texture_3D"))
481     {
482         caps->max3DTextureSize = std::min({QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE),
483                                            textureSizeLimit, max3dArrayTextureSizeLimit});
484     }
485     else
486     {
487         // Can't support ES3 without 3D textures
488         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
489     }
490 
491     caps->max2DTextureSize = std::min(QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE),
492                                       textureSizeLimit);  // GL 1.0 / ES 2.0
493     caps->maxCubeMapTextureSize =
494         std::min(QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE),
495                  textureSizeLimit);  // GL 1.3 / ES 2.0
496 
497     if (functions->isAtLeastGL(gl::Version(3, 0)) ||
498         functions->hasGLExtension("GL_EXT_texture_array") ||
499         functions->isAtLeastGLES(gl::Version(3, 0)))
500     {
501         caps->maxArrayTextureLayers =
502             std::min({QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS), textureSizeLimit,
503                       max3dArrayTextureSizeLimit});
504     }
505     else
506     {
507         // Can't support ES3 without array textures
508         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
509     }
510 
511     if (functions->isAtLeastGL(gl::Version(1, 5)) ||
512         functions->hasGLExtension("GL_EXT_texture_lod_bias") ||
513         functions->isAtLeastGLES(gl::Version(3, 0)))
514     {
515         caps->maxLODBias = QuerySingleGLFloat(functions, GL_MAX_TEXTURE_LOD_BIAS);
516     }
517     else
518     {
519         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
520     }
521 
522     if (functions->isAtLeastGL(gl::Version(3, 0)) ||
523         functions->hasGLExtension("GL_EXT_framebuffer_object") ||
524         functions->isAtLeastGLES(gl::Version(2, 0)))
525     {
526         caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE);
527         caps->maxColorAttachments = QuerySingleGLInt(functions, GL_MAX_COLOR_ATTACHMENTS);
528     }
529     else
530     {
531         // Can't support ES2 without framebuffers and renderbuffers
532         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
533     }
534 
535     if (functions->isAtLeastGL(gl::Version(2, 0)) ||
536         functions->hasGLExtension("ARB_draw_buffers") ||
537         functions->isAtLeastGLES(gl::Version(3, 0)) ||
538         functions->hasGLESExtension("GL_EXT_draw_buffers"))
539     {
540         caps->maxDrawBuffers = QuerySingleGLInt(functions, GL_MAX_DRAW_BUFFERS);
541     }
542     else
543     {
544         // Framebuffer is required to have at least one drawbuffer even if the extension is not
545         // supported
546         caps->maxDrawBuffers = 1;
547         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
548     }
549 
550     caps->maxViewportWidth =
551         QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 0);  // GL 1.0 / ES 2.0
552     caps->maxViewportHeight =
553         QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 1);  // GL 1.0 / ES 2.0
554 
555     if (functions->standard == STANDARD_GL_DESKTOP &&
556         (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
557     {
558         // Desktop GL core profile deprecated the GL_ALIASED_POINT_SIZE_RANGE query.  Use
559         // GL_POINT_SIZE_RANGE instead.
560         caps->minAliasedPointSize =
561             std::max(1.0f, QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 0));
562         caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 1);
563     }
564     else
565     {
566         caps->minAliasedPointSize =
567             std::max(1.0f, QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 0));
568         caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 1);
569     }
570 
571     caps->minAliasedLineWidth =
572         QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 0);  // GL 1.2 / ES 2.0
573     caps->maxAliasedLineWidth =
574         QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 1);  // GL 1.2 / ES 2.0
575 
576     // Table 6.29, implementation dependent values (cont.)
577     if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
578     {
579         caps->maxElementsIndices  = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_INDICES);
580         caps->maxElementsVertices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_VERTICES);
581     }
582     else
583     {
584         // Doesn't impact supported version
585     }
586 
587     if (functions->isAtLeastGL(gl::Version(4, 1)) ||
588         functions->hasGLExtension("GL_ARB_get_program_binary") ||
589         functions->isAtLeastGLES(gl::Version(3, 0)) ||
590         functions->hasGLESExtension("GL_OES_get_program_binary"))
591     {
592         // Able to support the GL_PROGRAM_BINARY_ANGLE format as long as another program binary
593         // format is available.
594         GLint numBinaryFormats = QuerySingleGLInt(functions, GL_NUM_PROGRAM_BINARY_FORMATS_OES);
595         if (numBinaryFormats > 0)
596         {
597             caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
598         }
599     }
600     else
601     {
602         // Doesn't impact supported version
603     }
604 
605     // glGetShaderPrecisionFormat is not available until desktop GL version 4.1 or
606     // GL_ARB_ES2_compatibility exists
607     if (functions->isAtLeastGL(gl::Version(4, 1)) ||
608         functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
609         functions->isAtLeastGLES(gl::Version(2, 0)))
610     {
611         caps->vertexHighpFloat   = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_FLOAT);
612         caps->vertexMediumpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_FLOAT);
613         caps->vertexLowpFloat    = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_FLOAT);
614         caps->fragmentHighpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_FLOAT);
615         caps->fragmentMediumpFloat =
616             QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT);
617         caps->fragmentLowpFloat  = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_FLOAT);
618         caps->vertexHighpInt     = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_INT);
619         caps->vertexMediumpInt   = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_INT);
620         caps->vertexLowpInt      = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_INT);
621         caps->fragmentHighpInt   = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_INT);
622         caps->fragmentMediumpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_INT);
623         caps->fragmentLowpInt    = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_INT);
624     }
625     else
626     {
627         // Doesn't impact supported version, set some default values
628         caps->vertexHighpFloat.setIEEEFloat();
629         caps->vertexMediumpFloat.setIEEEFloat();
630         caps->vertexLowpFloat.setIEEEFloat();
631         caps->fragmentHighpFloat.setIEEEFloat();
632         caps->fragmentMediumpFloat.setIEEEFloat();
633         caps->fragmentLowpFloat.setIEEEFloat();
634         caps->vertexHighpInt.setTwosComplementInt(32);
635         caps->vertexMediumpInt.setTwosComplementInt(32);
636         caps->vertexLowpInt.setTwosComplementInt(32);
637         caps->fragmentHighpInt.setTwosComplementInt(32);
638         caps->fragmentMediumpInt.setTwosComplementInt(32);
639         caps->fragmentLowpInt.setTwosComplementInt(32);
640     }
641 
642     if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") ||
643         functions->isAtLeastGLES(gl::Version(3, 0)))
644     {
645         // Work around Linux NVIDIA driver bug where GL_TIMEOUT_IGNORED is returned.
646         caps->maxServerWaitTimeout =
647             std::max<GLint64>(QuerySingleGLInt64(functions, GL_MAX_SERVER_WAIT_TIMEOUT), 0);
648     }
649     else
650     {
651         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
652     }
653 
654     // Table 6.31, implementation dependent vertex shader limits
655     if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->isAtLeastGLES(gl::Version(2, 0)))
656     {
657         caps->maxVertexAttributes = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIBS);
658         caps->maxShaderUniformComponents[gl::ShaderType::Vertex] =
659             QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_COMPONENTS);
660         caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] =
661             QuerySingleGLInt(functions, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
662     }
663     else
664     {
665         // Can't support ES2 version without these caps
666         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
667     }
668 
669     if (functions->isAtLeastGL(gl::Version(4, 1)) ||
670         functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
671         functions->isAtLeastGLES(gl::Version(2, 0)))
672     {
673         caps->maxVertexUniformVectors = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_VECTORS);
674         caps->maxFragmentUniformVectors =
675             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_VECTORS);
676     }
677     else
678     {
679         // Doesn't limit ES version, GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4 is acceptable.
680         caps->maxVertexUniformVectors =
681             caps->maxShaderUniformComponents[gl::ShaderType::Vertex] / 4;
682         // Doesn't limit ES version, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS / 4 is acceptable.
683         caps->maxFragmentUniformVectors =
684             caps->maxShaderUniformComponents[gl::ShaderType::Fragment] / 4;
685     }
686 
687     if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
688     {
689         caps->maxVertexOutputComponents =
690             QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
691     }
692     else
693     {
694         // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a
695         // safe limit instead of limiting the supported ES version.
696         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
697     }
698 
699     // Table 6.32, implementation dependent fragment shader limits
700     if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->isAtLeastGLES(gl::Version(2, 0)))
701     {
702         caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
703             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
704         caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] =
705             QuerySingleGLInt(functions, GL_MAX_TEXTURE_IMAGE_UNITS);
706     }
707     else
708     {
709         // Can't support ES2 version without these caps
710         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
711     }
712 
713     if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
714     {
715         caps->maxFragmentInputComponents =
716             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_INPUT_COMPONENTS);
717     }
718     else
719     {
720         // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a
721         // safe limit instead of limiting the supported ES version.
722         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
723     }
724 
725     if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->isAtLeastGLES(gl::Version(3, 0)))
726     {
727         caps->minProgramTexelOffset = QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXEL_OFFSET);
728         caps->maxProgramTexelOffset = QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXEL_OFFSET);
729     }
730     else
731     {
732         // Can't support ES3 without texel offset, could possibly be emulated in the shader
733         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
734     }
735 
736     // Table 6.33, implementation dependent aggregate shader limits
737     if (functions->isAtLeastGL(gl::Version(3, 1)) ||
738         functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
739         functions->isAtLeastGLES(gl::Version(3, 0)))
740     {
741         caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] =
742             QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_BLOCKS);
743         caps->maxShaderUniformBlocks[gl::ShaderType::Fragment] =
744             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_BLOCKS);
745         caps->maxUniformBufferBindings =
746             QuerySingleGLInt(functions, GL_MAX_UNIFORM_BUFFER_BINDINGS);
747         caps->maxUniformBlockSize = QuerySingleGLInt64(functions, GL_MAX_UNIFORM_BLOCK_SIZE);
748         caps->uniformBufferOffsetAlignment =
749             QuerySingleGLInt(functions, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
750         caps->maxCombinedUniformBlocks =
751             QuerySingleGLInt(functions, GL_MAX_COMBINED_UNIFORM_BLOCKS);
752         caps->maxCombinedShaderUniformComponents[gl::ShaderType::Vertex] =
753             QuerySingleGLInt64(functions, GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
754         caps->maxCombinedShaderUniformComponents[gl::ShaderType::Fragment] =
755             QuerySingleGLInt64(functions, GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);
756     }
757     else
758     {
759         // Can't support ES3 without uniform blocks
760         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
761     }
762 
763     if (functions->isAtLeastGL(gl::Version(3, 2)) &&
764         (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
765     {
766         caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
767     }
768     else if (functions->isAtLeastGL(gl::Version(3, 0)) ||
769              functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
770              functions->isAtLeastGLES(gl::Version(2, 0)))
771     {
772         caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_COMPONENTS);
773     }
774     else if (functions->isAtLeastGL(gl::Version(2, 0)))
775     {
776         caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_FLOATS);
777         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
778     }
779     else
780     {
781         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
782     }
783 
784     if (functions->isAtLeastGL(gl::Version(4, 1)) ||
785         functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
786         functions->isAtLeastGLES(gl::Version(2, 0)))
787     {
788         caps->maxVaryingVectors = QuerySingleGLInt(functions, GL_MAX_VARYING_VECTORS);
789     }
790     else
791     {
792         // Doesn't limit ES version, GL_MAX_VARYING_COMPONENTS / 4 is acceptable.
793         caps->maxVaryingVectors = caps->maxVaryingComponents / 4;
794     }
795 
796     // Determine the max combined texture image units by adding the vertex and fragment limits.  If
797     // the real cap is queried, it would contain the limits for shader types that are not available
798     // to ES.
799     caps->maxCombinedTextureImageUnits =
800         QuerySingleGLInt(functions, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
801 
802     // Table 6.34, implementation dependent transform feedback limits
803     if (functions->isAtLeastGL(gl::Version(4, 0)) ||
804         functions->hasGLExtension("GL_ARB_transform_feedback2") ||
805         functions->isAtLeastGLES(gl::Version(3, 0)))
806     {
807         caps->maxTransformFeedbackInterleavedComponents =
808             QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
809         caps->maxTransformFeedbackSeparateAttributes =
810             QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
811         caps->maxTransformFeedbackSeparateComponents =
812             QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
813     }
814     else
815     {
816         // Can't support ES3 without transform feedback
817         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
818     }
819 
820     GLint sampleCountLimit = std::numeric_limits<GLint>::max();
821     if (features.limitMaxMSAASamplesTo4.enabled)
822     {
823         sampleCountLimit = 4;
824     }
825 
826     // Table 6.35, Framebuffer Dependent Values
827     if (functions->isAtLeastGL(gl::Version(3, 0)) ||
828         functions->hasGLExtension("GL_EXT_framebuffer_multisample") ||
829         functions->isAtLeastGLES(gl::Version(3, 0)) ||
830         functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture"))
831     {
832         caps->maxSamples = std::min(QuerySingleGLInt(functions, GL_MAX_SAMPLES), sampleCountLimit);
833     }
834     else
835     {
836         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
837     }
838 
839     // Non-constant sampler array indexing is required for OpenGL ES 2 and OpenGL ES after 3.2.
840     // However having it available on OpenGL ES 2 is a specification bug, and using this
841     // indexing in WebGL is undefined. Requiring this feature would break WebGL 1 for some users
842     // so we don't check for it. (it is present with ESSL 100, ESSL >= 320, GLSL >= 400 and
843     // GL_ARB_gpu_shader5)
844 
845     // Check if sampler objects are supported
846     if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
847         !functions->hasGLExtension("GL_ARB_sampler_objects") &&
848         !functions->isAtLeastGLES(gl::Version(3, 0)))
849     {
850         // Can't support ES3 without sampler objects
851         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
852     }
853 
854     // Can't support ES3 without texture swizzling
855     if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
856         !functions->hasGLExtension("GL_ARB_texture_swizzle") &&
857         !functions->hasGLExtension("GL_EXT_texture_swizzle") &&
858         !functions->isAtLeastGLES(gl::Version(3, 0)))
859     {
860         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
861 
862         // Texture swizzling is required to work around the luminance texture format not being
863         // present in the core profile
864         if (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT)
865         {
866             LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
867         }
868     }
869 
870     // Can't support ES3 without the GLSL packing builtins. We have a workaround for all
871     // desktop OpenGL versions starting from 3.3 with the bit packing extension.
872     if (!functions->isAtLeastGL(gl::Version(4, 2)) &&
873         !(functions->isAtLeastGL(gl::Version(3, 2)) &&
874           functions->hasGLExtension("GL_ARB_shader_bit_encoding")) &&
875         !functions->hasGLExtension("GL_ARB_shading_language_packing") &&
876         !functions->isAtLeastGLES(gl::Version(3, 0)))
877     {
878         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
879     }
880 
881     // ES3 needs to support explicit layout location qualifiers, while it might be possible to
882     // fake them in our side, we currently don't support that.
883     if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
884         !functions->hasGLExtension("GL_ARB_explicit_attrib_location") &&
885         !functions->isAtLeastGLES(gl::Version(3, 0)))
886     {
887         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
888     }
889 
890     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
891         functions->hasGLExtension("GL_ARB_framebuffer_no_attachments"))
892     {
893         caps->maxFramebufferWidth  = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_WIDTH);
894         caps->maxFramebufferHeight = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_HEIGHT);
895         caps->maxFramebufferSamples =
896             std::min(QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_SAMPLES), sampleCountLimit);
897     }
898     else
899     {
900         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
901     }
902 
903     if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
904         functions->hasGLExtension("GL_ARB_texture_multisample"))
905     {
906         caps->maxSampleMaskWords = QuerySingleGLInt(functions, GL_MAX_SAMPLE_MASK_WORDS);
907         caps->maxColorTextureSamples =
908             std::min(QuerySingleGLInt(functions, GL_MAX_COLOR_TEXTURE_SAMPLES), sampleCountLimit);
909         caps->maxDepthTextureSamples =
910             std::min(QuerySingleGLInt(functions, GL_MAX_DEPTH_TEXTURE_SAMPLES), sampleCountLimit);
911         caps->maxIntegerSamples =
912             std::min(QuerySingleGLInt(functions, GL_MAX_INTEGER_SAMPLES), sampleCountLimit);
913     }
914     else
915     {
916         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
917     }
918 
919     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
920         functions->hasGLExtension("GL_ARB_vertex_attrib_binding"))
921     {
922         caps->maxVertexAttribRelativeOffset =
923             QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET);
924         caps->maxVertexAttribBindings = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_BINDINGS);
925 
926         // OpenGL 4.3 has no limit on maximum value of stride.
927         // [OpenGL 4.3 (Core Profile) - February 14, 2013] Chapter 10.3.1 Page 298
928         if (features.emulateMaxVertexAttribStride.enabled ||
929             (functions->standard == STANDARD_GL_DESKTOP && functions->version == gl::Version(4, 3)))
930         {
931             caps->maxVertexAttribStride = 2048;
932         }
933         else
934         {
935             caps->maxVertexAttribStride = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_STRIDE);
936         }
937     }
938     else
939     {
940         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
941     }
942 
943     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
944         functions->hasGLExtension("GL_ARB_shader_storage_buffer_object"))
945     {
946         caps->maxCombinedShaderOutputResources =
947             QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES);
948         caps->maxShaderStorageBlocks[gl::ShaderType::Fragment] =
949             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS);
950         caps->maxShaderStorageBlocks[gl::ShaderType::Vertex] =
951             QuerySingleGLInt(functions, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS);
952         caps->maxShaderStorageBufferBindings =
953             QuerySingleGLInt(functions, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
954         caps->maxShaderStorageBlockSize =
955             QuerySingleGLInt64(functions, GL_MAX_SHADER_STORAGE_BLOCK_SIZE);
956         caps->maxCombinedShaderStorageBlocks =
957             QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS);
958         caps->shaderStorageBufferOffsetAlignment =
959             QuerySingleGLInt(functions, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT);
960     }
961     else
962     {
963         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
964     }
965 
966     // OpenGL 4.2 is required for GL_ARB_compute_shader, some platform drivers have the extension,
967     // but their maximum supported GL versions are less than 4.2. Explicitly limit the minimum
968     // GL version to 4.2.
969     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
970         (functions->isAtLeastGL(gl::Version(4, 2)) &&
971          functions->hasGLExtension("GL_ARB_compute_shader") &&
972          functions->hasGLExtension("GL_ARB_shader_storage_buffer_object")))
973     {
974         for (GLuint index = 0u; index < 3u; ++index)
975         {
976             caps->maxComputeWorkGroupCount[index] =
977                 QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_COUNT, index);
978 
979             caps->maxComputeWorkGroupSize[index] =
980                 QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_SIZE, index);
981         }
982         caps->maxComputeWorkGroupInvocations =
983             QuerySingleGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS);
984         caps->maxShaderUniformBlocks[gl::ShaderType::Compute] =
985             QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_BLOCKS);
986         caps->maxShaderTextureImageUnits[gl::ShaderType::Compute] =
987             QuerySingleGLInt(functions, GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS);
988         caps->maxComputeSharedMemorySize =
989             QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHARED_MEMORY_SIZE);
990         caps->maxShaderUniformComponents[gl::ShaderType::Compute] =
991             QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_COMPONENTS);
992         caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Compute] =
993             QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS);
994         caps->maxShaderAtomicCounters[gl::ShaderType::Compute] =
995             QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTERS);
996         caps->maxShaderImageUniforms[gl::ShaderType::Compute] =
997             QuerySingleGLInt(functions, GL_MAX_COMPUTE_IMAGE_UNIFORMS);
998         caps->maxCombinedShaderUniformComponents[gl::ShaderType::Compute] =
999             QuerySingleGLInt(functions, GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS);
1000         caps->maxShaderStorageBlocks[gl::ShaderType::Compute] =
1001             QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS);
1002     }
1003     else
1004     {
1005         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1006     }
1007 
1008     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1009         functions->hasGLExtension("GL_ARB_explicit_uniform_location"))
1010     {
1011         caps->maxUniformLocations = QuerySingleGLInt(functions, GL_MAX_UNIFORM_LOCATIONS);
1012     }
1013     else
1014     {
1015         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1016     }
1017 
1018     if (functions->isAtLeastGL(gl::Version(4, 0)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1019         functions->hasGLExtension("GL_ARB_texture_gather"))
1020     {
1021         caps->minProgramTextureGatherOffset =
1022             QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET);
1023         caps->maxProgramTextureGatherOffset =
1024             QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET);
1025     }
1026     else
1027     {
1028         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1029     }
1030 
1031     if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1032         functions->hasGLExtension("GL_ARB_shader_image_load_store"))
1033     {
1034         caps->maxShaderImageUniforms[gl::ShaderType::Vertex] =
1035             QuerySingleGLInt(functions, GL_MAX_VERTEX_IMAGE_UNIFORMS);
1036         caps->maxShaderImageUniforms[gl::ShaderType::Fragment] =
1037             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_IMAGE_UNIFORMS);
1038         caps->maxImageUnits = QuerySingleGLInt(functions, GL_MAX_IMAGE_UNITS);
1039         caps->maxCombinedImageUniforms =
1040             QuerySingleGLInt(functions, GL_MAX_COMBINED_IMAGE_UNIFORMS);
1041     }
1042     else
1043     {
1044         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1045     }
1046 
1047     if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1048         functions->hasGLExtension("GL_ARB_shader_atomic_counters"))
1049     {
1050         caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Vertex] =
1051             QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS);
1052         caps->maxShaderAtomicCounters[gl::ShaderType::Vertex] =
1053             QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTERS);
1054         caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Fragment] =
1055             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS);
1056         caps->maxShaderAtomicCounters[gl::ShaderType::Fragment] =
1057             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTERS);
1058         caps->maxAtomicCounterBufferBindings =
1059             QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS);
1060         caps->maxAtomicCounterBufferSize =
1061             QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE);
1062         caps->maxCombinedAtomicCounterBuffers =
1063             QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS);
1064         caps->maxCombinedAtomicCounters =
1065             QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTERS);
1066     }
1067     else
1068     {
1069         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1070     }
1071 
1072     // TODO(geofflang): The gl-uniform-arrays WebGL conformance test struggles to complete on time
1073     // if the max uniform vectors is too large.  Artificially limit the maximum until the test is
1074     // updated.
1075     caps->maxVertexUniformVectors = std::min(1024u, caps->maxVertexUniformVectors);
1076     caps->maxShaderUniformComponents[gl::ShaderType::Vertex] =
1077         std::min(caps->maxVertexUniformVectors * 4,
1078                  caps->maxShaderUniformComponents[gl::ShaderType::Vertex]);
1079     caps->maxFragmentUniformVectors = std::min(1024u, caps->maxFragmentUniformVectors);
1080     caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
1081         std::min(caps->maxFragmentUniformVectors * 4,
1082                  caps->maxShaderUniformComponents[gl::ShaderType::Fragment]);
1083 
1084     // If it is not possible to support reading buffer data back, a shadow copy of the buffers must
1085     // be held. This disallows writing to buffers indirectly through transform feedback, thus
1086     // disallowing ES3.
1087     if (!CanMapBufferForRead(functions))
1088     {
1089         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1090     }
1091 
1092     // Extension support
1093     extensions->setTextureExtensionSupport(*textureCapsMap);
1094     extensions->textureCompressionASTCHDRKHR =
1095         extensions->textureCompressionASTCLDRKHR &&
1096         functions->hasGLESExtension("GL_KHR_texture_compression_astc_hdr");
1097     extensions->elementIndexUint = functions->standard == STANDARD_GL_DESKTOP ||
1098                                    functions->isAtLeastGLES(gl::Version(3, 0)) ||
1099                                    functions->hasGLESExtension("GL_OES_element_index_uint");
1100     extensions->getProgramBinary = caps->programBinaryFormats.size() > 0;
1101     extensions->readFormatBGRA   = functions->isAtLeastGL(gl::Version(1, 2)) ||
1102                                  functions->hasGLExtension("GL_EXT_bgra") ||
1103                                  functions->hasGLESExtension("GL_EXT_read_format_bgra");
1104     extensions->mapBuffer = functions->isAtLeastGL(gl::Version(1, 5)) ||
1105                             functions->isAtLeastGLES(gl::Version(3, 0)) ||
1106                             functions->hasGLESExtension("GL_OES_mapbuffer");
1107     extensions->mapBufferRange = functions->isAtLeastGL(gl::Version(3, 0)) ||
1108                                  functions->hasGLExtension("GL_ARB_map_buffer_range") ||
1109                                  functions->isAtLeastGLES(gl::Version(3, 0)) ||
1110                                  functions->hasGLESExtension("GL_EXT_map_buffer_range");
1111     extensions->textureNPOT = functions->standard == STANDARD_GL_DESKTOP ||
1112                               functions->isAtLeastGLES(gl::Version(3, 0)) ||
1113                               functions->hasGLESExtension("GL_OES_texture_npot");
1114     // TODO(jmadill): Investigate emulating EXT_draw_buffers on ES 3.0's core functionality.
1115     extensions->drawBuffers = functions->isAtLeastGL(gl::Version(2, 0)) ||
1116                               functions->hasGLExtension("ARB_draw_buffers") ||
1117                               functions->hasGLESExtension("GL_EXT_draw_buffers");
1118     extensions->textureStorage = functions->standard == STANDARD_GL_DESKTOP ||
1119                                  functions->hasGLESExtension("GL_EXT_texture_storage");
1120     extensions->textureFilterAnisotropic =
1121         functions->hasGLExtension("GL_EXT_texture_filter_anisotropic") ||
1122         functions->hasGLESExtension("GL_EXT_texture_filter_anisotropic");
1123     extensions->occlusionQueryBoolean = nativegl::SupportsOcclusionQueries(functions);
1124     extensions->maxTextureAnisotropy =
1125         extensions->textureFilterAnisotropic
1126             ? QuerySingleGLFloat(functions, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)
1127             : 0.0f;
1128     extensions->fence = FenceNVGL::Supported(functions) || FenceNVSyncGL::Supported(functions);
1129     extensions->blendMinMax = functions->isAtLeastGL(gl::Version(1, 5)) ||
1130                               functions->hasGLExtension("GL_EXT_blend_minmax") ||
1131                               functions->isAtLeastGLES(gl::Version(3, 0)) ||
1132                               functions->hasGLESExtension("GL_EXT_blend_minmax");
1133     extensions->framebufferBlit        = (functions->blitFramebuffer != nullptr);
1134     extensions->framebufferMultisample = caps->maxSamples > 0;
1135     extensions->standardDerivatives    = functions->isAtLeastGL(gl::Version(2, 0)) ||
1136                                       functions->hasGLExtension("GL_ARB_fragment_shader") ||
1137                                       functions->hasGLESExtension("GL_OES_standard_derivatives");
1138     extensions->shaderTextureLOD = functions->isAtLeastGL(gl::Version(3, 0)) ||
1139                                    functions->hasGLExtension("GL_ARB_shader_texture_lod") ||
1140                                    functions->hasGLESExtension("GL_EXT_shader_texture_lod");
1141     extensions->fragDepth = functions->standard == STANDARD_GL_DESKTOP ||
1142                             functions->hasGLESExtension("GL_EXT_frag_depth");
1143 
1144     if (functions->hasGLExtension("GL_ARB_shader_viewport_layer_array") ||
1145         functions->hasGLExtension("GL_NV_viewport_array2"))
1146     {
1147         extensions->multiview  = true;
1148         extensions->multiview2 = true;
1149         // GL_MAX_ARRAY_TEXTURE_LAYERS is guaranteed to be at least 256.
1150         const int maxLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS);
1151         // GL_MAX_VIEWPORTS is guaranteed to be at least 16.
1152         const int maxViewports = QuerySingleGLInt(functions, GL_MAX_VIEWPORTS);
1153         extensions->maxViews   = static_cast<GLuint>(
1154             std::min(static_cast<int>(gl::IMPLEMENTATION_ANGLE_MULTIVIEW_MAX_VIEWS),
1155                      std::min(maxLayers, maxViewports)));
1156         *multiviewImplementationType = MultiviewImplementationTypeGL::NV_VIEWPORT_ARRAY2;
1157     }
1158 
1159     extensions->fboRenderMipmap = functions->isAtLeastGL(gl::Version(3, 0)) ||
1160                                   functions->hasGLExtension("GL_EXT_framebuffer_object") ||
1161                                   functions->isAtLeastGLES(gl::Version(3, 0)) ||
1162                                   functions->hasGLESExtension("GL_OES_fbo_render_mipmap");
1163     extensions->textureBorderClamp = functions->standard == STANDARD_GL_DESKTOP ||
1164                                      functions->hasGLESExtension("GL_OES_texture_border_clamp") ||
1165                                      functions->hasGLESExtension("GL_EXT_texture_border_clamp") ||
1166                                      functions->hasGLESExtension("GL_NV_texture_border_clamp");
1167     extensions->instancedArraysANGLE = functions->isAtLeastGL(gl::Version(3, 1)) ||
1168                                        (functions->hasGLExtension("GL_ARB_instanced_arrays") &&
1169                                         (functions->hasGLExtension("GL_ARB_draw_instanced") ||
1170                                          functions->hasGLExtension("GL_EXT_draw_instanced"))) ||
1171                                        functions->isAtLeastGLES(gl::Version(3, 0)) ||
1172                                        functions->hasGLESExtension("GL_EXT_instanced_arrays");
1173     extensions->instancedArraysEXT = extensions->instancedArraysANGLE;
1174     extensions->unpackSubimage     = functions->standard == STANDARD_GL_DESKTOP ||
1175                                  functions->isAtLeastGLES(gl::Version(3, 0)) ||
1176                                  functions->hasGLESExtension("GL_EXT_unpack_subimage");
1177     extensions->packSubimage = functions->standard == STANDARD_GL_DESKTOP ||
1178                                functions->isAtLeastGLES(gl::Version(3, 0)) ||
1179                                functions->hasGLESExtension("GL_NV_pack_subimage");
1180     extensions->vertexArrayObject = functions->isAtLeastGL(gl::Version(3, 0)) ||
1181                                     functions->hasGLExtension("GL_ARB_vertex_array_object") ||
1182                                     functions->isAtLeastGLES(gl::Version(3, 0)) ||
1183                                     functions->hasGLESExtension("GL_OES_vertex_array_object");
1184     extensions->debugMarker = functions->isAtLeastGL(gl::Version(4, 3)) ||
1185                               functions->hasGLExtension("GL_KHR_debug") ||
1186                               functions->hasGLExtension("GL_EXT_debug_marker") ||
1187                               functions->isAtLeastGLES(gl::Version(3, 2)) ||
1188                               functions->hasGLESExtension("GL_KHR_debug") ||
1189                               functions->hasGLESExtension("GL_EXT_debug_marker");
1190     extensions->eglImage         = functions->hasGLESExtension("GL_OES_EGL_image");
1191     extensions->eglImageExternal = functions->hasGLESExtension("GL_OES_EGL_image_external");
1192     extensions->eglImageExternalEssl3 =
1193         functions->hasGLESExtension("GL_OES_EGL_image_external_essl3");
1194 
1195     extensions->eglSync = functions->hasGLESExtension("GL_OES_EGL_sync");
1196 
1197     if (functions->isAtLeastGL(gl::Version(3, 3)) ||
1198         functions->hasGLExtension("GL_ARB_timer_query") ||
1199         functions->hasGLESExtension("GL_EXT_disjoint_timer_query"))
1200     {
1201         extensions->disjointTimerQuery = true;
1202 
1203         // If we can't query the counter bits, leave them at 0.
1204         if (!features.queryCounterBitsGeneratesErrors.enabled)
1205         {
1206             extensions->queryCounterBitsTimeElapsed =
1207                 QueryQueryValue(functions, GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS);
1208             extensions->queryCounterBitsTimestamp =
1209                 QueryQueryValue(functions, GL_TIMESTAMP, GL_QUERY_COUNTER_BITS);
1210         }
1211     }
1212 
1213     // the EXT_multisample_compatibility is written against ES3.1 but can apply
1214     // to earlier versions so therefore we're only checking for the extension string
1215     // and not the specific GLES version.
1216     extensions->multisampleCompatibility =
1217         functions->isAtLeastGL(gl::Version(1, 3)) ||
1218         functions->hasGLESExtension("GL_EXT_multisample_compatibility");
1219 
1220     extensions->framebufferMixedSamples =
1221         functions->hasGLExtension("GL_NV_framebuffer_mixed_samples") ||
1222         functions->hasGLESExtension("GL_NV_framebuffer_mixed_samples");
1223 
1224     extensions->robustness = functions->isAtLeastGL(gl::Version(4, 5)) ||
1225                              functions->hasGLExtension("GL_KHR_robustness") ||
1226                              functions->hasGLExtension("GL_ARB_robustness") ||
1227                              functions->isAtLeastGLES(gl::Version(3, 2)) ||
1228                              functions->hasGLESExtension("GL_KHR_robustness") ||
1229                              functions->hasGLESExtension("GL_EXT_robustness");
1230 
1231     extensions->robustBufferAccessBehavior =
1232         extensions->robustness &&
1233         (functions->hasGLExtension("GL_ARB_robust_buffer_access_behavior") ||
1234          functions->hasGLESExtension("GL_KHR_robust_buffer_access_behavior"));
1235 
1236     extensions->copyTexture = true;
1237     extensions->syncQuery   = SyncQueryGL::IsSupported(functions);
1238 
1239     // Note that OES_texture_storage_multisample_2d_array support could be extended down to GL 3.2
1240     // if we emulated texStorage* API on top of texImage*.
1241     extensions->textureStorageMultisample2DArray =
1242         functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 2));
1243 
1244     extensions->multiviewMultisample = extensions->textureStorageMultisample2DArray &&
1245                                        (extensions->multiview || extensions->multiview2);
1246 
1247     extensions->textureMultisample = functions->isAtLeastGL(gl::Version(3, 2)) ||
1248                                      functions->hasGLExtension("GL_ARB_texture_multisample");
1249 
1250     // NV_path_rendering
1251     // We also need interface query which is available in
1252     // >= 4.3 core or ARB_interface_query or >= GLES 3.1
1253     const bool canEnableGLPathRendering =
1254         functions->hasGLExtension("GL_NV_path_rendering") &&
1255         (functions->hasGLExtension("GL_ARB_program_interface_query") ||
1256          functions->isAtLeastGL(gl::Version(4, 3)));
1257 
1258     const bool canEnableESPathRendering = functions->hasGLESExtension("GL_NV_path_rendering") &&
1259                                           functions->isAtLeastGLES(gl::Version(3, 1));
1260 
1261     extensions->pathRendering = canEnableGLPathRendering || canEnableESPathRendering;
1262 
1263     extensions->textureSRGBDecode = functions->hasGLExtension("GL_EXT_texture_sRGB_decode") ||
1264                                     functions->hasGLESExtension("GL_EXT_texture_sRGB_decode");
1265 
1266 #if defined(ANGLE_PLATFORM_APPLE)
1267     VendorID vendor = GetVendorID(functions);
1268     if ((IsAMD(vendor) || IsIntel(vendor)) && *maxSupportedESVersion >= gl::Version(3, 0))
1269     {
1270         // Apple Intel/AMD drivers do not correctly use the TEXTURE_SRGB_DECODE property of sampler
1271         // states.  Disable this extension when we would advertise any ES version that has samplers.
1272         extensions->textureSRGBDecode = false;
1273     }
1274 #endif
1275 
1276     extensions->sRGBWriteControl = functions->isAtLeastGL(gl::Version(3, 0)) ||
1277                                    functions->hasGLExtension("GL_EXT_framebuffer_sRGB") ||
1278                                    functions->hasGLExtension("GL_ARB_framebuffer_sRGB") ||
1279                                    functions->hasGLESExtension("GL_EXT_sRGB_write_control");
1280 
1281 #if defined(ANGLE_PLATFORM_ANDROID)
1282     // SRGB blending does not appear to work correctly on the Nexus 5. Writing to an SRGB
1283     // framebuffer with GL_FRAMEBUFFER_SRGB enabled and then reading back returns the same value.
1284     // Disabling GL_FRAMEBUFFER_SRGB will then convert in the wrong direction.
1285     extensions->sRGBWriteControl = false;
1286 
1287     // BGRA formats do not appear to be accepted by the Nexus 5X driver dispite the extension being
1288     // exposed.
1289     extensions->textureFormatBGRA8888 = false;
1290 #endif
1291 
1292     // EXT_discard_framebuffer can be implemented as long as glDiscardFramebufferEXT or
1293     // glInvalidateFramebuffer is available
1294     extensions->discardFramebuffer = functions->isAtLeastGL(gl::Version(4, 3)) ||
1295                                      functions->hasGLExtension("GL_ARB_invalidate_subdata") ||
1296                                      functions->isAtLeastGLES(gl::Version(3, 0)) ||
1297                                      functions->hasGLESExtension("GL_EXT_discard_framebuffer") ||
1298                                      functions->hasGLESExtension("GL_ARB_invalidate_subdata");
1299 
1300     extensions->translatedShaderSource = true;
1301 
1302     if (functions->isAtLeastGL(gl::Version(3, 1)) ||
1303         functions->hasGLExtension("GL_ARB_texture_rectangle"))
1304     {
1305         extensions->textureRectangle  = true;
1306         caps->maxRectangleTextureSize = std::min(
1307             QuerySingleGLInt(functions, GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE), textureSizeLimit);
1308     }
1309 
1310     // OpenGL 4.3 (and above) can support all features and constants defined in
1311     // GL_EXT_geometry_shader.
1312     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1313         functions->hasGLESExtension("GL_OES_geometry_shader") ||
1314         functions->hasGLESExtension("GL_EXT_geometry_shader") ||
1315         // OpenGL 4.0 adds the support for instanced geometry shader
1316         // GL_ARB_shader_atomic_counters adds atomic counters to geometry shader
1317         // GL_ARB_shader_storage_buffer_object adds shader storage buffers to geometry shader
1318         // GL_ARB_shader_image_load_store adds images to geometry shader
1319         (functions->isAtLeastGL(gl::Version(4, 0)) &&
1320          functions->hasGLExtension("GL_ARB_shader_atomic_counters") &&
1321          functions->hasGLExtension("GL_ARB_shader_storage_buffer_object") &&
1322          functions->hasGLExtension("GL_ARB_shader_image_load_store")))
1323     {
1324         extensions->geometryShader = true;
1325 
1326         caps->maxFramebufferLayers = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_LAYERS_EXT);
1327 
1328         // GL_PROVOKING_VERTEX isn't a valid return value of GL_LAYER_PROVOKING_VERTEX_EXT in
1329         // GL_EXT_geometry_shader SPEC, however it is legal in desktop OpenGL, which means the value
1330         // follows the one set by glProvokingVertex.
1331         // [OpenGL 4.3] Chapter 11.3.4.6
1332         // The vertex conventions followed for gl_Layer and gl_ViewportIndex may be determined by
1333         // calling GetIntegerv with the symbolic constants LAYER_PROVOKING_VERTEX and
1334         // VIEWPORT_INDEX_PROVOKING_VERTEX, respectively. For either query, if the value returned is
1335         // PROVOKING_VERTEX, then vertex selection follows the convention specified by
1336         // ProvokingVertex.
1337         caps->layerProvokingVertex = QuerySingleGLInt(functions, GL_LAYER_PROVOKING_VERTEX_EXT);
1338         if (caps->layerProvokingVertex == GL_PROVOKING_VERTEX)
1339         {
1340             // We should use GL_LAST_VERTEX_CONVENTION_EXT instead because desktop OpenGL SPEC
1341             // requires the initial value of provoking vertex mode is LAST_VERTEX_CONVENTION.
1342             // [OpenGL 4.3] Chapter 13.4
1343             // The initial value of the provoking vertex mode is LAST_VERTEX_CONVENTION.
1344             caps->layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
1345         }
1346 
1347         caps->maxShaderUniformComponents[gl::ShaderType::Geometry] =
1348             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT);
1349         caps->maxShaderUniformBlocks[gl::ShaderType::Geometry] =
1350             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT);
1351         caps->maxCombinedShaderUniformComponents[gl::ShaderType::Geometry] =
1352             QuerySingleGLInt(functions, GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT);
1353         caps->maxGeometryInputComponents =
1354             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT);
1355         caps->maxGeometryOutputComponents =
1356             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT);
1357         caps->maxGeometryOutputVertices =
1358             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT);
1359         caps->maxGeometryTotalOutputComponents =
1360             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT);
1361         caps->maxGeometryShaderInvocations =
1362             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT);
1363         caps->maxShaderTextureImageUnits[gl::ShaderType::Geometry] =
1364             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT);
1365         caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] =
1366             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT);
1367         caps->maxShaderAtomicCounters[gl::ShaderType::Geometry] =
1368             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT);
1369         caps->maxShaderImageUniforms[gl::ShaderType::Geometry] =
1370             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT);
1371         caps->maxShaderStorageBlocks[gl::ShaderType::Geometry] =
1372             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT);
1373     }
1374 
1375     // The real combined caps contain limits for shader types that are not available to ES, so limit
1376     // the caps to the sum of vertex+fragment+geometry shader caps.
1377     CapCombinedLimitToESShaders(&caps->maxCombinedUniformBlocks, caps->maxShaderUniformBlocks);
1378     CapCombinedLimitToESShaders(&caps->maxCombinedTextureImageUnits,
1379                                 caps->maxShaderTextureImageUnits);
1380     CapCombinedLimitToESShaders(&caps->maxCombinedShaderStorageBlocks,
1381                                 caps->maxShaderStorageBlocks);
1382     CapCombinedLimitToESShaders(&caps->maxCombinedImageUniforms, caps->maxShaderImageUniforms);
1383     CapCombinedLimitToESShaders(&caps->maxCombinedAtomicCounterBuffers,
1384                                 caps->maxShaderAtomicCounterBuffers);
1385     CapCombinedLimitToESShaders(&caps->maxCombinedAtomicCounters, caps->maxShaderAtomicCounters);
1386 
1387     // EXT_blend_func_extended.
1388     // Note that this could be implemented also on top of native EXT_blend_func_extended, but it's
1389     // currently not fully implemented.
1390     extensions->blendFuncExtended = !features.disableBlendFuncExtended.enabled &&
1391                                     functions->standard == STANDARD_GL_DESKTOP &&
1392                                     functions->hasGLExtension("GL_ARB_blend_func_extended");
1393     if (extensions->blendFuncExtended)
1394     {
1395         // TODO(http://anglebug.com/1085): Support greater values of
1396         // MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT queried from the driver. See comments in ProgramGL.cpp
1397         // for more information about this limitation.
1398         extensions->maxDualSourceDrawBuffers = 1;
1399     }
1400 
1401     // EXT_float_blend
1402     // Assume all desktop driver supports this by default.
1403     extensions->floatBlend = functions->standard == STANDARD_GL_DESKTOP ||
1404                              functions->hasGLESExtension("GL_EXT_float_blend");
1405 
1406     // GL_CHROMIUM_compressed_texture_etc
1407     // Expose this extension only when we support the formats or we're running on top of a native
1408     // ES driver.
1409     extensions->compressedTextureETC = functions->standard == STANDARD_GL_ES &&
1410                                        gl::DetermineCompressedTextureETCSupport(*textureCapsMap);
1411 
1412     // To work around broken unsized sRGB textures, sized sRGB textures are used. Disable EXT_sRGB
1413     // if those formats are not available.
1414     if (features.unsizedsRGBReadPixelsDoesntTransform.enabled &&
1415         !functions->isAtLeastGLES(gl::Version(3, 0)))
1416     {
1417         extensions->sRGB = false;
1418     }
1419 
1420     extensions->provokingVertex = functions->hasGLExtension("GL_ARB_provoking_vertex") ||
1421                                   functions->hasGLExtension("GL_EXT_provoking_vertex") ||
1422                                   functions->isAtLeastGL(gl::Version(3, 2));
1423 
1424     extensions->textureExternalUpdateANGLE = true;
1425     extensions->texture3DOES               = functions->isAtLeastGL(gl::Version(1, 2)) ||
1426                                functions->isAtLeastGLES(gl::Version(3, 0)) ||
1427                                functions->hasGLESExtension("GL_OES_texture_3D");
1428 
1429     extensions->memoryObject = functions->hasGLExtension("GL_EXT_memory_object") ||
1430                                functions->hasGLESExtension("GL_EXT_memory_object");
1431     extensions->semaphore = functions->hasGLExtension("GL_EXT_semaphore") ||
1432                             functions->hasGLESExtension("GL_EXT_semaphore");
1433     extensions->memoryObjectFd = functions->hasGLExtension("GL_EXT_memory_object_fd") ||
1434                                  functions->hasGLESExtension("GL_EXT_memory_object_fd");
1435     extensions->semaphoreFd = functions->hasGLExtension("GL_EXT_semaphore_fd") ||
1436                               functions->hasGLESExtension("GL_EXT_semaphore_fd");
1437 }
1438 
InitializeFeatures(const FunctionsGL * functions,angle::FeaturesGL * features)1439 void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *features)
1440 {
1441     VendorID vendor = GetVendorID(functions);
1442     uint32_t device = GetDeviceID(functions);
1443 
1444     // Don't use 1-bit alpha formats on desktop GL with AMD or Intel drivers.
1445     features->avoid1BitAlphaTextureFormats.enabled =
1446         functions->standard == STANDARD_GL_DESKTOP && (IsAMD(vendor));
1447 
1448     features->rgba4IsNotSupportedForColorRendering.enabled =
1449         functions->standard == STANDARD_GL_DESKTOP && IsIntel(vendor);
1450 
1451     features->emulateAbsIntFunction.enabled = IsIntel(vendor);
1452 
1453     features->addAndTrueToLoopCondition.enabled = IsIntel(vendor);
1454 
1455     features->emulateIsnanFloat.enabled = IsIntel(vendor);
1456 
1457     features->doesSRGBClearsOnLinearFramebufferAttachments.enabled =
1458         functions->standard == STANDARD_GL_DESKTOP && (IsIntel(vendor) || IsAMD(vendor));
1459 
1460     features->emulateMaxVertexAttribStride.enabled =
1461         IsLinux() && functions->standard == STANDARD_GL_DESKTOP && IsAMD(vendor);
1462     features->useUnusedBlocksWithStandardOrSharedLayout.enabled = IsLinux() && IsAMD(vendor);
1463 
1464     features->doWhileGLSLCausesGPUHang.enabled                  = IsApple();
1465     features->useUnusedBlocksWithStandardOrSharedLayout.enabled = IsApple();
1466     features->rewriteFloatUnaryMinusOperator.enabled            = IsApple() && IsIntel(vendor);
1467 
1468     // Triggers a bug on Marshmallow Adreno (4xx?) driver.
1469     // http://anglebug.com/2046
1470     features->dontInitializeUninitializedLocals.enabled = IsAndroid() && IsQualcomm(vendor);
1471 
1472     features->finishDoesNotCauseQueriesToBeAvailable.enabled =
1473         functions->standard == STANDARD_GL_DESKTOP && IsNvidia(vendor);
1474 
1475     // TODO(cwallez): Disable this workaround for MacOSX versions 10.9 or later.
1476     features->alwaysCallUseProgramAfterLink.enabled = true;
1477 
1478     features->unpackOverlappingRowsSeparatelyUnpackBuffer.enabled = IsNvidia(vendor);
1479     features->packOverlappingRowsSeparatelyPackBuffer.enabled     = IsNvidia(vendor);
1480 
1481     features->initializeCurrentVertexAttributes.enabled = IsNvidia(vendor);
1482 
1483     features->unpackLastRowSeparatelyForPaddingInclusion.enabled = IsApple() || IsNvidia(vendor);
1484     features->packLastRowSeparatelyForPaddingInclusion.enabled   = IsApple() || IsNvidia(vendor);
1485 
1486     features->removeInvariantAndCentroidForESSL3.enabled =
1487         functions->isAtMostGL(gl::Version(4, 1)) ||
1488         (functions->standard == STANDARD_GL_DESKTOP && IsAMD(vendor));
1489 
1490     // TODO(oetuaho): Make this specific to the affected driver versions. Versions that came after
1491     // 364 are known to be affected, at least up to 375.
1492     features->emulateAtan2Float.enabled = IsNvidia(vendor);
1493 
1494     features->reapplyUBOBindingsAfterUsingBinaryProgram.enabled = IsAMD(vendor);
1495 
1496     features->rewriteVectorScalarArithmetic.enabled = IsNvidia(vendor);
1497 
1498     // TODO(oetuaho): Make this specific to the affected driver versions. Versions at least up to
1499     // 390 are known to be affected. Versions after that are expected not to be affected.
1500     features->clampFragDepth.enabled = IsNvidia(vendor);
1501 
1502     // TODO(oetuaho): Make this specific to the affected driver versions. Versions since 397.31 are
1503     // not affected.
1504     features->rewriteRepeatedAssignToSwizzled.enabled = IsNvidia(vendor);
1505 
1506     // TODO(jmadill): Narrow workaround range for specific devices.
1507     features->reapplyUBOBindingsAfterUsingBinaryProgram.enabled = IsAndroid();
1508 
1509     features->clampPointSize.enabled = IsAndroid() || IsNvidia(vendor);
1510 
1511     features->dontUseLoopsToInitializeVariables.enabled = IsAndroid() && !IsNvidia(vendor);
1512 
1513     features->disableBlendFuncExtended.enabled = IsAMD(vendor) || IsIntel(vendor);
1514 
1515     features->unsizedsRGBReadPixelsDoesntTransform.enabled = IsAndroid() && IsQualcomm(vendor);
1516 
1517     features->queryCounterBitsGeneratesErrors.enabled = IsNexus5X(vendor, device);
1518 
1519     features->dontRelinkProgramsInParallel.enabled =
1520         IsAndroid() || (IsWindows() && IsIntel(vendor));
1521 
1522     // TODO(jie.a.chen@intel.com): Clean up the bugs.
1523     // anglebug.com/3031
1524     // crbug.com/922936
1525     features->disableWorkerContexts.enabled =
1526         (IsWindows() && (IsIntel(vendor) || IsAMD(vendor))) || (IsLinux() && IsNvidia(vendor));
1527 
1528     features->limitMaxTextureSizeTo4096.enabled = IsAndroid() || (IsIntel(vendor) && IsLinux());
1529     features->limitMaxMSAASamplesTo4.enabled    = IsAndroid();
1530     features->limitMax3dArrayTextureSizeTo1024.enabled = IsIntel(vendor) && IsLinux();
1531 
1532     features->allowClearForRobustResourceInit.enabled = IsApple();
1533 
1534     // The WebGL conformance/uniforms/out-of-bounds-uniform-array-access test has been seen to fail
1535     // on AMD and Android devices.
1536     features->clampArrayAccess.enabled = IsAndroid() || IsAMD(vendor);
1537 
1538     features->resetTexImage2DBaseLevel.enabled =
1539         IsApple() && IsIntel(vendor) && GetMacOSVersion() >= OSVersion(10, 12, 4);
1540 
1541     features->clearToZeroOrOneBroken.enabled =
1542         IsApple() && IsIntel(vendor) && GetMacOSVersion() < OSVersion(10, 12, 6);
1543 
1544     features->adjustSrcDstRegionBlitFramebuffer.enabled =
1545         IsLinux() || (IsAndroid() && IsNvidia(vendor)) || (IsWindows() && IsNvidia(vendor));
1546 
1547     features->clipSrcRegionBlitFramebuffer.enabled = IsApple();
1548 }
1549 
InitializeFrontendFeatures(const FunctionsGL * functions,angle::FrontendFeatures * features)1550 void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
1551 {
1552     VendorID vendor = GetVendorID(functions);
1553 
1554     features->disableProgramCachingForTransformFeedback.enabled = IsAndroid() && IsQualcomm(vendor);
1555     features->syncFramebufferBindingsOnTexImage.enabled         = IsWindows() && IsIntel(vendor);
1556 }
1557 
1558 }  // namespace nativegl_gl
1559 
1560 namespace nativegl
1561 {
SupportsFenceSync(const FunctionsGL * functions)1562 bool SupportsFenceSync(const FunctionsGL *functions)
1563 {
1564     return functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") ||
1565            functions->isAtLeastGLES(gl::Version(3, 0));
1566 }
1567 
SupportsOcclusionQueries(const FunctionsGL * functions)1568 bool SupportsOcclusionQueries(const FunctionsGL *functions)
1569 {
1570     return functions->isAtLeastGL(gl::Version(1, 5)) ||
1571            functions->hasGLExtension("GL_ARB_occlusion_query2") ||
1572            functions->isAtLeastGLES(gl::Version(3, 0)) ||
1573            functions->hasGLESExtension("GL_EXT_occlusion_query_boolean");
1574 }
1575 
SupportsNativeRendering(const FunctionsGL * functions,gl::TextureType type,GLenum internalFormat)1576 bool SupportsNativeRendering(const FunctionsGL *functions,
1577                              gl::TextureType type,
1578                              GLenum internalFormat)
1579 {
1580     // Some desktop drivers allow rendering to formats that are not required by the spec, this is
1581     // exposed through the GL_FRAMEBUFFER_RENDERABLE query.
1582     bool hasInternalFormatQuery = functions->isAtLeastGL(gl::Version(4, 3)) ||
1583                                   functions->hasGLExtension("GL_ARB_internalformat_query2");
1584 
1585     // Some Intel drivers have a bug that returns GL_FULL_SUPPORT when asked if they support
1586     // rendering to compressed texture formats yet return framebuffer incomplete when attempting to
1587     // render to the format.  Skip any native queries for compressed formats.
1588     const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
1589 
1590     if (hasInternalFormatQuery && !internalFormatInfo.compressed)
1591     {
1592         GLint framebufferRenderable = GL_NONE;
1593         functions->getInternalformativ(ToGLenum(type), internalFormat, GL_FRAMEBUFFER_RENDERABLE, 1,
1594                                        &framebufferRenderable);
1595         return framebufferRenderable != GL_NONE;
1596     }
1597     else
1598     {
1599         const nativegl::InternalFormat &nativeInfo =
1600             nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
1601         return nativegl_gl::MeetsRequirements(functions, nativeInfo.textureAttachment);
1602     }
1603 }
1604 
SupportsTexImage(gl::TextureType type)1605 bool SupportsTexImage(gl::TextureType type)
1606 {
1607     switch (type)
1608     {
1609             // Multi-sample texture types only support TexStorage data upload
1610         case gl::TextureType::_2DMultisample:
1611         case gl::TextureType::_2DMultisampleArray:
1612             return false;
1613 
1614         default:
1615             return true;
1616     }
1617 }
1618 
UseTexImage2D(gl::TextureType textureType)1619 bool UseTexImage2D(gl::TextureType textureType)
1620 {
1621     return textureType == gl::TextureType::_2D || textureType == gl::TextureType::CubeMap ||
1622            textureType == gl::TextureType::Rectangle ||
1623            textureType == gl::TextureType::_2DMultisample ||
1624            textureType == gl::TextureType::External;
1625 }
1626 
UseTexImage3D(gl::TextureType textureType)1627 bool UseTexImage3D(gl::TextureType textureType)
1628 {
1629     return textureType == gl::TextureType::_2DArray || textureType == gl::TextureType::_3D ||
1630            textureType == gl::TextureType::_2DMultisampleArray;
1631 }
1632 
GetTextureBindingQuery(gl::TextureType textureType)1633 GLenum GetTextureBindingQuery(gl::TextureType textureType)
1634 {
1635     switch (textureType)
1636     {
1637         case gl::TextureType::_2D:
1638             return GL_TEXTURE_BINDING_2D;
1639         case gl::TextureType::_2DArray:
1640             return GL_TEXTURE_BINDING_2D_ARRAY;
1641         case gl::TextureType::_2DMultisample:
1642             return GL_TEXTURE_BINDING_2D_MULTISAMPLE;
1643         case gl::TextureType::_2DMultisampleArray:
1644             return GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY;
1645         case gl::TextureType::_3D:
1646             return GL_TEXTURE_BINDING_3D;
1647         case gl::TextureType::External:
1648             return GL_TEXTURE_BINDING_EXTERNAL_OES;
1649         case gl::TextureType::Rectangle:
1650             return GL_TEXTURE_BINDING_RECTANGLE;
1651         case gl::TextureType::CubeMap:
1652             return GL_TEXTURE_BINDING_CUBE_MAP;
1653         default:
1654             UNREACHABLE();
1655             return 0;
1656     }
1657 }
1658 
1659 }  // namespace nativegl
1660 
GetFunctionsGL(const gl::Context * context)1661 const FunctionsGL *GetFunctionsGL(const gl::Context *context)
1662 {
1663     return GetImplAs<ContextGL>(context)->getFunctions();
1664 }
1665 
GetStateManagerGL(const gl::Context * context)1666 StateManagerGL *GetStateManagerGL(const gl::Context *context)
1667 {
1668     return GetImplAs<ContextGL>(context)->getStateManager();
1669 }
1670 
GetBlitGL(const gl::Context * context)1671 BlitGL *GetBlitGL(const gl::Context *context)
1672 {
1673     return GetImplAs<ContextGL>(context)->getBlitter();
1674 }
1675 
GetMultiviewClearer(const gl::Context * context)1676 ClearMultiviewGL *GetMultiviewClearer(const gl::Context *context)
1677 {
1678     return GetImplAs<ContextGL>(context)->getMultiviewClearer();
1679 }
1680 
GetFeaturesGL(const gl::Context * context)1681 const angle::FeaturesGL &GetFeaturesGL(const gl::Context *context)
1682 {
1683     return GetImplAs<ContextGL>(context)->getFeaturesGL();
1684 }
1685 
CanMapBufferForRead(const FunctionsGL * functions)1686 bool CanMapBufferForRead(const FunctionsGL *functions)
1687 {
1688     return (functions->mapBufferRange != nullptr) ||
1689            (functions->mapBuffer != nullptr && functions->standard == STANDARD_GL_DESKTOP);
1690 }
1691 
MapBufferRangeWithFallback(const FunctionsGL * functions,GLenum target,size_t offset,size_t length,GLbitfield access)1692 uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions,
1693                                     GLenum target,
1694                                     size_t offset,
1695                                     size_t length,
1696                                     GLbitfield access)
1697 {
1698     if (functions->mapBufferRange != nullptr)
1699     {
1700         return static_cast<uint8_t *>(functions->mapBufferRange(target, offset, length, access));
1701     }
1702     else if (functions->mapBuffer != nullptr &&
1703              (functions->standard == STANDARD_GL_DESKTOP || access == GL_MAP_WRITE_BIT))
1704     {
1705         // Only the read and write bits are supported
1706         ASSERT((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) != 0);
1707 
1708         GLenum accessEnum = 0;
1709         if (access == (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))
1710         {
1711             accessEnum = GL_READ_WRITE;
1712         }
1713         else if (access == GL_MAP_READ_BIT)
1714         {
1715             accessEnum = GL_READ_ONLY;
1716         }
1717         else if (access == GL_MAP_WRITE_BIT)
1718         {
1719             accessEnum = GL_WRITE_ONLY;
1720         }
1721         else
1722         {
1723             UNREACHABLE();
1724             return nullptr;
1725         }
1726 
1727         return static_cast<uint8_t *>(functions->mapBuffer(target, accessEnum)) + offset;
1728     }
1729     else
1730     {
1731         // No options available
1732         UNREACHABLE();
1733         return nullptr;
1734     }
1735 }
1736 
ShouldApplyLastRowPaddingWorkaround(ContextGL * contextGL,const gl::Extents & size,const gl::PixelStoreStateBase & state,const gl::Buffer * pixelBuffer,GLenum format,GLenum type,bool is3D,const void * pixels,bool * shouldApplyOut)1737 angle::Result ShouldApplyLastRowPaddingWorkaround(ContextGL *contextGL,
1738                                                   const gl::Extents &size,
1739                                                   const gl::PixelStoreStateBase &state,
1740                                                   const gl::Buffer *pixelBuffer,
1741                                                   GLenum format,
1742                                                   GLenum type,
1743                                                   bool is3D,
1744                                                   const void *pixels,
1745                                                   bool *shouldApplyOut)
1746 {
1747     if (pixelBuffer == nullptr)
1748     {
1749         *shouldApplyOut = false;
1750         return angle::Result::Continue;
1751     }
1752 
1753     // We are using an pack or unpack buffer, compute what the driver thinks is going to be the
1754     // last byte read or written. If it is past the end of the buffer, we will need to use the
1755     // workaround otherwise the driver will generate INVALID_OPERATION and not do the operation.
1756 
1757     const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
1758     GLuint endByte                     = 0;
1759     ANGLE_CHECK_GL_MATH(contextGL,
1760                         glFormat.computePackUnpackEndByte(type, size, state, is3D, &endByte));
1761     GLuint rowPitch = 0;
1762     ANGLE_CHECK_GL_MATH(contextGL, glFormat.computeRowPitch(type, size.width, state.alignment,
1763                                                             state.rowLength, &rowPitch));
1764 
1765     CheckedNumeric<size_t> checkedPixelBytes = glFormat.computePixelBytes(type);
1766     CheckedNumeric<size_t> checkedEndByte =
1767         angle::CheckedNumeric<size_t>(endByte) + reinterpret_cast<intptr_t>(pixels);
1768 
1769     // At this point checkedEndByte is the actual last byte read.
1770     // The driver adds an extra row padding (if any), mimic it.
1771     ANGLE_CHECK_GL_MATH(contextGL, checkedPixelBytes.IsValid());
1772     if (checkedPixelBytes.ValueOrDie() * size.width < rowPitch)
1773     {
1774         checkedEndByte += rowPitch - checkedPixelBytes * size.width;
1775     }
1776 
1777     ANGLE_CHECK_GL_MATH(contextGL, checkedEndByte.IsValid());
1778 
1779     *shouldApplyOut = checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelBuffer->getSize());
1780     return angle::Result::Continue;
1781 }
1782 
GenerateContextCreationToTry(EGLint requestedType,bool isMesaGLX)1783 std::vector<ContextCreationTry> GenerateContextCreationToTry(EGLint requestedType, bool isMesaGLX)
1784 {
1785     using Type                         = ContextCreationTry::Type;
1786     constexpr EGLint kPlatformOpenGL   = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
1787     constexpr EGLint kPlatformOpenGLES = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
1788 
1789     std::vector<ContextCreationTry> contextsToTry;
1790 
1791     if (requestedType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE || requestedType == kPlatformOpenGL)
1792     {
1793         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 5));
1794         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 4));
1795         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 3));
1796         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 2));
1797         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 1));
1798         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 0));
1799         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(3, 3));
1800         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(3, 2));
1801         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 3));
1802 
1803         // On Mesa, do not try to create OpenGL context versions between 3.0 and
1804         // 3.2 because of compatibility problems. See crbug.com/659030
1805         if (!isMesaGLX)
1806         {
1807             contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 2));
1808             contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 1));
1809             contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 0));
1810         }
1811 
1812         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(2, 1));
1813         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(2, 0));
1814         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 5));
1815         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 4));
1816         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 3));
1817         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 2));
1818         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 1));
1819         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 0));
1820     }
1821 
1822     if (requestedType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE ||
1823         requestedType == kPlatformOpenGLES)
1824     {
1825         contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 2));
1826         contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 1));
1827         contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 0));
1828         contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(2, 0));
1829     }
1830 
1831     return contextsToTry;
1832 }
1833 }  // namespace rx
1834