Chromium Code Reviews| 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 extern "C" { | 5 extern "C" { |
| 6 #include <X11/Xlib.h> | 6 #include <X11/Xlib.h> |
| 7 } | 7 } |
| 8 | 8 |
| 9 #include "ui/gl/gl_context_glx.h" | 9 #include "ui/gl/gl_context_glx.h" |
| 10 | 10 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 42 return display_; | 42 return display_; |
| 43 } | 43 } |
| 44 | 44 |
| 45 bool GLContextGLX::Initialize( | 45 bool GLContextGLX::Initialize( |
| 46 GLSurface* compatible_surface, GpuPreference gpu_preference) { | 46 GLSurface* compatible_surface, GpuPreference gpu_preference) { |
| 47 display_ = static_cast<Display*>(compatible_surface->GetDisplay()); | 47 display_ = static_cast<Display*>(compatible_surface->GetDisplay()); |
| 48 | 48 |
| 49 GLXContext share_handle = static_cast<GLXContext>( | 49 GLXContext share_handle = static_cast<GLXContext>( |
| 50 share_group() ? share_group()->GetHandle() : NULL); | 50 share_group() ? share_group()->GetHandle() : NULL); |
| 51 | 51 |
| 52 if (GLSurfaceGLX::IsCreateContextRobustnessSupported()) { | 52 if (GLSurfaceGLX::IsCreateContextSupported()) { |
| 53 DVLOG(1) << "GLX_ARB_create_context_robustness supported."; | 53 DVLOG(1) << "GLX_ARB_create_context supported."; |
| 54 | |
| 55 std::vector<int> attribs; | 54 std::vector<int> attribs; |
| 56 attribs.push_back(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); | 55 if (GLSurfaceGLX::IsCreateContextRobustnessSupported()) { |
| 57 attribs.push_back(GLX_LOSE_CONTEXT_ON_RESET_ARB); | 56 DVLOG(1) << "GLX_ARB_create_context_robustness supported."; |
| 57 attribs.push_back(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); | |
| 58 attribs.push_back(GLX_LOSE_CONTEXT_ON_RESET_ARB); | |
| 59 } | |
| 58 attribs.push_back(0); | 60 attribs.push_back(0); |
| 59 context_ = glXCreateContextAttribsARB( | 61 context_ = glXCreateContextAttribsARB( |
| 60 display_, | 62 display_, |
| 61 static_cast<GLXFBConfig>(compatible_surface->GetConfig()), | 63 static_cast<GLXFBConfig>(compatible_surface->GetConfig()), |
| 62 share_handle, | 64 share_handle, |
| 63 True, | 65 True, |
| 64 &attribs.front()); | 66 &attribs.front()); |
| 65 if (context_) { | 67 if (!context_) { |
| 66 DVLOG(1) << " Successfully allocated " | 68 LOG(ERROR) << "Failed to create GL context with " |
| 67 << (compatible_surface->IsOffscreen() ? | 69 << "glXCreateContextAttribsARB."; |
| 68 "offscreen" : "onscreen") | 70 return false; |
| 69 << " GL context with LOSE_CONTEXT_ON_RESET_ARB"; | 71 } |
| 70 } else { | 72 } else { |
| 71 // TODO(kbr): it is not expected that things will work properly | 73 DVLOG(1) << "GLX_ARB_create_context not supported."; |
| 72 // in this case, since we will likely allocate our offscreen | 74 context_ = glXCreateNewContext( |
| 73 // contexts with this bit set and the onscreen contexts without, | 75 display_, |
| 74 // and won't be able to put them in the same share group. | 76 static_cast<GLXFBConfig>(compatible_surface->GetConfig()), |
| 75 // Consider what to do here; force loss of all contexts and | 77 GLX_RGBA_TYPE, |
| 76 // reallocation without ARB_robustness? | 78 share_handle, |
| 77 LOG(ERROR) << | 79 True); |
| 78 " FAILED to allocate GL context with LOSE_CONTEXT_ON_RESET_ARB"; | 80 if (!context_) { |
| 81 LOG(ERROR) << "Failed to create GL context with glXCreateNewContext."; | |
| 82 return false; | |
| 79 } | 83 } |
| 80 } | 84 } |
| 81 | 85 DCHECK(context_); |
| 82 if (!context_) { | 86 DVLOG(1) << " Successfully allocated " |
| 83 // The means by which the context is created depends on whether | 87 << (compatible_surface->IsOffscreen() ? |
| 84 // the drawable type works reliably with GLX 1.3. If it does not | 88 "offscreen" : "onscreen") |
| 85 // then fall back to GLX 1.2. | 89 << " GL context with LOSE_CONTEXT_ON_RESET_ARB"; |
| 86 if (compatible_surface->IsOffscreen()) { | |
| 87 context_ = glXCreateNewContext( | |
| 88 display_, | |
| 89 static_cast<GLXFBConfig>(compatible_surface->GetConfig()), | |
| 90 GLX_RGBA_TYPE, | |
| 91 share_handle, | |
| 92 True); | |
| 93 } else { | |
| 94 // Get the visuals for the X drawable. | |
|
Ken Russell (switch to Gerrit)
2012/12/08 20:10:57
If the last patch didn't work on all clients then
ccameron
2012/12/10 00:28:06
For the failures that we looked into, they were al
Ken Russell (switch to Gerrit)
2012/12/10 18:44:51
My concern was whether GLSurface::GetConfig worked
| |
| 95 XWindowAttributes attributes; | |
| 96 if (!XGetWindowAttributes( | |
| 97 display_, | |
| 98 reinterpret_cast<GLXDrawable>(compatible_surface->GetHandle()), | |
| 99 &attributes)) { | |
| 100 LOG(ERROR) << "XGetWindowAttributes failed for window " << | |
| 101 reinterpret_cast<GLXDrawable>( | |
| 102 compatible_surface->GetHandle()) << "."; | |
| 103 return false; | |
| 104 } | |
| 105 | |
| 106 XVisualInfo visual_info_template; | |
| 107 visual_info_template.visualid = XVisualIDFromVisual(attributes.visual); | |
| 108 | |
| 109 int visual_info_count = 0; | |
| 110 scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visual_info_list( | |
| 111 XGetVisualInfo(display_, VisualIDMask, | |
| 112 &visual_info_template, | |
| 113 &visual_info_count)); | |
| 114 | |
| 115 DCHECK(visual_info_list.get()); | |
| 116 if (visual_info_count == 0) { | |
| 117 LOG(ERROR) << "No visual info for visual ID."; | |
| 118 return false; | |
| 119 } | |
| 120 | |
| 121 // Attempt to create a context with each visual in turn until one works. | |
| 122 context_ = glXCreateContext( | |
| 123 display_, | |
| 124 visual_info_list.get(), | |
| 125 share_handle, | |
| 126 True); | |
| 127 } | |
| 128 } | |
| 129 | |
| 130 if (!context_) { | |
| 131 LOG(ERROR) << "Couldn't create GL context."; | |
| 132 return false; | |
| 133 } | |
| 134 | 90 |
| 135 DVLOG(1) << (compatible_surface->IsOffscreen() ? "Offscreen" : "Onscreen") | 91 DVLOG(1) << (compatible_surface->IsOffscreen() ? "Offscreen" : "Onscreen") |
| 136 << " context was " | 92 << " context was " |
| 137 << (glXIsDirect(display_, | 93 << (glXIsDirect(display_, |
| 138 static_cast<GLXContext>(context_)) | 94 static_cast<GLXContext>(context_)) |
| 139 ? "direct" : "indirect") | 95 ? "direct" : "indirect") |
| 140 << "."; | 96 << "."; |
| 141 | 97 |
| 142 return true; | 98 return true; |
| 143 } | 99 } |
| 144 | 100 |
| 145 void GLContextGLX::Destroy() { | 101 void GLContextGLX::Destroy() { |
| 146 if (context_) { | 102 if (context_) { |
| 147 glXDestroyContext(display_, | 103 glXDestroyContext(display_, |
| 148 static_cast<GLXContext>(context_)); | 104 static_cast<GLXContext>(context_)); |
| 149 context_ = NULL; | 105 context_ = NULL; |
| 150 } | 106 } |
| 151 } | 107 } |
| 152 | 108 |
| 153 bool GLContextGLX::MakeCurrent(GLSurface* surface) { | 109 bool GLContextGLX::MakeCurrent(GLSurface* surface) { |
| 154 DCHECK(context_); | 110 DCHECK(context_); |
| 155 if (IsCurrent(surface)) | 111 if (IsCurrent(surface)) |
| 156 return true; | 112 return true; |
| 157 | 113 |
| 158 TRACE_EVENT0("gpu", "GLContextGLX::MakeCurrent"); | 114 TRACE_EVENT0("gpu", "GLContextGLX::MakeCurrent"); |
| 159 if (!glXMakeCurrent( | 115 if (!glXMakeContextCurrent( |
| 160 display_, | 116 display_, |
| 161 reinterpret_cast<GLXDrawable>(surface->GetHandle()), | 117 reinterpret_cast<GLXDrawable>(surface->GetHandle()), |
| 118 reinterpret_cast<GLXDrawable>(surface->GetHandle()), | |
| 162 static_cast<GLXContext>(context_))) { | 119 static_cast<GLXContext>(context_))) { |
| 163 LOG(ERROR) << "Couldn't make context current with X drawable."; | 120 LOG(ERROR) << "Couldn't make context current with X drawable."; |
| 164 Destroy(); | 121 Destroy(); |
| 165 return false; | 122 return false; |
| 166 } | 123 } |
| 167 | 124 |
| 168 SetCurrent(this, surface); | 125 SetCurrent(this, surface); |
| 169 if (!InitializeExtensionBindings()) { | 126 if (!InitializeExtensionBindings()) { |
| 170 ReleaseCurrent(surface); | 127 ReleaseCurrent(surface); |
| 171 Destroy(); | 128 Destroy(); |
| 172 return false; | 129 return false; |
| 173 } | 130 } |
| 174 | 131 |
| 175 if (!surface->OnMakeCurrent(this)) { | 132 if (!surface->OnMakeCurrent(this)) { |
| 176 LOG(ERROR) << "Could not make current."; | 133 LOG(ERROR) << "Could not make current."; |
| 177 ReleaseCurrent(surface); | 134 ReleaseCurrent(surface); |
| 178 Destroy(); | 135 Destroy(); |
| 179 return false; | 136 return false; |
| 180 } | 137 } |
| 181 | 138 |
| 182 SetRealGLApi(); | 139 SetRealGLApi(); |
| 183 return true; | 140 return true; |
| 184 } | 141 } |
| 185 | 142 |
| 186 void GLContextGLX::ReleaseCurrent(GLSurface* surface) { | 143 void GLContextGLX::ReleaseCurrent(GLSurface* surface) { |
| 187 if (!IsCurrent(surface)) | 144 if (!IsCurrent(surface)) |
| 188 return; | 145 return; |
| 189 | 146 |
| 190 SetCurrent(NULL, NULL); | 147 SetCurrent(NULL, NULL); |
| 191 if (!glXMakeCurrent(display_, 0, 0)) | 148 if (!glXMakeContextCurrent(display_, 0, 0, 0)) |
| 192 LOG(ERROR) << "glXMakeCurrent failed in ReleaseCurrent"; | 149 LOG(ERROR) << "glXMakeCurrent failed in ReleaseCurrent"; |
| 193 } | 150 } |
| 194 | 151 |
| 195 bool GLContextGLX::IsCurrent(GLSurface* surface) { | 152 bool GLContextGLX::IsCurrent(GLSurface* surface) { |
| 196 bool native_context_is_current = | 153 bool native_context_is_current = |
| 197 glXGetCurrentContext() == static_cast<GLXContext>(context_); | 154 glXGetCurrentContext() == static_cast<GLXContext>(context_); |
| 198 | 155 |
| 199 // If our context is current then our notion of which GLContext is | 156 // If our context is current then our notion of which GLContext is |
| 200 // current must be correct. On the other hand, third-party code | 157 // current must be correct. On the other hand, third-party code |
| 201 // using OpenGL might change the current context. | 158 // using OpenGL might change the current context. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 261 | 218 |
| 262 bool GLContextGLX::WasAllocatedUsingRobustnessExtension() { | 219 bool GLContextGLX::WasAllocatedUsingRobustnessExtension() { |
| 263 return GLSurfaceGLX::IsCreateContextRobustnessSupported(); | 220 return GLSurfaceGLX::IsCreateContextRobustnessSupported(); |
| 264 } | 221 } |
| 265 | 222 |
| 266 GLContextGLX::~GLContextGLX() { | 223 GLContextGLX::~GLContextGLX() { |
| 267 Destroy(); | 224 Destroy(); |
| 268 } | 225 } |
| 269 | 226 |
| 270 } // namespace gfx | 227 } // namespace gfx |
| OLD | NEW |