OOPIF: Allow navigations on a RFH without a site to stay in same process.
[chromium-blink-merge.git] / ui / gl / gl_context_wgl.cc
blobabe47e4f9f7a78be1c32d3c02689e191314ce344
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/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"
15 namespace gfx {
17 GLContextWGL::GLContextWGL(GLShareGroup* share_group)
18 : GLContextReal(share_group),
19 context_(NULL) {
22 GLContextWGL::~GLContextWGL() {
23 Destroy();
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();
33 if (extensions)
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()));
48 if (!context_) {
49 LOG(ERROR) << "Failed to create GL context.";
50 Destroy();
51 return false;
54 if (share_handle) {
55 if (!wglShareLists(share_handle, context_)) {
56 LOG(ERROR) << "Could not share GL contexts.";
57 Destroy();
58 return false;
62 return true;
65 void GLContextWGL::Destroy() {
66 if (context_) {
67 wglDeleteContext(context_);
68 context_ = NULL;
72 bool GLContextWGL::MakeCurrent(GLSurface* surface) {
73 DCHECK(context_);
74 if (IsCurrent(surface))
75 return true;
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.";
82 return false;
85 // Set this as soon as the context is current, since we might call into GL.
86 SetRealGLApi();
88 SetCurrent(surface);
89 if (!InitializeDynamicBindings()) {
90 return false;
93 if (!surface->OnMakeCurrent(this)) {
94 LOG(ERROR) << "Could not make current.";
95 return false;
98 release_current.Cancel();
99 return true;
102 void GLContextWGL::ReleaseCurrent(GLSurface* surface) {
103 if (!IsCurrent(surface))
104 return;
106 SetCurrent(NULL);
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)
120 return false;
122 if (surface) {
123 if (wglGetCurrentDC() != surface->GetHandle())
124 return false;
127 return true;
130 void* GLContextWGL::GetHandle() {
131 return context_;
134 void 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";
145 } // namespace gfx