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.
6 #include <X11/extensions/Xcomposite.h>
9 #include "ui/gl/gl_image_glx.h"
11 #include "base/basictypes.h"
12 #include "base/logging.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/message_loop/message_loop.h"
15 #include "ui/gfx/x/x11_types.h"
16 #include "ui/gl/gl_bindings.h"
17 #include "ui/gl/gl_surface_glx.h"
23 // scoped_ptr functor for XFree(). Use as follows:
24 // scoped_ptr<XVisualInfo, ScopedPtrXFree> foo(...);
25 // where "XVisualInfo" is any X type that is freed with XFree.
26 struct ScopedPtrXFree
{
27 void operator()(void* x
) const { ::XFree(x
); }
30 int BindToTextureFormat(int depth
) {
32 return GLX_BIND_TO_TEXTURE_RGBA_EXT
;
34 return GLX_BIND_TO_TEXTURE_RGB_EXT
;
37 int TextureFormat(int depth
) {
39 return GLX_TEXTURE_FORMAT_RGBA_EXT
;
41 return GLX_TEXTURE_FORMAT_RGB_EXT
;
44 } // namespace anonymous
46 GLImageGLX::GLImageGLX(gfx::PluginWindowHandle window
)
47 : display_(gfx::GetXDisplay()),
52 GLImageGLX::~GLImageGLX() { Destroy(); }
54 bool GLImageGLX::Initialize() {
55 if (!GLSurfaceGLX::IsTextureFromPixmapSupported()) {
56 LOG(ERROR
) << "GLX_EXT_texture_from_pixmap not supported.";
60 XWindowAttributes attributes
;
61 if (!XGetWindowAttributes(display_
, window_
, &attributes
)) {
62 LOG(ERROR
) << "XGetWindowAttributes failed for window " << window_
<< ".";
67 templ
.visualid
= XVisualIDFromVisual(attributes
.visual
);
69 scoped_ptr
<XVisualInfo
, ScopedPtrXFree
> visinfo(
70 XGetVisualInfo(display_
, VisualIDMask
, &templ
, &num_visinfo
));
72 LOG(ERROR
) << "XGetVisualInfo failed for visual id " << templ
.visualid
77 LOG(ERROR
) << "XGetVisualInfo returned 0 elements.";
81 int config_attribs
[] = {
82 static_cast<int>(GLX_VISUAL_ID
), static_cast<int>(visinfo
->visualid
),
83 GLX_DRAWABLE_TYPE
, GLX_PIXMAP_BIT
,
84 GLX_BIND_TO_TEXTURE_TARGETS_EXT
, GLX_TEXTURE_2D_EXT
,
85 BindToTextureFormat(visinfo
->depth
), GL_TRUE
,
88 scoped_ptr
<GLXFBConfig
, ScopedPtrXFree
> config(glXChooseFBConfig(
89 display_
, DefaultScreen(display_
), config_attribs
, &num_elements
));
91 LOG(ERROR
) << "glXChooseFBConfig failed.";
95 LOG(ERROR
) << "glXChooseFBConfig returned 0 elements.";
99 // Create backing pixmap reference.
100 pixmap_
= XCompositeNameWindowPixmap(display_
, window_
);
105 unsigned int width
= 0;
106 unsigned int height
= 0;
108 unsigned int depth
= 0;
110 display_
, pixmap_
, &root
, &x
, &y
, &width
, &height
, &bw
, &depth
)) {
111 LOG(ERROR
) << "XGetGeometry failed for pixmap " << pixmap_
<< ".";
115 int pixmap_attribs
[] = {GLX_TEXTURE_TARGET_EXT
, GLX_TEXTURE_2D_EXT
,
116 GLX_TEXTURE_FORMAT_EXT
, TextureFormat(visinfo
->depth
),
119 glXCreatePixmap(display_
, *config
.get(), pixmap_
, pixmap_attribs
);
121 LOG(ERROR
) << "glXCreatePixmap failed.";
125 size_
= gfx::Size(width
, height
);
129 void GLImageGLX::Destroy() {
131 glXDestroyGLXPixmap(display_
, glx_pixmap_
);
135 XFreePixmap(display_
, pixmap_
);
140 gfx::Size
GLImageGLX::GetSize() { return size_
; }
142 bool GLImageGLX::BindTexImage(unsigned target
) {
146 // Requires TEXTURE_2D target.
147 if (target
!= GL_TEXTURE_2D
)
150 glXBindTexImageEXT(display_
, glx_pixmap_
, GLX_FRONT_LEFT_EXT
, 0);
154 void GLImageGLX::ReleaseTexImage(unsigned target
) {
156 DCHECK_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
), target
);
158 glXReleaseTexImageEXT(display_
, glx_pixmap_
, GLX_FRONT_LEFT_EXT
);