gl_display.cc 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041
  1. // Copyright (c) 2022 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ui/gl/gl_display.h"
  5. #include <string>
  6. #include <type_traits>
  7. #include <vector>
  8. #include "base/command_line.h"
  9. #include "base/containers/contains.h"
  10. #include "base/debug/crash_logging.h"
  11. #include "base/export_template.h"
  12. #include "base/logging.h"
  13. #include "base/metrics/histogram_macros.h"
  14. #include "base/notreached.h"
  15. #include "base/strings/string_number_conversions.h"
  16. #include "base/strings/string_split.h"
  17. #include "base/system/sys_info.h"
  18. #include "build/build_config.h"
  19. #include "ui/gl/angle_platform_impl.h"
  20. #include "ui/gl/egl_util.h"
  21. #include "ui/gl/gl_bindings.h"
  22. #include "ui/gl/gl_context_egl.h"
  23. #include "ui/gl/gl_display_egl_util.h"
  24. #include "ui/gl/gl_implementation.h"
  25. #include "ui/gl/gl_surface.h"
  26. #if defined(USE_GLX)
  27. #include "ui/gl/glx_util.h"
  28. #endif // defined(USE_GLX)
  29. #if defined(USE_OZONE)
  30. #include "ui/ozone/buildflags.h"
  31. #endif // defined(USE_OZONE)
  32. #if BUILDFLAG(IS_ANDROID)
  33. #include <android/native_window_jni.h>
  34. #include "base/android/build_info.h"
  35. #endif
  36. // From ANGLE's egl/eglext.h.
  37. #ifndef EGL_ANGLE_platform_angle
  38. #define EGL_ANGLE_platform_angle 1
  39. #define EGL_PLATFORM_ANGLE_ANGLE 0x3202
  40. #define EGL_PLATFORM_ANGLE_TYPE_ANGLE 0x3203
  41. #define EGL_PLATFORM_ANGLE_MAX_VERSION_MAJOR_ANGLE 0x3204
  42. #define EGL_PLATFORM_ANGLE_MAX_VERSION_MINOR_ANGLE 0x3205
  43. #define EGL_PLATFORM_ANGLE_TYPE_DEFAULT_ANGLE 0x3206
  44. #define EGL_PLATFORM_ANGLE_DEBUG_LAYERS_ENABLED_ANGLE 0x3451
  45. #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE 0x3209
  46. #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE 0x348E
  47. #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE 0x320A
  48. #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE 0x345E
  49. #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE 0x3487
  50. #define EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE 0x348F
  51. #endif /* EGL_ANGLE_platform_angle */
  52. #ifndef EGL_ANGLE_platform_angle_d3d
  53. #define EGL_ANGLE_platform_angle_d3d 1
  54. #define EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE 0x3207
  55. #define EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE 0x3208
  56. #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_WARP_ANGLE 0x320B
  57. #define EGL_PLATFORM_ANGLE_DEVICE_TYPE_D3D_REFERENCE_ANGLE 0x320C
  58. #endif /* EGL_ANGLE_platform_angle_d3d */
  59. #ifndef EGL_ANGLE_platform_angle_d3d_luid
  60. #define EGL_ANGLE_platform_angle_d3d_luid 1
  61. #define EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE 0x34A0
  62. #define EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE 0x34A1
  63. #endif /* EGL_ANGLE_platform_angle_d3d_luid */
  64. #ifndef EGL_ANGLE_platform_angle_d3d11on12
  65. #define EGL_ANGLE_platform_angle_d3d11on12 1
  66. #define EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE 0x3488
  67. #endif /* EGL_ANGLE_platform_angle_d3d11on12 */
  68. #ifndef EGL_ANGLE_platform_angle_opengl
  69. #define EGL_ANGLE_platform_angle_opengl 1
  70. #define EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE 0x320D
  71. #define EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE 0x320E
  72. #endif /* EGL_ANGLE_platform_angle_opengl */
  73. #ifndef EGL_ANGLE_platform_angle_null
  74. #define EGL_ANGLE_platform_angle_null 1
  75. #define EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE 0x33AE
  76. #endif /* EGL_ANGLE_platform_angle_null */
  77. #ifndef EGL_ANGLE_platform_angle_vulkan
  78. #define EGL_ANGLE_platform_angle_vulkan 1
  79. #define EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE 0x3450
  80. #define EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE 0x34A5
  81. #endif /* EGL_ANGLE_platform_angle_vulkan */
  82. #ifndef EGL_ANGLE_platform_angle_metal
  83. #define EGL_ANGLE_platform_angle_metal 1
  84. #define EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE 0x3489
  85. #endif /* EGL_ANGLE_platform_angle_metal */
  86. #ifndef EGL_ANGLE_x11_visual
  87. #define EGL_ANGLE_x11_visual 1
  88. #define EGL_X11_VISUAL_ID_ANGLE 0x33A3
  89. #endif /* EGL_ANGLE_x11_visual */
  90. #ifndef EGL_ANGLE_direct_composition
  91. #define EGL_ANGLE_direct_composition 1
  92. #define EGL_DIRECT_COMPOSITION_ANGLE 0x33A5
  93. #endif /* EGL_ANGLE_direct_composition */
  94. #ifndef EGL_ANGLE_display_robust_resource_initialization
  95. #define EGL_ANGLE_display_robust_resource_initialization 1
  96. #define EGL_DISPLAY_ROBUST_RESOURCE_INITIALIZATION_ANGLE 0x3453
  97. #endif /* EGL_ANGLE_display_robust_resource_initialization */
  98. #ifndef EGL_ANGLE_display_power_preference
  99. #define EGL_ANGLE_display_power_preference 1
  100. #define EGL_POWER_PREFERENCE_ANGLE 0x3482
  101. #define EGL_LOW_POWER_ANGLE 0x0001
  102. #define EGL_HIGH_POWER_ANGLE 0x0002
  103. #endif /* EGL_ANGLE_power_preference */
  104. #ifndef EGL_ANGLE_platform_angle_device_id
  105. #define EGL_ANGLE_platform_angle_device_id
  106. #define EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE 0x34D6
  107. #define EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE 0x34D7
  108. #endif /* EGL_ANGLE_platform_angle_device_id */
  109. // From ANGLE's egl/eglext.h.
  110. #ifndef EGL_ANGLE_feature_control
  111. #define EGL_ANGLE_feature_control 1
  112. #define EGL_FEATURE_NAME_ANGLE 0x3460
  113. #define EGL_FEATURE_CATEGORY_ANGLE 0x3461
  114. #define EGL_FEATURE_DESCRIPTION_ANGLE 0x3462
  115. #define EGL_FEATURE_BUG_ANGLE 0x3463
  116. #define EGL_FEATURE_STATUS_ANGLE 0x3464
  117. #define EGL_FEATURE_COUNT_ANGLE 0x3465
  118. #define EGL_FEATURE_OVERRIDES_ENABLED_ANGLE 0x3466
  119. #define EGL_FEATURE_OVERRIDES_DISABLED_ANGLE 0x3467
  120. #define EGL_FEATURE_ALL_DISABLED_ANGLE 0x3469
  121. #endif /* EGL_ANGLE_feature_control */
  122. using ui::GetLastEGLErrorString;
  123. namespace gl {
  124. namespace {
  125. std::vector<const char*> GetAttribArrayFromStringVector(
  126. const std::vector<std::string>& strings) {
  127. std::vector<const char*> attribs;
  128. for (const std::string& item : strings) {
  129. attribs.push_back(item.c_str());
  130. }
  131. attribs.push_back(nullptr);
  132. return attribs;
  133. }
  134. std::vector<std::string> GetStringVectorFromCommandLine(
  135. const base::CommandLine* command_line,
  136. const char switch_name[]) {
  137. std::string command_string = command_line->GetSwitchValueASCII(switch_name);
  138. return base::SplitString(command_string, ", ;", base::TRIM_WHITESPACE,
  139. base::SPLIT_WANT_NONEMPTY);
  140. }
  141. EGLDisplay GetPlatformANGLEDisplay(
  142. EGLNativeDisplayType display,
  143. EGLenum platform_type,
  144. const std::vector<std::string>& enabled_features,
  145. const std::vector<std::string>& disabled_features,
  146. const std::vector<EGLAttrib>& extra_display_attribs) {
  147. std::vector<EGLAttrib> display_attribs(extra_display_attribs);
  148. display_attribs.push_back(EGL_PLATFORM_ANGLE_TYPE_ANGLE);
  149. display_attribs.push_back(static_cast<EGLAttrib>(platform_type));
  150. if (platform_type == EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE) {
  151. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  152. if (command_line->HasSwitch(switches::kUseAdapterLuid)) {
  153. // If the LUID is specified, the format is <high part>,<low part>. Split
  154. // and add them to the EGL_ANGLE_platform_angle_d3d_luid ext attributes.
  155. std::string luid =
  156. command_line->GetSwitchValueASCII(switches::kUseAdapterLuid);
  157. size_t comma = luid.find(',');
  158. if (comma != std::string::npos) {
  159. int32_t high;
  160. uint32_t low;
  161. if (!base::StringToInt(luid.substr(0, comma), &high) ||
  162. !base::StringToUint(luid.substr(comma + 1), &low))
  163. return EGL_NO_DISPLAY;
  164. display_attribs.push_back(EGL_PLATFORM_ANGLE_D3D_LUID_HIGH_ANGLE);
  165. display_attribs.push_back(high);
  166. display_attribs.push_back(EGL_PLATFORM_ANGLE_D3D_LUID_LOW_ANGLE);
  167. display_attribs.push_back(low);
  168. }
  169. }
  170. }
  171. GLDisplayEglUtil::GetInstance()->GetPlatformExtraDisplayAttribs(
  172. platform_type, &display_attribs);
  173. std::vector<const char*> enabled_features_attribs =
  174. GetAttribArrayFromStringVector(enabled_features);
  175. std::vector<const char*> disabled_features_attribs =
  176. GetAttribArrayFromStringVector(disabled_features);
  177. if (g_driver_egl.client_ext.b_EGL_ANGLE_feature_control) {
  178. if (!enabled_features_attribs.empty()) {
  179. display_attribs.push_back(EGL_FEATURE_OVERRIDES_ENABLED_ANGLE);
  180. display_attribs.push_back(
  181. reinterpret_cast<EGLAttrib>(enabled_features_attribs.data()));
  182. }
  183. if (!disabled_features_attribs.empty()) {
  184. display_attribs.push_back(EGL_FEATURE_OVERRIDES_DISABLED_ANGLE);
  185. display_attribs.push_back(
  186. reinterpret_cast<EGLAttrib>(disabled_features_attribs.data()));
  187. }
  188. }
  189. // TODO(dbehr) Add an attrib to Angle to pass EGL platform.
  190. if (g_driver_egl.client_ext.b_EGL_ANGLE_display_power_preference) {
  191. GpuPreference pref =
  192. GLSurface::AdjustGpuPreference(GpuPreference::kDefault);
  193. switch (pref) {
  194. case GpuPreference::kDefault:
  195. // Don't request any GPU, let ANGLE and the native driver decide.
  196. break;
  197. case GpuPreference::kLowPower:
  198. display_attribs.push_back(EGL_POWER_PREFERENCE_ANGLE);
  199. display_attribs.push_back(EGL_LOW_POWER_ANGLE);
  200. break;
  201. case GpuPreference::kHighPerformance:
  202. display_attribs.push_back(EGL_POWER_PREFERENCE_ANGLE);
  203. display_attribs.push_back(EGL_HIGH_POWER_ANGLE);
  204. break;
  205. default:
  206. NOTREACHED();
  207. }
  208. }
  209. display_attribs.push_back(EGL_NONE);
  210. // This is an EGL 1.5 function that we know ANGLE supports. It's used to pass
  211. // EGLAttribs (pointers) instead of EGLints into the display
  212. return eglGetPlatformDisplay(EGL_PLATFORM_ANGLE_ANGLE,
  213. reinterpret_cast<void*>(display),
  214. &display_attribs[0]);
  215. }
  216. EGLDisplay GetDisplayFromType(
  217. DisplayType display_type,
  218. EGLDisplayPlatform native_display,
  219. const std::vector<std::string>& enabled_angle_features,
  220. const std::vector<std::string>& disabled_angle_features,
  221. bool disable_all_angle_features,
  222. uint64_t system_device_id) {
  223. std::vector<EGLAttrib> extra_display_attribs;
  224. if (disable_all_angle_features) {
  225. extra_display_attribs.push_back(EGL_FEATURE_ALL_DISABLED_ANGLE);
  226. extra_display_attribs.push_back(EGL_TRUE);
  227. }
  228. if (system_device_id != 0 &&
  229. g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle_device_id) {
  230. uint32_t low_part = system_device_id & 0xffffffff;
  231. extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_ID_LOW_ANGLE);
  232. extra_display_attribs.push_back(low_part);
  233. uint32_t high_part = (system_device_id >> 32) & 0xffffffff;
  234. extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_ID_HIGH_ANGLE);
  235. extra_display_attribs.push_back(high_part);
  236. }
  237. EGLNativeDisplayType display = native_display.GetDisplay();
  238. switch (display_type) {
  239. case DEFAULT:
  240. case SWIFT_SHADER: {
  241. if (native_display.GetPlatform() != 0) {
  242. return eglGetPlatformDisplay(native_display.GetPlatform(),
  243. reinterpret_cast<void*>(display), nullptr);
  244. }
  245. return eglGetDisplay(display);
  246. }
  247. case ANGLE_D3D9:
  248. return GetPlatformANGLEDisplay(
  249. display, EGL_PLATFORM_ANGLE_TYPE_D3D9_ANGLE, enabled_angle_features,
  250. disabled_angle_features, extra_display_attribs);
  251. case ANGLE_D3D11:
  252. return GetPlatformANGLEDisplay(
  253. display, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, enabled_angle_features,
  254. disabled_angle_features, extra_display_attribs);
  255. case ANGLE_D3D11_NULL:
  256. extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
  257. extra_display_attribs.push_back(
  258. EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE);
  259. return GetPlatformANGLEDisplay(
  260. display, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, enabled_angle_features,
  261. disabled_angle_features, extra_display_attribs);
  262. case ANGLE_OPENGL:
  263. return GetPlatformANGLEDisplay(
  264. display, EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, enabled_angle_features,
  265. disabled_angle_features, extra_display_attribs);
  266. case ANGLE_OPENGL_EGL:
  267. extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
  268. extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE);
  269. return GetPlatformANGLEDisplay(
  270. display, EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, enabled_angle_features,
  271. disabled_angle_features, extra_display_attribs);
  272. case ANGLE_OPENGL_NULL:
  273. extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
  274. extra_display_attribs.push_back(
  275. EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE);
  276. return GetPlatformANGLEDisplay(
  277. display, EGL_PLATFORM_ANGLE_TYPE_OPENGL_ANGLE, enabled_angle_features,
  278. disabled_angle_features, extra_display_attribs);
  279. case ANGLE_OPENGLES:
  280. return GetPlatformANGLEDisplay(
  281. display, EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE,
  282. enabled_angle_features, disabled_angle_features,
  283. extra_display_attribs);
  284. case ANGLE_OPENGLES_EGL:
  285. extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
  286. extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_EGL_ANGLE);
  287. return GetPlatformANGLEDisplay(
  288. display, EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE,
  289. enabled_angle_features, disabled_angle_features,
  290. extra_display_attribs);
  291. case ANGLE_OPENGLES_NULL:
  292. extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
  293. extra_display_attribs.push_back(
  294. EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE);
  295. return GetPlatformANGLEDisplay(
  296. display, EGL_PLATFORM_ANGLE_TYPE_OPENGLES_ANGLE,
  297. enabled_angle_features, disabled_angle_features,
  298. extra_display_attribs);
  299. case ANGLE_NULL:
  300. return GetPlatformANGLEDisplay(
  301. display, EGL_PLATFORM_ANGLE_TYPE_NULL_ANGLE, enabled_angle_features,
  302. disabled_angle_features, extra_display_attribs);
  303. case ANGLE_VULKAN:
  304. return GetPlatformANGLEDisplay(
  305. display, EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE, enabled_angle_features,
  306. disabled_angle_features, extra_display_attribs);
  307. case ANGLE_VULKAN_NULL:
  308. extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
  309. extra_display_attribs.push_back(
  310. EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE);
  311. return GetPlatformANGLEDisplay(
  312. display, EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE, enabled_angle_features,
  313. disabled_angle_features, extra_display_attribs);
  314. case ANGLE_D3D11on12:
  315. extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_D3D11ON12_ANGLE);
  316. extra_display_attribs.push_back(EGL_TRUE);
  317. return GetPlatformANGLEDisplay(
  318. display, EGL_PLATFORM_ANGLE_TYPE_D3D11_ANGLE, enabled_angle_features,
  319. disabled_angle_features, extra_display_attribs);
  320. case ANGLE_SWIFTSHADER:
  321. extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
  322. extra_display_attribs.push_back(
  323. EGL_PLATFORM_ANGLE_DEVICE_TYPE_SWIFTSHADER_ANGLE);
  324. #if defined(USE_OZONE)
  325. #if BUILDFLAG(IS_CHROMEOS) && BUILDFLAG(OZONE_PLATFORM_X11)
  326. extra_display_attribs.push_back(
  327. EGL_PLATFORM_ANGLE_NATIVE_PLATFORM_TYPE_ANGLE);
  328. extra_display_attribs.push_back(
  329. EGL_PLATFORM_VULKAN_DISPLAY_MODE_HEADLESS_ANGLE);
  330. #endif // BUILDFLAG(OZONE_PLATFORM_X11)
  331. #endif // defined(USE_OZONE)
  332. return GetPlatformANGLEDisplay(
  333. display, EGL_PLATFORM_ANGLE_TYPE_VULKAN_ANGLE, enabled_angle_features,
  334. disabled_angle_features, extra_display_attribs);
  335. case ANGLE_METAL:
  336. return GetPlatformANGLEDisplay(
  337. display, EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE, enabled_angle_features,
  338. disabled_angle_features, extra_display_attribs);
  339. case ANGLE_METAL_NULL:
  340. extra_display_attribs.push_back(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE);
  341. extra_display_attribs.push_back(
  342. EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE);
  343. return GetPlatformANGLEDisplay(
  344. display, EGL_PLATFORM_ANGLE_TYPE_METAL_ANGLE, enabled_angle_features,
  345. disabled_angle_features, extra_display_attribs);
  346. default:
  347. NOTREACHED();
  348. return EGL_NO_DISPLAY;
  349. }
  350. }
  351. ANGLEImplementation GetANGLEImplementationFromDisplayType(
  352. DisplayType display_type) {
  353. switch (display_type) {
  354. case ANGLE_D3D9:
  355. return ANGLEImplementation::kD3D9;
  356. case ANGLE_D3D11:
  357. case ANGLE_D3D11_NULL:
  358. case ANGLE_D3D11on12:
  359. return ANGLEImplementation::kD3D11;
  360. case ANGLE_OPENGL:
  361. case ANGLE_OPENGL_NULL:
  362. return ANGLEImplementation::kOpenGL;
  363. case ANGLE_OPENGLES:
  364. case ANGLE_OPENGLES_NULL:
  365. return ANGLEImplementation::kOpenGLES;
  366. case ANGLE_NULL:
  367. return ANGLEImplementation::kNull;
  368. case ANGLE_VULKAN:
  369. case ANGLE_VULKAN_NULL:
  370. return ANGLEImplementation::kVulkan;
  371. case ANGLE_SWIFTSHADER:
  372. return ANGLEImplementation::kSwiftShader;
  373. case ANGLE_METAL:
  374. case ANGLE_METAL_NULL:
  375. return ANGLEImplementation::kMetal;
  376. default:
  377. return ANGLEImplementation::kNone;
  378. }
  379. }
  380. const char* DisplayTypeString(DisplayType display_type) {
  381. switch (display_type) {
  382. case DEFAULT:
  383. return "Default";
  384. case SWIFT_SHADER:
  385. return "SwiftShader";
  386. case ANGLE_D3D9:
  387. return "D3D9";
  388. case ANGLE_D3D11:
  389. return "D3D11";
  390. case ANGLE_D3D11_NULL:
  391. return "D3D11Null";
  392. case ANGLE_OPENGL:
  393. return "OpenGL";
  394. case ANGLE_OPENGL_NULL:
  395. return "OpenGLNull";
  396. case ANGLE_OPENGLES:
  397. return "OpenGLES";
  398. case ANGLE_OPENGLES_NULL:
  399. return "OpenGLESNull";
  400. case ANGLE_NULL:
  401. return "Null";
  402. case ANGLE_VULKAN:
  403. return "Vulkan";
  404. case ANGLE_VULKAN_NULL:
  405. return "VulkanNull";
  406. case ANGLE_D3D11on12:
  407. return "D3D11on12";
  408. case ANGLE_SWIFTSHADER:
  409. return "SwANGLE";
  410. case ANGLE_OPENGL_EGL:
  411. return "OpenGLEGL";
  412. case ANGLE_OPENGLES_EGL:
  413. return "OpenGLESEGL";
  414. case ANGLE_METAL:
  415. return "Metal";
  416. case ANGLE_METAL_NULL:
  417. return "MetalNull";
  418. default:
  419. NOTREACHED();
  420. return "Err";
  421. }
  422. }
  423. void AddInitDisplay(std::vector<DisplayType>* init_displays,
  424. DisplayType display_type) {
  425. // Make sure to not add the same display type twice.
  426. if (!base::Contains(*init_displays, display_type))
  427. init_displays->push_back(display_type);
  428. }
  429. const char* GetDebugMessageTypeString(EGLint source) {
  430. switch (source) {
  431. case EGL_DEBUG_MSG_CRITICAL_KHR:
  432. return "Critical";
  433. case EGL_DEBUG_MSG_ERROR_KHR:
  434. return "Error";
  435. case EGL_DEBUG_MSG_WARN_KHR:
  436. return "Warning";
  437. case EGL_DEBUG_MSG_INFO_KHR:
  438. return "Info";
  439. default:
  440. return "UNKNOWN";
  441. }
  442. }
  443. void EGLAPIENTRY LogEGLDebugMessage(EGLenum error,
  444. const char* command,
  445. EGLint message_type,
  446. EGLLabelKHR thread_label,
  447. EGLLabelKHR object_label,
  448. const char* message) {
  449. std::string formatted_message = std::string("EGL Driver message (") +
  450. GetDebugMessageTypeString(message_type) +
  451. ") " + command + ": " + message;
  452. // Assume that all labels that have been set are strings
  453. if (thread_label) {
  454. formatted_message += " thread: ";
  455. formatted_message += static_cast<const char*>(thread_label);
  456. }
  457. if (object_label) {
  458. formatted_message += " object: ";
  459. formatted_message += static_cast<const char*>(object_label);
  460. }
  461. if (message_type == EGL_DEBUG_MSG_CRITICAL_KHR ||
  462. message_type == EGL_DEBUG_MSG_ERROR_KHR) {
  463. LOG(ERROR) << formatted_message;
  464. } else {
  465. DVLOG(1) << formatted_message;
  466. }
  467. }
  468. void GetEGLInitDisplays(bool supports_angle_d3d,
  469. bool supports_angle_opengl,
  470. bool supports_angle_null,
  471. bool supports_angle_vulkan,
  472. bool supports_angle_swiftshader,
  473. bool supports_angle_egl,
  474. bool supports_angle_metal,
  475. const base::CommandLine* command_line,
  476. std::vector<DisplayType>* init_displays) {
  477. // If we're already requesting software GL, make sure we don't fallback to the
  478. // GPU
  479. bool forceSoftwareGL = IsSoftwareGLImplementation(GetGLImplementationParts());
  480. std::string requested_renderer =
  481. forceSoftwareGL ? kANGLEImplementationSwiftShaderName
  482. : command_line->GetSwitchValueASCII(switches::kUseANGLE);
  483. bool use_angle_default =
  484. !forceSoftwareGL &&
  485. (!command_line->HasSwitch(switches::kUseANGLE) ||
  486. requested_renderer == kANGLEImplementationDefaultName);
  487. if (supports_angle_null &&
  488. requested_renderer == kANGLEImplementationNullName) {
  489. AddInitDisplay(init_displays, ANGLE_NULL);
  490. return;
  491. }
  492. // If no display has been explicitly requested and the DefaultANGLEOpenGL
  493. // experiment is enabled, try creating OpenGL displays first.
  494. // TODO(oetuaho@nvidia.com): Only enable this path on specific GPUs with a
  495. // blocklist entry. http://crbug.com/693090
  496. if (supports_angle_opengl && use_angle_default &&
  497. base::FeatureList::IsEnabled(features::kDefaultANGLEOpenGL)) {
  498. AddInitDisplay(init_displays, ANGLE_OPENGL);
  499. AddInitDisplay(init_displays, ANGLE_OPENGLES);
  500. }
  501. if (supports_angle_metal && use_angle_default &&
  502. base::FeatureList::IsEnabled(features::kDefaultANGLEMetal)) {
  503. AddInitDisplay(init_displays, ANGLE_METAL);
  504. }
  505. if (supports_angle_vulkan && use_angle_default &&
  506. features::IsDefaultANGLEVulkan()) {
  507. AddInitDisplay(init_displays, ANGLE_VULKAN);
  508. }
  509. if (supports_angle_d3d) {
  510. if (use_angle_default) {
  511. // Default mode for ANGLE - try D3D11, else try D3D9
  512. if (!command_line->HasSwitch(switches::kDisableD3D11)) {
  513. AddInitDisplay(init_displays, ANGLE_D3D11);
  514. }
  515. AddInitDisplay(init_displays, ANGLE_D3D9);
  516. } else {
  517. if (requested_renderer == kANGLEImplementationD3D11Name) {
  518. AddInitDisplay(init_displays, ANGLE_D3D11);
  519. } else if (requested_renderer == kANGLEImplementationD3D9Name) {
  520. AddInitDisplay(init_displays, ANGLE_D3D9);
  521. } else if (requested_renderer == kANGLEImplementationD3D11NULLName) {
  522. AddInitDisplay(init_displays, ANGLE_D3D11_NULL);
  523. } else if (requested_renderer == kANGLEImplementationD3D11on12Name) {
  524. AddInitDisplay(init_displays, ANGLE_D3D11on12);
  525. }
  526. }
  527. }
  528. if (supports_angle_opengl) {
  529. if (use_angle_default && !supports_angle_d3d) {
  530. #if BUILDFLAG(IS_ANDROID)
  531. // Don't request desktopGL on android
  532. AddInitDisplay(init_displays, ANGLE_OPENGLES);
  533. #else
  534. AddInitDisplay(init_displays, ANGLE_OPENGL);
  535. AddInitDisplay(init_displays, ANGLE_OPENGLES);
  536. #endif // BUILDFLAG(IS_ANDROID)
  537. } else {
  538. if (requested_renderer == kANGLEImplementationOpenGLName) {
  539. AddInitDisplay(init_displays, ANGLE_OPENGL);
  540. } else if (requested_renderer == kANGLEImplementationOpenGLESName) {
  541. AddInitDisplay(init_displays, ANGLE_OPENGLES);
  542. } else if (requested_renderer == kANGLEImplementationOpenGLNULLName) {
  543. AddInitDisplay(init_displays, ANGLE_OPENGL_NULL);
  544. } else if (requested_renderer == kANGLEImplementationOpenGLESNULLName) {
  545. AddInitDisplay(init_displays, ANGLE_OPENGLES_NULL);
  546. } else if (requested_renderer == kANGLEImplementationOpenGLEGLName &&
  547. supports_angle_egl) {
  548. AddInitDisplay(init_displays, ANGLE_OPENGL_EGL);
  549. } else if (requested_renderer == kANGLEImplementationOpenGLESEGLName &&
  550. supports_angle_egl) {
  551. AddInitDisplay(init_displays, ANGLE_OPENGLES_EGL);
  552. }
  553. }
  554. }
  555. if (supports_angle_vulkan) {
  556. if (use_angle_default) {
  557. if (!supports_angle_d3d && !supports_angle_opengl) {
  558. AddInitDisplay(init_displays, ANGLE_VULKAN);
  559. }
  560. } else if (requested_renderer == kANGLEImplementationVulkanName) {
  561. AddInitDisplay(init_displays, ANGLE_VULKAN);
  562. } else if (requested_renderer == kANGLEImplementationVulkanNULLName) {
  563. AddInitDisplay(init_displays, ANGLE_VULKAN_NULL);
  564. }
  565. }
  566. if (supports_angle_swiftshader) {
  567. if (requested_renderer == kANGLEImplementationSwiftShaderName ||
  568. requested_renderer == kANGLEImplementationSwiftShaderForWebGLName) {
  569. AddInitDisplay(init_displays, ANGLE_SWIFTSHADER);
  570. }
  571. }
  572. if (supports_angle_metal) {
  573. if (use_angle_default) {
  574. if (!supports_angle_opengl) {
  575. AddInitDisplay(init_displays, ANGLE_METAL);
  576. }
  577. } else if (requested_renderer == kANGLEImplementationMetalName) {
  578. AddInitDisplay(init_displays, ANGLE_METAL);
  579. } else if (requested_renderer == kANGLEImplementationMetalNULLName) {
  580. AddInitDisplay(init_displays, ANGLE_METAL_NULL);
  581. }
  582. }
  583. // If no displays are available due to missing angle extensions or invalid
  584. // flags, request the default display.
  585. if (init_displays->empty()) {
  586. init_displays->push_back(DEFAULT);
  587. }
  588. }
  589. } // namespace
  590. void GetEGLInitDisplaysForTesting(bool supports_angle_d3d,
  591. bool supports_angle_opengl,
  592. bool supports_angle_null,
  593. bool supports_angle_vulkan,
  594. bool supports_angle_swiftshader,
  595. bool supports_angle_egl,
  596. bool supports_angle_metal,
  597. const base::CommandLine* command_line,
  598. std::vector<DisplayType>* init_displays) {
  599. GetEGLInitDisplays(supports_angle_d3d, supports_angle_opengl,
  600. supports_angle_null, supports_angle_vulkan,
  601. supports_angle_swiftshader, supports_angle_egl,
  602. supports_angle_metal, command_line, init_displays);
  603. }
  604. GLDisplay::GLDisplay(uint64_t system_device_id, DisplayPlatform type)
  605. : system_device_id_(system_device_id), type_(type) {}
  606. GLDisplay::~GLDisplay() = default;
  607. template <typename GLDisplayPlatform>
  608. GLDisplayPlatform* GLDisplay::GetAs() {
  609. bool type_checked = false;
  610. switch (type_) {
  611. case NONE:
  612. NOTREACHED();
  613. break;
  614. case EGL:
  615. #if defined(USE_EGL)
  616. type_checked = std::is_same<GLDisplayPlatform, GLDisplayEGL>::value;
  617. #endif // defined(USE_EGL)
  618. break;
  619. case X11:
  620. #if defined(USE_GLX)
  621. type_checked = std::is_same<GLDisplayPlatform, GLDisplayX11>::value;
  622. #endif // defined(USE_GLX)
  623. break;
  624. }
  625. if (type_checked)
  626. return static_cast<GLDisplayPlatform*>(this);
  627. return nullptr;
  628. }
  629. #if defined(USE_EGL)
  630. template EXPORT_TEMPLATE_DEFINE(GL_EXPORT)
  631. GLDisplayEGL* GLDisplay::GetAs<GLDisplayEGL>();
  632. #endif // defined(USE_EGL)
  633. #if defined(USE_GLX)
  634. template EXPORT_TEMPLATE_DEFINE(GL_EXPORT)
  635. GLDisplayX11* GLDisplay::GetAs<GLDisplayX11>();
  636. #endif // defined(USE_GLX)
  637. #if defined(USE_EGL)
  638. GLDisplayEGL::EGLGpuSwitchingObserver::EGLGpuSwitchingObserver(
  639. EGLDisplay display)
  640. : display_(display) {
  641. DCHECK(display != EGL_NO_DISPLAY);
  642. }
  643. void GLDisplayEGL::EGLGpuSwitchingObserver::OnGpuSwitched(
  644. GpuPreference active_gpu_heuristic) {
  645. eglHandleGPUSwitchANGLE(display_);
  646. }
  647. GLDisplayEGL::GLDisplayEGL(uint64_t system_device_id)
  648. : GLDisplay(system_device_id, EGL), display_(EGL_NO_DISPLAY) {
  649. ext = std::make_unique<DisplayExtensionsEGL>();
  650. }
  651. GLDisplayEGL::~GLDisplayEGL() = default;
  652. EGLDisplay GLDisplayEGL::GetDisplay() {
  653. return display_;
  654. }
  655. void GLDisplayEGL::Shutdown() {
  656. if (display_ == EGL_NO_DISPLAY)
  657. return;
  658. if (gpu_switching_observer_.get()) {
  659. ui::GpuSwitchingManager::GetInstance()->RemoveObserver(
  660. gpu_switching_observer_.get());
  661. gpu_switching_observer_.reset();
  662. }
  663. angle::ResetPlatform(display_);
  664. DCHECK(g_driver_egl.fn.eglTerminateFn);
  665. eglTerminate(display_);
  666. display_ = EGL_NO_DISPLAY;
  667. egl_surfaceless_context_supported_ = false;
  668. egl_context_priority_supported_ = false;
  669. egl_android_native_fence_sync_supported_ = false;
  670. }
  671. bool GLDisplayEGL::IsInitialized() {
  672. return display_ != EGL_NO_DISPLAY;
  673. }
  674. void GLDisplayEGL::SetDisplay(EGLDisplay display) {
  675. display_ = display;
  676. }
  677. EGLDisplayPlatform GLDisplayEGL::GetNativeDisplay() const {
  678. return native_display_;
  679. }
  680. DisplayType GLDisplayEGL::GetDisplayType() const {
  681. return display_type_;
  682. }
  683. // static
  684. GLDisplayEGL* GLDisplayEGL::GetDisplayForCurrentContext() {
  685. GLContext* context = GLContext::GetCurrent();
  686. return context ? context->GetGLDisplayEGL() : nullptr;
  687. }
  688. bool GLDisplayEGL::IsEGLSurfacelessContextSupported() {
  689. return egl_surfaceless_context_supported_;
  690. }
  691. bool GLDisplayEGL::IsEGLContextPrioritySupported() {
  692. return egl_context_priority_supported_;
  693. }
  694. bool GLDisplayEGL::IsAndroidNativeFenceSyncSupported() {
  695. return egl_android_native_fence_sync_supported_;
  696. }
  697. bool GLDisplayEGL::IsANGLEExternalContextAndSurfaceSupported() {
  698. return this->ext->b_EGL_ANGLE_external_context_and_surface;
  699. }
  700. bool GLDisplayEGL::Initialize(EGLDisplayPlatform native_display) {
  701. if (display_ != EGL_NO_DISPLAY)
  702. return true;
  703. if (!InitializeDisplay(native_display))
  704. return false;
  705. InitializeCommon();
  706. if (ext->b_EGL_ANGLE_power_preference) {
  707. gpu_switching_observer_ =
  708. std::make_unique<EGLGpuSwitchingObserver>(display_);
  709. ui::GpuSwitchingManager::GetInstance()->AddObserver(
  710. gpu_switching_observer_.get());
  711. }
  712. return true;
  713. }
  714. void GLDisplayEGL::InitializeForTesting() {
  715. display_ = eglGetCurrentDisplay();
  716. ext->InitializeExtensionSettings(display_);
  717. InitializeCommon();
  718. }
  719. bool GLDisplayEGL::InitializeExtensionSettings() {
  720. if (display_ == EGL_NO_DISPLAY)
  721. return false;
  722. ext->UpdateConditionalExtensionSettings(display_);
  723. return true;
  724. }
  725. // InitializeDisplay is necessary because the static binding code
  726. // needs a full Display init before it can query the Display extensions.
  727. bool GLDisplayEGL::InitializeDisplay(EGLDisplayPlatform native_display) {
  728. if (display_ != EGL_NO_DISPLAY)
  729. return true;
  730. native_display_ = native_display;
  731. bool supports_egl_debug = g_driver_egl.client_ext.b_EGL_KHR_debug;
  732. if (supports_egl_debug) {
  733. EGLAttrib controls[] = {
  734. EGL_DEBUG_MSG_CRITICAL_KHR,
  735. EGL_TRUE,
  736. EGL_DEBUG_MSG_ERROR_KHR,
  737. EGL_TRUE,
  738. EGL_DEBUG_MSG_WARN_KHR,
  739. EGL_TRUE,
  740. EGL_DEBUG_MSG_INFO_KHR,
  741. EGL_TRUE,
  742. EGL_NONE,
  743. EGL_NONE,
  744. };
  745. eglDebugMessageControlKHR(&LogEGLDebugMessage, controls);
  746. }
  747. bool supports_angle_d3d = false;
  748. bool supports_angle_opengl = false;
  749. bool supports_angle_null = false;
  750. bool supports_angle_vulkan = false;
  751. bool supports_angle_swiftshader = false;
  752. bool supports_angle_egl = false;
  753. bool supports_angle_metal = false;
  754. // Check for availability of ANGLE extensions.
  755. if (g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle) {
  756. supports_angle_d3d = g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle_d3d;
  757. supports_angle_opengl =
  758. g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle_opengl;
  759. supports_angle_null =
  760. g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle_null;
  761. supports_angle_vulkan =
  762. g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle_vulkan;
  763. supports_angle_swiftshader =
  764. g_driver_egl.client_ext
  765. .b_EGL_ANGLE_platform_angle_device_type_swiftshader;
  766. supports_angle_egl = g_driver_egl.client_ext
  767. .b_EGL_ANGLE_platform_angle_device_type_egl_angle;
  768. supports_angle_metal =
  769. g_driver_egl.client_ext.b_EGL_ANGLE_platform_angle_metal;
  770. }
  771. bool supports_angle = supports_angle_d3d || supports_angle_opengl ||
  772. supports_angle_null || supports_angle_vulkan ||
  773. supports_angle_swiftshader || supports_angle_metal;
  774. std::vector<DisplayType> init_displays;
  775. base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  776. GetEGLInitDisplays(supports_angle_d3d, supports_angle_opengl,
  777. supports_angle_null, supports_angle_vulkan,
  778. supports_angle_swiftshader, supports_angle_egl,
  779. supports_angle_metal, command_line, &init_displays);
  780. std::vector<std::string> enabled_angle_features =
  781. GetStringVectorFromCommandLine(command_line,
  782. switches::kEnableANGLEFeatures);
  783. std::vector<std::string> disabled_angle_features =
  784. GetStringVectorFromCommandLine(command_line,
  785. switches::kDisableANGLEFeatures);
  786. bool disable_all_angle_features =
  787. command_line->HasSwitch(switches::kDisableGpuDriverBugWorkarounds);
  788. for (size_t disp_index = 0; disp_index < init_displays.size(); ++disp_index) {
  789. DisplayType display_type = init_displays[disp_index];
  790. EGLDisplay display = GetDisplayFromType(
  791. display_type, native_display, enabled_angle_features,
  792. disabled_angle_features, disable_all_angle_features, system_device_id_);
  793. if (display == EGL_NO_DISPLAY) {
  794. LOG(ERROR) << "EGL display query failed with error "
  795. << GetLastEGLErrorString();
  796. }
  797. // Init ANGLE platform now that we have the global display.
  798. if (supports_angle) {
  799. if (!angle::InitializePlatform(display)) {
  800. LOG(ERROR) << "ANGLE Platform initialization failed.";
  801. }
  802. SetANGLEImplementation(
  803. GetANGLEImplementationFromDisplayType(display_type));
  804. }
  805. // The platform may need to unset its platform specific display env in case
  806. // of vulkan if the platform doesn't support Vulkan surface.
  807. absl::optional<base::ScopedEnvironmentVariableOverride> unset_display;
  808. if (display_type == ANGLE_VULKAN) {
  809. unset_display = GLDisplayEglUtil::GetInstance()
  810. ->MaybeGetScopedDisplayUnsetForVulkan();
  811. }
  812. if (!eglInitialize(display, nullptr, nullptr)) {
  813. bool is_last = disp_index == init_displays.size() - 1;
  814. LOG(ERROR) << "eglInitialize " << DisplayTypeString(display_type)
  815. << " failed with error " << GetLastEGLErrorString()
  816. << (is_last ? "" : ", trying next display type");
  817. continue;
  818. }
  819. std::ostringstream display_type_string;
  820. auto gl_implementation = GetGLImplementationParts();
  821. display_type_string << GetGLImplementationGLName(gl_implementation);
  822. if (gl_implementation.gl == kGLImplementationEGLANGLE) {
  823. display_type_string << ":" << DisplayTypeString(display_type);
  824. }
  825. static auto* egl_display_type_key = base::debug::AllocateCrashKeyString(
  826. "egl-display-type", base::debug::CrashKeySize::Size32);
  827. base::debug::SetCrashKeyString(egl_display_type_key,
  828. display_type_string.str());
  829. UMA_HISTOGRAM_ENUMERATION("GPU.EGLDisplayType", display_type,
  830. DISPLAY_TYPE_MAX);
  831. display_ = display;
  832. display_type_ = display_type;
  833. ext->InitializeExtensionSettings(display);
  834. return true;
  835. }
  836. return false;
  837. }
  838. void GLDisplayEGL::InitializeCommon() {
  839. // According to https://source.android.com/compatibility/android-cdd.html the
  840. // EGL_IMG_context_priority extension is mandatory for Virtual Reality High
  841. // Performance support, but due to a bug in Android Nougat the extension
  842. // isn't being reported even when it's present. As a fallback, check if other
  843. // related extensions that were added for VR support are present, and assume
  844. // that this implies context priority is also supported. See also:
  845. // https://github.com/googlevr/gvr-android-sdk/issues/330
  846. egl_context_priority_supported_ =
  847. ext->b_EGL_IMG_context_priority ||
  848. (ext->b_EGL_ANDROID_front_buffer_auto_refresh &&
  849. ext->b_EGL_ANDROID_create_native_client_buffer);
  850. // Check if SurfacelessEGL is supported.
  851. egl_surfaceless_context_supported_ = ext->b_EGL_KHR_surfaceless_context;
  852. // TODO(oetuaho@nvidia.com): Surfaceless is disabled on Android as a temporary
  853. // workaround, since code written for Android WebView takes different paths
  854. // based on whether GL surface objects have underlying EGL surface handles,
  855. // conflicting with the use of surfaceless. ANGLE can still expose surfacelss
  856. // because it is emulated with pbuffers if native support is not present. See
  857. // https://crbug.com/382349.
  858. #if BUILDFLAG(IS_ANDROID)
  859. // Use the WebGL compatibility extension for detecting ANGLE. ANGLE always
  860. // exposes it.
  861. bool is_angle = ext->b_EGL_ANGLE_create_context_webgl_compatibility;
  862. if (!is_angle) {
  863. egl_surfaceless_context_supported_ = false;
  864. }
  865. #endif // BUILDFLAG(IS_ANDROID)
  866. if (egl_surfaceless_context_supported_) {
  867. // EGL_KHR_surfaceless_context is supported but ensure
  868. // GL_OES_surfaceless_context is also supported. We need a current context
  869. // to query for supported GL extensions.
  870. scoped_refptr<GLSurface> surface =
  871. new SurfacelessEGL(this, gfx::Size(1, 1));
  872. scoped_refptr<GLContext> context = InitializeGLContext(
  873. new GLContextEGL(nullptr), surface.get(), GLContextAttribs());
  874. if (!context || !context->MakeCurrent(surface.get()))
  875. egl_surfaceless_context_supported_ = false;
  876. // Ensure context supports GL_OES_surfaceless_context.
  877. if (egl_surfaceless_context_supported_) {
  878. egl_surfaceless_context_supported_ =
  879. context->HasExtension("GL_OES_surfaceless_context");
  880. context->ReleaseCurrent(surface.get());
  881. }
  882. }
  883. // The native fence sync extension is a bit complicated. It's reported as
  884. // present for ChromeOS, but Android currently doesn't report this extension
  885. // even when it's present, and older devices and Android emulator may export
  886. // a useless wrapper function. See crbug.com/775707 for details. In short, if
  887. // the symbol is present and we're on Android N or newer and we are not on
  888. // Android emulator, assume that it's usable even if the extension wasn't
  889. // reported. TODO(https://crbug.com/1086781): Once this is fixed at the
  890. // Android level, update the heuristic to trust the reported extension from
  891. // that version onward.
  892. egl_android_native_fence_sync_supported_ =
  893. ext->b_EGL_ANDROID_native_fence_sync;
  894. #if BUILDFLAG(IS_ANDROID)
  895. if (!egl_android_native_fence_sync_supported_ &&
  896. base::android::BuildInfo::GetInstance()->sdk_int() >=
  897. base::android::SDK_VERSION_NOUGAT &&
  898. g_driver_egl.fn.eglDupNativeFenceFDANDROIDFn &&
  899. base::SysInfo::GetAndroidHardwareEGL() != "swiftshader" &&
  900. base::SysInfo::GetAndroidHardwareEGL() != "emulation") {
  901. egl_android_native_fence_sync_supported_ = true;
  902. }
  903. #endif // BUILDFLAG(IS_ANDROID)
  904. }
  905. #endif // defined(USE_EGL)
  906. #if defined(USE_GLX)
  907. GLDisplayX11::GLDisplayX11(uint64_t system_device_id)
  908. : GLDisplay(system_device_id, X11) {}
  909. GLDisplayX11::~GLDisplayX11() = default;
  910. void* GLDisplayX11::GetDisplay() {
  911. return x11::Connection::Get()->GetXlibDisplay();
  912. }
  913. void GLDisplayX11::Shutdown() {}
  914. bool GLDisplayX11::IsInitialized() {
  915. return true;
  916. }
  917. #endif // defined(USE_GLX)
  918. } // namespace gl