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 |