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.
5 // This file implements the GLContextWGL and PbufferGLContext classes.
7 #include "ui/gl/gl_context_wgl.h"
9 #include "base/logging.h"
10 #include "base/trace_event/trace_event.h"
11 #include "ui/gl/gl_bindings.h"
12 #include "ui/gl/gl_implementation.h"
13 #include "ui/gl/gl_surface_wgl.h"
17 GLContextWGL::GLContextWGL(GLShareGroup
* share_group
)
18 : GLContextReal(share_group
),
22 GLContextWGL::~GLContextWGL() {
26 std::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();
34 return GLContext::GetExtensions() + " " + extensions
;
36 return GLContext::GetExtensions();
39 bool 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());
46 context_
= wglCreateContext(
47 static_cast<HDC
>(compatible_surface
->GetHandle()));
49 LOG(ERROR
) << "Failed to create GL context.";
55 if (!wglShareLists(share_handle
, context_
)) {
56 LOG(ERROR
) << "Could not share GL contexts.";
65 void GLContextWGL::Destroy() {
67 wglDeleteContext(context_
);
72 bool GLContextWGL::MakeCurrent(GLSurface
* surface
) {
74 if (IsCurrent(surface
))
77 ScopedReleaseCurrent release_current
;
78 TRACE_EVENT0("gpu", "GLContextWGL::MakeCurrent");
80 if (!wglMakeCurrent(static_cast<HDC
>(surface
->GetHandle()), context_
)) {
81 LOG(ERROR
) << "Unable to make gl context current.";
85 // Set this as soon as the context is current, since we might call into GL.
89 if (!InitializeDynamicBindings()) {
93 if (!surface
->OnMakeCurrent(this)) {
94 LOG(ERROR
) << "Could not make current.";
98 release_current
.Cancel();
102 void GLContextWGL::ReleaseCurrent(GLSurface
* surface
) {
103 if (!IsCurrent(surface
))
107 wglMakeCurrent(NULL
, NULL
);
110 bool GLContextWGL::IsCurrent(GLSurface
* surface
) {
111 bool native_context_is_current
=
112 wglGetCurrentContext() == context_
;
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));
119 if (!native_context_is_current
)
123 if (wglGetCurrentDC() != surface
->GetHandle())
130 void* GLContextWGL::GetHandle() {
134 void GLContextWGL::OnSetSwapInterval(int interval
) {
135 DCHECK(IsCurrent(NULL
));
136 if (gfx::g_driver_wgl
.ext
.b_WGL_EXT_swap_control
) {
137 wglSwapIntervalEXT(interval
);
140 "Could not disable vsync: driver does not "
141 "support WGL_EXT_swap_control";