| 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 std::vector<int> attribs; |
| 52 if (GLSurfaceGLX::IsCreateContextRobustnessSupported()) { | 53 if (GLSurfaceGLX::IsCreateContextRobustnessSupported()) { |
| 53 DVLOG(1) << "GLX_ARB_create_context_robustness supported."; | 54 DVLOG(1) << "GLX_ARB_create_context_robustness supported."; |
| 54 | |
| 55 std::vector<int> attribs; | |
| 56 attribs.push_back(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); | 55 attribs.push_back(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB); |
| 57 attribs.push_back(GLX_LOSE_CONTEXT_ON_RESET_ARB); | 56 attribs.push_back(GLX_LOSE_CONTEXT_ON_RESET_ARB); |
| 58 attribs.push_back(0); | |
| 59 context_ = glXCreateContextAttribsARB( | |
| 60 display_, | |
| 61 static_cast<GLXFBConfig>(compatible_surface->GetConfig()), | |
| 62 share_handle, | |
| 63 True, | |
| 64 &attribs.front()); | |
| 65 if (context_) { | |
| 66 DVLOG(1) << " Successfully allocated " | |
| 67 << (compatible_surface->IsOffscreen() ? | |
| 68 "offscreen" : "onscreen") | |
| 69 << " GL context with LOSE_CONTEXT_ON_RESET_ARB"; | |
| 70 } else { | |
| 71 // TODO(kbr): it is not expected that things will work properly | |
| 72 // in this case, since we will likely allocate our offscreen | |
| 73 // contexts with this bit set and the onscreen contexts without, | |
| 74 // and won't be able to put them in the same share group. | |
| 75 // Consider what to do here; force loss of all contexts and | |
| 76 // reallocation without ARB_robustness? | |
| 77 LOG(ERROR) << | |
| 78 " FAILED to allocate GL context with LOSE_CONTEXT_ON_RESET_ARB"; | |
| 79 } | |
| 80 } | 57 } |
| 81 | 58 attribs.push_back(0); |
| 82 if (!context_) { | 59 context_ = glXCreateContextAttribsARB( |
| 83 // The means by which the context is created depends on whether | 60 display_, |
| 84 // the drawable type works reliably with GLX 1.3. If it does not | 61 static_cast<GLXFBConfig>(compatible_surface->GetConfig()), |
| 85 // then fall back to GLX 1.2. | 62 share_handle, |
| 86 if (compatible_surface->IsOffscreen()) { | 63 True, |
| 87 context_ = glXCreateNewContext( | 64 &attribs.front()); |
| 88 display_, | 65 if (context_) { |
| 89 static_cast<GLXFBConfig>(compatible_surface->GetConfig()), | 66 DVLOG(1) << " Successfully allocated " |
| 90 GLX_RGBA_TYPE, | 67 << (compatible_surface->IsOffscreen() ? |
| 91 share_handle, | 68 "offscreen" : "onscreen") |
| 92 True); | 69 << " GL context with LOSE_CONTEXT_ON_RESET_ARB"; |
| 93 } else { | 70 } else { |
| 94 // Get the visuals for the X drawable. | |
| 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."; | 71 LOG(ERROR) << "Couldn't create GL context."; |
| 132 return false; | 72 return false; |
| 133 } | 73 } |
| 134 | 74 |
| 135 DVLOG(1) << (compatible_surface->IsOffscreen() ? "Offscreen" : "Onscreen") | 75 DVLOG(1) << (compatible_surface->IsOffscreen() ? "Offscreen" : "Onscreen") |
| 136 << " context was " | 76 << " context was " |
| 137 << (glXIsDirect(display_, | 77 << (glXIsDirect(display_, |
| 138 static_cast<GLXContext>(context_)) | 78 static_cast<GLXContext>(context_)) |
| 139 ? "direct" : "indirect") | 79 ? "direct" : "indirect") |
| 140 << "."; | 80 << "."; |
| 141 | 81 |
| 142 return true; | 82 return true; |
| 143 } | 83 } |
| 144 | 84 |
| 145 void GLContextGLX::Destroy() { | 85 void GLContextGLX::Destroy() { |
| 146 if (context_) { | 86 if (context_) { |
| 147 glXDestroyContext(display_, | 87 glXDestroyContext(display_, |
| 148 static_cast<GLXContext>(context_)); | 88 static_cast<GLXContext>(context_)); |
| 149 context_ = NULL; | 89 context_ = NULL; |
| 150 } | 90 } |
| 151 } | 91 } |
| 152 | 92 |
| 153 bool GLContextGLX::MakeCurrent(GLSurface* surface) { | 93 bool GLContextGLX::MakeCurrent(GLSurface* surface) { |
| 154 DCHECK(context_); | 94 DCHECK(context_); |
| 155 if (IsCurrent(surface)) | 95 if (IsCurrent(surface)) |
| 156 return true; | 96 return true; |
| 157 | 97 |
| 158 TRACE_EVENT0("gpu", "GLContextGLX::MakeCurrent"); | 98 TRACE_EVENT0("gpu", "GLContextGLX::MakeCurrent"); |
| 159 if (!glXMakeCurrent( | 99 if (!glXMakeContextCurrent( |
| 160 display_, | 100 display_, |
| 161 reinterpret_cast<GLXDrawable>(surface->GetHandle()), | 101 reinterpret_cast<GLXDrawable>(surface->GetHandle()), |
| 102 reinterpret_cast<GLXDrawable>(surface->GetHandle()), |
| 162 static_cast<GLXContext>(context_))) { | 103 static_cast<GLXContext>(context_))) { |
| 163 LOG(ERROR) << "Couldn't make context current with X drawable."; | 104 LOG(ERROR) << "Couldn't make context current with X drawable."; |
| 164 Destroy(); | 105 Destroy(); |
| 165 return false; | 106 return false; |
| 166 } | 107 } |
| 167 | 108 |
| 168 SetCurrent(this, surface); | 109 SetCurrent(this, surface); |
| 169 if (!InitializeExtensionBindings()) { | 110 if (!InitializeExtensionBindings()) { |
| 170 ReleaseCurrent(surface); | 111 ReleaseCurrent(surface); |
| 171 Destroy(); | 112 Destroy(); |
| 172 return false; | 113 return false; |
| 173 } | 114 } |
| 174 | 115 |
| 175 if (!surface->OnMakeCurrent(this)) { | 116 if (!surface->OnMakeCurrent(this)) { |
| 176 LOG(ERROR) << "Could not make current."; | 117 LOG(ERROR) << "Could not make current."; |
| 177 ReleaseCurrent(surface); | 118 ReleaseCurrent(surface); |
| 178 Destroy(); | 119 Destroy(); |
| 179 return false; | 120 return false; |
| 180 } | 121 } |
| 181 | 122 |
| 182 SetRealGLApi(); | 123 SetRealGLApi(); |
| 183 return true; | 124 return true; |
| 184 } | 125 } |
| 185 | 126 |
| 186 void GLContextGLX::ReleaseCurrent(GLSurface* surface) { | 127 void GLContextGLX::ReleaseCurrent(GLSurface* surface) { |
| 187 if (!IsCurrent(surface)) | 128 if (!IsCurrent(surface)) |
| 188 return; | 129 return; |
| 189 | 130 |
| 190 SetCurrent(NULL, NULL); | 131 SetCurrent(NULL, NULL); |
| 191 if (!glXMakeCurrent(display_, 0, 0)) | 132 if (!glXMakeContextCurrent(display_, 0, 0, 0)) |
| 192 LOG(ERROR) << "glXMakeCurrent failed in ReleaseCurrent"; | 133 LOG(ERROR) << "glXMakeCurrent failed in ReleaseCurrent"; |
| 193 } | 134 } |
| 194 | 135 |
| 195 bool GLContextGLX::IsCurrent(GLSurface* surface) { | 136 bool GLContextGLX::IsCurrent(GLSurface* surface) { |
| 196 bool native_context_is_current = | 137 bool native_context_is_current = |
| 197 glXGetCurrentContext() == static_cast<GLXContext>(context_); | 138 glXGetCurrentContext() == static_cast<GLXContext>(context_); |
| 198 | 139 |
| 199 // If our context is current then our notion of which GLContext is | 140 // If our context is current then our notion of which GLContext is |
| 200 // current must be correct. On the other hand, third-party code | 141 // current must be correct. On the other hand, third-party code |
| 201 // using OpenGL might change the current context. | 142 // using OpenGL might change the current context. |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 261 | 202 |
| 262 bool GLContextGLX::WasAllocatedUsingRobustnessExtension() { | 203 bool GLContextGLX::WasAllocatedUsingRobustnessExtension() { |
| 263 return GLSurfaceGLX::IsCreateContextRobustnessSupported(); | 204 return GLSurfaceGLX::IsCreateContextRobustnessSupported(); |
| 264 } | 205 } |
| 265 | 206 |
| 266 GLContextGLX::~GLContextGLX() { | 207 GLContextGLX::~GLContextGLX() { |
| 267 Destroy(); | 208 Destroy(); |
| 268 } | 209 } |
| 269 | 210 |
| 270 } // namespace gfx | 211 } // namespace gfx |
| OLD | NEW |