| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 file implements the ViewGLContext and PbufferGLContext classes. | 5 // This file implements the ViewGLContext and PbufferGLContext classes. |
| 6 | 6 |
| 7 #include <dlfcn.h> | |
| 8 #include <GL/glew.h> | |
| 9 #include <GL/glxew.h> | |
| 10 #include <GL/glx.h> | |
| 11 #include <GL/osmew.h> | |
| 12 #include <X11/Xlib.h> | |
| 13 #include <X11/Xutil.h> | |
| 14 | |
| 15 #include "app/x11_util.h" | 7 #include "app/x11_util.h" |
| 16 #include "base/logging.h" | 8 #include "base/logging.h" |
| 17 #include "base/scoped_ptr.h" | 9 #include "base/scoped_ptr.h" |
| 10 #include "app/gfx/gl/gl_bindings.h" |
| 18 #include "app/gfx/gl/gl_context.h" | 11 #include "app/gfx/gl/gl_context.h" |
| 19 #include "app/gfx/gl/gl_context_osmesa.h" | 12 #include "app/gfx/gl/gl_context_osmesa.h" |
| 13 #include "app/gfx/gl/gl_context_stub.h" |
| 14 #include "app/gfx/gl/gl_implementation.h" |
| 20 | 15 |
| 21 namespace gfx { | 16 namespace gfx { |
| 22 | 17 |
| 23 typedef GLXContext GLContextHandle; | 18 typedef GLXContext GLContextHandle; |
| 24 typedef GLXPbuffer PbufferHandle; | 19 typedef GLXPbuffer PbufferHandle; |
| 25 | 20 |
| 26 // This class is a wrapper around a GL context that renders directly to a | 21 // This class is a wrapper around a GL context that renders directly to a |
| 27 // window. | 22 // window. |
| 28 class ViewGLContext : public GLContext { | 23 class ViewGLContext : public GLContext { |
| 29 public: | 24 public: |
| (...skipping 25 matching lines...) Expand all Loading... |
| 55 // It is initially backed by a 1x1 pbuffer. Use it to create an FBO to do useful | 50 // It is initially backed by a 1x1 pbuffer. Use it to create an FBO to do useful |
| 56 // rendering. | 51 // rendering. |
| 57 class PbufferGLContext : public GLContext { | 52 class PbufferGLContext : public GLContext { |
| 58 public: | 53 public: |
| 59 explicit PbufferGLContext() | 54 explicit PbufferGLContext() |
| 60 : context_(NULL), | 55 : context_(NULL), |
| 61 pbuffer_(0) { | 56 pbuffer_(0) { |
| 62 } | 57 } |
| 63 | 58 |
| 64 // Initializes the GL context. | 59 // Initializes the GL context. |
| 65 bool Initialize(void* shared_handle); | 60 bool Initialize(GLContext* shared_context); |
| 66 | 61 |
| 67 virtual void Destroy(); | 62 virtual void Destroy(); |
| 68 virtual bool MakeCurrent(); | 63 virtual bool MakeCurrent(); |
| 69 virtual bool IsCurrent(); | 64 virtual bool IsCurrent(); |
| 70 virtual bool IsOffscreen(); | 65 virtual bool IsOffscreen(); |
| 71 virtual void SwapBuffers(); | 66 virtual void SwapBuffers(); |
| 72 virtual gfx::Size GetSize(); | 67 virtual gfx::Size GetSize(); |
| 73 virtual void* GetHandle(); | 68 virtual void* GetHandle(); |
| 74 | 69 |
| 75 private: | 70 private: |
| 76 GLContextHandle context_; | 71 GLContextHandle context_; |
| 77 PbufferHandle pbuffer_; | 72 PbufferHandle pbuffer_; |
| 78 | 73 |
| 79 DISALLOW_COPY_AND_ASSIGN(PbufferGLContext); | 74 DISALLOW_COPY_AND_ASSIGN(PbufferGLContext); |
| 80 }; | 75 }; |
| 81 | 76 |
| 82 // Backup context if Pbuffers (GLX 1.3) aren't supported. May run slower... | 77 // Backup context if Pbuffers (GLX 1.3) aren't supported. May run slower... |
| 83 class PixmapGLContext : public GLContext { | 78 class PixmapGLContext : public GLContext { |
| 84 public: | 79 public: |
| 85 explicit PixmapGLContext() | 80 explicit PixmapGLContext() |
| 86 : context_(NULL), | 81 : context_(NULL), |
| 87 pixmap_(0), | 82 pixmap_(0), |
| 88 glx_pixmap_(0) { | 83 glx_pixmap_(0) { |
| 89 } | 84 } |
| 90 | 85 |
| 91 // Initializes the GL context. | 86 // Initializes the GL context. |
| 92 bool Initialize(void* shared_handle); | 87 bool Initialize(GLContext* shared_context); |
| 93 | 88 |
| 94 virtual void Destroy(); | 89 virtual void Destroy(); |
| 95 virtual bool MakeCurrent(); | 90 virtual bool MakeCurrent(); |
| 96 virtual bool IsCurrent(); | 91 virtual bool IsCurrent(); |
| 97 virtual bool IsOffscreen(); | 92 virtual bool IsOffscreen(); |
| 98 virtual void SwapBuffers(); | 93 virtual void SwapBuffers(); |
| 99 virtual gfx::Size GetSize(); | 94 virtual gfx::Size GetSize(); |
| 100 virtual void* GetHandle(); | 95 virtual void* GetHandle(); |
| 101 | 96 |
| 102 private: | 97 private: |
| 103 GLContextHandle context_; | 98 GLContextHandle context_; |
| 104 Pixmap pixmap_; | 99 Pixmap pixmap_; |
| 105 GLXPixmap glx_pixmap_; | 100 GLXPixmap glx_pixmap_; |
| 106 | 101 |
| 107 DISALLOW_COPY_AND_ASSIGN(PixmapGLContext); | 102 DISALLOW_COPY_AND_ASSIGN(PixmapGLContext); |
| 108 }; | 103 }; |
| 109 | 104 |
| 110 // scoped_ptr functor for XFree(). Use as follows: | 105 // scoped_ptr functor for XFree(). Use as follows: |
| 111 // scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...); | 106 // scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...); |
| 112 // where "XVisualInfo" is any X type that is freed with XFree. | 107 // where "XVisualInfo" is any X type that is freed with XFree. |
| 113 class ScopedPtrXFree { | 108 class ScopedPtrXFree { |
| 114 public: | 109 public: |
| 115 void operator()(void* x) const { | 110 void operator()(void* x) const { |
| 116 ::XFree(x); | 111 ::XFree(x); |
| 117 } | 112 } |
| 118 }; | 113 }; |
| 119 | 114 |
| 120 // Some versions of NVIDIA's GL libGL.so include a broken version of | |
| 121 // dlopen/dlsym, and so linking it into chrome breaks it. So we dynamically | |
| 122 // load it, and use glew to dynamically resolve symbols. | |
| 123 // See http://code.google.com/p/chromium/issues/detail?id=16800 | |
| 124 | |
| 125 static bool InitializeOneOff() { | 115 static bool InitializeOneOff() { |
| 126 static bool initialized = false; | 116 static bool initialized = false; |
| 127 if (initialized) | 117 if (initialized) |
| 128 return true; | 118 return true; |
| 129 | 119 |
| 130 osmewInit(); | 120 // Initialize the GL bindings if they haven't already been initialized. If |
| 131 if (!OSMesaCreateContext) { | 121 // the GPU unit tests are running, the mock GL implementation will already |
| 132 void* handle = dlopen("libGL.so.1", RTLD_LAZY | RTLD_GLOBAL); | 122 // have been initialized. |
| 133 if (!handle) { | 123 if (!InitializeGLBindings(kGLImplementationDesktopGL)) { |
| 134 LOG(ERROR) << "Could not find libGL.so.1"; | 124 LOG(ERROR) << "Could not initialize GL."; |
| 135 return false; | 125 return false; |
| 136 } | 126 } |
| 137 | 127 |
| 138 // Initializes context-independent parts of GLEW | 128 // Only check the GLX version if we are in fact using GLX. We might actually |
| 139 if (glxewInit() != GLEW_OK) { | 129 // be using the mock GL implementation. |
| 140 LOG(ERROR) << "glxewInit failed"; | 130 if (GetGLImplementation() == kGLImplementationDesktopGL) { |
| 141 return false; | |
| 142 } | |
| 143 // glxewContextInit really only needs a display connection to | |
| 144 // complete, and we don't want to have to create an OpenGL context | |
| 145 // just to get access to GLX 1.3 entry points to create pbuffers. | |
| 146 // We therefore added a glxewContextInitWithDisplay entry point. | |
| 147 Display* display = x11_util::GetXDisplay(); | 131 Display* display = x11_util::GetXDisplay(); |
| 148 if (glxewContextInitWithDisplay(display) != GLEW_OK) { | |
| 149 LOG(ERROR) << "glxewContextInit failed"; | |
| 150 return false; | |
| 151 } | |
| 152 | |
| 153 int major, minor; | 132 int major, minor; |
| 154 if (!glXQueryVersion(display, &major, &minor)) { | 133 if (!glXQueryVersion(display, &major, &minor)) { |
| 155 LOG(ERROR) << "glxQueryVersion failed"; | 134 LOG(ERROR) << "glxQueryVersion failed"; |
| 156 return false; | 135 return false; |
| 157 } | 136 } |
| 158 | 137 |
| 159 if (major == 1 && minor < 3) { | 138 if (major == 1 && minor < 3) { |
| 160 LOG(WARNING) << "GLX 1.3 or later is recommended."; | 139 LOG(WARNING) << "GLX 1.3 or later is recommended."; |
| 161 } | 140 } |
| 162 } | 141 } |
| (...skipping 29 matching lines...) Expand all Loading... |
| 192 LOG(ERROR) << "Couldn't create GL context."; | 171 LOG(ERROR) << "Couldn't create GL context."; |
| 193 return false; | 172 return false; |
| 194 } | 173 } |
| 195 | 174 |
| 196 if (!MakeCurrent()) { | 175 if (!MakeCurrent()) { |
| 197 Destroy(); | 176 Destroy(); |
| 198 LOG(ERROR) << "Couldn't make context current for initialization."; | 177 LOG(ERROR) << "Couldn't make context current for initialization."; |
| 199 return false; | 178 return false; |
| 200 } | 179 } |
| 201 | 180 |
| 202 if (!InitializeGLEW()) { | |
| 203 Destroy(); | |
| 204 return false; | |
| 205 } | |
| 206 | |
| 207 if (!InitializeCommon()) { | 181 if (!InitializeCommon()) { |
| 208 Destroy(); | 182 Destroy(); |
| 209 return false; | 183 return false; |
| 210 } | 184 } |
| 211 | 185 |
| 212 return true; | 186 return true; |
| 213 } | 187 } |
| 214 | 188 |
| 215 void ViewGLContext::Destroy() { | 189 void ViewGLContext::Destroy() { |
| 216 Display* display = x11_util::GetXDisplay(); | 190 Display* display = x11_util::GetXDisplay(); |
| 217 Bool result = glXMakeCurrent(display, 0, 0); | 191 bool result = glXMakeCurrent(display, 0, 0); |
| 218 | 192 |
| 219 // glXMakeCurrent isn't supposed to fail when unsetting the context, unless | 193 // glXMakeCurrent isn't supposed to fail when unsetting the context, unless |
| 220 // we have pending draws on an invalid window - which shouldn't be the case | 194 // we have pending draws on an invalid window - which shouldn't be the case |
| 221 // here. | 195 // here. |
| 222 DCHECK(result); | 196 DCHECK(result); |
| 223 if (context_) { | 197 if (context_) { |
| 224 glXDestroyContext(display, context_); | 198 glXDestroyContext(display, context_); |
| 225 context_ = NULL; | 199 context_ = NULL; |
| 226 } | 200 } |
| 227 } | 201 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 265 | 239 |
| 266 void* ViewGLContext::GetHandle() { | 240 void* ViewGLContext::GetHandle() { |
| 267 return context_; | 241 return context_; |
| 268 } | 242 } |
| 269 | 243 |
| 270 GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window, | 244 GLContext* GLContext::CreateViewGLContext(gfx::PluginWindowHandle window, |
| 271 bool multisampled) { | 245 bool multisampled) { |
| 272 if (!InitializeOneOff()) | 246 if (!InitializeOneOff()) |
| 273 return NULL; | 247 return NULL; |
| 274 | 248 |
| 275 if (OSMesaCreateContext) { | 249 switch (GetGLImplementation()) { |
| 276 // TODO(apatrick): Support OSMesa rendering to a window on Linux. | 250 case kGLImplementationDesktopGL: { |
| 277 NOTREACHED() << "OSMesa rendering to a window is not yet implemented."; | 251 scoped_ptr<ViewGLContext> context(new ViewGLContext(window)); |
| 278 return NULL; | |
| 279 } else { | |
| 280 scoped_ptr<ViewGLContext> context(new ViewGLContext(window)); | |
| 281 | 252 |
| 282 if (!context->Initialize(multisampled)) | 253 if (!context->Initialize(multisampled)) |
| 254 return NULL; |
| 255 |
| 256 return context.release(); |
| 257 } |
| 258 case kGLImplementationMockGL: |
| 259 return new StubGLContext; |
| 260 default: |
| 261 NOTREACHED(); |
| 283 return NULL; | 262 return NULL; |
| 284 | |
| 285 return context.release(); | |
| 286 } | 263 } |
| 287 } | 264 } |
| 288 | 265 |
| 289 bool PbufferGLContext::Initialize(void* shared_handle) { | 266 bool PbufferGLContext::Initialize(GLContext* shared_context) { |
| 290 if (!glXChooseFBConfig || | |
| 291 !glXCreateNewContext || | |
| 292 !glXCreatePbuffer || | |
| 293 !glXDestroyPbuffer) { | |
| 294 LOG(ERROR) << "Pbuffer support not available."; | |
| 295 return false; | |
| 296 } | |
| 297 | |
| 298 static const int config_attributes[] = { | 267 static const int config_attributes[] = { |
| 299 GLX_DRAWABLE_TYPE, | 268 GLX_DRAWABLE_TYPE, |
| 300 GLX_PBUFFER_BIT, | 269 GLX_PBUFFER_BIT, |
| 301 GLX_RENDER_TYPE, | 270 GLX_RENDER_TYPE, |
| 302 GLX_RGBA_BIT, | 271 GLX_RGBA_BIT, |
| 303 GLX_DOUBLEBUFFER, | 272 GLX_DOUBLEBUFFER, |
| 304 0, | 273 0, |
| 305 0 | 274 0 |
| 306 }; | 275 }; |
| 307 | 276 |
| 308 Display* display = x11_util::GetXDisplay(); | 277 Display* display = x11_util::GetXDisplay(); |
| 309 | 278 |
| 310 int nelements = 0; | 279 int nelements = 0; |
| 311 // TODO(kbr): figure out whether hardcoding screen to 0 is sufficient. | 280 // TODO(kbr): figure out whether hardcoding screen to 0 is sufficient. |
| 312 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> config( | 281 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> config( |
| 313 glXChooseFBConfig(display, 0, config_attributes, &nelements)); | 282 glXChooseFBConfig(display, 0, config_attributes, &nelements)); |
| 314 if (!config.get()) { | 283 if (!config.get()) { |
| 315 LOG(ERROR) << "glXChooseFBConfig failed."; | 284 LOG(ERROR) << "glXChooseFBConfig failed."; |
| 316 return false; | 285 return false; |
| 317 } | 286 } |
| 318 if (!nelements) { | 287 if (!nelements) { |
| 319 LOG(ERROR) << "glXChooseFBConfig returned 0 elements."; | 288 LOG(ERROR) << "glXChooseFBConfig returned 0 elements."; |
| 320 return false; | 289 return false; |
| 321 } | 290 } |
| 291 |
| 292 GLContextHandle shared_handle = NULL; |
| 293 if (shared_context) |
| 294 shared_handle = static_cast<GLContextHandle>(shared_context->GetHandle()); |
| 295 |
| 322 context_ = glXCreateNewContext(display, | 296 context_ = glXCreateNewContext(display, |
| 323 config.get()[0], | 297 config.get()[0], |
| 324 GLX_RGBA_TYPE, | 298 GLX_RGBA_TYPE, |
| 325 static_cast<GLContextHandle>(shared_handle), | 299 shared_handle, |
| 326 True); | 300 True); |
| 327 if (!context_) { | 301 if (!context_) { |
| 328 LOG(ERROR) << "glXCreateNewContext failed."; | 302 LOG(ERROR) << "glXCreateNewContext failed."; |
| 329 return false; | 303 return false; |
| 330 } | 304 } |
| 331 static const int pbuffer_attributes[] = { | 305 static const int pbuffer_attributes[] = { |
| 332 GLX_PBUFFER_WIDTH, | 306 GLX_PBUFFER_WIDTH, |
| 333 1, | 307 1, |
| 334 GLX_PBUFFER_HEIGHT, | 308 GLX_PBUFFER_HEIGHT, |
| 335 1, | 309 1, |
| 336 0 | 310 0 |
| 337 }; | 311 }; |
| 338 pbuffer_ = glXCreatePbuffer(display, | 312 pbuffer_ = glXCreatePbuffer(display, |
| 339 config.get()[0], pbuffer_attributes); | 313 config.get()[0], pbuffer_attributes); |
| 340 if (!pbuffer_) { | 314 if (!pbuffer_) { |
| 341 Destroy(); | 315 Destroy(); |
| 342 LOG(ERROR) << "glXCreatePbuffer failed."; | 316 LOG(ERROR) << "glXCreatePbuffer failed."; |
| 343 return false; | 317 return false; |
| 344 } | 318 } |
| 345 | 319 |
| 346 if (!MakeCurrent()) { | 320 if (!MakeCurrent()) { |
| 347 Destroy(); | 321 Destroy(); |
| 348 LOG(ERROR) << "Couldn't make context current for initialization."; | 322 LOG(ERROR) << "Couldn't make context current for initialization."; |
| 349 return false; | 323 return false; |
| 350 } | 324 } |
| 351 | 325 |
| 352 if (!InitializeGLEW()) { | |
| 353 Destroy(); | |
| 354 return false; | |
| 355 } | |
| 356 | |
| 357 if (!InitializeCommon()) { | 326 if (!InitializeCommon()) { |
| 358 Destroy(); | 327 Destroy(); |
| 359 return false; | 328 return false; |
| 360 } | 329 } |
| 361 | 330 |
| 362 return true; | 331 return true; |
| 363 } | 332 } |
| 364 | 333 |
| 365 void PbufferGLContext::Destroy() { | 334 void PbufferGLContext::Destroy() { |
| 366 Display* display = x11_util::GetXDisplay(); | 335 Display* display = x11_util::GetXDisplay(); |
| 367 Bool result = glXMakeCurrent(display, 0, 0); | 336 bool result = glXMakeCurrent(display, 0, 0); |
| 368 // glXMakeCurrent isn't supposed to fail when unsetting the context, unless | 337 // glXMakeCurrent isn't supposed to fail when unsetting the context, unless |
| 369 // we have pending draws on an invalid window - which shouldn't be the case | 338 // we have pending draws on an invalid window - which shouldn't be the case |
| 370 // here. | 339 // here. |
| 371 DCHECK(result); | 340 DCHECK(result); |
| 372 if (context_) { | 341 if (context_) { |
| 373 glXDestroyContext(display, context_); | 342 glXDestroyContext(display, context_); |
| 374 context_ = NULL; | 343 context_ = NULL; |
| 375 } | 344 } |
| 376 | 345 |
| 377 if (pbuffer_) { | 346 if (pbuffer_) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 410 | 379 |
| 411 gfx::Size PbufferGLContext::GetSize() { | 380 gfx::Size PbufferGLContext::GetSize() { |
| 412 NOTREACHED() << "Should not be requesting size of this pbuffer."; | 381 NOTREACHED() << "Should not be requesting size of this pbuffer."; |
| 413 return gfx::Size(1, 1); | 382 return gfx::Size(1, 1); |
| 414 } | 383 } |
| 415 | 384 |
| 416 void* PbufferGLContext::GetHandle() { | 385 void* PbufferGLContext::GetHandle() { |
| 417 return context_; | 386 return context_; |
| 418 } | 387 } |
| 419 | 388 |
| 420 bool PixmapGLContext::Initialize(void* shared_handle) { | 389 bool PixmapGLContext::Initialize(GLContext* shared_context) { |
| 421 LOG(INFO) << "GL context: using pixmaps."; | 390 LOG(INFO) << "GL context: using pixmaps."; |
| 422 if (!glXChooseVisual || | |
| 423 !glXCreateGLXPixmap || | |
| 424 !glXDestroyGLXPixmap) { | |
| 425 LOG(ERROR) << "Pixmap support not available."; | |
| 426 return false; | |
| 427 } | |
| 428 | 391 |
| 429 static int attributes[] = { | 392 static int attributes[] = { |
| 430 GLX_RGBA, | 393 GLX_RGBA, |
| 431 0 | 394 0 |
| 432 }; | 395 }; |
| 433 | 396 |
| 434 Display* display = x11_util::GetXDisplay(); | 397 Display* display = x11_util::GetXDisplay(); |
| 435 int screen = DefaultScreen(display); | 398 int screen = DefaultScreen(display); |
| 436 | 399 |
| 437 scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visual_info( | 400 scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visual_info( |
| 438 glXChooseVisual(display, screen, attributes)); | 401 glXChooseVisual(display, screen, attributes)); |
| 439 | 402 |
| 440 if (!visual_info.get()) { | 403 if (!visual_info.get()) { |
| 441 LOG(ERROR) << "glXChooseVisual failed."; | 404 LOG(ERROR) << "glXChooseVisual failed."; |
| 442 return false; | 405 return false; |
| 443 } | 406 } |
| 444 context_ = glXCreateContext(display, visual_info.get(), | 407 |
| 445 static_cast<GLContextHandle>(shared_handle), | 408 GLContextHandle shared_handle = NULL; |
| 446 True); | 409 if (shared_context) |
| 410 shared_handle = static_cast<GLContextHandle>(shared_context->GetHandle()); |
| 411 |
| 412 context_ = glXCreateContext(display, visual_info.get(), shared_handle, True); |
| 447 if (!context_) { | 413 if (!context_) { |
| 448 LOG(ERROR) << "glXCreateContext failed."; | 414 LOG(ERROR) << "glXCreateContext failed."; |
| 449 return false; | 415 return false; |
| 450 } | 416 } |
| 451 | 417 |
| 452 pixmap_ = XCreatePixmap(display, RootWindow(display, screen), 1, 1, | 418 pixmap_ = XCreatePixmap(display, RootWindow(display, screen), 1, 1, |
| 453 visual_info->depth); | 419 visual_info->depth); |
| 454 if (!pixmap_) { | 420 if (!pixmap_) { |
| 455 LOG(ERROR) << "XCreatePixmap failed."; | 421 LOG(ERROR) << "XCreatePixmap failed."; |
| 456 return false; | 422 return false; |
| 457 } | 423 } |
| 458 | 424 |
| 459 glx_pixmap_ = glXCreateGLXPixmap(display, visual_info.get(), pixmap_); | 425 glx_pixmap_ = glXCreateGLXPixmap(display, visual_info.get(), pixmap_); |
| 460 if (!glx_pixmap_) { | 426 if (!glx_pixmap_) { |
| 461 LOG(ERROR) << "XCreatePixmap failed."; | 427 LOG(ERROR) << "XCreatePixmap failed."; |
| 462 return false; | 428 return false; |
| 463 } | 429 } |
| 464 | 430 |
| 465 if (!MakeCurrent()) { | 431 if (!MakeCurrent()) { |
| 466 Destroy(); | 432 Destroy(); |
| 467 LOG(ERROR) << "Couldn't make context current for initialization."; | 433 LOG(ERROR) << "Couldn't make context current for initialization."; |
| 468 return false; | 434 return false; |
| 469 } | 435 } |
| 470 | 436 |
| 471 if (!InitializeGLEW()) { | |
| 472 Destroy(); | |
| 473 return false; | |
| 474 } | |
| 475 | |
| 476 if (!InitializeCommon()) { | 437 if (!InitializeCommon()) { |
| 477 Destroy(); | 438 Destroy(); |
| 478 return false; | 439 return false; |
| 479 } | 440 } |
| 480 | 441 |
| 481 return true; | 442 return true; |
| 482 } | 443 } |
| 483 | 444 |
| 484 void PixmapGLContext::Destroy() { | 445 void PixmapGLContext::Destroy() { |
| 485 Display* display = x11_util::GetXDisplay(); | 446 Display* display = x11_util::GetXDisplay(); |
| 486 Bool result = glXMakeCurrent(display, 0, 0); | 447 bool result = glXMakeCurrent(display, 0, 0); |
| 487 // glXMakeCurrent isn't supposed to fail when unsetting the context, unless | 448 // glXMakeCurrent isn't supposed to fail when unsetting the context, unless |
| 488 // we have pending draws on an invalid window - which shouldn't be the case | 449 // we have pending draws on an invalid window - which shouldn't be the case |
| 489 // here. | 450 // here. |
| 490 DCHECK(result); | 451 DCHECK(result); |
| 491 if (context_) { | 452 if (context_) { |
| 492 glXDestroyContext(display, context_); | 453 glXDestroyContext(display, context_); |
| 493 context_ = NULL; | 454 context_ = NULL; |
| 494 } | 455 } |
| 495 | 456 |
| 496 if (glx_pixmap_) { | 457 if (glx_pixmap_) { |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 534 | 495 |
| 535 gfx::Size PixmapGLContext::GetSize() { | 496 gfx::Size PixmapGLContext::GetSize() { |
| 536 NOTREACHED() << "Should not be requesting size of this pixmap."; | 497 NOTREACHED() << "Should not be requesting size of this pixmap."; |
| 537 return gfx::Size(1, 1); | 498 return gfx::Size(1, 1); |
| 538 } | 499 } |
| 539 | 500 |
| 540 void* PixmapGLContext::GetHandle() { | 501 void* PixmapGLContext::GetHandle() { |
| 541 return context_; | 502 return context_; |
| 542 } | 503 } |
| 543 | 504 |
| 544 GLContext* GLContext::CreateOffscreenGLContext(void* shared_handle) { | 505 GLContext* GLContext::CreateOffscreenGLContext(GLContext* shared_context) { |
| 545 if (!InitializeOneOff()) | 506 if (!InitializeOneOff()) |
| 546 return NULL; | 507 return NULL; |
| 547 | 508 |
| 548 if (OSMesaCreateContext) { | 509 switch (GetGLImplementation()) { |
| 549 scoped_ptr<OSMesaGLContext> context(new OSMesaGLContext); | 510 case kGLImplementationDesktopGL: { |
| 511 scoped_ptr<PbufferGLContext> context(new PbufferGLContext); |
| 512 if (context->Initialize(shared_context)) |
| 513 return context.release(); |
| 550 | 514 |
| 551 if (!context->Initialize(shared_handle)) | 515 scoped_ptr<PixmapGLContext> context_pixmap(new PixmapGLContext); |
| 516 if (context_pixmap->Initialize(shared_context)) |
| 517 return context_pixmap.release(); |
| 518 |
| 552 return NULL; | 519 return NULL; |
| 553 | 520 } |
| 554 return context.release(); | 521 case kGLImplementationMockGL: |
| 555 } else { | 522 return new StubGLContext; |
| 556 scoped_ptr<PbufferGLContext> context(new PbufferGLContext); | 523 default: |
| 557 if (context->Initialize(shared_handle)) | 524 NOTREACHED(); |
| 558 return context.release(); | 525 return NULL; |
| 559 | |
| 560 scoped_ptr<PixmapGLContext> context_pixmap(new PixmapGLContext); | |
| 561 if (context_pixmap->Initialize(shared_handle)) | |
| 562 return context_pixmap.release(); | |
| 563 | |
| 564 return NULL; | |
| 565 } | 526 } |
| 566 } | 527 } |
| 567 | 528 |
| 568 } // namespace gfx | 529 } // namespace gfx |
| OLD | NEW |