Move "pack" button in the top toolbar to an action in the list of unpacked items.
[chromium-blink-merge.git] / ui / gl / gl_context_glx.cc
blobeb4e366ab4fae59749f656113b7be6b587c6c785
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 extern "C" {
6 #include <X11/Xlib.h>
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 "third_party/mesa/src/include/GL/osmesa.h"
15 #include "ui/gl/GL/glextchromium.h"
16 #include "ui/gl/gl_bindings.h"
17 #include "ui/gl/gl_implementation.h"
18 #include "ui/gl/gl_surface_glx.h"
20 namespace gfx {
22 namespace {
24 // scoped_ptr functor for XFree(). Use as follows:
25 // scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...);
26 // where "XVisualInfo" is any X type that is freed with XFree.
27 class ScopedPtrXFree {
28 public:
29 void operator()(void* x) const {
30 ::XFree(x);
34 } // namespace
36 GLContextGLX::GLContextGLX(GLShareGroup* share_group)
37 : GLContextReal(share_group),
38 context_(NULL),
39 display_(NULL) {
42 Display* GLContextGLX::display() {
43 return display_;
46 bool GLContextGLX::Initialize(
47 GLSurface* compatible_surface, GpuPreference gpu_preference) {
48 display_ = static_cast<Display*>(compatible_surface->GetDisplay());
50 GLXContext share_handle = static_cast<GLXContext>(
51 share_group() ? share_group()->GetHandle() : NULL);
53 if (GLSurfaceGLX::IsCreateContextSupported()) {
54 DVLOG(1) << "GLX_ARB_create_context supported.";
55 std::vector<int> attribs;
56 if (GLSurfaceGLX::IsCreateContextRobustnessSupported()) {
57 DVLOG(1) << "GLX_ARB_create_context_robustness supported.";
58 attribs.push_back(GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB);
59 attribs.push_back(GLX_LOSE_CONTEXT_ON_RESET_ARB);
61 attribs.push_back(0);
62 context_ = glXCreateContextAttribsARB(
63 display_,
64 static_cast<GLXFBConfig>(compatible_surface->GetConfig()),
65 share_handle,
66 True,
67 &attribs.front());
68 if (!context_) {
69 LOG(ERROR) << "Failed to create GL context with "
70 << "glXCreateContextAttribsARB.";
71 return false;
73 } else {
74 DVLOG(1) << "GLX_ARB_create_context not supported.";
75 context_ = glXCreateNewContext(
76 display_,
77 static_cast<GLXFBConfig>(compatible_surface->GetConfig()),
78 GLX_RGBA_TYPE,
79 share_handle,
80 True);
81 if (!context_) {
82 LOG(ERROR) << "Failed to create GL context with glXCreateNewContext.";
83 return false;
86 DCHECK(context_);
87 DVLOG(1) << " Successfully allocated "
88 << (compatible_surface->IsOffscreen() ?
89 "offscreen" : "onscreen")
90 << " GL context with LOSE_CONTEXT_ON_RESET_ARB";
92 DVLOG(1) << (compatible_surface->IsOffscreen() ? "Offscreen" : "Onscreen")
93 << " context was "
94 << (glXIsDirect(display_,
95 static_cast<GLXContext>(context_))
96 ? "direct" : "indirect")
97 << ".";
99 return true;
102 void GLContextGLX::Destroy() {
103 if (context_) {
104 glXDestroyContext(display_,
105 static_cast<GLXContext>(context_));
106 context_ = NULL;
110 bool GLContextGLX::MakeCurrent(GLSurface* surface) {
111 DCHECK(context_);
112 if (IsCurrent(surface))
113 return true;
115 TRACE_EVENT0("gpu", "GLContextGLX::MakeCurrent");
116 if (!glXMakeContextCurrent(
117 display_,
118 reinterpret_cast<GLXDrawable>(surface->GetHandle()),
119 reinterpret_cast<GLXDrawable>(surface->GetHandle()),
120 static_cast<GLXContext>(context_))) {
121 LOG(ERROR) << "Couldn't make context current with X drawable.";
122 Destroy();
123 return false;
126 // Set this as soon as the context is current, since we might call into GL.
127 SetRealGLApi();
129 SetCurrent(surface);
130 if (!InitializeExtensionBindings()) {
131 ReleaseCurrent(surface);
132 Destroy();
133 return false;
136 if (!surface->OnMakeCurrent(this)) {
137 LOG(ERROR) << "Could not make current.";
138 ReleaseCurrent(surface);
139 Destroy();
140 return false;
143 return true;
146 void GLContextGLX::ReleaseCurrent(GLSurface* surface) {
147 if (!IsCurrent(surface))
148 return;
150 SetCurrent(NULL);
151 if (!glXMakeContextCurrent(display_, 0, 0, 0))
152 LOG(ERROR) << "glXMakeCurrent failed in ReleaseCurrent";
155 bool GLContextGLX::IsCurrent(GLSurface* surface) {
156 bool native_context_is_current =
157 glXGetCurrentContext() == static_cast<GLXContext>(context_);
159 // If our context is current then our notion of which GLContext is
160 // current must be correct. On the other hand, third-party code
161 // using OpenGL might change the current context.
162 DCHECK(!native_context_is_current || (GetRealCurrent() == this));
164 if (!native_context_is_current)
165 return false;
167 if (surface) {
168 if (glXGetCurrentDrawable() !=
169 reinterpret_cast<GLXDrawable>(surface->GetHandle())) {
170 return false;
174 return true;
177 void* GLContextGLX::GetHandle() {
178 return context_;
181 void GLContextGLX::SetSwapInterval(int interval) {
182 DCHECK(IsCurrent(NULL));
183 if (HasExtension("GLX_EXT_swap_control") &&
184 g_driver_glx.fn.glXSwapIntervalEXTFn) {
185 glXSwapIntervalEXT(
186 display_,
187 glXGetCurrentDrawable(),
188 interval);
189 } else if (HasExtension("GLX_MESA_swap_control") &&
190 g_driver_glx.fn.glXSwapIntervalMESAFn) {
191 glXSwapIntervalMESA(interval);
192 } else {
193 if(interval == 0)
194 LOG(WARNING) <<
195 "Could not disable vsync: driver does not "
196 "support GLX_EXT_swap_control";
200 std::string GLContextGLX::GetExtensions() {
201 DCHECK(IsCurrent(NULL));
202 const char* extensions = GLSurfaceGLX::GetGLXExtensions();
203 if (extensions) {
204 return GLContext::GetExtensions() + " " + extensions;
207 return GLContext::GetExtensions();
210 bool GLContextGLX::GetTotalGpuMemory(size_t* bytes) {
211 DCHECK(bytes);
212 *bytes = 0;
213 if (HasExtension("GL_NVX_gpu_memory_info")) {
214 GLint kbytes = 0;
215 glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &kbytes);
216 *bytes = 1024*kbytes;
217 return true;
219 return false;
222 bool GLContextGLX::WasAllocatedUsingRobustnessExtension() {
223 return GLSurfaceGLX::IsCreateContextRobustnessSupported();
226 GLContextGLX::~GLContextGLX() {
227 Destroy();
230 } // namespace gfx