• 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 <array>
13 #include <limits>
14 
15 #include "common/android_util.h"
16 #include "common/mathutil.h"
17 #include "common/platform.h"
18 #include "common/string_utils.h"
19 #include "gpu_info_util/SystemInfo.h"
20 #include "libANGLE/Buffer.h"
21 #include "libANGLE/Caps.h"
22 #include "libANGLE/Context.h"
23 #include "libANGLE/formatutils.h"
24 #include "libANGLE/queryconversions.h"
25 #include "libANGLE/renderer/driver_utils.h"
26 #include "libANGLE/renderer/gl/ContextGL.h"
27 #include "libANGLE/renderer/gl/FenceNVGL.h"
28 #include "libANGLE/renderer/gl/FunctionsGL.h"
29 #include "libANGLE/renderer/gl/QueryGL.h"
30 #include "libANGLE/renderer/gl/formatutilsgl.h"
31 #include "platform/autogen/FeaturesGL_autogen.h"
32 #include "platform/autogen/FrontendFeatures_autogen.h"
33 
34 #include <EGL/eglext.h>
35 #include <algorithm>
36 #include <sstream>
37 
38 using angle::CheckedNumeric;
39 
40 namespace rx
41 {
42 
43 namespace
44 {
45 
GetString(const FunctionsGL * functions,GLenum name)46 const char *GetString(const FunctionsGL *functions, GLenum name)
47 {
48     const char *cStr = reinterpret_cast<const char *>(functions->getString(name));
49     if (cStr == nullptr)
50     {
51         return "";
52     }
53     return cStr;
54 }
55 
IsMesa(const FunctionsGL * functions,std::array<int,3> * version)56 bool IsMesa(const FunctionsGL *functions, std::array<int, 3> *version)
57 {
58     ASSERT(version);
59 
60     std::string nativeVersionString(GetString(functions, GL_VERSION));
61     size_t pos = nativeVersionString.find("Mesa");
62     if (pos == std::string::npos)
63     {
64         return false;
65     }
66 
67     int *data = version->data();
68     data[0] = data[1] = data[2] = 0;
69     std::sscanf(nativeVersionString.c_str() + pos, "Mesa %d.%d.%d", data, data + 1, data + 2);
70 
71     return true;
72 }
73 
getAdrenoNumber(const FunctionsGL * functions)74 int getAdrenoNumber(const FunctionsGL *functions)
75 {
76     static int number = -1;
77     if (number == -1)
78     {
79         const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
80         if (std::sscanf(nativeGLRenderer, "Adreno (TM) %d", &number) < 1 &&
81             std::sscanf(nativeGLRenderer, "FD%d", &number) < 1)
82         {
83             number = 0;
84         }
85     }
86     return number;
87 }
88 
GetQualcommVersion(const FunctionsGL * functions)89 int GetQualcommVersion(const FunctionsGL *functions)
90 {
91     static int version = -1;
92     if (version == -1)
93     {
94         const std::string nativeVersionString(GetString(functions, GL_VERSION));
95         const size_t pos = nativeVersionString.find("V@");
96         if (pos == std::string::npos ||
97             std::sscanf(nativeVersionString.c_str() + pos, "V@%d", &version) < 1)
98         {
99             version = 0;
100         }
101     }
102     return version;
103 }
104 
getMaliTNumber(const FunctionsGL * functions)105 int getMaliTNumber(const FunctionsGL *functions)
106 {
107     static int number = -1;
108     if (number == -1)
109     {
110         const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
111         if (std::sscanf(nativeGLRenderer, "Mali-T%d", &number) < 1)
112         {
113             number = 0;
114         }
115     }
116     return number;
117 }
118 
getMaliGNumber(const FunctionsGL * functions)119 int getMaliGNumber(const FunctionsGL *functions)
120 {
121     static int number = -1;
122     if (number == -1)
123     {
124         const char *nativeGLRenderer = GetString(functions, GL_RENDERER);
125         if (std::sscanf(nativeGLRenderer, "Mali-G%d", &number) < 1)
126         {
127             number = 0;
128         }
129     }
130     return number;
131 }
132 
IsAdreno3xx(const FunctionsGL * functions)133 bool IsAdreno3xx(const FunctionsGL *functions)
134 {
135     int number = getAdrenoNumber(functions);
136     return number != 0 && number >= 300 && number < 400;
137 }
138 
IsAdreno42xOr3xx(const FunctionsGL * functions)139 bool IsAdreno42xOr3xx(const FunctionsGL *functions)
140 {
141     int number = getAdrenoNumber(functions);
142     return number != 0 && getAdrenoNumber(functions) < 430;
143 }
144 
IsAdreno4xx(const FunctionsGL * functions)145 bool IsAdreno4xx(const FunctionsGL *functions)
146 {
147     int number = getAdrenoNumber(functions);
148     return number != 0 && number >= 400 && number < 500;
149 }
150 
IsAdreno5xxOrOlder(const FunctionsGL * functions)151 bool IsAdreno5xxOrOlder(const FunctionsGL *functions)
152 {
153     int number = getAdrenoNumber(functions);
154     return number != 0 && number < 600;
155 }
156 
IsAdreno5xx(const FunctionsGL * functions)157 bool IsAdreno5xx(const FunctionsGL *functions)
158 {
159     int number = getAdrenoNumber(functions);
160     return number != 0 && number >= 500 && number < 600;
161 }
162 
IsMaliT8xxOrOlder(const FunctionsGL * functions)163 bool IsMaliT8xxOrOlder(const FunctionsGL *functions)
164 {
165     int number = getMaliTNumber(functions);
166     return number != 0 && number < 900;
167 }
168 
IsMaliG31OrOlder(const FunctionsGL * functions)169 bool IsMaliG31OrOlder(const FunctionsGL *functions)
170 {
171     int number = getMaliGNumber(functions);
172     return number != 0 && number <= 31;
173 }
174 
IsMaliG72OrG76OrG51(const FunctionsGL * functions)175 bool IsMaliG72OrG76OrG51(const FunctionsGL *functions)
176 {
177     int number = getMaliGNumber(functions);
178     return number == 72 || number == 76 || number == 51;
179 }
180 
IsMaliValhall(const FunctionsGL * functions)181 bool IsMaliValhall(const FunctionsGL *functions)
182 {
183     int number = getMaliGNumber(functions);
184     return number == 57 || number == 77 || number == 68 || number == 78 || number == 310 ||
185            number == 510 || number == 610 || number == 710 || number == 615 || number == 715;
186 }
187 
IsPixel7OrPixel8(const FunctionsGL * functions)188 bool IsPixel7OrPixel8(const FunctionsGL *functions)
189 {
190     int number = getMaliGNumber(functions);
191     return number == 710 || number == 715;
192 }
193 
IsAndroidEmulator(const FunctionsGL * functions)194 [[maybe_unused]] bool IsAndroidEmulator(const FunctionsGL *functions)
195 {
196     constexpr char androidEmulator[] = "Android Emulator";
197     const char *nativeGLRenderer     = GetString(functions, GL_RENDERER);
198     return angle::BeginsWith(nativeGLRenderer, androidEmulator);
199 }
200 
IsPowerVrRogue(const FunctionsGL * functions)201 bool IsPowerVrRogue(const FunctionsGL *functions)
202 {
203     constexpr char powerVRRogue[] = "PowerVR Rogue";
204     const char *nativeGLRenderer  = GetString(functions, GL_RENDERER);
205     return angle::BeginsWith(nativeGLRenderer, powerVRRogue);
206 }
207 
208 }  // namespace
209 
SwapControlData()210 SwapControlData::SwapControlData()
211     : targetSwapInterval(0), maxSwapInterval(-1), currentSwapInterval(-1)
212 {}
213 
GetVendorID(const FunctionsGL * functions)214 VendorID GetVendorID(const FunctionsGL *functions)
215 {
216     std::string nativeVendorString(GetString(functions, GL_VENDOR));
217     // Concatenate GL_RENDERER to the string being checked because some vendors put their names in
218     // GL_RENDERER
219     nativeVendorString += " ";
220     nativeVendorString += GetString(functions, GL_RENDERER);
221 
222     if (nativeVendorString.find("NVIDIA") != std::string::npos)
223     {
224         return VENDOR_ID_NVIDIA;
225     }
226     else if (nativeVendorString.find("ATI") != std::string::npos ||
227              nativeVendorString.find("AMD") != std::string::npos ||
228              nativeVendorString.find("Radeon") != std::string::npos)
229     {
230         return VENDOR_ID_AMD;
231     }
232     else if (nativeVendorString.find("Qualcomm") != std::string::npos)
233     {
234         return VENDOR_ID_QUALCOMM;
235     }
236     else if (nativeVendorString.find("Intel") != std::string::npos)
237     {
238         return VENDOR_ID_INTEL;
239     }
240     else if (nativeVendorString.find("Imagination") != std::string::npos)
241     {
242         return VENDOR_ID_POWERVR;
243     }
244     else if (nativeVendorString.find("Vivante") != std::string::npos)
245     {
246         return VENDOR_ID_VIVANTE;
247     }
248     else if (nativeVendorString.find("Mali") != std::string::npos)
249     {
250         return VENDOR_ID_ARM;
251     }
252     else
253     {
254         return VENDOR_ID_UNKNOWN;
255     }
256 }
257 
GetDeviceID(const FunctionsGL * functions)258 uint32_t GetDeviceID(const FunctionsGL *functions)
259 {
260     std::string nativeRendererString(GetString(functions, GL_RENDERER));
261     constexpr std::pair<const char *, uint32_t> kKnownDeviceIDs[] = {
262         {"Adreno (TM) 418", ANDROID_DEVICE_ID_NEXUS5X},
263         {"Adreno (TM) 530", ANDROID_DEVICE_ID_PIXEL1XL},
264         {"Adreno (TM) 540", ANDROID_DEVICE_ID_PIXEL2},
265     };
266 
267     for (const auto &knownDeviceID : kKnownDeviceIDs)
268     {
269         if (nativeRendererString.find(knownDeviceID.first) != std::string::npos)
270         {
271             return knownDeviceID.second;
272         }
273     }
274 
275     return 0;
276 }
277 
GetShaderOutputType(const FunctionsGL * functions)278 ShShaderOutput GetShaderOutputType(const FunctionsGL *functions)
279 {
280     ASSERT(functions);
281 
282     if (functions->standard == STANDARD_GL_DESKTOP)
283     {
284         // GLSL outputs
285         if (functions->isAtLeastGL(gl::Version(4, 5)))
286         {
287             return SH_GLSL_450_CORE_OUTPUT;
288         }
289         else if (functions->isAtLeastGL(gl::Version(4, 4)))
290         {
291             return SH_GLSL_440_CORE_OUTPUT;
292         }
293         else if (functions->isAtLeastGL(gl::Version(4, 3)))
294         {
295             return SH_GLSL_430_CORE_OUTPUT;
296         }
297         else if (functions->isAtLeastGL(gl::Version(4, 2)))
298         {
299             return SH_GLSL_420_CORE_OUTPUT;
300         }
301         else if (functions->isAtLeastGL(gl::Version(4, 1)))
302         {
303             return SH_GLSL_410_CORE_OUTPUT;
304         }
305         else if (functions->isAtLeastGL(gl::Version(4, 0)))
306         {
307             return SH_GLSL_400_CORE_OUTPUT;
308         }
309         else if (functions->isAtLeastGL(gl::Version(3, 3)))
310         {
311             return SH_GLSL_330_CORE_OUTPUT;
312         }
313         else if (functions->isAtLeastGL(gl::Version(3, 2)))
314         {
315             return SH_GLSL_150_CORE_OUTPUT;
316         }
317         else if (functions->isAtLeastGL(gl::Version(3, 1)))
318         {
319             return SH_GLSL_140_OUTPUT;
320         }
321         else if (functions->isAtLeastGL(gl::Version(3, 0)))
322         {
323             return SH_GLSL_130_OUTPUT;
324         }
325         else
326         {
327             return SH_GLSL_COMPATIBILITY_OUTPUT;
328         }
329     }
330     else if (functions->standard == STANDARD_GL_ES)
331     {
332         // ESSL outputs
333         return SH_ESSL_OUTPUT;
334     }
335     else
336     {
337         UNREACHABLE();
338         return ShShaderOutput(0);
339     }
340 }
341 
342 namespace nativegl_gl
343 {
344 
MeetsRequirements(const FunctionsGL * functions,const nativegl::SupportRequirement & requirements)345 static bool MeetsRequirements(const FunctionsGL *functions,
346                               const nativegl::SupportRequirement &requirements)
347 {
348     bool hasRequiredExtensions = false;
349     for (const std::vector<std::string> &exts : requirements.requiredExtensions)
350     {
351         bool hasAllExtensionsInSet = true;
352         for (const std::string &extension : exts)
353         {
354             if (!functions->hasExtension(extension))
355             {
356                 hasAllExtensionsInSet = false;
357                 break;
358             }
359         }
360         if (hasAllExtensionsInSet)
361         {
362             hasRequiredExtensions = true;
363             break;
364         }
365     }
366     if (!requirements.requiredExtensions.empty() && !hasRequiredExtensions)
367     {
368         return false;
369     }
370 
371     if (functions->version >= requirements.version)
372     {
373         return true;
374     }
375     else if (!requirements.versionExtensions.empty())
376     {
377         for (const std::string &extension : requirements.versionExtensions)
378         {
379             if (!functions->hasExtension(extension))
380             {
381                 return false;
382             }
383         }
384         return true;
385     }
386     else
387     {
388         return false;
389     }
390 }
391 
CheckSizedInternalFormatTextureRenderability(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)392 static bool CheckSizedInternalFormatTextureRenderability(const FunctionsGL *functions,
393                                                          const angle::FeaturesGL &features,
394                                                          GLenum internalFormat)
395 {
396     const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
397     ASSERT(formatInfo.sized);
398 
399     // Query the current texture so it can be rebound afterwards
400     GLint oldTextureBinding = 0;
401     functions->getIntegerv(GL_TEXTURE_BINDING_2D, &oldTextureBinding);
402 
403     // Create a small texture with the same format and type that gl::Texture would use
404     GLuint texture = 0;
405     functions->genTextures(1, &texture);
406     functions->bindTexture(GL_TEXTURE_2D, texture);
407 
408     // Nearest filter needed for framebuffer completeness on some drivers.
409     functions->texParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
410 
411     nativegl::TexImageFormat texImageFormat = nativegl::GetTexImageFormat(
412         functions, features, formatInfo.internalFormat, formatInfo.format, formatInfo.type);
413     constexpr GLsizei kTextureSize = 16;
414     functions->texImage2D(GL_TEXTURE_2D, 0, texImageFormat.internalFormat, kTextureSize,
415                           kTextureSize, 0, texImageFormat.format, texImageFormat.type, nullptr);
416 
417     // Query the current framebuffer so it can be rebound afterwards
418     GLint oldFramebufferBinding = 0;
419     functions->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding);
420 
421     // Bind the texture to the framebuffer and check renderability
422     GLuint fbo = 0;
423     functions->genFramebuffers(1, &fbo);
424     functions->bindFramebuffer(GL_FRAMEBUFFER, fbo);
425     functions->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture,
426                                     0);
427 
428     bool supported = functions->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
429 
430     // Delete the framebuffer and restore the previous binding
431     functions->deleteFramebuffers(1, &fbo);
432     functions->bindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(oldFramebufferBinding));
433 
434     // Delete the texture and restore the previous binding
435     functions->deleteTextures(1, &texture);
436     functions->bindTexture(GL_TEXTURE_2D, static_cast<GLuint>(oldTextureBinding));
437 
438     if (!supported)
439     {
440         ANGLE_GL_CLEAR_ERRORS(functions);
441     }
442 
443     ASSERT(functions->getError() == GL_NO_ERROR);
444     return supported;
445 }
446 
CheckInternalFormatRenderbufferRenderability(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat)447 static bool CheckInternalFormatRenderbufferRenderability(const FunctionsGL *functions,
448                                                          const angle::FeaturesGL &features,
449                                                          GLenum internalFormat)
450 {
451     const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
452     ASSERT(formatInfo.sized);
453 
454     // Query the current renderbuffer so it can be rebound afterwards
455     GLint oldRenderbufferBinding = 0;
456     functions->getIntegerv(GL_RENDERBUFFER_BINDING, &oldRenderbufferBinding);
457 
458     // Create a small renderbuffer with the same format and type that gl::Renderbuffer would use
459     GLuint renderbuffer = 0;
460     functions->genRenderbuffers(1, &renderbuffer);
461     functions->bindRenderbuffer(GL_RENDERBUFFER, renderbuffer);
462 
463     nativegl::RenderbufferFormat renderbufferFormat =
464         nativegl::GetRenderbufferFormat(functions, features, formatInfo.internalFormat);
465     constexpr GLsizei kRenderbufferSize = 16;
466     functions->renderbufferStorage(GL_RENDERBUFFER, renderbufferFormat.internalFormat,
467                                    kRenderbufferSize, kRenderbufferSize);
468 
469     // Query the current framebuffer so it can be rebound afterwards
470     GLint oldFramebufferBinding = 0;
471     functions->getIntegerv(GL_FRAMEBUFFER_BINDING, &oldFramebufferBinding);
472 
473     // Bind the texture to the framebuffer and check renderability
474     GLuint fbo = 0;
475     functions->genFramebuffers(1, &fbo);
476     functions->bindFramebuffer(GL_FRAMEBUFFER, fbo);
477     functions->framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
478                                        renderbuffer);
479 
480     bool supported = functions->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
481 
482     // Delete the framebuffer and restore the previous binding
483     functions->deleteFramebuffers(1, &fbo);
484     functions->bindFramebuffer(GL_FRAMEBUFFER, static_cast<GLuint>(oldFramebufferBinding));
485 
486     // Delete the renderbuffer and restore the previous binding
487     functions->deleteRenderbuffers(1, &renderbuffer);
488     functions->bindRenderbuffer(GL_RENDERBUFFER, static_cast<GLuint>(oldRenderbufferBinding));
489 
490     if (!supported)
491     {
492         ANGLE_GL_CLEAR_ERRORS(functions);
493     }
494 
495     ASSERT(functions->getError() == GL_NO_ERROR);
496     return supported;
497 }
498 
LimitVersion(gl::Version * curVersion,const gl::Version & maxVersion)499 static void LimitVersion(gl::Version *curVersion, const gl::Version &maxVersion)
500 {
501     if (*curVersion >= maxVersion)
502     {
503         *curVersion = maxVersion;
504     }
505 }
506 
GenerateTextureFormatCaps(const FunctionsGL * functions,const angle::FeaturesGL & features,GLenum internalFormat,gl::Version * maxSupportedESVersion)507 static gl::TextureCaps GenerateTextureFormatCaps(const FunctionsGL *functions,
508                                                  const angle::FeaturesGL &features,
509                                                  GLenum internalFormat,
510                                                  gl::Version *maxSupportedESVersion)
511 {
512     ASSERT(functions->getError() == GL_NO_ERROR);
513 
514     gl::TextureCaps textureCaps;
515 
516     const nativegl::InternalFormat &formatInfo =
517         nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
518     textureCaps.texturable = MeetsRequirements(functions, formatInfo.texture);
519     textureCaps.filterable =
520         textureCaps.texturable && MeetsRequirements(functions, formatInfo.filter);
521     textureCaps.textureAttachment = MeetsRequirements(functions, formatInfo.textureAttachment);
522     textureCaps.renderbuffer      = MeetsRequirements(functions, formatInfo.renderbuffer);
523     textureCaps.blendable         = textureCaps.renderbuffer || textureCaps.textureAttachment;
524 
525     // Do extra renderability validation for some formats.
526     if (internalFormat == GL_R16F || internalFormat == GL_RG16F || internalFormat == GL_RGB16F)
527     {
528         // SupportRequirement can't currently express a condition of the form (version && extension)
529         // || other extensions, so do the (version && extension) part here.
530         if (functions->isAtLeastGLES(gl::Version(3, 0)) &&
531             functions->hasGLESExtension("GL_EXT_color_buffer_half_float"))
532         {
533             textureCaps.textureAttachment = true;
534             textureCaps.renderbuffer      = true;
535         }
536     }
537 
538     // We require GL_RGBA16F is renderable to expose EXT_color_buffer_half_float but we can't know
539     // if the format is supported unless we try to create a framebuffer.
540     // Renderability of signed normalized formats is optional on desktop GL.
541     if (internalFormat == GL_RGBA16F ||
542         (functions->standard == STANDARD_GL_DESKTOP &&
543          (internalFormat == GL_R8_SNORM || internalFormat == GL_R16_SNORM ||
544           internalFormat == GL_RG8_SNORM || internalFormat == GL_RG16_SNORM ||
545           internalFormat == GL_RGBA8_SNORM || internalFormat == GL_RGBA16_SNORM)))
546     {
547         if (textureCaps.textureAttachment)
548         {
549             textureCaps.textureAttachment =
550                 CheckSizedInternalFormatTextureRenderability(functions, features, internalFormat);
551         }
552         if (textureCaps.renderbuffer)
553         {
554             textureCaps.renderbuffer =
555                 CheckInternalFormatRenderbufferRenderability(functions, features, internalFormat);
556         }
557     }
558 
559     // glGetInternalformativ is not available until version 4.2 but may be available through the 3.0
560     // extension GL_ARB_internalformat_query
561     if (textureCaps.renderbuffer && functions->getInternalformativ)
562     {
563         GLenum queryInternalFormat = internalFormat;
564 
565         if (internalFormat == GL_BGRA8_EXT || internalFormat == GL_BGRA_EXT)
566         {
567             // Querying GL_NUM_SAMPLE_COUNTS for GL_BGRA8_EXT generates an INVALID_ENUM on some
568             // drivers.  It seems however that allocating a multisampled renderbuffer of this format
569             // succeeds. To avoid breaking multisampling for this format, query the supported sample
570             // counts for GL_RGBA8 instead.
571             queryInternalFormat = GL_RGBA8;
572         }
573 
574         ANGLE_GL_CLEAR_ERRORS(functions);
575         GLint numSamples = 0;
576         functions->getInternalformativ(GL_RENDERBUFFER, queryInternalFormat, GL_NUM_SAMPLE_COUNTS,
577                                        1, &numSamples);
578         GLenum error = functions->getError();
579         if (error != GL_NO_ERROR)
580         {
581             ERR() << "glGetInternalformativ generated error " << gl::FmtHex(error) << " for format "
582                   << gl::FmtHex(queryInternalFormat) << ". Skipping multisample checks.";
583             numSamples = 0;
584         }
585 
586         if (numSamples > 0)
587         {
588             std::vector<GLint> samples(numSamples);
589             functions->getInternalformativ(GL_RENDERBUFFER, queryInternalFormat, GL_SAMPLES,
590                                            static_cast<GLsizei>(samples.size()), &samples[0]);
591 
592             for (size_t sampleIndex = 0; sampleIndex < samples.size(); sampleIndex++)
593             {
594                 if (features.limitMaxMSAASamplesTo4.enabled && samples[sampleIndex] > 4)
595                 {
596                     continue;
597                 }
598 
599                 // Some NVIDIA drivers expose multisampling modes implemented as a combination of
600                 // multisampling and supersampling. These are non-conformant and should not be
601                 // exposed through ANGLE. Query which formats are conformant from the driver if
602                 // supported.
603                 GLint conformant = GL_TRUE;
604                 if (functions->getInternalformatSampleivNV)
605                 {
606                     ASSERT(functions->getError() == GL_NO_ERROR);
607                     functions->getInternalformatSampleivNV(GL_RENDERBUFFER, queryInternalFormat,
608                                                            samples[sampleIndex], GL_CONFORMANT_NV,
609                                                            1, &conformant);
610                     // getInternalFormatSampleivNV does not work for all formats on NVIDIA Shield TV
611                     // drivers. Assume that formats with large sample counts are non-conformant in
612                     // case the query generates an error.
613                     if (functions->getError() != GL_NO_ERROR)
614                     {
615                         conformant = (samples[sampleIndex] <= 8) ? GL_TRUE : GL_FALSE;
616                     }
617                 }
618                 if (conformant == GL_TRUE)
619                 {
620                     textureCaps.sampleCounts.insert(samples[sampleIndex]);
621                 }
622             }
623         }
624     }
625 
626     // GLES 3.0.5 section 4.4.2.2: "Implementations must support creation of renderbuffers in these
627     // required formats with up to the value of MAX_SAMPLES multisamples, with the exception of
628     // signed and unsigned integer formats."
629     const gl::InternalFormat &glFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
630     if (textureCaps.renderbuffer && !glFormatInfo.isInt() &&
631         glFormatInfo.isRequiredRenderbufferFormat(gl::Version(3, 0)) &&
632         textureCaps.getMaxSamples() < 4)
633     {
634         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
635     }
636 
637     ASSERT(functions->getError() == GL_NO_ERROR);
638     return textureCaps;
639 }
640 
QuerySingleGLInt(const FunctionsGL * functions,GLenum name)641 static GLint QuerySingleGLInt(const FunctionsGL *functions, GLenum name)
642 {
643     GLint result = 0;
644     functions->getIntegerv(name, &result);
645     return result;
646 }
647 
QuerySingleIndexGLInt(const FunctionsGL * functions,GLenum name,GLuint index)648 static GLint QuerySingleIndexGLInt(const FunctionsGL *functions, GLenum name, GLuint index)
649 {
650     GLint result;
651     functions->getIntegeri_v(name, index, &result);
652     return result;
653 }
654 
QueryGLIntRange(const FunctionsGL * functions,GLenum name,size_t index)655 static GLint QueryGLIntRange(const FunctionsGL *functions, GLenum name, size_t index)
656 {
657     GLint result[2] = {};
658     functions->getIntegerv(name, result);
659     return result[index];
660 }
661 
QuerySingleGLInt64(const FunctionsGL * functions,GLenum name)662 static GLint64 QuerySingleGLInt64(const FunctionsGL *functions, GLenum name)
663 {
664     // Fall back to 32-bit int if 64-bit query is not available. This can become relevant for some
665     // caps that are defined as 64-bit values in core spec, but were introduced earlier in
666     // extensions as 32-bit. Triggered in some cases by RenderDoc's emulated OpenGL driver.
667     if (!functions->getInteger64v)
668     {
669         GLint result = 0;
670         functions->getIntegerv(name, &result);
671         return static_cast<GLint64>(result);
672     }
673     else
674     {
675         GLint64 result = 0;
676         functions->getInteger64v(name, &result);
677         return result;
678     }
679 }
680 
QuerySingleGLFloat(const FunctionsGL * functions,GLenum name)681 static GLfloat QuerySingleGLFloat(const FunctionsGL *functions, GLenum name)
682 {
683     GLfloat result = 0.0f;
684     functions->getFloatv(name, &result);
685     return result;
686 }
687 
QueryGLFloatRange(const FunctionsGL * functions,GLenum name,size_t index)688 static GLfloat QueryGLFloatRange(const FunctionsGL *functions, GLenum name, size_t index)
689 {
690     GLfloat result[2] = {};
691     functions->getFloatv(name, result);
692     return result[index];
693 }
694 
QueryTypePrecision(const FunctionsGL * functions,GLenum shaderType,GLenum precisionType)695 static gl::TypePrecision QueryTypePrecision(const FunctionsGL *functions,
696                                             GLenum shaderType,
697                                             GLenum precisionType)
698 {
699     gl::TypePrecision precision;
700     functions->getShaderPrecisionFormat(shaderType, precisionType, precision.range.data(),
701                                         &precision.precision);
702     return precision;
703 }
704 
QueryQueryValue(const FunctionsGL * functions,GLenum target,GLenum name)705 static GLint QueryQueryValue(const FunctionsGL *functions, GLenum target, GLenum name)
706 {
707     GLint result;
708     functions->getQueryiv(target, name, &result);
709     return result;
710 }
711 
CapCombinedLimitToESShaders(GLint * combinedLimit,gl::ShaderMap<GLint> & perShaderLimit)712 void CapCombinedLimitToESShaders(GLint *combinedLimit, gl::ShaderMap<GLint> &perShaderLimit)
713 {
714     GLint combinedESLimit = 0;
715     for (gl::ShaderType shaderType : gl::kAllGraphicsShaderTypes)
716     {
717         combinedESLimit += perShaderLimit[shaderType];
718     }
719 
720     *combinedLimit = std::min(*combinedLimit, combinedESLimit);
721 }
722 
GenerateCaps(const FunctionsGL * functions,const angle::FeaturesGL & features,gl::Caps * caps,gl::TextureCapsMap * textureCapsMap,gl::Extensions * extensions,gl::Limitations * limitations,gl::Version * maxSupportedESVersion,MultiviewImplementationTypeGL * multiviewImplementationType,ShPixelLocalStorageOptions * plsOptions)723 void GenerateCaps(const FunctionsGL *functions,
724                   const angle::FeaturesGL &features,
725                   gl::Caps *caps,
726                   gl::TextureCapsMap *textureCapsMap,
727                   gl::Extensions *extensions,
728                   gl::Limitations *limitations,
729                   gl::Version *maxSupportedESVersion,
730                   MultiviewImplementationTypeGL *multiviewImplementationType,
731                   ShPixelLocalStorageOptions *plsOptions)
732 {
733     // Start by assuming ES3.1 support and work down
734     *maxSupportedESVersion = gl::Version(3, 1);
735 
736     // Texture format support checks
737     const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats();
738     for (GLenum internalFormat : allFormats)
739     {
740         gl::TextureCaps textureCaps =
741             GenerateTextureFormatCaps(functions, features, internalFormat, maxSupportedESVersion);
742         textureCapsMap->insert(internalFormat, textureCaps);
743     }
744 
745     // Table 6.28, implementation dependent values
746     if (functions->isAtLeastGL(gl::Version(4, 3)) ||
747         functions->hasGLExtension("GL_ARB_ES3_compatibility") ||
748         functions->isAtLeastGLES(gl::Version(3, 0)))
749     {
750         caps->maxElementIndex = QuerySingleGLInt64(functions, GL_MAX_ELEMENT_INDEX);
751 
752         // Work around the null driver limitations.
753         if (caps->maxElementIndex == 0)
754         {
755             caps->maxElementIndex = 0xFFFF;
756         }
757     }
758     else
759     {
760         // Doesn't affect ES3 support, can use a pre-defined limit
761         caps->maxElementIndex = static_cast<GLint64>(std::numeric_limits<unsigned int>::max());
762     }
763 
764     if (features.limitWebglMaxTextureSizeTo4096.enabled)
765     {
766         limitations->webGLTextureSizeLimit = 4096;
767     }
768     else if (features.limitWebglMaxTextureSizeTo8192.enabled)
769     {
770         limitations->webGLTextureSizeLimit = 8192;
771     }
772 
773     GLint max3dArrayTextureSizeLimit = std::numeric_limits<GLint>::max();
774     if (features.limitMax3dArrayTextureSizeTo1024.enabled)
775     {
776         max3dArrayTextureSizeLimit = 1024;
777     }
778 
779     if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)) ||
780         functions->hasGLESExtension("GL_OES_texture_3D"))
781     {
782         caps->max3DTextureSize = std::min(
783             {QuerySingleGLInt(functions, GL_MAX_3D_TEXTURE_SIZE), max3dArrayTextureSizeLimit});
784     }
785     else
786     {
787         // Can't support ES3 without 3D textures
788         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
789     }
790 
791     caps->max2DTextureSize = QuerySingleGLInt(functions, GL_MAX_TEXTURE_SIZE);  // GL 1.0 / ES 2.0
792     caps->maxCubeMapTextureSize =
793         QuerySingleGLInt(functions, GL_MAX_CUBE_MAP_TEXTURE_SIZE);  // GL 1.3 / ES 2.0
794 
795     if (functions->isAtLeastGL(gl::Version(3, 0)) ||
796         functions->hasGLExtension("GL_EXT_texture_array") ||
797         functions->isAtLeastGLES(gl::Version(3, 0)))
798     {
799         caps->maxArrayTextureLayers = std::min(
800             {QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS), max3dArrayTextureSizeLimit});
801     }
802     else
803     {
804         // Can't support ES3 without array textures
805         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
806     }
807 
808     if (functions->isAtLeastGL(gl::Version(1, 5)) ||
809         functions->hasGLExtension("GL_EXT_texture_lod_bias") ||
810         functions->isAtLeastGLES(gl::Version(3, 0)))
811     {
812         caps->maxLODBias = QuerySingleGLFloat(functions, GL_MAX_TEXTURE_LOD_BIAS);
813     }
814     else
815     {
816         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
817     }
818 
819     if (functions->isAtLeastGL(gl::Version(3, 0)) ||
820         functions->hasGLExtension("GL_EXT_framebuffer_object") ||
821         functions->isAtLeastGLES(gl::Version(3, 0)))
822     {
823         caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE);
824         caps->maxColorAttachments = QuerySingleGLInt(functions, GL_MAX_COLOR_ATTACHMENTS);
825     }
826     else if (functions->isAtLeastGLES(gl::Version(2, 0)))
827     {
828         caps->maxRenderbufferSize = QuerySingleGLInt(functions, GL_MAX_RENDERBUFFER_SIZE);
829         caps->maxColorAttachments = 1;
830     }
831     else
832     {
833         // Can't support ES2 without framebuffers and renderbuffers
834         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
835     }
836 
837     if (functions->isAtLeastGL(gl::Version(2, 0)) ||
838         functions->hasGLExtension("ARB_draw_buffers") ||
839         functions->isAtLeastGLES(gl::Version(3, 0)) ||
840         functions->hasGLESExtension("GL_EXT_draw_buffers"))
841     {
842         caps->maxDrawBuffers = QuerySingleGLInt(functions, GL_MAX_DRAW_BUFFERS);
843     }
844     else
845     {
846         // Framebuffer is required to have at least one drawbuffer even if the extension is not
847         // supported
848         caps->maxDrawBuffers = 1;
849         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
850     }
851 
852     caps->maxViewportWidth =
853         QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 0);  // GL 1.0 / ES 2.0
854     caps->maxViewportHeight =
855         QueryGLIntRange(functions, GL_MAX_VIEWPORT_DIMS, 1);  // GL 1.0 / ES 2.0
856 
857     if (functions->standard == STANDARD_GL_DESKTOP &&
858         (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
859     {
860         // Desktop GL core profile deprecated the GL_ALIASED_POINT_SIZE_RANGE query.  Use
861         // GL_POINT_SIZE_RANGE instead.
862         caps->minAliasedPointSize =
863             std::max(1.0f, QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 0));
864         caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_POINT_SIZE_RANGE, 1);
865     }
866     else
867     {
868         caps->minAliasedPointSize =
869             std::max(1.0f, QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 0));
870         caps->maxAliasedPointSize = QueryGLFloatRange(functions, GL_ALIASED_POINT_SIZE_RANGE, 1);
871     }
872 
873     caps->minAliasedLineWidth =
874         QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 0);  // GL 1.2 / ES 2.0
875     caps->maxAliasedLineWidth =
876         QueryGLFloatRange(functions, GL_ALIASED_LINE_WIDTH_RANGE, 1);  // GL 1.2 / ES 2.0
877 
878     // Table 6.29, implementation dependent values (cont.)
879     if (functions->isAtLeastGL(gl::Version(1, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
880     {
881         caps->maxElementsIndices  = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_INDICES);
882         caps->maxElementsVertices = QuerySingleGLInt(functions, GL_MAX_ELEMENTS_VERTICES);
883     }
884     else
885     {
886         // Doesn't impact supported version
887     }
888 
889     if (functions->isAtLeastGL(gl::Version(4, 1)) ||
890         functions->hasGLExtension("GL_ARB_get_program_binary") ||
891         functions->isAtLeastGLES(gl::Version(3, 0)) ||
892         functions->hasGLESExtension("GL_OES_get_program_binary"))
893     {
894         // Able to support the GL_PROGRAM_BINARY_ANGLE format as long as another program binary
895         // format is available.
896         GLint numBinaryFormats = QuerySingleGLInt(functions, GL_NUM_PROGRAM_BINARY_FORMATS_OES);
897         if (numBinaryFormats > 0)
898         {
899             caps->programBinaryFormats.push_back(GL_PROGRAM_BINARY_ANGLE);
900         }
901     }
902     else
903     {
904         // Doesn't impact supported version
905     }
906 
907     // glGetShaderPrecisionFormat is not available until desktop GL version 4.1 or
908     // GL_ARB_ES2_compatibility exists
909     if (functions->isAtLeastGL(gl::Version(4, 1)) ||
910         functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
911         functions->isAtLeastGLES(gl::Version(2, 0)))
912     {
913         caps->vertexHighpFloat   = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_FLOAT);
914         caps->vertexMediumpFloat = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_FLOAT);
915         caps->vertexLowpFloat    = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_FLOAT);
916         caps->fragmentHighpFloat = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_FLOAT);
917         caps->fragmentMediumpFloat =
918             QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_FLOAT);
919         caps->fragmentLowpFloat  = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_FLOAT);
920         caps->vertexHighpInt     = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_HIGH_INT);
921         caps->vertexMediumpInt   = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_MEDIUM_INT);
922         caps->vertexLowpInt      = QueryTypePrecision(functions, GL_VERTEX_SHADER, GL_LOW_INT);
923         caps->fragmentHighpInt   = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_HIGH_INT);
924         caps->fragmentMediumpInt = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_MEDIUM_INT);
925         caps->fragmentLowpInt    = QueryTypePrecision(functions, GL_FRAGMENT_SHADER, GL_LOW_INT);
926     }
927     else
928     {
929         // Doesn't impact supported version, set some default values
930         caps->vertexHighpFloat.setIEEEFloat();
931         caps->vertexMediumpFloat.setIEEEFloat();
932         caps->vertexLowpFloat.setIEEEFloat();
933         caps->fragmentHighpFloat.setIEEEFloat();
934         caps->fragmentMediumpFloat.setIEEEFloat();
935         caps->fragmentLowpFloat.setIEEEFloat();
936         caps->vertexHighpInt.setTwosComplementInt(32);
937         caps->vertexMediumpInt.setTwosComplementInt(32);
938         caps->vertexLowpInt.setTwosComplementInt(32);
939         caps->fragmentHighpInt.setTwosComplementInt(32);
940         caps->fragmentMediumpInt.setTwosComplementInt(32);
941         caps->fragmentLowpInt.setTwosComplementInt(32);
942     }
943 
944     if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") ||
945         functions->isAtLeastGLES(gl::Version(3, 0)))
946     {
947         // Work around Linux NVIDIA driver bug where GL_TIMEOUT_IGNORED is returned.
948         caps->maxServerWaitTimeout =
949             std::max<GLint64>(QuerySingleGLInt64(functions, GL_MAX_SERVER_WAIT_TIMEOUT), 0);
950     }
951     else
952     {
953         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
954     }
955 
956     // Table 6.31, implementation dependent vertex shader limits
957     if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->isAtLeastGLES(gl::Version(2, 0)))
958     {
959         caps->maxVertexAttributes = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIBS);
960         caps->maxShaderUniformComponents[gl::ShaderType::Vertex] =
961             QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_COMPONENTS);
962         caps->maxShaderTextureImageUnits[gl::ShaderType::Vertex] =
963             QuerySingleGLInt(functions, GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS);
964     }
965     else
966     {
967         // Can't support ES2 version without these caps
968         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
969     }
970 
971     if (functions->isAtLeastGL(gl::Version(4, 1)) ||
972         functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
973         functions->isAtLeastGLES(gl::Version(2, 0)))
974     {
975         caps->maxVertexUniformVectors = QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_VECTORS);
976         caps->maxFragmentUniformVectors =
977             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_VECTORS);
978     }
979     else
980     {
981         // Doesn't limit ES version, GL_MAX_VERTEX_UNIFORM_COMPONENTS / 4 is acceptable.
982         caps->maxVertexUniformVectors =
983             caps->maxShaderUniformComponents[gl::ShaderType::Vertex] / 4;
984         // Doesn't limit ES version, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS / 4 is acceptable.
985         caps->maxFragmentUniformVectors =
986             caps->maxShaderUniformComponents[gl::ShaderType::Fragment] / 4;
987     }
988 
989     if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
990     {
991         caps->maxVertexOutputComponents =
992             QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
993     }
994     else
995     {
996         // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a
997         // safe limit instead of limiting the supported ES version.
998         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
999     }
1000 
1001     // Table 6.32, implementation dependent fragment shader limits
1002     if (functions->isAtLeastGL(gl::Version(2, 0)) || functions->isAtLeastGLES(gl::Version(2, 0)))
1003     {
1004         caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
1005             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_COMPONENTS);
1006         caps->maxShaderTextureImageUnits[gl::ShaderType::Fragment] =
1007             QuerySingleGLInt(functions, GL_MAX_TEXTURE_IMAGE_UNITS);
1008     }
1009     else
1010     {
1011         // Can't support ES2 version without these caps
1012         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
1013     }
1014 
1015     if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 0)))
1016     {
1017         caps->maxFragmentInputComponents =
1018             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_INPUT_COMPONENTS);
1019     }
1020     else
1021     {
1022         // There doesn't seem, to be a desktop extension to add this cap, maybe it could be given a
1023         // safe limit instead of limiting the supported ES version.
1024         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1025     }
1026 
1027     if (functions->isAtLeastGL(gl::Version(3, 0)) || functions->isAtLeastGLES(gl::Version(3, 0)))
1028     {
1029         caps->minProgramTexelOffset = QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXEL_OFFSET);
1030         caps->maxProgramTexelOffset = QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXEL_OFFSET);
1031     }
1032     else
1033     {
1034         // Can't support ES3 without texel offset, could possibly be emulated in the shader
1035         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1036     }
1037 
1038     // Table 6.33, implementation dependent aggregate shader limits
1039     if (functions->isAtLeastGL(gl::Version(3, 1)) ||
1040         functions->hasGLExtension("GL_ARB_uniform_buffer_object") ||
1041         functions->isAtLeastGLES(gl::Version(3, 0)))
1042     {
1043         caps->maxShaderUniformBlocks[gl::ShaderType::Vertex] =
1044             QuerySingleGLInt(functions, GL_MAX_VERTEX_UNIFORM_BLOCKS);
1045         caps->maxShaderUniformBlocks[gl::ShaderType::Fragment] =
1046             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_UNIFORM_BLOCKS);
1047         caps->maxUniformBufferBindings =
1048             QuerySingleGLInt(functions, GL_MAX_UNIFORM_BUFFER_BINDINGS);
1049         caps->maxUniformBlockSize = QuerySingleGLInt64(functions, GL_MAX_UNIFORM_BLOCK_SIZE);
1050         caps->uniformBufferOffsetAlignment =
1051             QuerySingleGLInt(functions, GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
1052         caps->maxCombinedUniformBlocks =
1053             QuerySingleGLInt(functions, GL_MAX_COMBINED_UNIFORM_BLOCKS);
1054         caps->maxCombinedShaderUniformComponents[gl::ShaderType::Vertex] =
1055             QuerySingleGLInt64(functions, GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS);
1056         caps->maxCombinedShaderUniformComponents[gl::ShaderType::Fragment] =
1057             QuerySingleGLInt64(functions, GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS);
1058 
1059         // Clamp the maxUniformBlockSize to 64KB (majority of devices support up to this size
1060         // currently), some drivers expose an excessively large value.
1061         caps->maxUniformBlockSize = std::min<GLint64>(0x10000, caps->maxUniformBlockSize);
1062     }
1063     else
1064     {
1065         // Can't support ES3 without uniform blocks
1066         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1067     }
1068 
1069     if (functions->isAtLeastGL(gl::Version(3, 2)) &&
1070         (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) != 0)
1071     {
1072         caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VERTEX_OUTPUT_COMPONENTS);
1073     }
1074     else if (functions->isAtLeastGL(gl::Version(3, 0)) ||
1075              functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
1076              functions->isAtLeastGLES(gl::Version(2, 0)))
1077     {
1078         caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_COMPONENTS);
1079     }
1080     else if (functions->isAtLeastGL(gl::Version(2, 0)))
1081     {
1082         caps->maxVaryingComponents = QuerySingleGLInt(functions, GL_MAX_VARYING_FLOATS);
1083         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1084     }
1085     else
1086     {
1087         LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
1088     }
1089 
1090     if (functions->isAtLeastGL(gl::Version(4, 1)) ||
1091         functions->hasGLExtension("GL_ARB_ES2_compatibility") ||
1092         functions->isAtLeastGLES(gl::Version(2, 0)))
1093     {
1094         caps->maxVaryingVectors = QuerySingleGLInt(functions, GL_MAX_VARYING_VECTORS);
1095     }
1096     else
1097     {
1098         // Doesn't limit ES version, GL_MAX_VARYING_COMPONENTS / 4 is acceptable.
1099         caps->maxVaryingVectors = caps->maxVaryingComponents / 4;
1100     }
1101 
1102     // Determine the max combined texture image units by adding the vertex and fragment limits.  If
1103     // the real cap is queried, it would contain the limits for shader types that are not available
1104     // to ES.
1105     caps->maxCombinedTextureImageUnits =
1106         QuerySingleGLInt(functions, GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS);
1107 
1108     // Table 6.34, implementation dependent transform feedback limits
1109     if (functions->isAtLeastGL(gl::Version(4, 0)) ||
1110         functions->hasGLExtension("GL_ARB_transform_feedback2") ||
1111         functions->isAtLeastGLES(gl::Version(3, 0)))
1112     {
1113         caps->maxTransformFeedbackInterleavedComponents =
1114             QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS);
1115         caps->maxTransformFeedbackSeparateAttributes =
1116             QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS);
1117         caps->maxTransformFeedbackSeparateComponents =
1118             QuerySingleGLInt(functions, GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS);
1119     }
1120     else
1121     {
1122         // Can't support ES3 without transform feedback
1123         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1124     }
1125 
1126     GLint sampleCountLimit = std::numeric_limits<GLint>::max();
1127     if (features.limitMaxMSAASamplesTo4.enabled)
1128     {
1129         sampleCountLimit = 4;
1130     }
1131 
1132     // Table 6.35, Framebuffer Dependent Values
1133     if (functions->isAtLeastGL(gl::Version(3, 0)) ||
1134         functions->hasGLExtension("GL_EXT_framebuffer_multisample") ||
1135         functions->isAtLeastGLES(gl::Version(3, 0)) ||
1136         functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture"))
1137     {
1138         caps->maxSamples = std::min(QuerySingleGLInt(functions, GL_MAX_SAMPLES), sampleCountLimit);
1139     }
1140     else
1141     {
1142         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1143     }
1144 
1145     // Non-constant sampler array indexing is required for OpenGL ES 2 and OpenGL ES after 3.2.
1146     // However having it available on OpenGL ES 2 is a specification bug, and using this
1147     // indexing in WebGL is undefined. Requiring this feature would break WebGL 1 for some users
1148     // so we don't check for it. (it is present with ESSL 100, ESSL >= 320, GLSL >= 400 and
1149     // GL_ARB_gpu_shader5)
1150 
1151     // Check if sampler objects are supported
1152     if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
1153         !functions->hasGLExtension("GL_ARB_sampler_objects") &&
1154         !functions->isAtLeastGLES(gl::Version(3, 0)))
1155     {
1156         // Can't support ES3 without sampler objects
1157         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1158     }
1159 
1160     // Can't support ES3 without texture swizzling
1161     if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
1162         !functions->hasGLExtension("GL_ARB_texture_swizzle") &&
1163         !functions->hasGLExtension("GL_EXT_texture_swizzle") &&
1164         !functions->isAtLeastGLES(gl::Version(3, 0)))
1165     {
1166         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1167 
1168         // Texture swizzling is required to work around the luminance texture format not being
1169         // present in the core profile
1170         if (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT)
1171         {
1172             LimitVersion(maxSupportedESVersion, gl::Version(0, 0));
1173         }
1174     }
1175 
1176     // Can't support ES3 without the GLSL packing builtins. We have a workaround for all
1177     // desktop OpenGL versions starting from 3.3 with the bit packing extension.
1178     if (!functions->isAtLeastGL(gl::Version(4, 2)) &&
1179         !(functions->isAtLeastGL(gl::Version(3, 2)) &&
1180           functions->hasGLExtension("GL_ARB_shader_bit_encoding")) &&
1181         !functions->hasGLExtension("GL_ARB_shading_language_packing") &&
1182         !functions->isAtLeastGLES(gl::Version(3, 0)))
1183     {
1184         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1185     }
1186 
1187     // ES3 needs to support explicit layout location qualifiers, while it might be possible to
1188     // fake them in our side, we currently don't support that.
1189     if (!functions->isAtLeastGL(gl::Version(3, 3)) &&
1190         !functions->hasGLExtension("GL_ARB_explicit_attrib_location") &&
1191         !functions->isAtLeastGLES(gl::Version(3, 0)))
1192     {
1193         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1194     }
1195 
1196     if (!functions->isAtLeastGL(gl::Version(4, 3)) &&
1197         !functions->hasGLExtension("GL_ARB_stencil_texturing") &&
1198         !functions->isAtLeastGLES(gl::Version(3, 1)))
1199     {
1200         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1201     }
1202 
1203     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1204         functions->hasGLExtension("GL_ARB_framebuffer_no_attachments"))
1205     {
1206         caps->maxFramebufferWidth  = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_WIDTH);
1207         caps->maxFramebufferHeight = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_HEIGHT);
1208         caps->maxFramebufferSamples =
1209             std::min(QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_SAMPLES), sampleCountLimit);
1210     }
1211     else
1212     {
1213         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1214     }
1215 
1216     if (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1217         functions->hasGLExtension("GL_ARB_texture_multisample"))
1218     {
1219         caps->maxSampleMaskWords = QuerySingleGLInt(functions, GL_MAX_SAMPLE_MASK_WORDS);
1220         caps->maxColorTextureSamples =
1221             std::min(QuerySingleGLInt(functions, GL_MAX_COLOR_TEXTURE_SAMPLES), sampleCountLimit);
1222         caps->maxDepthTextureSamples =
1223             std::min(QuerySingleGLInt(functions, GL_MAX_DEPTH_TEXTURE_SAMPLES), sampleCountLimit);
1224         caps->maxIntegerSamples =
1225             std::min(QuerySingleGLInt(functions, GL_MAX_INTEGER_SAMPLES), sampleCountLimit);
1226     }
1227     else
1228     {
1229         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1230     }
1231 
1232     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1233         functions->hasGLExtension("GL_ARB_vertex_attrib_binding"))
1234     {
1235         caps->maxVertexAttribRelativeOffset =
1236             QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_RELATIVE_OFFSET);
1237         caps->maxVertexAttribBindings = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_BINDINGS);
1238 
1239         // OpenGL 4.3 has no limit on maximum value of stride.
1240         // [OpenGL 4.3 (Core Profile) - February 14, 2013] Chapter 10.3.1 Page 298
1241         if (features.emulateMaxVertexAttribStride.enabled ||
1242             (functions->standard == STANDARD_GL_DESKTOP && functions->version == gl::Version(4, 3)))
1243         {
1244             caps->maxVertexAttribStride = 2048;
1245         }
1246         else
1247         {
1248             caps->maxVertexAttribStride = QuerySingleGLInt(functions, GL_MAX_VERTEX_ATTRIB_STRIDE);
1249         }
1250     }
1251     else
1252     {
1253         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1254         // Set maxVertexAttribBindings anyway, a number of places assume this value is at least as
1255         // much as maxVertexAttributes.
1256         caps->maxVertexAttribBindings = caps->maxVertexAttributes;
1257     }
1258 
1259     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1260         functions->hasGLExtension("GL_ARB_shader_storage_buffer_object"))
1261     {
1262         caps->maxCombinedShaderOutputResources =
1263             QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_OUTPUT_RESOURCES);
1264         caps->maxShaderStorageBlocks[gl::ShaderType::Fragment] =
1265             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS);
1266         caps->maxShaderStorageBlocks[gl::ShaderType::Vertex] =
1267             QuerySingleGLInt(functions, GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS);
1268         caps->maxShaderStorageBufferBindings =
1269             QuerySingleGLInt(functions, GL_MAX_SHADER_STORAGE_BUFFER_BINDINGS);
1270         caps->maxShaderStorageBlockSize =
1271             QuerySingleGLInt64(functions, GL_MAX_SHADER_STORAGE_BLOCK_SIZE);
1272         caps->maxCombinedShaderStorageBlocks =
1273             QuerySingleGLInt(functions, GL_MAX_COMBINED_SHADER_STORAGE_BLOCKS);
1274         caps->shaderStorageBufferOffsetAlignment =
1275             QuerySingleGLInt(functions, GL_SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT);
1276     }
1277     else
1278     {
1279         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1280     }
1281 
1282     if (nativegl::SupportsCompute(functions))
1283     {
1284         for (GLuint index = 0u; index < 3u; ++index)
1285         {
1286             caps->maxComputeWorkGroupCount[index] =
1287                 QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_COUNT, index);
1288 
1289             caps->maxComputeWorkGroupSize[index] =
1290                 QuerySingleIndexGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_SIZE, index);
1291         }
1292         caps->maxComputeWorkGroupInvocations =
1293             QuerySingleGLInt(functions, GL_MAX_COMPUTE_WORK_GROUP_INVOCATIONS);
1294         caps->maxShaderUniformBlocks[gl::ShaderType::Compute] =
1295             QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_BLOCKS);
1296         caps->maxShaderTextureImageUnits[gl::ShaderType::Compute] =
1297             QuerySingleGLInt(functions, GL_MAX_COMPUTE_TEXTURE_IMAGE_UNITS);
1298         caps->maxComputeSharedMemorySize =
1299             QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHARED_MEMORY_SIZE);
1300         caps->maxShaderUniformComponents[gl::ShaderType::Compute] =
1301             QuerySingleGLInt(functions, GL_MAX_COMPUTE_UNIFORM_COMPONENTS);
1302         caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Compute] =
1303             QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTER_BUFFERS);
1304         caps->maxShaderAtomicCounters[gl::ShaderType::Compute] =
1305             QuerySingleGLInt(functions, GL_MAX_COMPUTE_ATOMIC_COUNTERS);
1306         caps->maxShaderImageUniforms[gl::ShaderType::Compute] =
1307             QuerySingleGLInt(functions, GL_MAX_COMPUTE_IMAGE_UNIFORMS);
1308         caps->maxCombinedShaderUniformComponents[gl::ShaderType::Compute] =
1309             QuerySingleGLInt(functions, GL_MAX_COMBINED_COMPUTE_UNIFORM_COMPONENTS);
1310         caps->maxShaderStorageBlocks[gl::ShaderType::Compute] =
1311             QuerySingleGLInt(functions, GL_MAX_COMPUTE_SHADER_STORAGE_BLOCKS);
1312     }
1313     else
1314     {
1315         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1316     }
1317 
1318     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1319         functions->hasGLExtension("GL_ARB_explicit_uniform_location"))
1320     {
1321         caps->maxUniformLocations = QuerySingleGLInt(functions, GL_MAX_UNIFORM_LOCATIONS);
1322     }
1323     else
1324     {
1325         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1326     }
1327 
1328     if (functions->isAtLeastGL(gl::Version(4, 0)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1329         functions->hasGLExtension("GL_ARB_texture_gather"))
1330     {
1331         caps->minProgramTextureGatherOffset =
1332             QuerySingleGLInt(functions, GL_MIN_PROGRAM_TEXTURE_GATHER_OFFSET);
1333         caps->maxProgramTextureGatherOffset =
1334             QuerySingleGLInt(functions, GL_MAX_PROGRAM_TEXTURE_GATHER_OFFSET);
1335     }
1336     else
1337     {
1338         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1339     }
1340 
1341     if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1342         functions->hasGLExtension("GL_ARB_shader_image_load_store"))
1343     {
1344         caps->maxShaderImageUniforms[gl::ShaderType::Vertex] =
1345             QuerySingleGLInt(functions, GL_MAX_VERTEX_IMAGE_UNIFORMS);
1346         caps->maxShaderImageUniforms[gl::ShaderType::Fragment] =
1347             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_IMAGE_UNIFORMS);
1348         caps->maxImageUnits = QuerySingleGLInt(functions, GL_MAX_IMAGE_UNITS);
1349         caps->maxCombinedImageUniforms =
1350             QuerySingleGLInt(functions, GL_MAX_COMBINED_IMAGE_UNIFORMS);
1351         if (features.forceMaxCombinedShaderOutputResources.enabled)
1352         {
1353             caps->maxCombinedShaderOutputResources = caps->maxCombinedImageUniforms +
1354                                                      caps->maxCombinedShaderStorageBlocks +
1355                                                      caps->maxColorAttachments;
1356         }
1357     }
1358     else
1359     {
1360         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1361     }
1362 
1363     if (functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 1)) ||
1364         functions->hasGLExtension("GL_ARB_shader_atomic_counters"))
1365     {
1366         caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Vertex] =
1367             QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTER_BUFFERS);
1368         caps->maxShaderAtomicCounters[gl::ShaderType::Vertex] =
1369             QuerySingleGLInt(functions, GL_MAX_VERTEX_ATOMIC_COUNTERS);
1370         caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Fragment] =
1371             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTER_BUFFERS);
1372         caps->maxShaderAtomicCounters[gl::ShaderType::Fragment] =
1373             QuerySingleGLInt(functions, GL_MAX_FRAGMENT_ATOMIC_COUNTERS);
1374         caps->maxAtomicCounterBufferBindings =
1375             QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_BINDINGS);
1376         caps->maxAtomicCounterBufferSize =
1377             QuerySingleGLInt(functions, GL_MAX_ATOMIC_COUNTER_BUFFER_SIZE);
1378         caps->maxCombinedAtomicCounterBuffers =
1379             QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTER_BUFFERS);
1380         caps->maxCombinedAtomicCounters =
1381             QuerySingleGLInt(functions, GL_MAX_COMBINED_ATOMIC_COUNTERS);
1382     }
1383     else
1384     {
1385         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1386     }
1387 
1388     // TODO(geofflang): The gl-uniform-arrays WebGL conformance test struggles to complete on time
1389     // if the max uniform vectors is too large.  Artificially limit the maximum until the test is
1390     // updated.
1391     caps->maxVertexUniformVectors = std::min(1024, caps->maxVertexUniformVectors);
1392     caps->maxShaderUniformComponents[gl::ShaderType::Vertex] =
1393         std::min(caps->maxVertexUniformVectors * 4,
1394                  caps->maxShaderUniformComponents[gl::ShaderType::Vertex]);
1395     caps->maxFragmentUniformVectors = std::min(1024, caps->maxFragmentUniformVectors);
1396     caps->maxShaderUniformComponents[gl::ShaderType::Fragment] =
1397         std::min(caps->maxFragmentUniformVectors * 4,
1398                  caps->maxShaderUniformComponents[gl::ShaderType::Fragment]);
1399 
1400     // If it is not possible to support reading buffer data back, a shadow copy of the buffers must
1401     // be held. This disallows writing to buffers indirectly through transform feedback, thus
1402     // disallowing ES3.
1403     if (!CanMapBufferForRead(functions))
1404     {
1405         LimitVersion(maxSupportedESVersion, gl::Version(2, 0));
1406     }
1407 
1408     // GL_OES_texture_cube_map_array
1409     if (functions->isAtLeastGL(gl::Version(4, 0)) ||
1410         functions->hasGLESExtension("GL_OES_texture_cube_map_array") ||
1411         functions->hasGLESExtension("GL_EXT_texture_cube_map_array") ||
1412         functions->hasGLExtension("GL_ARB_texture_cube_map_array") ||
1413         functions->isAtLeastGLES(gl::Version(3, 2)))
1414     {
1415         extensions->textureCubeMapArrayOES = true;
1416         extensions->textureCubeMapArrayEXT = true;
1417     }
1418     else
1419     {
1420         // Can't support ES3.2 without cube map array textures
1421         LimitVersion(maxSupportedESVersion, gl::Version(3, 1));
1422     }
1423 
1424     if (!nativegl::SupportsVertexArrayObjects(functions) ||
1425         features.syncAllVertexArraysToDefault.enabled)
1426     {
1427         // ES 3.1 vertex bindings are not emulated on the default vertex array
1428         LimitVersion(maxSupportedESVersion, gl::Version(3, 0));
1429     }
1430 
1431     // Extension support
1432     extensions->setTextureExtensionSupport(*textureCapsMap);
1433 
1434     // Expose this extension only when we support the formats or we're running on top of a native
1435     // ES driver.
1436     extensions->textureCompressionAstcLdrKHR =
1437         extensions->textureCompressionAstcLdrKHR &&
1438         (features.allowAstcFormats.enabled || functions->standard == STANDARD_GL_ES);
1439     extensions->textureCompressionAstcHdrKHR =
1440         extensions->textureCompressionAstcLdrKHR &&
1441         functions->hasExtension("GL_KHR_texture_compression_astc_hdr");
1442     extensions->textureCompressionAstcSliced3dKHR =
1443         (extensions->textureCompressionAstcLdrKHR &&
1444          functions->hasExtension("GL_KHR_texture_compression_astc_sliced_3d")) ||
1445         extensions->textureCompressionAstcHdrKHR;
1446     extensions->elementIndexUintOES = functions->standard == STANDARD_GL_DESKTOP ||
1447                                       functions->isAtLeastGLES(gl::Version(3, 0)) ||
1448                                       functions->hasGLESExtension("GL_OES_element_index_uint");
1449     extensions->getProgramBinaryOES = caps->programBinaryFormats.size() > 0;
1450     extensions->readFormatBgraEXT   = functions->isAtLeastGL(gl::Version(1, 2)) ||
1451                                     functions->hasGLExtension("GL_EXT_bgra") ||
1452                                     functions->hasGLESExtension("GL_EXT_read_format_bgra");
1453     extensions->pixelBufferObjectNV = functions->isAtLeastGL(gl::Version(2, 1)) ||
1454                                       functions->isAtLeastGLES(gl::Version(3, 0)) ||
1455                                       functions->hasGLExtension("GL_ARB_pixel_buffer_object") ||
1456                                       functions->hasGLExtension("GL_EXT_pixel_buffer_object") ||
1457                                       functions->hasGLESExtension("GL_NV_pixel_buffer_object");
1458     extensions->syncARB      = nativegl::SupportsFenceSync(functions);
1459     extensions->mapbufferOES = functions->isAtLeastGL(gl::Version(1, 5)) ||
1460                                functions->isAtLeastGLES(gl::Version(3, 0)) ||
1461                                functions->hasGLESExtension("GL_OES_mapbuffer");
1462     extensions->mapBufferRangeEXT = functions->isAtLeastGL(gl::Version(3, 0)) ||
1463                                     functions->hasGLExtension("GL_ARB_map_buffer_range") ||
1464                                     functions->isAtLeastGLES(gl::Version(3, 0)) ||
1465                                     functions->hasGLESExtension("GL_EXT_map_buffer_range");
1466     extensions->textureNpotOES = functions->standard == STANDARD_GL_DESKTOP ||
1467                                  functions->isAtLeastGLES(gl::Version(3, 0)) ||
1468                                  functions->hasGLESExtension("GL_OES_texture_npot");
1469     // Note that we could emulate EXT_draw_buffers on ES 3.0's core functionality.
1470     extensions->drawBuffersEXT = functions->isAtLeastGL(gl::Version(2, 0)) ||
1471                                  functions->hasGLExtension("ARB_draw_buffers") ||
1472                                  functions->hasGLESExtension("GL_EXT_draw_buffers");
1473     extensions->drawBuffersIndexedEXT =
1474         !features.disableDrawBuffersIndexed.enabled &&
1475         (functions->isAtLeastGL(gl::Version(4, 0)) ||
1476          (functions->hasGLExtension("GL_EXT_draw_buffers2") &&
1477           functions->hasGLExtension("GL_ARB_draw_buffers_blend")) ||
1478          functions->isAtLeastGLES(gl::Version(3, 2)) ||
1479          functions->hasGLESExtension("GL_OES_draw_buffers_indexed") ||
1480          functions->hasGLESExtension("GL_EXT_draw_buffers_indexed"));
1481     extensions->drawBuffersIndexedOES = extensions->drawBuffersIndexedEXT;
1482     extensions->textureStorageEXT     = functions->standard == STANDARD_GL_DESKTOP ||
1483                                     functions->hasGLESExtension("GL_EXT_texture_storage");
1484     extensions->textureFilterAnisotropicEXT =
1485         functions->hasGLExtension("GL_EXT_texture_filter_anisotropic") ||
1486         functions->hasGLESExtension("GL_EXT_texture_filter_anisotropic");
1487     extensions->occlusionQueryBooleanEXT = nativegl::SupportsOcclusionQueries(functions);
1488     caps->maxTextureAnisotropy =
1489         extensions->textureFilterAnisotropicEXT
1490             ? QuerySingleGLFloat(functions, GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT)
1491             : 0.0f;
1492     extensions->fenceNV = FenceNVGL::Supported(functions) || FenceNVSyncGL::Supported(functions);
1493     extensions->blendMinmaxEXT = functions->isAtLeastGL(gl::Version(1, 5)) ||
1494                                  functions->hasGLExtension("GL_EXT_blend_minmax") ||
1495                                  functions->isAtLeastGLES(gl::Version(3, 0)) ||
1496                                  functions->hasGLESExtension("GL_EXT_blend_minmax");
1497     extensions->framebufferBlitNV = functions->isAtLeastGL(gl::Version(3, 0)) ||
1498                                     functions->hasGLExtension("GL_EXT_framebuffer_blit") ||
1499                                     functions->isAtLeastGLES(gl::Version(3, 0)) ||
1500                                     functions->hasGLESExtension("GL_NV_framebuffer_blit");
1501     extensions->framebufferBlitANGLE =
1502         extensions->framebufferBlitNV || functions->hasGLESExtension("GL_ANGLE_framebuffer_blit");
1503     extensions->framebufferMultisampleANGLE =
1504         extensions->framebufferBlitANGLE && caps->maxSamples > 0;
1505     extensions->multisampledRenderToTextureEXT =
1506         !features.disableMultisampledRenderToTexture.enabled &&
1507         (functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture") ||
1508          functions->hasGLESExtension("GL_IMG_multisampled_render_to_texture"));
1509     extensions->multisampledRenderToTexture2EXT =
1510         !features.disableMultisampledRenderToTexture.enabled &&
1511         extensions->multisampledRenderToTextureEXT &&
1512         functions->hasGLESExtension("GL_EXT_multisampled_render_to_texture2");
1513     extensions->standardDerivativesOES = functions->isAtLeastGL(gl::Version(2, 0)) ||
1514                                          functions->hasGLExtension("GL_ARB_fragment_shader") ||
1515                                          functions->hasGLESExtension("GL_OES_standard_derivatives");
1516     extensions->shaderTextureLodEXT = functions->isAtLeastGL(gl::Version(3, 0)) ||
1517                                       functions->hasGLExtension("GL_ARB_shader_texture_lod") ||
1518                                       functions->hasGLESExtension("GL_EXT_shader_texture_lod");
1519     extensions->fragDepthEXT = functions->standard == STANDARD_GL_DESKTOP ||
1520                                functions->hasGLESExtension("GL_EXT_frag_depth");
1521     extensions->conservativeDepthEXT = functions->isAtLeastGL(gl::Version(4, 2)) ||
1522                                        functions->hasGLExtension("GL_ARB_conservative_depth") ||
1523                                        functions->hasGLESExtension("GL_EXT_conservative_depth");
1524     extensions->depthClampEXT = functions->isAtLeastGL(gl::Version(3, 2)) ||
1525                                 functions->hasGLExtension("GL_ARB_depth_clamp") ||
1526                                 functions->hasGLESExtension("GL_EXT_depth_clamp");
1527     extensions->polygonOffsetClampEXT = functions->hasExtension("GL_EXT_polygon_offset_clamp");
1528 
1529     if (functions->standard == STANDARD_GL_DESKTOP)
1530     {
1531         extensions->polygonModeNV = true;
1532     }
1533     else if (functions->hasGLESExtension("GL_NV_polygon_mode"))
1534     {
1535         // Some drivers expose the extension string without supporting its caps.
1536         ANGLE_GL_CLEAR_ERRORS(functions);
1537         functions->isEnabled(GL_POLYGON_OFFSET_LINE_NV);
1538         if (functions->getError() != GL_NO_ERROR)
1539         {
1540             WARN() << "Not enabling GL_NV_polygon_mode because "
1541                       "its native driver support is incomplete.";
1542         }
1543         else
1544         {
1545             extensions->polygonModeNV = true;
1546         }
1547     }
1548     extensions->polygonModeANGLE = extensions->polygonModeNV;
1549 
1550     // This functionality is provided by Shader Model 5 and should be available in GLSL 4.00
1551     // or even in older versions with GL_ARB_sample_shading and GL_ARB_gpu_shader5. However,
1552     // some OpenGL implementations (e.g., macOS) that do not support higher context versions
1553     // do not pass the tests so GLSL 4.20 is required here.
1554     extensions->sampleVariablesOES = functions->isAtLeastGL(gl::Version(4, 2)) ||
1555                                      functions->isAtLeastGLES(gl::Version(3, 2)) ||
1556                                      functions->hasGLESExtension("GL_OES_sample_variables");
1557     // Some drivers do not support sample qualifiers in ESSL 3.00, so ESSL 3.10 is required on ES.
1558     extensions->shaderMultisampleInterpolationOES =
1559         functions->isAtLeastGL(gl::Version(4, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1560         (functions->isAtLeastGLES(gl::Version(3, 1)) &&
1561          functions->hasGLESExtension("GL_OES_shader_multisample_interpolation"));
1562     if (extensions->shaderMultisampleInterpolationOES)
1563     {
1564         caps->minInterpolationOffset =
1565             QuerySingleGLFloat(functions, GL_MIN_FRAGMENT_INTERPOLATION_OFFSET_OES);
1566         caps->maxInterpolationOffset =
1567             QuerySingleGLFloat(functions, GL_MAX_FRAGMENT_INTERPOLATION_OFFSET_OES);
1568         caps->subPixelInterpolationOffsetBits =
1569             QuerySingleGLInt(functions, GL_FRAGMENT_INTERPOLATION_OFFSET_BITS_OES);
1570     }
1571 
1572     // Support video texture extension on non Android backends.
1573     // TODO(crbug.com/776222): support Android and Apple devices.
1574     extensions->videoTextureWEBGL = !IsAndroid() && !IsApple();
1575 
1576     if (functions->hasGLExtension("GL_ARB_shader_viewport_layer_array") ||
1577         functions->hasGLExtension("GL_NV_viewport_array2"))
1578     {
1579         extensions->multiviewOVR  = true;
1580         extensions->multiview2OVR = true;
1581         // GL_MAX_ARRAY_TEXTURE_LAYERS is guaranteed to be at least 256.
1582         const int maxLayers = QuerySingleGLInt(functions, GL_MAX_ARRAY_TEXTURE_LAYERS);
1583         // GL_MAX_VIEWPORTS is guaranteed to be at least 16.
1584         const int maxViewports       = QuerySingleGLInt(functions, GL_MAX_VIEWPORTS);
1585         caps->maxViews               = static_cast<GLuint>(std::min(maxLayers, maxViewports));
1586         *multiviewImplementationType = MultiviewImplementationTypeGL::NV_VIEWPORT_ARRAY2;
1587     }
1588 
1589     extensions->fboRenderMipmapOES = functions->isAtLeastGL(gl::Version(3, 0)) ||
1590                                      functions->hasGLExtension("GL_EXT_framebuffer_object") ||
1591                                      functions->isAtLeastGLES(gl::Version(3, 0)) ||
1592                                      functions->hasGLESExtension("GL_OES_fbo_render_mipmap");
1593 
1594     extensions->textureBorderClampEXT =
1595         !features.disableTextureClampToBorder.enabled &&
1596         (functions->standard == STANDARD_GL_DESKTOP ||
1597          functions->hasGLESExtension("GL_EXT_texture_border_clamp") ||
1598          functions->hasGLESExtension("GL_OES_texture_border_clamp") ||
1599          functions->hasGLESExtension("GL_NV_texture_border_clamp"));
1600     extensions->textureBorderClampOES = extensions->textureBorderClampEXT;
1601 
1602     // This functionality is supported on macOS but the extension
1603     // strings are not listed there for historical reasons.
1604     extensions->textureMirrorClampToEdgeEXT =
1605         !features.disableTextureMirrorClampToEdge.enabled &&
1606         (IsMac() || functions->isAtLeastGL(gl::Version(4, 4)) ||
1607          functions->hasGLExtension("GL_ARB_texture_mirror_clamp_to_edge") ||
1608          functions->hasGLExtension("GL_EXT_texture_mirror_clamp") ||
1609          functions->hasGLExtension("GL_ATI_texture_mirror_once") ||
1610          functions->hasGLESExtension("GL_EXT_texture_mirror_clamp_to_edge"));
1611 
1612     extensions->textureShadowLodEXT = functions->hasExtension("GL_EXT_texture_shadow_lod");
1613 
1614     extensions->multiDrawIndirectEXT = true;
1615     extensions->instancedArraysANGLE = functions->isAtLeastGL(gl::Version(3, 1)) ||
1616                                        (functions->hasGLExtension("GL_ARB_instanced_arrays") &&
1617                                         (functions->hasGLExtension("GL_ARB_draw_instanced") ||
1618                                          functions->hasGLExtension("GL_EXT_draw_instanced"))) ||
1619                                        functions->isAtLeastGLES(gl::Version(3, 0)) ||
1620                                        functions->hasGLESExtension("GL_EXT_instanced_arrays");
1621     extensions->instancedArraysEXT = extensions->instancedArraysANGLE;
1622     extensions->unpackSubimageEXT  = functions->standard == STANDARD_GL_DESKTOP ||
1623                                     functions->isAtLeastGLES(gl::Version(3, 0)) ||
1624                                     functions->hasGLESExtension("GL_EXT_unpack_subimage");
1625     // Some drivers do not support this extension in ESSL 3.00, so ESSL 3.10 is required on ES.
1626     extensions->shaderNoperspectiveInterpolationNV =
1627         functions->isAtLeastGL(gl::Version(3, 0)) ||
1628         (functions->isAtLeastGLES(gl::Version(3, 1)) &&
1629          functions->hasGLESExtension("GL_NV_shader_noperspective_interpolation"));
1630     extensions->packSubimageNV = functions->standard == STANDARD_GL_DESKTOP ||
1631                                  functions->isAtLeastGLES(gl::Version(3, 0)) ||
1632                                  functions->hasGLESExtension("GL_NV_pack_subimage");
1633     extensions->vertexArrayObjectOES = functions->isAtLeastGL(gl::Version(3, 0)) ||
1634                                        functions->hasGLExtension("GL_ARB_vertex_array_object") ||
1635                                        functions->isAtLeastGLES(gl::Version(3, 0)) ||
1636                                        functions->hasGLESExtension("GL_OES_vertex_array_object");
1637     extensions->debugMarkerEXT = functions->isAtLeastGL(gl::Version(4, 3)) ||
1638                                  functions->hasGLExtension("GL_KHR_debug") ||
1639                                  functions->hasGLExtension("GL_EXT_debug_marker") ||
1640                                  functions->isAtLeastGLES(gl::Version(3, 2)) ||
1641                                  functions->hasGLESExtension("GL_KHR_debug") ||
1642                                  functions->hasGLESExtension("GL_EXT_debug_marker");
1643     extensions->EGLImageOES         = functions->hasGLESExtension("GL_OES_EGL_image");
1644     extensions->EGLImageExternalOES = functions->hasGLESExtension("GL_OES_EGL_image_external");
1645     extensions->EGLImageExternalWrapModesEXT =
1646         functions->hasExtension("GL_EXT_EGL_image_external_wrap_modes");
1647     extensions->EGLImageExternalEssl3OES =
1648         functions->hasGLESExtension("GL_OES_EGL_image_external_essl3");
1649     extensions->EGLImageArrayEXT = functions->hasGLESExtension("GL_EXT_EGL_image_array");
1650 
1651     extensions->EGLSyncOES = functions->hasGLESExtension("GL_OES_EGL_sync");
1652 
1653     if (!features.disableTimestampQueries.enabled &&
1654         (functions->isAtLeastGL(gl::Version(3, 3)) ||
1655          functions->hasGLExtension("GL_ARB_timer_query") ||
1656          functions->hasGLESExtension("GL_EXT_disjoint_timer_query")))
1657     {
1658         extensions->disjointTimerQueryEXT = true;
1659 
1660         // If we can't query the counter bits, leave them at 0.
1661         if (!features.queryCounterBitsGeneratesErrors.enabled)
1662         {
1663             caps->queryCounterBitsTimeElapsed =
1664                 QueryQueryValue(functions, GL_TIME_ELAPSED, GL_QUERY_COUNTER_BITS);
1665             caps->queryCounterBitsTimestamp =
1666                 QueryQueryValue(functions, GL_TIMESTAMP, GL_QUERY_COUNTER_BITS);
1667         }
1668     }
1669 
1670     // the EXT_multisample_compatibility is written against ES3.1 but can apply
1671     // to earlier versions so therefore we're only checking for the extension string
1672     // and not the specific GLES version.
1673     extensions->multisampleCompatibilityEXT =
1674         functions->isAtLeastGL(gl::Version(1, 3)) ||
1675         functions->hasGLESExtension("GL_EXT_multisample_compatibility");
1676 
1677     extensions->framebufferMixedSamplesCHROMIUM =
1678         functions->hasGLExtension("GL_NV_framebuffer_mixed_samples") ||
1679         functions->hasGLESExtension("GL_NV_framebuffer_mixed_samples");
1680 
1681     extensions->robustnessEXT = functions->isAtLeastGL(gl::Version(4, 5)) ||
1682                                 functions->hasGLExtension("GL_KHR_robustness") ||
1683                                 functions->hasGLExtension("GL_ARB_robustness") ||
1684                                 functions->isAtLeastGLES(gl::Version(3, 2)) ||
1685                                 functions->hasGLESExtension("GL_KHR_robustness") ||
1686                                 functions->hasGLESExtension("GL_EXT_robustness");
1687     extensions->robustnessKHR = functions->isAtLeastGL(gl::Version(4, 5)) ||
1688                                 functions->hasGLExtension("GL_KHR_robustness") ||
1689                                 functions->isAtLeastGLES(gl::Version(3, 2)) ||
1690                                 functions->hasGLESExtension("GL_KHR_robustness");
1691 
1692     extensions->robustBufferAccessBehaviorKHR =
1693         extensions->robustnessEXT &&
1694         (functions->hasGLExtension("GL_ARB_robust_buffer_access_behavior") ||
1695          functions->hasGLESExtension("GL_KHR_robust_buffer_access_behavior"));
1696 
1697     extensions->stencilTexturingANGLE = functions->isAtLeastGL(gl::Version(4, 3)) ||
1698                                         functions->hasGLExtension("GL_ARB_stencil_texturing") ||
1699                                         functions->isAtLeastGLES(gl::Version(3, 1));
1700 
1701     if (features.supportsShaderFramebufferFetchEXT.enabled && extensions->drawBuffersIndexedAny())
1702     {
1703         // We can support PLS natively, probably in tiled memory.
1704         extensions->shaderPixelLocalStorageANGLE         = true;
1705         extensions->shaderPixelLocalStorageCoherentANGLE = true;
1706         plsOptions->type             = ShPixelLocalStorageType::FramebufferFetch;
1707         plsOptions->fragmentSyncType = ShFragmentSynchronizationType::Automatic;
1708     }
1709     else
1710     {
1711         bool hasFragmentShaderImageLoadStore = false;
1712         if (functions->isAtLeastGL(gl::Version(4, 2)) ||
1713             functions->hasGLExtension("GL_ARB_shader_image_load_store"))
1714         {
1715             // [ANGLE_shader_pixel_local_storage] "New Implementation Dependent State":
1716             // MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE must be at least 4.
1717             //
1718             // MAX_FRAGMENT_IMAGE_UNIFORMS is at least 8 on Desktop Core and ARB.
1719             hasFragmentShaderImageLoadStore = true;
1720         }
1721         else if (functions->isAtLeastGLES(gl::Version(3, 1)))
1722         {
1723             // [ANGLE_shader_pixel_local_storage] "New Implementation Dependent State":
1724             // MAX_PIXEL_LOCAL_STORAGE_PLANES_ANGLE must be at least 4.
1725             //
1726             // ES 3.1, Table 20.44: MAX_FRAGMENT_IMAGE_UNIFORMS can be 0.
1727             hasFragmentShaderImageLoadStore =
1728                 caps->maxShaderImageUniforms[gl::ShaderType::Fragment] >= 4;
1729         }
1730         if (hasFragmentShaderImageLoadStore &&
1731             (features.supportsFragmentShaderInterlockNV.enabled ||
1732              features.supportsFragmentShaderOrderingINTEL.enabled ||
1733              features.supportsFragmentShaderInterlockARB.enabled))
1734         {
1735             // If shader image load/store can be coherent, prefer it over
1736             // EXT_shader_framebuffer_fetch_non_coherent.
1737             extensions->shaderPixelLocalStorageANGLE         = true;
1738             extensions->shaderPixelLocalStorageCoherentANGLE = true;
1739             plsOptions->type = ShPixelLocalStorageType::ImageLoadStore;
1740             // Prefer vendor-specific extensions first. The PixelLocalStorageTest.Coherency test
1741             // doesn't always pass on Intel when we use the ARB extension.
1742             if (features.supportsFragmentShaderInterlockNV.enabled)
1743             {
1744                 plsOptions->fragmentSyncType =
1745                     ShFragmentSynchronizationType::FragmentShaderInterlock_NV_GL;
1746             }
1747             else if (features.supportsFragmentShaderOrderingINTEL.enabled)
1748             {
1749                 plsOptions->fragmentSyncType =
1750                     ShFragmentSynchronizationType::FragmentShaderOrdering_INTEL_GL;
1751             }
1752             else
1753             {
1754                 ASSERT(features.supportsFragmentShaderInterlockARB.enabled);
1755                 plsOptions->fragmentSyncType =
1756                     ShFragmentSynchronizationType::FragmentShaderInterlock_ARB_GL;
1757             }
1758             // OpenGL ES only allows read/write access to "r32*" images.
1759             plsOptions->supportsNativeRGBA8ImageFormats =
1760                 functions->standard != StandardGL::STANDARD_GL_ES;
1761         }
1762         else if (features.supportsShaderFramebufferFetchNonCoherentEXT.enabled)
1763         {
1764             extensions->shaderPixelLocalStorageANGLE = true;
1765             plsOptions->type                         = ShPixelLocalStorageType::FramebufferFetch;
1766         }
1767         else if (hasFragmentShaderImageLoadStore)
1768         {
1769             extensions->shaderPixelLocalStorageANGLE = true;
1770             plsOptions->type                         = ShPixelLocalStorageType::ImageLoadStore;
1771             // OpenGL ES only allows read/write access to "r32*" images.
1772             plsOptions->supportsNativeRGBA8ImageFormats =
1773                 functions->standard != StandardGL::STANDARD_GL_ES;
1774         }
1775     }
1776 
1777     // EXT_shader_framebuffer_fetch.
1778     if (features.supportsShaderFramebufferFetchEXT.enabled)
1779     {
1780         extensions->shaderFramebufferFetchEXT = true;
1781     }
1782 
1783     // TODO(http://anglebug.com/42266350): Support ARM_shader_framebuffer_fetch
1784 
1785     // EXT_shader_framebuffer_fetch_non_coherent.
1786     if (features.supportsShaderFramebufferFetchNonCoherentEXT.enabled)
1787     {
1788         extensions->shaderFramebufferFetchNonCoherentEXT = true;
1789     }
1790 
1791     extensions->copyTextureCHROMIUM = true;
1792     extensions->syncQueryCHROMIUM   = SyncQueryGL::IsSupported(functions);
1793 
1794     // Note that OES_texture_storage_multisample_2d_array support could be extended down to GL 3.2
1795     // if we emulated texStorage* API on top of texImage*.
1796     extensions->textureStorageMultisample2dArrayOES =
1797         functions->isAtLeastGL(gl::Version(4, 3)) ||
1798         functions->hasGLExtension("GL_ARB_texture_storage_multisample") ||
1799         functions->hasGLESExtension("GL_OES_texture_storage_multisample_2d_array");
1800 
1801     extensions->multiviewMultisampleANGLE = extensions->textureStorageMultisample2dArrayOES &&
1802                                             (extensions->multiviewOVR || extensions->multiview2OVR);
1803 
1804     extensions->textureMultisampleANGLE = functions->isAtLeastGL(gl::Version(3, 2)) ||
1805                                           functions->hasGLExtension("GL_ARB_texture_multisample") ||
1806                                           functions->isAtLeastGLES(gl::Version(3, 1));
1807 
1808     extensions->textureSRGBDecodeEXT = functions->hasGLExtension("GL_EXT_texture_sRGB_decode") ||
1809                                        functions->hasGLESExtension("GL_EXT_texture_sRGB_decode");
1810 
1811     // ANGLE treats ETC1 as ETC2 for ES 3.0 and higher because it becomes a core format, and they
1812     // are backwards compatible.
1813     extensions->compressedETC1RGB8SubTextureEXT =
1814         extensions->compressedETC2RGB8TextureOES || functions->isAtLeastGLES(gl::Version(3, 0)) ||
1815         functions->hasGLESExtension("GL_EXT_compressed_ETC1_RGB8_sub_texture");
1816 
1817 #if ANGLE_ENABLE_CGL
1818     VendorID vendor = GetVendorID(functions);
1819     if ((IsAMD(vendor) || IsIntel(vendor)) && *maxSupportedESVersion >= gl::Version(3, 0))
1820     {
1821         // Apple Intel/AMD drivers do not correctly use the TEXTURE_SRGB_DECODE property of
1822         // sampler states.  Disable this extension when we would advertise any ES version
1823         // that has samplers.
1824         extensions->textureSRGBDecodeEXT = false;
1825     }
1826 #endif
1827 
1828     extensions->sRGBWriteControlEXT = !features.srgbBlendingBroken.enabled &&
1829                                       (functions->isAtLeastGL(gl::Version(3, 0)) ||
1830                                        functions->hasGLExtension("GL_EXT_framebuffer_sRGB") ||
1831                                        functions->hasGLExtension("GL_ARB_framebuffer_sRGB") ||
1832                                        functions->hasGLESExtension("GL_EXT_sRGB_write_control"));
1833 
1834     if (features.bgraTexImageFormatsBroken.enabled)
1835     {
1836         extensions->textureFormatBGRA8888EXT = false;
1837     }
1838 
1839     // EXT_discard_framebuffer can be implemented as long as glDiscardFramebufferEXT or
1840     // glInvalidateFramebuffer is available
1841     extensions->discardFramebufferEXT = functions->isAtLeastGL(gl::Version(4, 3)) ||
1842                                         functions->hasGLExtension("GL_ARB_invalidate_subdata") ||
1843                                         functions->isAtLeastGLES(gl::Version(3, 0)) ||
1844                                         functions->hasGLESExtension("GL_EXT_discard_framebuffer") ||
1845                                         functions->hasGLESExtension("GL_ARB_invalidate_subdata");
1846 
1847     extensions->translatedShaderSourceANGLE = true;
1848 
1849     if (functions->isAtLeastGL(gl::Version(3, 1)) ||
1850         functions->hasGLExtension("GL_ARB_texture_rectangle"))
1851     {
1852         extensions->textureRectangleANGLE = true;
1853         caps->maxRectangleTextureSize =
1854             QuerySingleGLInt(functions, GL_MAX_RECTANGLE_TEXTURE_SIZE_ANGLE);
1855     }
1856 
1857     // OpenGL 4.3 (and above) and OpenGL ES 3.2 can support all features and constants defined in
1858     // GL_EXT_geometry_shader.
1859     bool hasCoreGSSupport =
1860         functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 2));
1861     // OpenGL 4.0 adds the support for instanced geometry shader
1862     // GL_ARB_shader_atomic_counters adds atomic counters to geometry shader
1863     // GL_ARB_shader_storage_buffer_object adds shader storage buffers to geometry shader
1864     // GL_ARB_shader_image_load_store adds images to geometry shader
1865     bool hasInstancedGSSupport = functions->isAtLeastGL(gl::Version(4, 0)) &&
1866                                  functions->hasGLExtension("GL_ARB_shader_atomic_counters") &&
1867                                  functions->hasGLExtension("GL_ARB_shader_storage_buffer_object") &&
1868                                  functions->hasGLExtension("GL_ARB_shader_image_load_store");
1869     if (hasCoreGSSupport || functions->hasGLESExtension("GL_OES_geometry_shader") ||
1870         functions->hasGLESExtension("GL_EXT_geometry_shader") || hasInstancedGSSupport)
1871     {
1872         extensions->geometryShaderEXT = functions->hasGLESExtension("GL_EXT_geometry_shader") ||
1873                                         hasCoreGSSupport || hasInstancedGSSupport;
1874         extensions->geometryShaderOES = functions->hasGLESExtension("GL_OES_geometry_shader") ||
1875                                         hasCoreGSSupport || hasInstancedGSSupport;
1876 
1877         caps->maxFramebufferLayers = QuerySingleGLInt(functions, GL_MAX_FRAMEBUFFER_LAYERS_EXT);
1878 
1879         // GL_PROVOKING_VERTEX isn't a valid return value of GL_LAYER_PROVOKING_VERTEX_EXT in
1880         // GL_EXT_geometry_shader SPEC, however it is legal in desktop OpenGL, which means the value
1881         // follows the one set by glProvokingVertex.
1882         // [OpenGL 4.3] Chapter 11.3.4.6
1883         // The vertex conventions followed for gl_Layer and gl_ViewportIndex may be determined by
1884         // calling GetIntegerv with the symbolic constants LAYER_PROVOKING_VERTEX and
1885         // VIEWPORT_INDEX_PROVOKING_VERTEX, respectively. For either query, if the value returned is
1886         // PROVOKING_VERTEX, then vertex selection follows the convention specified by
1887         // ProvokingVertex.
1888         caps->layerProvokingVertex = QuerySingleGLInt(functions, GL_LAYER_PROVOKING_VERTEX_EXT);
1889         if (caps->layerProvokingVertex == GL_PROVOKING_VERTEX)
1890         {
1891             // We should use GL_LAST_VERTEX_CONVENTION_EXT instead because desktop OpenGL SPEC
1892             // requires the initial value of provoking vertex mode is LAST_VERTEX_CONVENTION.
1893             // [OpenGL 4.3] Chapter 13.4
1894             // The initial value of the provoking vertex mode is LAST_VERTEX_CONVENTION.
1895             caps->layerProvokingVertex = GL_LAST_VERTEX_CONVENTION_EXT;
1896         }
1897 
1898         caps->maxShaderUniformComponents[gl::ShaderType::Geometry] =
1899             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT);
1900         caps->maxShaderUniformBlocks[gl::ShaderType::Geometry] =
1901             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT);
1902         caps->maxCombinedShaderUniformComponents[gl::ShaderType::Geometry] =
1903             QuerySingleGLInt(functions, GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS_EXT);
1904         caps->maxGeometryInputComponents =
1905             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT);
1906         caps->maxGeometryOutputComponents =
1907             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT);
1908         caps->maxGeometryOutputVertices =
1909             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT);
1910         caps->maxGeometryTotalOutputComponents =
1911             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT);
1912         caps->maxGeometryShaderInvocations =
1913             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT);
1914         caps->maxShaderTextureImageUnits[gl::ShaderType::Geometry] =
1915             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT);
1916         caps->maxShaderAtomicCounterBuffers[gl::ShaderType::Geometry] =
1917             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT);
1918         caps->maxShaderAtomicCounters[gl::ShaderType::Geometry] =
1919             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT);
1920         caps->maxShaderImageUniforms[gl::ShaderType::Geometry] =
1921             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT);
1922         caps->maxShaderStorageBlocks[gl::ShaderType::Geometry] =
1923             QuerySingleGLInt(functions, GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT);
1924     }
1925 
1926     // The real combined caps contain limits for shader types that are not available to ES, so limit
1927     // the caps to the sum of vertex+fragment+geometry shader caps.
1928     CapCombinedLimitToESShaders(&caps->maxCombinedUniformBlocks, caps->maxShaderUniformBlocks);
1929     CapCombinedLimitToESShaders(&caps->maxCombinedTextureImageUnits,
1930                                 caps->maxShaderTextureImageUnits);
1931     CapCombinedLimitToESShaders(&caps->maxCombinedShaderStorageBlocks,
1932                                 caps->maxShaderStorageBlocks);
1933     CapCombinedLimitToESShaders(&caps->maxCombinedImageUniforms, caps->maxShaderImageUniforms);
1934     CapCombinedLimitToESShaders(&caps->maxCombinedAtomicCounterBuffers,
1935                                 caps->maxShaderAtomicCounterBuffers);
1936     CapCombinedLimitToESShaders(&caps->maxCombinedAtomicCounters, caps->maxShaderAtomicCounters);
1937 
1938     // EXT_blend_func_extended is not implemented on top of ARB_blend_func_extended
1939     // because the latter does not support fragment shader output layout qualifiers.
1940     extensions->blendFuncExtendedEXT = !features.disableBlendFuncExtended.enabled &&
1941                                        (functions->isAtLeastGL(gl::Version(3, 3)) ||
1942                                         functions->hasGLESExtension("GL_EXT_blend_func_extended"));
1943     if (extensions->blendFuncExtendedEXT)
1944     {
1945         // TODO(http://anglebug.com/40644593): Support greater values of
1946         // MAX_DUAL_SOURCE_DRAW_BUFFERS_EXT queried from the driver. See comments in ProgramGL.cpp
1947         // for more information about this limitation.
1948         caps->maxDualSourceDrawBuffers = 1;
1949     }
1950 
1951     // EXT_float_blend
1952     // Assume all desktop driver supports this by default.
1953     extensions->floatBlendEXT = functions->standard == STANDARD_GL_DESKTOP ||
1954                                 functions->hasGLESExtension("GL_EXT_float_blend") ||
1955                                 functions->isAtLeastGLES(gl::Version(3, 2));
1956 
1957     // ANGLE_base_vertex_base_instance
1958     extensions->baseVertexBaseInstanceANGLE =
1959         !features.disableBaseInstanceVertex.enabled &&
1960         (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1961          functions->hasGLESExtension("GL_OES_draw_elements_base_vertex") ||
1962          functions->hasGLESExtension("GL_EXT_draw_elements_base_vertex"));
1963 
1964     // EXT_base_instance
1965     extensions->baseInstanceEXT =
1966         !features.disableBaseInstanceVertex.enabled &&
1967         (functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1968          functions->hasGLESExtension("GL_OES_draw_elements_base_vertex") ||
1969          functions->hasGLESExtension("GL_EXT_draw_elements_base_vertex") ||
1970          functions->hasGLESExtension("GL_EXT_base_instance"));
1971 
1972     // ANGLE_base_vertex_base_instance_shader_builtin
1973     extensions->baseVertexBaseInstanceShaderBuiltinANGLE = extensions->baseVertexBaseInstanceANGLE;
1974 
1975     // OES_draw_elements_base_vertex
1976     extensions->drawElementsBaseVertexOES =
1977         functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1978         functions->hasGLESExtension("GL_OES_draw_elements_base_vertex");
1979 
1980     // EXT_draw_elements_base_vertex
1981     extensions->drawElementsBaseVertexEXT =
1982         functions->isAtLeastGL(gl::Version(3, 2)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
1983         functions->hasGLESExtension("GL_EXT_draw_elements_base_vertex");
1984 
1985     // ANGLE_compressed_texture_etc
1986     // Expose this extension only when we support the formats or we're running on top of a native
1987     // ES driver.
1988     extensions->compressedTextureEtcANGLE =
1989         (features.allowETCFormats.enabled || functions->standard == STANDARD_GL_ES) &&
1990         gl::DetermineCompressedTextureETCSupport(*textureCapsMap);
1991 
1992     // When running on top of desktop OpenGL drivers and allow_etc_formats feature is not enabled,
1993     // mark ETC1 as emulated to hide it from WebGL clients.
1994     limitations->emulatedEtc1 =
1995         !features.allowETCFormats.enabled && functions->standard == STANDARD_GL_DESKTOP;
1996 
1997     // To work around broken unsized sRGB textures, sized sRGB textures are used. Disable EXT_sRGB
1998     // if those formats are not available.
1999     if (features.unsizedSRGBReadPixelsDoesntTransform.enabled &&
2000         !functions->isAtLeastGLES(gl::Version(3, 0)))
2001     {
2002         extensions->sRGBEXT = false;
2003     }
2004 
2005     extensions->provokingVertexANGLE = functions->hasGLExtension("GL_ARB_provoking_vertex") ||
2006                                        functions->hasGLExtension("GL_EXT_provoking_vertex") ||
2007                                        functions->isAtLeastGL(gl::Version(3, 2));
2008 
2009     extensions->textureExternalUpdateANGLE = true;
2010     extensions->texture3DOES               = functions->isAtLeastGL(gl::Version(1, 2)) ||
2011                                functions->isAtLeastGLES(gl::Version(3, 0)) ||
2012                                functions->hasGLESExtension("GL_OES_texture_3D");
2013 
2014     extensions->memoryObjectEXT = functions->hasGLExtension("GL_EXT_memory_object") ||
2015                                   functions->hasGLESExtension("GL_EXT_memory_object");
2016     extensions->semaphoreEXT = functions->hasGLExtension("GL_EXT_semaphore") ||
2017                                functions->hasGLESExtension("GL_EXT_semaphore");
2018     extensions->memoryObjectFdEXT = functions->hasGLExtension("GL_EXT_memory_object_fd") ||
2019                                     functions->hasGLESExtension("GL_EXT_memory_object_fd");
2020     extensions->semaphoreFdEXT = !features.disableSemaphoreFd.enabled &&
2021                                  (functions->hasGLExtension("GL_EXT_semaphore_fd") ||
2022                                   functions->hasGLESExtension("GL_EXT_semaphore_fd"));
2023     extensions->gpuShader5EXT = functions->isAtLeastGL(gl::Version(4, 0)) ||
2024                                 functions->isAtLeastGLES(gl::Version(3, 2)) ||
2025                                 functions->hasGLExtension("GL_ARB_gpu_shader5") ||
2026                                 functions->hasGLESExtension("GL_EXT_gpu_shader5") ||
2027                                 functions->hasGLESExtension("GL_OES_gpu_shader5");
2028     extensions->gpuShader5OES     = extensions->gpuShader5EXT;
2029     extensions->shaderIoBlocksOES = functions->isAtLeastGL(gl::Version(3, 2)) ||
2030                                     functions->isAtLeastGLES(gl::Version(3, 2)) ||
2031                                     functions->hasGLESExtension("GL_OES_shader_io_blocks") ||
2032                                     functions->hasGLESExtension("GL_EXT_shader_io_blocks");
2033     extensions->shaderIoBlocksEXT = extensions->shaderIoBlocksOES;
2034 
2035     extensions->shadowSamplersEXT = functions->isAtLeastGL(gl::Version(2, 0)) ||
2036                                     functions->isAtLeastGLES(gl::Version(3, 0)) ||
2037                                     functions->hasGLESExtension("GL_EXT_shadow_samplers");
2038 
2039     if (!features.disableClipControl.enabled)
2040     {
2041         extensions->clipControlEXT = functions->isAtLeastGL(gl::Version(4, 5)) ||
2042                                      functions->hasGLExtension("GL_ARB_clip_control") ||
2043                                      functions->hasGLESExtension("GL_EXT_clip_control");
2044     }
2045 
2046     if (features.disableRenderSnorm.enabled)
2047     {
2048         extensions->renderSnormEXT = false;
2049     }
2050 
2051     constexpr uint32_t kRequiredClipDistances                = 8;
2052     constexpr uint32_t kRequiredCullDistances                = 8;
2053     constexpr uint32_t kRequiredCombinedClipAndCullDistances = 8;
2054 
2055     // GL_APPLE_clip_distance cannot be implemented on top of GL_EXT_clip_cull_distance,
2056     // so require either native support or desktop GL.
2057     extensions->clipDistanceAPPLE = functions->isAtLeastGL(gl::Version(3, 0)) ||
2058                                     functions->hasGLESExtension("GL_APPLE_clip_distance");
2059     if (extensions->clipDistanceAPPLE)
2060     {
2061         caps->maxClipDistances = QuerySingleGLInt(functions, GL_MAX_CLIP_DISTANCES_APPLE);
2062 
2063         if (caps->maxClipDistances < kRequiredClipDistances)
2064         {
2065             WARN() << "Disabling GL_APPLE_clip_distance because only " << caps->maxClipDistances
2066                    << " clip distances are supported by the driver.";
2067             extensions->clipDistanceAPPLE = false;
2068         }
2069     }
2070 
2071     // GL_EXT_clip_cull_distance spec requires shader interface blocks to support
2072     // built-in array redeclarations on OpenGL ES.
2073     extensions->clipCullDistanceEXT =
2074         functions->isAtLeastGL(gl::Version(4, 5)) ||
2075         (functions->isAtLeastGL(gl::Version(3, 0)) &&
2076          functions->hasGLExtension("GL_ARB_cull_distance")) ||
2077         (extensions->shaderIoBlocksEXT && functions->hasGLESExtension("GL_EXT_clip_cull_distance"));
2078     if (extensions->clipCullDistanceEXT)
2079     {
2080         caps->maxClipDistances = QuerySingleGLInt(functions, GL_MAX_CLIP_DISTANCES_EXT);
2081         caps->maxCullDistances = QuerySingleGLInt(functions, GL_MAX_CULL_DISTANCES_EXT);
2082         caps->maxCombinedClipAndCullDistances =
2083             QuerySingleGLInt(functions, GL_MAX_COMBINED_CLIP_AND_CULL_DISTANCES_EXT);
2084 
2085         if (caps->maxClipDistances < kRequiredClipDistances ||
2086             caps->maxCullDistances < kRequiredCullDistances ||
2087             caps->maxCombinedClipAndCullDistances < kRequiredCombinedClipAndCullDistances)
2088         {
2089             WARN() << "Disabling GL_EXT_clip_cull_distance because only " << caps->maxClipDistances
2090                    << " clip distances, " << caps->maxCullDistances << " cull distances and "
2091                    << caps->maxCombinedClipAndCullDistances
2092                    << " combined clip/cull distances are supported by the driver.";
2093             extensions->clipCullDistanceEXT = false;
2094         }
2095     }
2096 
2097     // Same as GL_EXT_clip_cull_distance but with cull distance support being optional.
2098     extensions->clipCullDistanceANGLE =
2099         (functions->isAtLeastGL(gl::Version(3, 0)) || extensions->clipCullDistanceEXT) &&
2100         caps->maxClipDistances >= kRequiredClipDistances;
2101     ASSERT(!extensions->clipCullDistanceANGLE || caps->maxClipDistances > 0);
2102 
2103     // GL_OES_shader_image_atomic
2104     //
2105     // Note that imageAtomicExchange() is allowed to accept float textures (of r32f format) in this
2106     // extension, but that's not supported by ARB_shader_image_load_store which this extension is
2107     // based on, neither in the spec it was merged into it.  This support was only added to desktop
2108     // GLSL in version 4.5
2109     if (functions->isAtLeastGL(gl::Version(4, 5)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
2110         functions->hasGLESExtension("GL_OES_shader_image_atomic"))
2111     {
2112         extensions->shaderImageAtomicOES = true;
2113     }
2114 
2115     // GL_OES_texture_buffer
2116     if (functions->isAtLeastGL(gl::Version(4, 3)) || functions->isAtLeastGLES(gl::Version(3, 2)) ||
2117         functions->hasGLESExtension("GL_OES_texture_buffer") ||
2118         functions->hasGLESExtension("GL_EXT_texture_buffer") ||
2119         functions->hasGLExtension("GL_ARB_texture_buffer_object"))
2120     {
2121         caps->maxTextureBufferSize = QuerySingleGLInt(functions, GL_MAX_TEXTURE_BUFFER_SIZE);
2122         caps->textureBufferOffsetAlignment =
2123             QuerySingleGLInt(functions, GL_TEXTURE_BUFFER_OFFSET_ALIGNMENT);
2124         extensions->textureBufferOES = true;
2125         extensions->textureBufferEXT = true;
2126     }
2127     else
2128     {
2129         // Can't support ES3.2 without texture buffer objects
2130         LimitVersion(maxSupportedESVersion, gl::Version(3, 1));
2131     }
2132 
2133     extensions->YUVTargetEXT = functions->hasGLESExtension("GL_EXT_YUV_target");
2134 
2135     // GL_MESA_framebuffer_flip_y
2136     extensions->framebufferFlipYMESA = functions->hasGLESExtension("GL_MESA_framebuffer_flip_y") ||
2137                                        functions->hasGLExtension("GL_MESA_framebuffer_flip_y");
2138 
2139     // GL_KHR_parallel_shader_compile
2140     extensions->parallelShaderCompileKHR = !features.disableNativeParallelCompile.enabled &&
2141                                            (functions->maxShaderCompilerThreadsKHR != nullptr ||
2142                                             functions->maxShaderCompilerThreadsARB != nullptr);
2143 
2144     // GL_ANGLE_logic_op
2145     extensions->logicOpANGLE = functions->isAtLeastGL(gl::Version(2, 0));
2146 
2147     // GL_EXT_clear_texture
2148     extensions->clearTextureEXT = functions->isAtLeastGL(gl::Version(4, 4)) ||
2149                                   functions->hasGLESExtension("GL_EXT_clear_texture") ||
2150                                   functions->hasGLExtension("GL_ARB_clear_texture");
2151 
2152     // GL_QCOM_tiled_rendering
2153     extensions->tiledRenderingQCOM = !features.disableTiledRendering.enabled &&
2154                                      functions->hasGLESExtension("GL_QCOM_tiled_rendering");
2155 
2156     extensions->blendEquationAdvancedKHR =
2157         !features.disableBlendEquationAdvanced.enabled &&
2158         (functions->hasGLExtension("GL_NV_blend_equation_advanced") ||
2159          functions->hasGLExtension("GL_KHR_blend_equation_advanced") ||
2160          functions->isAtLeastGLES(gl::Version(3, 2)) ||
2161          functions->hasGLESExtension("GL_KHR_blend_equation_advanced"));
2162     extensions->blendEquationAdvancedCoherentKHR =
2163         !features.disableBlendEquationAdvanced.enabled &&
2164         (functions->hasGLExtension("GL_NV_blend_equation_advanced_coherent") ||
2165          functions->hasGLExtension("GL_KHR_blend_equation_advanced_coherent") ||
2166          functions->isAtLeastGLES(gl::Version(3, 2)) ||
2167          functions->hasGLESExtension("GL_KHR_blend_equation_advanced_coherent"));
2168 
2169     // PVRTC1 textures must be squares on Apple platforms.
2170     if (IsApple())
2171     {
2172         limitations->squarePvrtc1 = true;
2173     }
2174 
2175     // Check if the driver clamps constant blend color
2176     if (IsQualcomm(GetVendorID(functions)))
2177     {
2178         // Backup current state
2179         float oldColor[4];
2180         functions->getFloatv(GL_BLEND_COLOR, oldColor);
2181 
2182         // Probe clamping
2183         float color[4];
2184         functions->blendColor(2.0, 0.0, 0.0, 0.0);
2185         functions->getFloatv(GL_BLEND_COLOR, color);
2186         limitations->noUnclampedBlendColor = color[0] == 1.0;
2187 
2188         // Restore previous state
2189         functions->blendColor(oldColor[0], oldColor[1], oldColor[2], oldColor[3]);
2190     }
2191 }
2192 
GetSystemInfoVendorIDAndDeviceID(const FunctionsGL * functions,angle::SystemInfo * outSystemInfo,angle::VendorID * outVendor,angle::DeviceID * outDevice)2193 bool GetSystemInfoVendorIDAndDeviceID(const FunctionsGL *functions,
2194                                       angle::SystemInfo *outSystemInfo,
2195                                       angle::VendorID *outVendor,
2196                                       angle::DeviceID *outDevice)
2197 {
2198     // Get vendor from GL itself, so on multi-GPU systems the correct GPU is selected.
2199     *outVendor = GetVendorID(functions);
2200     *outDevice = 0;
2201 
2202     // Gather additional information from the system to detect multi-GPU scenarios. Do not collect
2203     // system info on Android as it may use Vulkan which can crash on older devices. All the system
2204     // info we need is available in the version and renderer strings on Android.
2205     bool isGetSystemInfoSuccess = !IsAndroid() && angle::GetSystemInfo(outSystemInfo);
2206 
2207     // Get the device id from system info, corresponding to the vendor of the active GPU.
2208     if (isGetSystemInfoSuccess && !outSystemInfo->gpus.empty())
2209     {
2210         if (*outVendor == VENDOR_ID_UNKNOWN)
2211         {
2212             // If vendor ID is unknown, take the best estimate of the active GPU.  Chances are there
2213             // is only one GPU anyway.
2214             *outVendor = outSystemInfo->gpus[outSystemInfo->activeGPUIndex].vendorId;
2215             *outDevice = outSystemInfo->gpus[outSystemInfo->activeGPUIndex].deviceId;
2216         }
2217         else
2218         {
2219             for (const angle::GPUDeviceInfo &gpu : outSystemInfo->gpus)
2220             {
2221                 if (*outVendor == gpu.vendorId)
2222                 {
2223                     // Note that deviceId may not necessarily have been possible to retrieve.
2224                     *outDevice = gpu.deviceId;
2225                     break;
2226                 }
2227             }
2228         }
2229     }
2230     else
2231     {
2232         // If system info is not available, attempt to deduce the device from GL itself.
2233         *outDevice = GetDeviceID(functions);
2234     }
2235 
2236     return isGetSystemInfoSuccess;
2237 }
2238 
Has9thGenIntelGPU(const angle::SystemInfo & systemInfo)2239 bool Has9thGenIntelGPU(const angle::SystemInfo &systemInfo)
2240 {
2241     for (const angle::GPUDeviceInfo &deviceInfo : systemInfo.gpus)
2242     {
2243         if (IsIntel(deviceInfo.vendorId) && Is9thGenIntel(deviceInfo.deviceId))
2244         {
2245             return true;
2246         }
2247     }
2248 
2249     return false;
2250 }
2251 
InitializeFeatures(const FunctionsGL * functions,angle::FeaturesGL * features)2252 void InitializeFeatures(const FunctionsGL *functions, angle::FeaturesGL *features)
2253 {
2254     angle::VendorID vendor;
2255     angle::DeviceID device;
2256     angle::SystemInfo systemInfo;
2257 
2258     bool isGetSystemInfoSuccess =
2259         GetSystemInfoVendorIDAndDeviceID(functions, &systemInfo, &vendor, &device);
2260 
2261     bool isAMD      = IsAMD(vendor);
2262     bool isApple    = IsAppleGPU(vendor);
2263     bool isIntel    = IsIntel(vendor);
2264     bool isNvidia   = IsNvidia(vendor);
2265     bool isQualcomm = IsQualcomm(vendor);
2266     bool isVMWare   = IsVMWare(vendor);
2267     bool hasAMD     = systemInfo.hasAMDGPU();
2268     bool isMali     = IsARM(vendor);
2269 
2270     std::array<int, 3> mesaVersion = {0, 0, 0};
2271     bool isMesa                    = IsMesa(functions, &mesaVersion);
2272 
2273     int qualcommVersion = -1;
2274     if (!isMesa && isQualcomm)
2275     {
2276         qualcommVersion = GetQualcommVersion(functions);
2277     }
2278 
2279     // Don't use 1-bit alpha formats on desktop GL with AMD drivers.
2280     ANGLE_FEATURE_CONDITION(features, avoid1BitAlphaTextureFormats,
2281                             functions->standard == STANDARD_GL_DESKTOP && isAMD);
2282 
2283     ANGLE_FEATURE_CONDITION(features, RGBA4IsNotSupportedForColorRendering,
2284                             functions->standard == STANDARD_GL_DESKTOP && isIntel);
2285 
2286     // Although "Sandy Bridge", "Ivy Bridge", and "Haswell" may support GL_ARB_ES3_compatibility
2287     // extension, ETC2/EAC formats are emulated there. Newer Intel GPUs support them natively.
2288     ANGLE_FEATURE_CONDITION(
2289         features, allowETCFormats,
2290         isIntel && !IsSandyBridge(device) && !IsIvyBridge(device) && !IsHaswell(device));
2291 
2292     // Mesa always exposes ASTC extension but only Intel Gen9, Gen11, and Gen12 have hardware
2293     // support for it. Newer Intel GPUs (Gen12.5+) do not support ASTC.
2294     ANGLE_FEATURE_CONDITION(features, allowAstcFormats,
2295                             !isMesa || isIntel && (Is9thGenIntel(device) || IsGeminiLake(device) ||
2296                                                    IsCoffeeLake(device) || Is11thGenIntel(device) ||
2297                                                    Is12thGenIntel(device)));
2298 
2299     // Ported from gpu_driver_bug_list.json (#183)
2300     ANGLE_FEATURE_CONDITION(features, emulateAbsIntFunction, IsApple() && isIntel);
2301 
2302     ANGLE_FEATURE_CONDITION(features, addAndTrueToLoopCondition, IsApple() && isIntel);
2303 
2304     // Ported from gpu_driver_bug_list.json (#191)
2305     ANGLE_FEATURE_CONDITION(
2306         features, emulateIsnanFloat,
2307         isIntel && IsApple() && IsSkylake(device) && GetMacOSVersion() < OSVersion(10, 13, 2));
2308 
2309     // https://anglebug.com/42266803
2310     ANGLE_FEATURE_CONDITION(features, clearsWithGapsNeedFlush,
2311                             !isMesa && isQualcomm && qualcommVersion < 490);
2312 
2313     ANGLE_FEATURE_CONDITION(features, doesSRGBClearsOnLinearFramebufferAttachments,
2314                             isIntel || isAMD);
2315 
2316     ANGLE_FEATURE_CONDITION(features, emulateMaxVertexAttribStride,
2317                             IsLinux() && functions->standard == STANDARD_GL_DESKTOP && isAMD);
2318     ANGLE_FEATURE_CONDITION(
2319         features, useUnusedBlocksWithStandardOrSharedLayout,
2320         (IsApple() && functions->standard == STANDARD_GL_DESKTOP) || (IsLinux() && isAMD));
2321 
2322     // Ported from gpu_driver_bug_list.json (#187)
2323     ANGLE_FEATURE_CONDITION(features, doWhileGLSLCausesGPUHang,
2324                             IsApple() && functions->standard == STANDARD_GL_DESKTOP &&
2325                                 GetMacOSVersion() < OSVersion(10, 11, 0));
2326 
2327     // Ported from gpu_driver_bug_list.json (#211)
2328     ANGLE_FEATURE_CONDITION(features, rewriteFloatUnaryMinusOperator,
2329                             IsApple() && isIntel && GetMacOSVersion() < OSVersion(10, 12, 0));
2330 
2331     ANGLE_FEATURE_CONDITION(features, vertexIDDoesNotIncludeBaseVertex, IsApple() && isAMD);
2332 
2333     // Triggers a bug on Marshmallow Adreno (4xx?) driver.
2334     // http://anglebug.com/40096454
2335     ANGLE_FEATURE_CONDITION(features, dontInitializeUninitializedLocals, !isMesa && isQualcomm);
2336 
2337     ANGLE_FEATURE_CONDITION(features, finishDoesNotCauseQueriesToBeAvailable,
2338                             functions->standard == STANDARD_GL_DESKTOP && isNvidia);
2339 
2340     // TODO(cwallez): Disable this workaround for MacOSX versions 10.9 or later.
2341     ANGLE_FEATURE_CONDITION(features, alwaysCallUseProgramAfterLink, true);
2342 
2343     ANGLE_FEATURE_CONDITION(features, unpackOverlappingRowsSeparatelyUnpackBuffer, isNvidia);
2344     ANGLE_FEATURE_CONDITION(features, packOverlappingRowsSeparatelyPackBuffer, isNvidia);
2345 
2346     ANGLE_FEATURE_CONDITION(features, initializeCurrentVertexAttributes, isNvidia);
2347 
2348     ANGLE_FEATURE_CONDITION(features, unpackLastRowSeparatelyForPaddingInclusion,
2349                             IsApple() || isNvidia);
2350     ANGLE_FEATURE_CONDITION(features, packLastRowSeparatelyForPaddingInclusion,
2351                             IsApple() || isNvidia);
2352 
2353     ANGLE_FEATURE_CONDITION(features, removeInvariantAndCentroidForESSL3,
2354                             functions->isAtMostGL(gl::Version(4, 1)) ||
2355                                 (functions->standard == STANDARD_GL_DESKTOP && isAMD));
2356 
2357     // TODO(oetuaho): Make this specific to the affected driver versions. Versions that came after
2358     // 364 are known to be affected, at least up to 375.
2359     ANGLE_FEATURE_CONDITION(features, emulateAtan2Float, isNvidia);
2360 
2361     ANGLE_FEATURE_CONDITION(features, reapplyUBOBindingsAfterUsingBinaryProgram,
2362                             isAMD || IsAndroid());
2363 
2364     // TODO(oetuaho): Make this specific to the affected driver versions. Versions at least up to
2365     // 390 are known to be affected. Versions after that are expected not to be affected.
2366     ANGLE_FEATURE_CONDITION(features, clampFragDepth, isNvidia);
2367 
2368     // TODO(oetuaho): Make this specific to the affected driver versions. Versions since 397.31 are
2369     // not affected.
2370     ANGLE_FEATURE_CONDITION(features, rewriteRepeatedAssignToSwizzled, isNvidia);
2371 
2372     // TODO(jmadill): Narrow workaround range for specific devices.
2373 
2374     ANGLE_FEATURE_CONDITION(features, clampPointSize, IsAndroid() || isNvidia);
2375 
2376     // Ported from gpu_driver_bug_list.json (#246, #258)
2377     ANGLE_FEATURE_CONDITION(features, dontUseLoopsToInitializeVariables,
2378                             (!isMesa && isQualcomm) || (isIntel && IsApple()));
2379 
2380     // Intel macOS condition ported from gpu_driver_bug_list.json (#327)
2381     ANGLE_FEATURE_CONDITION(features, disableBlendFuncExtended,
2382                             IsApple() && isIntel && GetMacOSVersion() < OSVersion(10, 14, 0));
2383 
2384     ANGLE_FEATURE_CONDITION(features, avoidBindFragDataLocation, !isMesa && isQualcomm);
2385 
2386     ANGLE_FEATURE_CONDITION(features, unsizedSRGBReadPixelsDoesntTransform, !isMesa && isQualcomm);
2387 
2388     ANGLE_FEATURE_CONDITION(features, queryCounterBitsGeneratesErrors, IsNexus5X(vendor, device));
2389 
2390     bool isAndroidLessThan14 = IsAndroid() && GetAndroidSDKVersion() < 34;
2391     bool isAndroidAtLeast14  = IsAndroid() && GetAndroidSDKVersion() >= 34;
2392     bool isIntelLinuxLessThanKernelVersion5 =
2393         isIntel && IsLinux() && GetLinuxOSVersion() < OSVersion(5, 0, 0);
2394     ANGLE_FEATURE_CONDITION(features, limitWebglMaxTextureSizeTo4096,
2395                             isAndroidLessThan14 || isIntelLinuxLessThanKernelVersion5);
2396     ANGLE_FEATURE_CONDITION(features, limitWebglMaxTextureSizeTo8192, isAndroidAtLeast14);
2397     // On Apple switchable graphics, GL_MAX_SAMPLES may differ between the GPUs.
2398     // 4 is a lowest common denominator that is always supported.
2399     ANGLE_FEATURE_CONDITION(features, limitMaxMSAASamplesTo4,
2400                             IsAndroid() || (IsApple() && (isIntel || isAMD || isNvidia)));
2401     ANGLE_FEATURE_CONDITION(features, limitMax3dArrayTextureSizeTo1024,
2402                             isIntelLinuxLessThanKernelVersion5);
2403 
2404     ANGLE_FEATURE_CONDITION(features, allowClearForRobustResourceInit, IsApple());
2405 
2406     // NVidia and PowerVR Rogue report MAX_COMBINED_SHADER_OUTPUT_RESOURCES incorrectly.
2407     // Force it to the sum of all sublimits.
2408     ANGLE_FEATURE_CONDITION(features, forceMaxCombinedShaderOutputResources,
2409                             isNvidia || IsPowerVrRogue(functions));
2410 
2411     // The WebGL conformance/uniforms/out-of-bounds-uniform-array-access test has been seen to fail
2412     // on AMD and Android devices.
2413     // This test is also flaky on Linux Nvidia. So we just turn it on everywhere and don't rely on
2414     // driver since security is important.
2415     ANGLE_FEATURE_CONDITION(
2416         features, clampArrayAccess,
2417         IsAndroid() || isAMD || !functions->hasExtension("GL_KHR_robust_buffer_access_behavior"));
2418 
2419     ANGLE_FEATURE_CONDITION(features, resetTexImage2DBaseLevel,
2420                             IsApple() && isIntel && GetMacOSVersion() >= OSVersion(10, 12, 4));
2421 
2422     ANGLE_FEATURE_CONDITION(features, clearToZeroOrOneBroken,
2423                             IsApple() && isIntel && GetMacOSVersion() < OSVersion(10, 12, 6));
2424 
2425     ANGLE_FEATURE_CONDITION(features, adjustSrcDstRegionForBlitFramebuffer,
2426                             IsLinux() || (IsAndroid() && isNvidia) || (IsWindows() && isNvidia) ||
2427                                 (IsApple() && functions->standard == STANDARD_GL_ES));
2428 
2429     ANGLE_FEATURE_CONDITION(features, clipSrcRegionForBlitFramebuffer,
2430                             IsApple() || (IsLinux() && isAMD));
2431 
2432     ANGLE_FEATURE_CONDITION(features, RGBDXT1TexturesSampleZeroAlpha, IsApple());
2433 
2434     ANGLE_FEATURE_CONDITION(features, unfoldShortCircuits, IsApple());
2435 
2436     ANGLE_FEATURE_CONDITION(features, emulatePrimitiveRestartFixedIndex,
2437                             functions->standard == STANDARD_GL_DESKTOP &&
2438                                 functions->isAtLeastGL(gl::Version(3, 1)) &&
2439                                 !functions->isAtLeastGL(gl::Version(4, 3)));
2440     ANGLE_FEATURE_CONDITION(
2441         features, setPrimitiveRestartFixedIndexForDrawArrays,
2442         features->emulatePrimitiveRestartFixedIndex.enabled && IsApple() && isIntel);
2443 
2444     ANGLE_FEATURE_CONDITION(features, removeDynamicIndexingOfSwizzledVector,
2445                             IsApple() || IsAndroid() || IsWindows());
2446 
2447     // Ported from gpu_driver_bug_list.json (#89)
2448     ANGLE_FEATURE_CONDITION(features, regenerateStructNames, IsApple());
2449 
2450     // Ported from gpu_driver_bug_list.json (#184)
2451     ANGLE_FEATURE_CONDITION(features, preAddTexelFetchOffsets, IsApple() && isIntel);
2452 
2453     // Workaround for the widespread OpenGL ES driver implementaion bug
2454     ANGLE_FEATURE_CONDITION(features, readPixelsUsingImplementationColorReadFormatForNorm16,
2455                             !isIntel && functions->standard == STANDARD_GL_ES &&
2456                                 functions->isAtLeastGLES(gl::Version(3, 1)) &&
2457                                 functions->hasGLESExtension("GL_EXT_texture_norm16"));
2458 
2459     // anglebug.com/40644715
2460     ANGLE_FEATURE_CONDITION(features, flushBeforeDeleteTextureIfCopiedTo, IsApple() && isIntel);
2461 
2462     // anglebug.com/40096480
2463     // Seems to affect both Intel and AMD GPUs. Enable workaround for all GPUs on macOS.
2464     ANGLE_FEATURE_CONDITION(features, rewriteRowMajorMatrices,
2465                             // IsApple() && functions->standard == STANDARD_GL_DESKTOP);
2466                             // TODO(anglebug.com/40096480): diagnose crashes with this workaround.
2467                             false);
2468 
2469     ANGLE_FEATURE_CONDITION(features, disableDrawBuffersIndexed, IsWindows() && isAMD);
2470 
2471     ANGLE_FEATURE_CONDITION(
2472         features, disableSemaphoreFd,
2473         IsLinux() && isAMD && isMesa && mesaVersion < (std::array<int, 3>{19, 3, 5}));
2474 
2475     ANGLE_FEATURE_CONDITION(
2476         features, disableTimestampQueries,
2477         (IsLinux() && isVMWare) || (IsAndroid() && isNvidia) ||
2478             (IsAndroid() && GetAndroidSDKVersion() < 27 && IsAdreno5xxOrOlder(functions)) ||
2479             (!isMesa && IsMaliT8xxOrOlder(functions)) || (!isMesa && IsMaliG31OrOlder(functions)));
2480 
2481     ANGLE_FEATURE_CONDITION(features, decodeEncodeSRGBForGenerateMipmap, IsApple());
2482 
2483     // anglebug.com/42263273
2484     // The (redundant) explicit exclusion of Windows AMD is because the workaround fails
2485     // Texture2DRGTest.TextureRGUNormTest on that platform, and the test is skipped. If
2486     // you'd like to enable the workaround on Windows AMD, please fix the test first.
2487     ANGLE_FEATURE_CONDITION(
2488         features, emulateCopyTexImage2DFromRenderbuffers,
2489         IsApple() && functions->standard == STANDARD_GL_ES && !(isAMD && IsWindows()));
2490 
2491     // anglebug.com/40096747
2492     // Replace copyTexImage2D with texImage2D + copyTexSubImage2D to bypass driver bug.
2493     ANGLE_FEATURE_CONDITION(features, emulateCopyTexImage2D, isApple);
2494 
2495     // Don't attempt to use the discrete GPU on NVIDIA-based MacBook Pros, since the
2496     // driver is unstable in this situation.
2497     //
2498     // Note that this feature is only set here in order to advertise this workaround
2499     // externally. GPU switching support must be enabled or disabled early, during display
2500     // initialization, before these features are set up.
2501     bool isDualGPUMacWithNVIDIA = false;
2502     if (IsApple() && functions->standard == STANDARD_GL_DESKTOP)
2503     {
2504         if (isGetSystemInfoSuccess)
2505         {
2506             // The full system information must be queried to see whether it's a dual-GPU
2507             // NVIDIA MacBook Pro since it's likely that the integrated GPU will be active
2508             // when these features are initialized.
2509             isDualGPUMacWithNVIDIA = systemInfo.isMacSwitchable && systemInfo.hasNVIDIAGPU();
2510         }
2511     }
2512     ANGLE_FEATURE_CONDITION(features, disableGPUSwitchingSupport, isDualGPUMacWithNVIDIA);
2513 
2514     // Workaround issue in NVIDIA GL driver on Linux when TSAN is enabled
2515     // http://crbug.com/1094869
2516     bool isTSANBuild = false;
2517 #ifdef THREAD_SANITIZER
2518     isTSANBuild = true;
2519 #endif
2520     ANGLE_FEATURE_CONDITION(features, disableNativeParallelCompile,
2521                             isTSANBuild && IsLinux() && isNvidia);
2522 
2523     // anglebug.com/40096712
2524     ANGLE_FEATURE_CONDITION(features, emulatePackSkipRowsAndPackSkipPixels, IsApple());
2525 
2526     // http://crbug.com/1042393
2527     // XWayland defaults to a 1hz refresh rate when the "surface is not visible", which sometimes
2528     // causes issues in Chrome. To get around this, default to a 30Hz refresh rate if we see bogus
2529     // from the driver.
2530     ANGLE_FEATURE_CONDITION(features, clampMscRate, IsLinux() && IsWayland());
2531 
2532     ANGLE_FEATURE_CONDITION(features, bindTransformFeedbackBufferBeforeBindBufferRange, IsApple());
2533 
2534     // http://crbug.com/1137851
2535     // Speculative fix for above issue, users can enable it via flags.
2536     // http://crbug.com/1187475
2537     // Disable on Mesa 20 / Intel
2538     ANGLE_FEATURE_CONDITION(features, disableSyncControlSupport,
2539                             IsLinux() && isIntel && isMesa && mesaVersion[0] == 20);
2540 
2541     ANGLE_FEATURE_CONDITION(features, keepBufferShadowCopy, !CanMapBufferForRead(functions));
2542 
2543     ANGLE_FEATURE_CONDITION(features, setZeroLevelBeforeGenerateMipmap, IsApple());
2544 
2545     ANGLE_FEATURE_CONDITION(features, promotePackedFormatsTo8BitPerChannel, IsApple() && hasAMD);
2546 
2547     // crbug.com/1171371
2548     // If output variable gl_FragColor is written by fragment shader, it may cause context lost with
2549     // Adreno 42x and 3xx.
2550     ANGLE_FEATURE_CONDITION(features, initFragmentOutputVariables, IsAdreno42xOr3xx(functions));
2551 
2552     // http://crbug.com/1144207
2553     // The Mac bot with Intel Iris GPU seems unaffected by this bug. Exclude the Haswell family for
2554     // now.
2555     ANGLE_FEATURE_CONDITION(features, shiftInstancedArrayDataWithOffset,
2556                             IsApple() && IsIntel(vendor) && !IsHaswell(device));
2557     ANGLE_FEATURE_CONDITION(features, syncAllVertexArraysToDefault,
2558                             !nativegl::SupportsVertexArrayObjects(functions));
2559 
2560     // NVIDIA OpenGL ES emulated profile cannot handle client arrays
2561     ANGLE_FEATURE_CONDITION(features, syncDefaultVertexArraysToDefault,
2562                             nativegl::CanUseDefaultVertexArrayObject(functions) && !isNvidia);
2563 
2564     // http://crbug.com/1181193
2565     // On desktop Linux/AMD when using the amdgpu drivers, the precise kernel and DRM version are
2566     // leaked via GL_RENDERER. We workaround this too improve user security.
2567     ANGLE_FEATURE_CONDITION(features, sanitizeAMDGPURendererString, IsLinux() && hasAMD);
2568 
2569     // http://crbug.com/1187513
2570     // Imagination drivers are buggy with context switching. It needs to unbind fbo before context
2571     // switching to workadround the driver issues.
2572     ANGLE_FEATURE_CONDITION(features, unbindFBOBeforeSwitchingContext, IsPowerVR(vendor));
2573 
2574     // http://crbug.com/1181068 and http://crbug.com/783979
2575     ANGLE_FEATURE_CONDITION(features, flushOnFramebufferChange,
2576                             IsApple() && Has9thGenIntelGPU(systemInfo));
2577 
2578     // Disable GL_EXT_multisampled_render_to_texture on a bunch of different configurations:
2579 
2580     // http://crbug.com/490379
2581     // http://crbug.com/767913
2582     bool isAdreno4xxOnAndroidLessThan51 =
2583         IsAndroid() && IsAdreno4xx(functions) && GetAndroidSDKVersion() < 22;
2584 
2585     // http://crbug.com/612474
2586     bool isAdreno4xxOnAndroid70 =
2587         IsAndroid() && IsAdreno4xx(functions) && GetAndroidSDKVersion() == 24;
2588     bool isAdreno5xxOnAndroidLessThan70 =
2589         IsAndroid() && IsAdreno5xx(functions) && GetAndroidSDKVersion() < 24;
2590 
2591     // http://crbug.com/663811
2592     bool isAdreno5xxOnAndroid71 =
2593         IsAndroid() && IsAdreno5xx(functions) && GetAndroidSDKVersion() == 25;
2594 
2595     // http://crbug.com/594016
2596     bool isLinuxVivante = IsLinux() && IsVivante(device);
2597 
2598     // http://anglebug.com/42266736
2599     bool isWindowsNVIDIA = IsWindows() && IsNvidia(vendor);
2600 
2601     // Temporarily disable on all of Android. http://crbug.com/1417485
2602     ANGLE_FEATURE_CONDITION(features, disableMultisampledRenderToTexture,
2603                             isAdreno4xxOnAndroidLessThan51 || isAdreno4xxOnAndroid70 ||
2604                                 isAdreno5xxOnAndroidLessThan70 || isAdreno5xxOnAndroid71 ||
2605                                 isLinuxVivante || isWindowsNVIDIA);
2606 
2607     // http://crbug.com/1181068
2608     ANGLE_FEATURE_CONDITION(features, uploadTextureDataInChunks, IsApple());
2609 
2610     // https://crbug.com/1060012
2611     ANGLE_FEATURE_CONDITION(features, emulateImmutableCompressedTexture3D, isQualcomm);
2612 
2613     // https://crbug.com/1300575
2614     ANGLE_FEATURE_CONDITION(features, emulateRGB10, functions->standard == STANDARD_GL_DESKTOP);
2615 
2616     // https://anglebug.com/42264072
2617     ANGLE_FEATURE_CONDITION(features, alwaysUnbindFramebufferTexture2D,
2618                             isNvidia && (IsWindows() || IsLinux()));
2619 
2620     // https://anglebug.com/42265877
2621     ANGLE_FEATURE_CONDITION(features, disableTextureClampToBorder, false);
2622 
2623     // https://anglebug.com/42265995
2624     ANGLE_FEATURE_CONDITION(features, passHighpToPackUnormSnormBuiltins, isQualcomm);
2625 
2626     // https://anglebug.com/42266348
2627     ANGLE_FEATURE_CONDITION(features, emulateClipDistanceState, isQualcomm);
2628 
2629     // https://anglebug.com/42266817
2630     ANGLE_FEATURE_CONDITION(features, emulateClipOrigin,
2631                             !isMesa && isQualcomm && qualcommVersion < 490 &&
2632                                 functions->hasGLESExtension("GL_EXT_clip_control"));
2633 
2634     // https://anglebug.com/42266740
2635     ANGLE_FEATURE_CONDITION(features, explicitFragmentLocations, isQualcomm);
2636 
2637     // Desktop GLSL-only fragment synchronization extensions. These are injected internally by the
2638     // compiler to make pixel local storage coherent.
2639     // https://anglebug.com/40096838
2640     ANGLE_FEATURE_CONDITION(features, supportsFragmentShaderInterlockNV,
2641                             functions->isAtLeastGL(gl::Version(4, 3)) &&
2642                                 functions->hasGLExtension("GL_NV_fragment_shader_interlock"));
2643     ANGLE_FEATURE_CONDITION(features, supportsFragmentShaderOrderingINTEL,
2644                             functions->isAtLeastGL(gl::Version(4, 4)) &&
2645                                 functions->hasGLExtension("GL_INTEL_fragment_shader_ordering"));
2646     ANGLE_FEATURE_CONDITION(features, supportsFragmentShaderInterlockARB,
2647                             functions->isAtLeastGL(gl::Version(4, 5)) &&
2648                                 functions->hasGLExtension("GL_ARB_fragment_shader_interlock"));
2649 
2650     // EXT_shader_framebuffer_fetch
2651     ANGLE_FEATURE_CONDITION(features, supportsShaderFramebufferFetchEXT,
2652                             functions->hasGLESExtension("GL_EXT_shader_framebuffer_fetch"));
2653 
2654     // EXT_shader_framebuffer_fetch_non_coherent
2655     ANGLE_FEATURE_CONDITION(
2656         features, supportsShaderFramebufferFetchNonCoherentEXT,
2657         functions->hasGLESExtension("GL_EXT_shader_framebuffer_fetch_non_coherent"));
2658 
2659     // https://crbug.com/1356053
2660     ANGLE_FEATURE_CONDITION(features, bindCompleteFramebufferForTimerQueries, isMali);
2661 
2662     // https://crbug.com/40264674
2663     ANGLE_FEATURE_CONDITION(features, disableClipControl, IsMaliG72OrG76OrG51(functions));
2664 
2665     // https://anglebug.com/42266811
2666     ANGLE_FEATURE_CONDITION(features, resyncDepthRangeOnClipControl, !isMesa && isQualcomm);
2667 
2668     // https://anglebug.com/42266745
2669     ANGLE_FEATURE_CONDITION(features, disableRenderSnorm,
2670                             isMesa && (mesaVersion < (std::array<int, 3>{21, 3, 0}) ||
2671                                        (mesaVersion < (std::array<int, 3>{23, 3, 0}) &&
2672                                         functions->standard == STANDARD_GL_ES)));
2673 
2674     // https://anglebug.com/42266748
2675     ANGLE_FEATURE_CONDITION(features, disableTextureMirrorClampToEdge,
2676                             functions->standard == STANDARD_GL_ES && isMesa &&
2677                                 mesaVersion < (std::array<int, 3>{23, 1, 7}));
2678 
2679     // http://anglebug.com/42266610
2680     ANGLE_FEATURE_CONDITION(features, disableBaseInstanceVertex, IsMaliValhall(functions));
2681 
2682     // Mali: http://crbug.com/40063287
2683     // Nvidia: http://crbug.com/328015191
2684     ANGLE_FEATURE_CONDITION(features, scalarizeVecAndMatConstructorArgs, isMali || isNvidia);
2685 
2686     // http://crbug.com/40066076
2687     ANGLE_FEATURE_CONDITION(features, ensureNonEmptyBufferIsBoundForDraw, IsApple() || IsAndroid());
2688 
2689     // https://anglebug.com/42266857
2690     ANGLE_FEATURE_CONDITION(features, preTransformTextureCubeGradDerivatives, isApple);
2691 
2692     // https://crbug.com/40279678
2693     ANGLE_FEATURE_CONDITION(features, useIntermediateTextureForGenerateMipmap,
2694                             IsPixel7OrPixel8(functions));
2695 
2696     // SRGB blending does not appear to work correctly on the Nexus 5 + other QC devices. Writing to
2697     // an SRGB framebuffer with GL_FRAMEBUFFER_SRGB enabled and then reading back returns the same
2698     // value. Disabling GL_FRAMEBUFFER_SRGB will then convert in the wrong direction.
2699     ANGLE_FEATURE_CONDITION(features, srgbBlendingBroken, IsQualcomm(vendor));
2700 
2701     // BGRA formats do not appear to be accepted by the qualcomm driver despite the extension being
2702     // exposed.
2703     ANGLE_FEATURE_CONDITION(features, bgraTexImageFormatsBroken, IsQualcomm(vendor));
2704 
2705     // https://github.com/flutter/flutter/issues/47164
2706     // https://github.com/flutter/flutter/issues/47804
2707     // Some devices expose the QCOM tiled memory extension string but don't actually provide the
2708     // start and end tiling functions.
2709     bool missingTilingEntryPoints = functions->hasGLESExtension("GL_QCOM_tiled_rendering") &&
2710                                     (!functions->startTilingQCOM || !functions->endTilingQCOM);
2711 
2712     // http://skbug.com/9491: Nexus5 produces rendering artifacts when we use QCOM_tiled_rendering.
2713     ANGLE_FEATURE_CONDITION(features, disableTiledRendering,
2714                             missingTilingEntryPoints || IsAdreno3xx(functions));
2715 
2716     // Intel desktop GL drivers fail many Skia blend tests.
2717     // Block on older Qualcomm and ARM, following Skia's blocklists.
2718     ANGLE_FEATURE_CONDITION(
2719         features, disableBlendEquationAdvanced,
2720         (isIntel && IsWindows()) || IsAdreno4xx(functions) || IsAdreno5xx(functions) || isMali);
2721 }
2722 
InitializeFrontendFeatures(const FunctionsGL * functions,angle::FrontendFeatures * features)2723 void InitializeFrontendFeatures(const FunctionsGL *functions, angle::FrontendFeatures *features)
2724 {
2725     VendorID vendor = GetVendorID(functions);
2726     bool isQualcomm = IsQualcomm(vendor);
2727 
2728     std::array<int, 3> mesaVersion = {0, 0, 0};
2729     bool isMesa                    = IsMesa(functions, &mesaVersion);
2730 
2731     ANGLE_FEATURE_CONDITION(features, disableProgramCachingForTransformFeedback,
2732                             !isMesa && isQualcomm);
2733     // https://crbug.com/480992
2734     // Disable shader program cache to workaround PowerVR Rogue issues.
2735     ANGLE_FEATURE_CONDITION(features, disableProgramBinary, IsPowerVrRogue(functions));
2736 
2737     // The compile and link jobs need a context, and previous experiments showed setting up temp
2738     // contexts in threads for the sake of program link triggers too many driver bugs.  See
2739     // https://chromium-review.googlesource.com/c/angle/angle/+/4774785 for context.
2740     //
2741     // As a result, the compile and link jobs are done in the same thread as the call.  If the
2742     // native driver supports parallel compile/link, it's still done internally by the driver, and
2743     // ANGLE supports delaying post-compile and post-link operations until that is done.
2744     ANGLE_FEATURE_CONDITION(features, compileJobIsThreadSafe, false);
2745     ANGLE_FEATURE_CONDITION(features, linkJobIsThreadSafe, false);
2746 
2747     ANGLE_FEATURE_CONDITION(features, cacheCompiledShader, true);
2748 }
2749 
ReInitializeFeaturesAtGPUSwitch(const FunctionsGL * functions,angle::FeaturesGL * features)2750 void ReInitializeFeaturesAtGPUSwitch(const FunctionsGL *functions, angle::FeaturesGL *features)
2751 {
2752     angle::VendorID vendor;
2753     angle::DeviceID device;
2754     angle::SystemInfo systemInfo;
2755 
2756     GetSystemInfoVendorIDAndDeviceID(functions, &systemInfo, &vendor, &device);
2757 
2758     // http://crbug.com/1144207
2759     // The Mac bot with Intel Iris GPU seems unaffected by this bug. Exclude the Haswell family for
2760     // now.
2761     // We need to reinitialize this feature when switching between buggy and non-buggy GPUs.
2762     ANGLE_FEATURE_CONDITION(features, shiftInstancedArrayDataWithOffset,
2763                             IsApple() && IsIntel(vendor) && !IsHaswell(device));
2764 }
2765 
2766 }  // namespace nativegl_gl
2767 
2768 namespace nativegl
2769 {
2770 
SupportsVertexArrayObjects(const FunctionsGL * functions)2771 bool SupportsVertexArrayObjects(const FunctionsGL *functions)
2772 {
2773     return functions->isAtLeastGLES(gl::Version(3, 0)) ||
2774            functions->hasGLESExtension("GL_OES_vertex_array_object") ||
2775            functions->isAtLeastGL(gl::Version(3, 0)) ||
2776            functions->hasGLExtension("GL_ARB_vertex_array_object");
2777 }
2778 
CanUseDefaultVertexArrayObject(const FunctionsGL * functions)2779 bool CanUseDefaultVertexArrayObject(const FunctionsGL *functions)
2780 {
2781     return (functions->profile & GL_CONTEXT_CORE_PROFILE_BIT) == 0;
2782 }
2783 
CanUseClientSideArrays(const FunctionsGL * functions,GLuint vao)2784 bool CanUseClientSideArrays(const FunctionsGL *functions, GLuint vao)
2785 {
2786     // Can use client arrays on GLES or GL compatability profile only on the default VAO
2787     return CanUseDefaultVertexArrayObject(functions) && vao == 0;
2788 }
2789 
SupportsCompute(const FunctionsGL * functions)2790 bool SupportsCompute(const FunctionsGL *functions)
2791 {
2792     // OpenGL 4.2 is required for GL_ARB_compute_shader, some platform drivers have the extension,
2793     // but their maximum supported GL versions are less than 4.2. Explicitly limit the minimum
2794     // GL version to 4.2.
2795     return (functions->isAtLeastGL(gl::Version(4, 3)) ||
2796             functions->isAtLeastGLES(gl::Version(3, 1)) ||
2797             (functions->isAtLeastGL(gl::Version(4, 2)) &&
2798              functions->hasGLExtension("GL_ARB_compute_shader") &&
2799              functions->hasGLExtension("GL_ARB_shader_storage_buffer_object")));
2800 }
2801 
SupportsFenceSync(const FunctionsGL * functions)2802 bool SupportsFenceSync(const FunctionsGL *functions)
2803 {
2804     return functions->isAtLeastGL(gl::Version(3, 2)) || functions->hasGLExtension("GL_ARB_sync") ||
2805            functions->isAtLeastGLES(gl::Version(3, 0));
2806 }
2807 
SupportsOcclusionQueries(const FunctionsGL * functions)2808 bool SupportsOcclusionQueries(const FunctionsGL *functions)
2809 {
2810     return functions->isAtLeastGL(gl::Version(1, 5)) ||
2811            functions->hasGLExtension("GL_ARB_occlusion_query2") ||
2812            functions->isAtLeastGLES(gl::Version(3, 0)) ||
2813            functions->hasGLESExtension("GL_EXT_occlusion_query_boolean");
2814 }
2815 
SupportsNativeRendering(const FunctionsGL * functions,gl::TextureType type,GLenum internalFormat)2816 bool SupportsNativeRendering(const FunctionsGL *functions,
2817                              gl::TextureType type,
2818                              GLenum internalFormat)
2819 {
2820     // Some desktop drivers allow rendering to formats that are not required by the spec, this is
2821     // exposed through the GL_FRAMEBUFFER_RENDERABLE query.
2822     bool hasInternalFormatQuery = functions->isAtLeastGL(gl::Version(4, 3)) ||
2823                                   functions->hasGLExtension("GL_ARB_internalformat_query2");
2824 
2825     // Some Intel drivers have a bug that returns GL_FULL_SUPPORT when asked if they support
2826     // rendering to compressed texture formats yet return framebuffer incomplete when attempting to
2827     // render to the format.  Skip any native queries for compressed formats.
2828     const gl::InternalFormat &internalFormatInfo = gl::GetSizedInternalFormatInfo(internalFormat);
2829 
2830     if (hasInternalFormatQuery && !internalFormatInfo.compressed)
2831     {
2832         GLint framebufferRenderable = GL_NONE;
2833         functions->getInternalformativ(ToGLenum(type), internalFormat, GL_FRAMEBUFFER_RENDERABLE, 1,
2834                                        &framebufferRenderable);
2835         return framebufferRenderable != GL_NONE;
2836     }
2837     else
2838     {
2839         const nativegl::InternalFormat &nativeInfo =
2840             nativegl::GetInternalFormatInfo(internalFormat, functions->standard);
2841         return nativegl_gl::MeetsRequirements(functions, nativeInfo.textureAttachment);
2842     }
2843 }
2844 
SupportsTexImage(gl::TextureType type)2845 bool SupportsTexImage(gl::TextureType type)
2846 {
2847     switch (type)
2848     {
2849             // Multi-sample texture types only support TexStorage data upload
2850         case gl::TextureType::_2DMultisample:
2851         case gl::TextureType::_2DMultisampleArray:
2852             return false;
2853 
2854         default:
2855             return true;
2856     }
2857 }
2858 
UseTexImage2D(gl::TextureType textureType)2859 bool UseTexImage2D(gl::TextureType textureType)
2860 {
2861     return textureType == gl::TextureType::_2D || textureType == gl::TextureType::CubeMap ||
2862            textureType == gl::TextureType::Rectangle ||
2863            textureType == gl::TextureType::_2DMultisample ||
2864            textureType == gl::TextureType::External || textureType == gl::TextureType::VideoImage;
2865 }
2866 
UseTexImage3D(gl::TextureType textureType)2867 bool UseTexImage3D(gl::TextureType textureType)
2868 {
2869     return textureType == gl::TextureType::_2DArray || textureType == gl::TextureType::_3D ||
2870            textureType == gl::TextureType::_2DMultisampleArray ||
2871            textureType == gl::TextureType::CubeMapArray;
2872 }
2873 
GetTextureBindingQuery(gl::TextureType textureType)2874 GLenum GetTextureBindingQuery(gl::TextureType textureType)
2875 {
2876     switch (textureType)
2877     {
2878         case gl::TextureType::_2D:
2879             return GL_TEXTURE_BINDING_2D;
2880         case gl::TextureType::_2DArray:
2881             return GL_TEXTURE_BINDING_2D_ARRAY;
2882         case gl::TextureType::_2DMultisample:
2883             return GL_TEXTURE_BINDING_2D_MULTISAMPLE;
2884         case gl::TextureType::_2DMultisampleArray:
2885             return GL_TEXTURE_BINDING_2D_MULTISAMPLE_ARRAY;
2886         case gl::TextureType::_3D:
2887             return GL_TEXTURE_BINDING_3D;
2888         case gl::TextureType::External:
2889             return GL_TEXTURE_BINDING_EXTERNAL_OES;
2890         case gl::TextureType::Rectangle:
2891             return GL_TEXTURE_BINDING_RECTANGLE;
2892         case gl::TextureType::CubeMap:
2893             return GL_TEXTURE_BINDING_CUBE_MAP;
2894         case gl::TextureType::CubeMapArray:
2895             return GL_TEXTURE_BINDING_CUBE_MAP_ARRAY_OES;
2896         case gl::TextureType::Buffer:
2897             return GL_TEXTURE_BINDING_BUFFER;
2898         default:
2899             UNREACHABLE();
2900             return 0;
2901     }
2902 }
2903 
GetTextureBindingTarget(gl::TextureType textureType)2904 GLenum GetTextureBindingTarget(gl::TextureType textureType)
2905 {
2906     return ToGLenum(GetNativeTextureType(textureType));
2907 }
2908 
GetTextureBindingTarget(gl::TextureTarget textureTarget)2909 GLenum GetTextureBindingTarget(gl::TextureTarget textureTarget)
2910 {
2911     return ToGLenum(GetNativeTextureTarget(textureTarget));
2912 }
2913 
GetBufferBindingQuery(gl::BufferBinding bufferBinding)2914 GLenum GetBufferBindingQuery(gl::BufferBinding bufferBinding)
2915 {
2916     switch (bufferBinding)
2917     {
2918         case gl::BufferBinding::Array:
2919             return GL_ARRAY_BUFFER_BINDING;
2920         case gl::BufferBinding::AtomicCounter:
2921             return GL_ATOMIC_COUNTER_BUFFER_BINDING;
2922         case gl::BufferBinding::CopyRead:
2923             return GL_COPY_READ_BUFFER_BINDING;
2924         case gl::BufferBinding::CopyWrite:
2925             return GL_COPY_WRITE_BUFFER_BINDING;
2926         case gl::BufferBinding::DispatchIndirect:
2927             return GL_DISPATCH_INDIRECT_BUFFER_BINDING;
2928         case gl::BufferBinding::DrawIndirect:
2929             return GL_DRAW_INDIRECT_BUFFER_BINDING;
2930         case gl::BufferBinding::ElementArray:
2931             return GL_ELEMENT_ARRAY_BUFFER_BINDING;
2932         case gl::BufferBinding::PixelPack:
2933             return GL_PIXEL_PACK_BUFFER_BINDING;
2934         case gl::BufferBinding::PixelUnpack:
2935             return GL_PIXEL_UNPACK_BUFFER_BINDING;
2936         case gl::BufferBinding::ShaderStorage:
2937             return GL_SHADER_STORAGE_BUFFER_BINDING;
2938         case gl::BufferBinding::TransformFeedback:
2939             return GL_TRANSFORM_FEEDBACK_BUFFER_BINDING;
2940         case gl::BufferBinding::Uniform:
2941             return GL_UNIFORM_BUFFER_BINDING;
2942         case gl::BufferBinding::Texture:
2943             return GL_TEXTURE_BUFFER_BINDING;
2944         default:
2945             UNREACHABLE();
2946             return 0;
2947     }
2948 }
2949 
GetBufferBindingString(gl::BufferBinding bufferBinding)2950 std::string GetBufferBindingString(gl::BufferBinding bufferBinding)
2951 {
2952     std::ostringstream os;
2953     os << bufferBinding << "_BINDING";
2954     return os.str();
2955 }
2956 
GetNativeTextureType(gl::TextureType type)2957 gl::TextureType GetNativeTextureType(gl::TextureType type)
2958 {
2959     // VideoImage texture type is a WebGL type. It doesn't have
2960     // directly mapping type in native OpenGL/OpenGLES.
2961     // Actually, it will be translated to different texture type
2962     // (TEXTURE2D, TEXTURE_EXTERNAL_OES and TEXTURE_RECTANGLE)
2963     // based on OS and other conditions.
2964     // This will introduce problem that binding VideoImage may
2965     // unbind native image implicitly. Please make sure state
2966     // manager is aware of this implicit unbind behaviour.
2967     if (type != gl::TextureType::VideoImage)
2968     {
2969         return type;
2970     }
2971 
2972     // TODO(http://anglebug.com/42262534): need to figure out rectangle texture and
2973     // external image when these backend are implemented.
2974     return gl::TextureType::_2D;
2975 }
2976 
GetNativeTextureTarget(gl::TextureTarget target)2977 gl::TextureTarget GetNativeTextureTarget(gl::TextureTarget target)
2978 {
2979     // VideoImage texture type is a WebGL type. It doesn't have
2980     // directly mapping type in native OpenGL/OpenGLES.
2981     // Actually, it will be translated to different texture target
2982     // (TEXTURE2D, TEXTURE_EXTERNAL_OES and TEXTURE_RECTANGLE)
2983     // based on OS and other conditions.
2984     // This will introduce problem that binding VideoImage may
2985     // unbind native image implicitly. Please make sure state
2986     // manager is aware of this implicit unbind behaviour.
2987     if (target != gl::TextureTarget::VideoImage)
2988     {
2989         return target;
2990     }
2991 
2992     // TODO(http://anglebug.com/42262534): need to figure out rectangle texture and
2993     // external image when these backend are implemented.
2994     return gl::TextureTarget::_2D;
2995 }
2996 
2997 }  // namespace nativegl
2998 
GetFunctionsGL(const gl::Context * context)2999 const FunctionsGL *GetFunctionsGL(const gl::Context *context)
3000 {
3001     return GetImplAs<ContextGL>(context)->getFunctions();
3002 }
3003 
GetStateManagerGL(const gl::Context * context)3004 StateManagerGL *GetStateManagerGL(const gl::Context *context)
3005 {
3006     return GetImplAs<ContextGL>(context)->getStateManager();
3007 }
3008 
GetBlitGL(const gl::Context * context)3009 BlitGL *GetBlitGL(const gl::Context *context)
3010 {
3011     return GetImplAs<ContextGL>(context)->getBlitter();
3012 }
3013 
GetMultiviewClearer(const gl::Context * context)3014 ClearMultiviewGL *GetMultiviewClearer(const gl::Context *context)
3015 {
3016     return GetImplAs<ContextGL>(context)->getMultiviewClearer();
3017 }
3018 
GetFeaturesGL(const gl::Context * context)3019 const angle::FeaturesGL &GetFeaturesGL(const gl::Context *context)
3020 {
3021     return GetImplAs<ContextGL>(context)->getFeaturesGL();
3022 }
3023 
ClearErrors(const FunctionsGL * functions,const char * file,const char * function,unsigned int line)3024 void ClearErrors(const FunctionsGL *functions,
3025                  const char *file,
3026                  const char *function,
3027                  unsigned int line)
3028 {
3029     GLenum error = functions->getError();
3030     while (error != GL_NO_ERROR)
3031     {
3032         INFO() << "Preexisting GL error " << gl::FmtHex(error) << " as of " << file << ", "
3033                << function << ":" << line << ". ";
3034 
3035         // Skip GL_CONTEXT_LOST errors, they will be generated continuously and result in an
3036         // infinite loop.
3037         if (error == GL_CONTEXT_LOST)
3038         {
3039             return;
3040         }
3041 
3042         error = functions->getError();
3043     }
3044 }
3045 
ClearErrors(const gl::Context * context,const char * file,const char * function,unsigned int line)3046 void ClearErrors(const gl::Context *context,
3047                  const char *file,
3048                  const char *function,
3049                  unsigned int line)
3050 {
3051     const FunctionsGL *functions = GetFunctionsGL(context);
3052     ClearErrors(functions, file, function, line);
3053 }
3054 
CheckError(const gl::Context * context,const char * call,const char * file,const char * function,unsigned int line)3055 angle::Result CheckError(const gl::Context *context,
3056                          const char *call,
3057                          const char *file,
3058                          const char *function,
3059                          unsigned int line)
3060 {
3061     return HandleError(context, GetFunctionsGL(context)->getError(), call, file, function, line);
3062 }
3063 
HandleError(const gl::Context * context,GLenum error,const char * call,const char * file,const char * function,unsigned int line)3064 angle::Result HandleError(const gl::Context *context,
3065                           GLenum error,
3066                           const char *call,
3067                           const char *file,
3068                           const char *function,
3069                           unsigned int line)
3070 {
3071     const FunctionsGL *functions = GetFunctionsGL(context);
3072     if (ANGLE_UNLIKELY(error != GL_NO_ERROR))
3073     {
3074         ContextGL *contextGL = GetImplAs<ContextGL>(context);
3075         contextGL->handleError(error, "Unexpected driver error.", file, function, line);
3076         ERR() << "GL call " << call << " generated error " << gl::FmtHex(error) << " in " << file
3077               << ", " << function << ":" << line << ". ";
3078 
3079         // Check that only one GL error was generated, ClearErrors should have been called first.
3080         // Skip GL_CONTEXT_LOST errors, they will be generated continuously and result in an
3081         // infinite loop.
3082         GLenum nextError = functions->getError();
3083         while (nextError != GL_NO_ERROR && nextError != GL_CONTEXT_LOST)
3084         {
3085             ERR() << "Additional GL error " << gl::FmtHex(nextError) << " generated.";
3086             nextError = functions->getError();
3087         }
3088 
3089         return angle::Result::Stop;
3090     }
3091 
3092     return angle::Result::Continue;
3093 }
3094 
CanMapBufferForRead(const FunctionsGL * functions)3095 bool CanMapBufferForRead(const FunctionsGL *functions)
3096 {
3097     return (functions->mapBufferRange != nullptr) ||
3098            (functions->mapBuffer != nullptr && functions->standard == STANDARD_GL_DESKTOP);
3099 }
3100 
MapBufferRangeWithFallback(const FunctionsGL * functions,GLenum target,size_t offset,size_t length,GLbitfield access)3101 uint8_t *MapBufferRangeWithFallback(const FunctionsGL *functions,
3102                                     GLenum target,
3103                                     size_t offset,
3104                                     size_t length,
3105                                     GLbitfield access)
3106 {
3107     if (functions->mapBufferRange != nullptr)
3108     {
3109         return static_cast<uint8_t *>(functions->mapBufferRange(target, offset, length, access));
3110     }
3111     else if (functions->mapBuffer != nullptr &&
3112              (functions->standard == STANDARD_GL_DESKTOP || access == GL_MAP_WRITE_BIT))
3113     {
3114         // Only the read and write bits are supported
3115         ASSERT((access & (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT)) != 0);
3116 
3117         GLenum accessEnum = 0;
3118         if (access == (GL_MAP_READ_BIT | GL_MAP_WRITE_BIT))
3119         {
3120             accessEnum = GL_READ_WRITE;
3121         }
3122         else if (access == GL_MAP_READ_BIT)
3123         {
3124             accessEnum = GL_READ_ONLY;
3125         }
3126         else if (access == GL_MAP_WRITE_BIT)
3127         {
3128             accessEnum = GL_WRITE_ONLY;
3129         }
3130         else
3131         {
3132             UNREACHABLE();
3133             return nullptr;
3134         }
3135 
3136         return static_cast<uint8_t *>(functions->mapBuffer(target, accessEnum)) + offset;
3137     }
3138     else
3139     {
3140         // No options available
3141         UNREACHABLE();
3142         return nullptr;
3143     }
3144 }
3145 
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)3146 angle::Result ShouldApplyLastRowPaddingWorkaround(ContextGL *contextGL,
3147                                                   const gl::Extents &size,
3148                                                   const gl::PixelStoreStateBase &state,
3149                                                   const gl::Buffer *pixelBuffer,
3150                                                   GLenum format,
3151                                                   GLenum type,
3152                                                   bool is3D,
3153                                                   const void *pixels,
3154                                                   bool *shouldApplyOut)
3155 {
3156     if (pixelBuffer == nullptr)
3157     {
3158         *shouldApplyOut = false;
3159         return angle::Result::Continue;
3160     }
3161 
3162     // We are using an pack or unpack buffer, compute what the driver thinks is going to be the
3163     // last byte read or written. If it is past the end of the buffer, we will need to use the
3164     // workaround otherwise the driver will generate INVALID_OPERATION and not do the operation.
3165 
3166     const gl::InternalFormat &glFormat = gl::GetInternalFormatInfo(format, type);
3167     GLuint endByte                     = 0;
3168     ANGLE_CHECK_GL_MATH(contextGL,
3169                         glFormat.computePackUnpackEndByte(type, size, state, is3D, &endByte));
3170     GLuint rowPitch = 0;
3171     ANGLE_CHECK_GL_MATH(contextGL, glFormat.computeRowPitch(type, size.width, state.alignment,
3172                                                             state.rowLength, &rowPitch));
3173 
3174     CheckedNumeric<size_t> checkedPixelBytes = glFormat.computePixelBytes(type);
3175     CheckedNumeric<size_t> checkedEndByte =
3176         angle::CheckedNumeric<size_t>(endByte) + reinterpret_cast<intptr_t>(pixels);
3177 
3178     // At this point checkedEndByte is the actual last byte read.
3179     // The driver adds an extra row padding (if any), mimic it.
3180     ANGLE_CHECK_GL_MATH(contextGL, checkedPixelBytes.IsValid());
3181     if (static_cast<size_t>(checkedPixelBytes.ValueOrDie()) * size.width < rowPitch)
3182     {
3183         checkedEndByte += rowPitch - checkedPixelBytes * size.width;
3184     }
3185 
3186     ANGLE_CHECK_GL_MATH(contextGL, checkedEndByte.IsValid());
3187 
3188     *shouldApplyOut = checkedEndByte.ValueOrDie() > static_cast<size_t>(pixelBuffer->getSize());
3189     return angle::Result::Continue;
3190 }
3191 
GenerateContextCreationToTry(EGLint requestedType,bool isMesaGLX)3192 std::vector<ContextCreationTry> GenerateContextCreationToTry(EGLint requestedType, bool isMesaGLX)
3193 {
3194     using Type                         = ContextCreationTry::Type;
3195     constexpr EGLint kPlatformOpenGL   = EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE;
3196     constexpr EGLint kPlatformOpenGLES = EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE;
3197 
3198     std::vector<ContextCreationTry> contextsToTry;
3199 
3200     if (requestedType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE || requestedType == kPlatformOpenGL)
3201     {
3202         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 5));
3203         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 4));
3204         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 3));
3205         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 2));
3206         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 1));
3207         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(4, 0));
3208         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(3, 3));
3209         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_CORE, gl::Version(3, 2));
3210         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 3));
3211 
3212         // On Mesa, do not try to create OpenGL context versions between 3.0 and
3213         // 3.2 because of compatibility problems. See crbug.com/659030
3214         if (!isMesaGLX)
3215         {
3216             contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 2));
3217             contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 1));
3218             contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(3, 0));
3219         }
3220 
3221         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(2, 1));
3222         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(2, 0));
3223         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 5));
3224         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 4));
3225         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 3));
3226         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 2));
3227         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 1));
3228         contextsToTry.emplace_back(kPlatformOpenGL, Type::DESKTOP_LEGACY, gl::Version(1, 0));
3229     }
3230 
3231     if (requestedType == EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE ||
3232         requestedType == kPlatformOpenGLES)
3233     {
3234         contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 2));
3235         contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 1));
3236         contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(3, 0));
3237         contextsToTry.emplace_back(kPlatformOpenGLES, Type::ES, gl::Version(2, 0));
3238     }
3239 
3240     return contextsToTry;
3241 }
3242 
GetRendererString(const FunctionsGL * functions)3243 std::string GetRendererString(const FunctionsGL *functions)
3244 {
3245     return GetString(functions, GL_RENDERER);
3246 }
3247 
GetVendorString(const FunctionsGL * functions)3248 std::string GetVendorString(const FunctionsGL *functions)
3249 {
3250     return GetString(functions, GL_VENDOR);
3251 }
3252 
GetVersionString(const FunctionsGL * functions)3253 std::string GetVersionString(const FunctionsGL *functions)
3254 {
3255     return GetString(functions, GL_VERSION);
3256 }
3257 
3258 }  // namespace rx
3259