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 3 // found in the LICENSE file. 4 5 // This file implements the GLContextWGL and PbufferGLContext classes. 6 7 #include "ui/gl/gl_context_wgl.h" 8 9 #include "base/debug/trace_event.h" 10 #include "base/logging.h" 11 #include "ui/gl/gl_bindings.h" 12 #include "ui/gl/gl_implementation.h" 13 #include "ui/gl/gl_surface_wgl.h" 14 15 namespace gfx { 16 GLContextWGL(GLShareGroup * share_group)17GLContextWGL::GLContextWGL(GLShareGroup* share_group) 18 : GLContextReal(share_group), 19 context_(NULL) { 20 } 21 ~GLContextWGL()22GLContextWGL::~GLContextWGL() { 23 Destroy(); 24 } 25 GetExtensions()26std::string GLContextWGL::GetExtensions() { 27 const char* extensions = NULL; 28 if (g_driver_wgl.fn.wglGetExtensionsStringARBFn) 29 extensions = wglGetExtensionsStringARB(GLSurfaceWGL::GetDisplayDC()); 30 else if (g_driver_wgl.fn.wglGetExtensionsStringEXTFn) 31 extensions = wglGetExtensionsStringEXT(); 32 33 if (extensions) 34 return GLContext::GetExtensions() + " " + extensions; 35 36 return GLContext::GetExtensions(); 37 } 38 Initialize(GLSurface * compatible_surface,GpuPreference gpu_preference)39bool GLContextWGL::Initialize( 40 GLSurface* compatible_surface, GpuPreference gpu_preference) { 41 // Get the handle of another initialized context in the share group _before_ 42 // setting context_. Otherwise this context will be considered initialized 43 // and could potentially be returned by GetHandle. 44 HGLRC share_handle = static_cast<HGLRC>(share_group()->GetHandle()); 45 46 context_ = wglCreateContext( 47 static_cast<HDC>(compatible_surface->GetHandle())); 48 if (!context_) { 49 LOG(ERROR) << "Failed to create GL context."; 50 Destroy(); 51 return false; 52 } 53 54 if (share_handle) { 55 if (!wglShareLists(share_handle, context_)) { 56 LOG(ERROR) << "Could not share GL contexts."; 57 Destroy(); 58 return false; 59 } 60 } 61 62 return true; 63 } 64 Destroy()65void GLContextWGL::Destroy() { 66 if (context_) { 67 wglDeleteContext(context_); 68 context_ = NULL; 69 } 70 } 71 MakeCurrent(GLSurface * surface)72bool GLContextWGL::MakeCurrent(GLSurface* surface) { 73 DCHECK(context_); 74 if (IsCurrent(surface)) 75 return true; 76 77 ScopedReleaseCurrent release_current; 78 TRACE_EVENT0("gpu", "GLContextWGL::MakeCurrent"); 79 80 if (!wglMakeCurrent(static_cast<HDC>(surface->GetHandle()), context_)) { 81 LOG(ERROR) << "Unable to make gl context current."; 82 return false; 83 } 84 85 // Set this as soon as the context is current, since we might call into GL. 86 SetRealGLApi(); 87 88 SetCurrent(surface); 89 if (!InitializeDynamicBindings()) { 90 return false; 91 } 92 93 if (!surface->OnMakeCurrent(this)) { 94 LOG(ERROR) << "Could not make current."; 95 return false; 96 } 97 98 release_current.Cancel(); 99 return true; 100 } 101 ReleaseCurrent(GLSurface * surface)102void GLContextWGL::ReleaseCurrent(GLSurface* surface) { 103 if (!IsCurrent(surface)) 104 return; 105 106 SetCurrent(NULL); 107 wglMakeCurrent(NULL, NULL); 108 } 109 IsCurrent(GLSurface * surface)110bool GLContextWGL::IsCurrent(GLSurface* surface) { 111 bool native_context_is_current = 112 wglGetCurrentContext() == context_; 113 114 // If our context is current then our notion of which GLContext is 115 // current must be correct. On the other hand, third-party code 116 // using OpenGL might change the current context. 117 DCHECK(!native_context_is_current || (GetRealCurrent() == this)); 118 119 if (!native_context_is_current) 120 return false; 121 122 if (surface) { 123 if (wglGetCurrentDC() != surface->GetHandle()) 124 return false; 125 } 126 127 return true; 128 } 129 GetHandle()130void* GLContextWGL::GetHandle() { 131 return context_; 132 } 133 SetSwapInterval(int interval)134void GLContextWGL::SetSwapInterval(int interval) { 135 DCHECK(IsCurrent(NULL)); 136 if (gfx::g_driver_wgl.ext.b_WGL_EXT_swap_control) { 137 wglSwapIntervalEXT(interval); 138 } else { 139 LOG(WARNING) << 140 "Could not disable vsync: driver does not " 141 "support WGL_EXT_swap_control"; 142 } 143 } 144 145 } // namespace gfx 146