• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)17 GLContextWGL::GLContextWGL(GLShareGroup* share_group)
18     : GLContextReal(share_group),
19       context_(NULL) {
20 }
21 
~GLContextWGL()22 GLContextWGL::~GLContextWGL() {
23   Destroy();
24 }
25 
GetExtensions()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();
32 
33   if (extensions)
34     return GLContext::GetExtensions() + " " + extensions;
35 
36   return GLContext::GetExtensions();
37 }
38 
Initialize(GLSurface * compatible_surface,GpuPreference gpu_preference)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());
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()65 void GLContextWGL::Destroy() {
66   if (context_) {
67     wglDeleteContext(context_);
68     context_ = NULL;
69   }
70 }
71 
MakeCurrent(GLSurface * surface)72 bool 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)102 void GLContextWGL::ReleaseCurrent(GLSurface* surface) {
103   if (!IsCurrent(surface))
104     return;
105 
106   SetCurrent(NULL);
107   wglMakeCurrent(NULL, NULL);
108 }
109 
IsCurrent(GLSurface * surface)110 bool 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()130 void* GLContextWGL::GetHandle() {
131   return context_;
132 }
133 
SetSwapInterval(int interval)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";
142   }
143 }
144 
145 }  // namespace gfx
146