Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1149)

Side by Side Diff: gpu/command_buffer/service/x_utils.cc

Issue 1540004: Implemented offscreen rendering path for GLES2CmdDecoder on Linux.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « gpu/command_buffer/service/x_utils.h ('k') | third_party/glew/README.chromium » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2009 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 // This class implements the XWindowWrapper class. 5 // This class implements the XWindowWrapper class.
6 6
7 #include <dlfcn.h> 7 #include <dlfcn.h>
8 8
9 #include "base/scoped_ptr.h"
9 #include "gpu/command_buffer/service/precompile.h" 10 #include "gpu/command_buffer/service/precompile.h"
10 #include "gpu/command_buffer/common/logging.h" 11 #include "gpu/command_buffer/common/logging.h"
11 #include "gpu/command_buffer/service/x_utils.h" 12 #include "gpu/command_buffer/service/x_utils.h"
12 13
13 namespace gpu { 14 namespace gpu {
14 15
16 // scoped_ptr functor for XFree(). Use as follows:
17 // scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...);
18 // where "XVisualInfo" is any X type that is freed with XFree.
19 class ScopedPtrXFree {
20 public:
21 void operator()(void* x) const {
22 ::XFree(x);
23 }
24 };
25
15 // Some versions of NVIDIA's GL libGL.so include a broken version of 26 // Some versions of NVIDIA's GL libGL.so include a broken version of
16 // dlopen/dlsym, and so linking it into chrome breaks it. So we dynamically 27 // dlopen/dlsym, and so linking it into chrome breaks it. So we dynamically
17 // load it, and use glew to dynamically resolve symbols. 28 // load it, and use glew to dynamically resolve symbols.
18 // See http://code.google.com/p/chromium/issues/detail?id=16800 29 // See http://code.google.com/p/chromium/issues/detail?id=16800
19 30
31 static bool g_glxew_initialized = false;
20 static bool g_glew_initialized = false; 32 static bool g_glew_initialized = false;
21 33
22 bool XWindowWrapper::Initialize() { 34 static bool InitializeGLXEW() {
23 if (!g_glew_initialized) { 35 if (!g_glxew_initialized) {
24 void* handle = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); 36 void* handle = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL);
25 if (!handle) { 37 if (!handle) {
26 LOG(ERROR) << "Could not find libGL.so.1"; 38 LOG(ERROR) << "Could not find libGL.so.1";
27 return false; 39 return false;
28 } 40 }
29 41
30 // Initializes context-independent parts of GLEW 42 // Initializes context-independent parts of GLEW
31 if (glxewInit() != GLEW_OK) { 43 if (glxewInit() != GLEW_OK) {
32 LOG(ERROR) << "GLXEW failed initialization"; 44 LOG(ERROR) << "glxewInit failed";
45 return false;
46 }
47 // Hack to work around apparently incorrect assumption in
48 // glxewContextInit. Documentation indicates that all of the work
49 // it does is actually context-independent. We require GLX 1.3
50 // entry points to be present for successful initialization of the
51 // off-screen code path in the GLES2Decoder. TODO(kbr): clean this
52 // up.
53 if (glxewContextInit() != GLEW_OK) {
54 LOG(ERROR) << "glxewContextInit failed";
55 return false;
56 }
57 g_glxew_initialized = true;
58 }
59 return true;
60 }
61
62 // GLEW initialization is extremely expensive because it looks up
63 // hundreds of function pointers. Realistically we are not going to
64 // switch between GL implementations on the fly, so for the time being
65 // we only do the context-dependent GLEW initialization once.
66 static bool InitializeGLEW() {
67 if (!g_glew_initialized) {
68 // Initializes context-dependent parts of GLEW
69 if (glewInit() != GLEW_OK) {
70 LOG(ERROR) << "GLEW failed initialization";
71 return false;
72 }
73
74 if (!glewIsSupported("GL_VERSION_2_0")) {
75 LOG(ERROR) << "GL implementation doesn't support GL version 2.0";
33 return false; 76 return false;
34 } 77 }
35 g_glew_initialized = true; 78 g_glew_initialized = true;
36 } 79 }
37 XWindowAttributes attributes; 80 return true;
38 XGetWindowAttributes(display_, window_, &attributes); 81 }
39 XVisualInfo visual_info_template; 82
40 visual_info_template.visualid = XVisualIDFromVisual(attributes.visual); 83 GLXContextWrapper::~GLXContextWrapper() {
41 int visual_info_count = 0; 84 }
42 XVisualInfo *visual_info_list = XGetVisualInfo(display_, VisualIDMask, 85
43 &visual_info_template, 86 bool GLXContextWrapper::Initialize() {
44 &visual_info_count);
45 DCHECK(visual_info_list);
46 DCHECK_GT(visual_info_count, 0);
47 context_ = 0;
48 for (int i = 0; i < visual_info_count; ++i) {
49 context_ = glXCreateContext(display_, visual_info_list + i, 0,
50 True);
51 if (context_) break;
52 }
53 XFree(visual_info_list);
54 if (!context_) {
55 DLOG(ERROR) << "Couldn't create GL context.";
56 return false;
57 }
58 if (!MakeCurrent()) { 87 if (!MakeCurrent()) {
59 return false; 88 Destroy();
60 } 89 DLOG(ERROR) << "Couldn't make context current for initialization.";
61 90 return false;
62 // Initializes context-dependent parts of GLEW 91 }
63 if (glewInit() != GLEW_OK) { 92
64 LOG(ERROR) << "GLEW failed initialization"; 93 if (!InitializeGLEW()) {
65 return false; 94 Destroy();
66 } 95 return false;
67 96 }
68 if (!glewIsSupported("GL_VERSION_2_0")) { 97
69 LOG(ERROR) << "GL implementation doesn't support GL version 2.0"; 98 return true;
70 return false; 99 }
71 } 100
72 101 void GLXContextWrapper::Destroy() {
73 return true; 102 Bool result = glXMakeCurrent(GetDisplay(), 0, 0);
74 }
75
76 bool XWindowWrapper::MakeCurrent() {
77 if (glXGetCurrentDrawable() == window_ &&
78 glXGetCurrentContext() == context_) {
79 return true;
80 }
81 if (glXMakeCurrent(display_, window_, context_) != True) {
82 glXDestroyContext(display_, context_);
83 context_ = 0;
84 DLOG(ERROR) << "Couldn't make context current.";
85 return false;
86 }
87 return true;
88 }
89
90 void XWindowWrapper::Destroy() {
91 Bool result = glXMakeCurrent(display_, 0, 0);
92 // glXMakeCurrent isn't supposed to fail when unsetting the context, unless 103 // glXMakeCurrent isn't supposed to fail when unsetting the context, unless
93 // we have pending draws on an invalid window - which shouldn't be the case 104 // we have pending draws on an invalid window - which shouldn't be the case
94 // here. 105 // here.
95 DCHECK(result); 106 DCHECK(result);
96 if (context_) { 107 if (GetContext()) {
97 glXDestroyContext(display_, context_); 108 glXDestroyContext(GetDisplay(), GetContext());
98 context_ = 0; 109 SetContext(NULL);
99 } 110 }
111 }
112
113 bool XWindowWrapper::Initialize() {
114 if (!InitializeGLXEW())
115 return false;
116
117 XWindowAttributes attributes;
118 XGetWindowAttributes(GetDisplay(), window_, &attributes);
119 XVisualInfo visual_info_template;
120 visual_info_template.visualid = XVisualIDFromVisual(attributes.visual);
121 int visual_info_count = 0;
122 scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visual_info_list(
123 XGetVisualInfo(GetDisplay(), VisualIDMask,
124 &visual_info_template,
125 &visual_info_count));
126 DCHECK(visual_info_list.get());
127 DCHECK_GT(visual_info_count, 0);
128 SetContext(NULL);
129 for (int i = 0; i < visual_info_count; ++i) {
130 SetContext(glXCreateContext(GetDisplay(), visual_info_list.get() + i, 0,
131 True));
132 if (GetContext())
133 break;
134 }
135 if (!GetContext()) {
136 DLOG(ERROR) << "Couldn't create GL context.";
137 return false;
138 }
139 return GLXContextWrapper::Initialize();
140 }
141
142 bool XWindowWrapper::MakeCurrent() {
143 if (glXGetCurrentDrawable() == window_ &&
144 glXGetCurrentContext() == GetContext()) {
145 return true;
146 }
147 if (glXMakeCurrent(GetDisplay(), window_, GetContext()) != True) {
148 glXDestroyContext(GetDisplay(), GetContext());
149 SetContext(0);
150 DLOG(ERROR) << "Couldn't make context current.";
151 return false;
152 }
153 return true;
154 }
155
156 bool XWindowWrapper::IsOffscreen() {
157 return false;
100 } 158 }
101 159
102 void XWindowWrapper::SwapBuffers() { 160 void XWindowWrapper::SwapBuffers() {
103 glXSwapBuffers(display_, window_); 161 glXSwapBuffers(GetDisplay(), window_);
162 }
163
164 bool GLXPbufferWrapper::Initialize() {
165 if (!InitializeGLXEW())
166 return false;
167
168 if (!glXChooseFBConfig ||
169 !glXCreateNewContext ||
170 !glXCreatePbuffer ||
171 !glXDestroyPbuffer) {
172 DLOG(ERROR) << "Pbuffer support not available.";
173 return false;
174 }
175
176 static const int config_attributes[] = {
177 GLX_DRAWABLE_TYPE,
178 GLX_PBUFFER_BIT,
179 GLX_RENDER_TYPE,
180 GLX_RGBA_BIT,
181 GLX_DOUBLEBUFFER,
182 0,
183 0
184 };
185
186 int nelements = 0;
187 // TODO(kbr): figure out whether hardcoding screen to 0 is sufficient.
188 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> config(
189 glXChooseFBConfig(GetDisplay(), 0, config_attributes, &nelements));
190 if (!config.get()) {
191 DLOG(ERROR) << "glXChooseFBConfig failed.";
192 return false;
193 }
194 if (!nelements) {
195 DLOG(ERROR) << "glXChooseFBConfig returned 0 elements.";
196 return false;
197 }
198 SetContext(glXCreateNewContext(GetDisplay(),
199 config.get()[0], GLX_RGBA_TYPE, 0, True));
200 if (!GetContext()) {
201 DLOG(ERROR) << "glXCreateNewContext failed.";
202 return false;
203 }
204 static const int pbuffer_attributes[] = {
205 GLX_PBUFFER_WIDTH,
206 1,
207 GLX_PBUFFER_HEIGHT,
208 1,
209 0
210 };
211 pbuffer_ = glXCreatePbuffer(GetDisplay(),
212 config.get()[0], pbuffer_attributes);
213 if (!pbuffer_) {
214 Destroy();
215 DLOG(ERROR) << "glXCreatePbuffer failed.";
216 return false;
217 }
218 return GLXContextWrapper::Initialize();
219 }
220
221 void GLXPbufferWrapper::Destroy() {
222 GLXContextWrapper::Destroy();
223 if (pbuffer_) {
224 glXDestroyPbuffer(GetDisplay(), pbuffer_);
225 pbuffer_ = NULL;
226 }
227 }
228
229 bool GLXPbufferWrapper::MakeCurrent() {
230 if (glXGetCurrentDrawable() == pbuffer_ &&
231 glXGetCurrentContext() == GetContext()) {
232 return true;
233 }
234 if (glXMakeCurrent(GetDisplay(), pbuffer_, GetContext()) != True) {
235 glXDestroyContext(GetDisplay(), GetContext());
236 SetContext(0);
237 DLOG(ERROR) << "Couldn't make context current.";
238 return false;
239 }
240 return true;
241 }
242
243 bool GLXPbufferWrapper::IsOffscreen() {
244 return true;
245 }
246
247 void GLXPbufferWrapper::SwapBuffers() {
104 } 248 }
105 249
106 } // namespace gpu 250 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/x_utils.h ('k') | third_party/glew/README.chromium » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698