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.
9 #include "ui/gl/gl_context_glx.h"
11 #include "base/debug/trace_event.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "ui/gl/GL/glextchromium.h"
15 #include "ui/gl/gl_bindings.h"
16 #include "ui/gl/gl_implementation.h"
17 #include "ui/gl/gl_surface_glx.h"
21 GLContextGLX::GLContextGLX(GLShareGroup
* share_group
)
22 : GLContextReal(share_group
),
27 XDisplay
* GLContextGLX::display() {
31 bool GLContextGLX::Initialize(
32 GLSurface
* compatible_surface
, GpuPreference gpu_preference
) {
33 display_
= static_cast<XDisplay
*>(compatible_surface
->GetDisplay());
35 GLXContext share_handle
= static_cast<GLXContext
>(
36 share_group() ? share_group()->GetHandle() : NULL
);
38 if (GLSurfaceGLX::IsCreateContextSupported()) {
39 DVLOG(1) << "GLX_ARB_create_context supported.";
40 std::vector
<int> attribs
;
41 if (GLSurfaceGLX::IsCreateContextRobustnessSupported()) {
42 DVLOG(1) << "GLX_ARB_create_context_robustness supported.";
43 attribs
.push_back(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB
);
44 attribs
.push_back(GLX_LOSE_CONTEXT_ON_RESET_ARB
);
47 context_
= glXCreateContextAttribsARB(
49 static_cast<GLXFBConfig
>(compatible_surface
->GetConfig()),
54 LOG(ERROR
) << "Failed to create GL context with "
55 << "glXCreateContextAttribsARB.";
59 DVLOG(1) << "GLX_ARB_create_context not supported.";
60 context_
= glXCreateNewContext(
62 static_cast<GLXFBConfig
>(compatible_surface
->GetConfig()),
67 LOG(ERROR
) << "Failed to create GL context with glXCreateNewContext.";
72 DVLOG(1) << " Successfully allocated "
73 << (compatible_surface
->IsOffscreen() ?
74 "offscreen" : "onscreen")
75 << " GL context with LOSE_CONTEXT_ON_RESET_ARB";
77 DVLOG(1) << (compatible_surface
->IsOffscreen() ? "Offscreen" : "Onscreen")
79 << (glXIsDirect(display_
,
80 static_cast<GLXContext
>(context_
))
81 ? "direct" : "indirect")
87 void GLContextGLX::Destroy() {
89 glXDestroyContext(display_
,
90 static_cast<GLXContext
>(context_
));
95 bool GLContextGLX::MakeCurrent(GLSurface
* surface
) {
97 if (IsCurrent(surface
))
100 ScopedReleaseCurrent release_current
;
101 TRACE_EVENT0("gpu", "GLContextGLX::MakeCurrent");
102 if (!glXMakeContextCurrent(
104 reinterpret_cast<GLXDrawable
>(surface
->GetHandle()),
105 reinterpret_cast<GLXDrawable
>(surface
->GetHandle()),
106 static_cast<GLXContext
>(context_
))) {
107 LOG(ERROR
) << "Couldn't make context current with X drawable.";
112 // Set this as soon as the context is current, since we might call into GL.
116 if (!InitializeDynamicBindings()) {
121 if (!surface
->OnMakeCurrent(this)) {
122 LOG(ERROR
) << "Could not make current.";
127 release_current
.Cancel();
131 void GLContextGLX::ReleaseCurrent(GLSurface
* surface
) {
132 if (!IsCurrent(surface
))
136 if (!glXMakeContextCurrent(display_
, 0, 0, 0))
137 LOG(ERROR
) << "glXMakeCurrent failed in ReleaseCurrent";
140 bool GLContextGLX::IsCurrent(GLSurface
* surface
) {
141 bool native_context_is_current
=
142 glXGetCurrentContext() == static_cast<GLXContext
>(context_
);
144 // If our context is current then our notion of which GLContext is
145 // current must be correct. On the other hand, third-party code
146 // using OpenGL might change the current context.
147 DCHECK(!native_context_is_current
|| (GetRealCurrent() == this));
149 if (!native_context_is_current
)
153 if (glXGetCurrentDrawable() !=
154 reinterpret_cast<GLXDrawable
>(surface
->GetHandle())) {
162 void* GLContextGLX::GetHandle() {
166 void GLContextGLX::SetSwapInterval(int interval
) {
167 DCHECK(IsCurrent(NULL
));
168 if (HasExtension("GLX_EXT_swap_control") &&
169 g_driver_glx
.fn
.glXSwapIntervalEXTFn
) {
172 glXGetCurrentDrawable(),
174 } else if (HasExtension("GLX_MESA_swap_control") &&
175 g_driver_glx
.fn
.glXSwapIntervalMESAFn
) {
176 glXSwapIntervalMESA(interval
);
180 "Could not disable vsync: driver does not "
181 "support GLX_EXT_swap_control";
185 std::string
GLContextGLX::GetExtensions() {
186 DCHECK(IsCurrent(NULL
));
187 const char* extensions
= GLSurfaceGLX::GetGLXExtensions();
189 return GLContext::GetExtensions() + " " + extensions
;
192 return GLContext::GetExtensions();
195 bool GLContextGLX::GetTotalGpuMemory(size_t* bytes
) {
198 if (HasExtension("GL_NVX_gpu_memory_info")) {
200 glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX
, &kbytes
);
201 *bytes
= 1024*kbytes
;
207 bool GLContextGLX::WasAllocatedUsingRobustnessExtension() {
208 return GLSurfaceGLX::IsCreateContextRobustnessSupported();
211 GLContextGLX::~GLContextGLX() {