| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gl/gl_context_glx.h" | 5 #include "ui/gl/gl_context_glx.h" |
| 6 | 6 |
| 7 extern "C" { | 7 extern "C" { |
| 8 #include <X11/Xlib.h> | 8 #include <X11/Xlib.h> |
| 9 } | 9 } |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 GLXContext context = | 64 GLXContext context = |
| 65 glXCreateContextAttribsARB(display, config, share, True, attribs.data()); | 65 glXCreateContextAttribsARB(display, config, share, True, attribs.data()); |
| 66 XSetErrorHandler(old_error_handler); | 66 XSetErrorHandler(old_error_handler); |
| 67 | 67 |
| 68 return context; | 68 return context; |
| 69 } | 69 } |
| 70 | 70 |
| 71 GLXContext CreateHighestVersionContext(Display* display, | 71 GLXContext CreateHighestVersionContext(Display* display, |
| 72 GLXFBConfig config, | 72 GLXFBConfig config, |
| 73 GLXContext share) { | 73 GLXContext share) { |
| 74 // It is commonly assumed that glXCreateContextAttrib will create a context | 74 // The only way to get a core profile context of the highest version using |
| 75 // of the highest version possible but it is not specified in the spec and | 75 // glXCreateContextAttrib is to try creationg contexts in decreasing version |
| 76 // is not true on the Mesa drivers. On Mesa, Instead we try to create a | 76 // numbers. It might look that asking for a core context of version (0, 0) |
| 77 // context per GL version until we succeed, starting from newer version. | 77 // works on some driver but it create a _compatibility_ context of the highest |
| 78 // On both Mesa and other drivers we try to create a desktop context and fall | 78 // version instead. The cost of failing a context creation is small (< 0.1 ms) |
| 79 // back to ES context. | 79 // on Mesa but is unfortunately a bit expensive on the Nvidia driver (~3ms). |
| 80 // The code could be simpler if the Mesa code path was used for all drivers, | 80 |
| 81 // however the cost of failing a context creation can be high (3 milliseconds | 81 // Also try to get any Desktop GL context, but if that fails fallback to |
| 82 // for the NVIDIA driver). The good thing is that failed context creation only | 82 // asking for OpenGL ES contexts. |
| 83 // takes 0.1 milliseconds on Mesa. | 83 |
| 84 std::string client_vendor = glXGetClientString(display, GLX_VENDOR); |
| 85 bool is_mesa = client_vendor.find("Mesa") != std::string::npos; |
| 84 | 86 |
| 85 struct ContextCreationInfo { | 87 struct ContextCreationInfo { |
| 88 ContextCreationInfo(int profileFlag, GLVersion version) |
| 89 : profileFlag(profileFlag), version(version) {} |
| 86 int profileFlag; | 90 int profileFlag; |
| 87 GLVersion version; | 91 GLVersion version; |
| 88 }; | 92 }; |
| 89 | 93 |
| 90 // clang-format off | 94 std::vector<ContextCreationInfo> contexts_to_try; |
| 91 // For regular drivers we try to create a compatibility, core, then ES | 95 contexts_to_try.emplace_back(GLX_CONTEXT_CORE_PROFILE_BIT_ARB, |
| 92 // context. Without requiring any specific version. | 96 GLVersion(4, 5)); |
| 93 const ContextCreationInfo contexts_to_try[] = { | 97 contexts_to_try.emplace_back(GLX_CONTEXT_CORE_PROFILE_BIT_ARB, |
| 94 { 0, GLVersion(0, 0) }, | 98 GLVersion(4, 4)); |
| 95 { GLX_CONTEXT_CORE_PROFILE_BIT_ARB, GLVersion(0, 0) }, | 99 contexts_to_try.emplace_back(GLX_CONTEXT_CORE_PROFILE_BIT_ARB, |
| 96 { GLX_CONTEXT_ES2_PROFILE_BIT_EXT, GLVersion(0, 0) }, | 100 GLVersion(4, 3)); |
| 97 }; | 101 contexts_to_try.emplace_back(GLX_CONTEXT_CORE_PROFILE_BIT_ARB, |
| 102 GLVersion(4, 2)); |
| 103 contexts_to_try.emplace_back(GLX_CONTEXT_CORE_PROFILE_BIT_ARB, |
| 104 GLVersion(4, 1)); |
| 105 contexts_to_try.emplace_back(GLX_CONTEXT_CORE_PROFILE_BIT_ARB, |
| 106 GLVersion(4, 0)); |
| 107 contexts_to_try.emplace_back(GLX_CONTEXT_CORE_PROFILE_BIT_ARB, |
| 108 GLVersion(3, 3)); |
| 98 | 109 |
| 99 // On Mesa we try to create a core context, except for versions below 3.2 | 110 // On Mesa, do not try to create OpenGL context versions between 3.0 and |
| 100 // where it is not applicable. (and fallback to ES as well) | 111 // 3.2 because of compatibility problems. See crbug.com/659030 |
| 101 const ContextCreationInfo mesa_contexts_to_try[] = { | 112 if (!is_mesa) { |
| 102 { GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { GLVersion(4, 5) } }, | 113 contexts_to_try.emplace_back(0, GLVersion(3, 2)); |
| 103 { GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { GLVersion(4, 4) } }, | 114 contexts_to_try.emplace_back(0, GLVersion(3, 1)); |
| 104 { GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { GLVersion(4, 3) } }, | 115 contexts_to_try.emplace_back(0, GLVersion(3, 0)); |
| 105 { GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { GLVersion(4, 2) } }, | |
| 106 { GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { GLVersion(4, 1) } }, | |
| 107 { GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { GLVersion(4, 0) } }, | |
| 108 { GLX_CONTEXT_CORE_PROFILE_BIT_ARB, { GLVersion(3, 3) } }, | |
| 109 // Do not try to create OpenGL context versions between 3.0 and | |
| 110 // 3.2 because of compatibility problems. crbug.com/659030 | |
| 111 { 0, { GLVersion(2, 0) } }, | |
| 112 { 0, { GLVersion(1, 5) } }, | |
| 113 { 0, { GLVersion(1, 4) } }, | |
| 114 { 0, { GLVersion(1, 3) } }, | |
| 115 { 0, { GLVersion(1, 2) } }, | |
| 116 { 0, { GLVersion(1, 1) } }, | |
| 117 { 0, { GLVersion(1, 0) } }, | |
| 118 { GLX_CONTEXT_ES2_PROFILE_BIT_EXT, { GLVersion(3, 2) } }, | |
| 119 { GLX_CONTEXT_ES2_PROFILE_BIT_EXT, { GLVersion(3, 1) } }, | |
| 120 { GLX_CONTEXT_ES2_PROFILE_BIT_EXT, { GLVersion(3, 0) } }, | |
| 121 { GLX_CONTEXT_ES2_PROFILE_BIT_EXT, { GLVersion(2, 0) } }, | |
| 122 }; | |
| 123 // clang-format on | |
| 124 | |
| 125 std::string client_vendor = glXGetClientString(display, GLX_VENDOR); | |
| 126 bool is_mesa = client_vendor.find("Mesa") != std::string::npos; | |
| 127 | |
| 128 const ContextCreationInfo* to_try = contexts_to_try; | |
| 129 size_t to_try_length = arraysize(contexts_to_try); | |
| 130 if (is_mesa) { | |
| 131 to_try = mesa_contexts_to_try; | |
| 132 to_try_length = arraysize(mesa_contexts_to_try); | |
| 133 } | 116 } |
| 134 | 117 |
| 135 for (size_t i = 0; i < to_try_length; ++i) { | 118 contexts_to_try.emplace_back(0, GLVersion(2, 1)); |
| 136 const ContextCreationInfo& info = to_try[i]; | 119 contexts_to_try.emplace_back(0, GLVersion(2, 0)); |
| 120 contexts_to_try.emplace_back(0, GLVersion(1, 5)); |
| 121 contexts_to_try.emplace_back(0, GLVersion(1, 4)); |
| 122 contexts_to_try.emplace_back(0, GLVersion(1, 3)); |
| 123 contexts_to_try.emplace_back(0, GLVersion(1, 2)); |
| 124 contexts_to_try.emplace_back(0, GLVersion(1, 1)); |
| 125 contexts_to_try.emplace_back(0, GLVersion(1, 0)); |
| 126 contexts_to_try.emplace_back(GLX_CONTEXT_ES2_PROFILE_BIT_EXT, |
| 127 GLVersion(3, 2)); |
| 128 contexts_to_try.emplace_back(GLX_CONTEXT_ES2_PROFILE_BIT_EXT, |
| 129 GLVersion(3, 1)); |
| 130 contexts_to_try.emplace_back(GLX_CONTEXT_ES2_PROFILE_BIT_EXT, |
| 131 GLVersion(3, 0)); |
| 132 contexts_to_try.emplace_back(GLX_CONTEXT_ES2_PROFILE_BIT_EXT, |
| 133 GLVersion(2, 0)); |
| 134 |
| 135 for (const auto& info : contexts_to_try) { |
| 137 if (!GLSurfaceGLX::IsCreateContextES2ProfileSupported() && | 136 if (!GLSurfaceGLX::IsCreateContextES2ProfileSupported() && |
| 138 info.profileFlag == GLX_CONTEXT_ES2_PROFILE_BIT_EXT) { | 137 info.profileFlag == GLX_CONTEXT_ES2_PROFILE_BIT_EXT) { |
| 139 continue; | 138 continue; |
| 140 } | 139 } |
| 141 GLXContext context = CreateContextAttribs(display, config, share, | 140 GLXContext context = CreateContextAttribs(display, config, share, |
| 142 info.version, info.profileFlag); | 141 info.version, info.profileFlag); |
| 143 if (context != nullptr) { | 142 if (context != nullptr) { |
| 144 return context; | 143 return context; |
| 145 } | 144 } |
| 146 } | 145 } |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 324 | 323 |
| 325 bool GLContextGLX::WasAllocatedUsingRobustnessExtension() { | 324 bool GLContextGLX::WasAllocatedUsingRobustnessExtension() { |
| 326 return GLSurfaceGLX::IsCreateContextRobustnessSupported(); | 325 return GLSurfaceGLX::IsCreateContextRobustnessSupported(); |
| 327 } | 326 } |
| 328 | 327 |
| 329 GLContextGLX::~GLContextGLX() { | 328 GLContextGLX::~GLContextGLX() { |
| 330 Destroy(); | 329 Destroy(); |
| 331 } | 330 } |
| 332 | 331 |
| 333 } // namespace gl | 332 } // namespace gl |
| OLD | NEW |