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/gl/gl_bindings.h"
16 #include "ui/gl/gl_surface_glx.h"
22 // scoped_ptr functor for XFree(). Use as follows:
23 // scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...);
24 // where "XVisualInfo" is any X type that is freed with XFree.
25 class ScopedPtrXFree
{
27 void operator()(void* x
) const {
32 int BindToTextureFormat(int depth
) {
34 return GLX_BIND_TO_TEXTURE_RGBA_EXT
;
36 return GLX_BIND_TO_TEXTURE_RGB_EXT
;
39 int TextureFormat(int depth
) {
41 return GLX_TEXTURE_FORMAT_RGBA_EXT
;
43 return GLX_TEXTURE_FORMAT_RGB_EXT
;
46 } // namespace anonymous
48 GLImageGLX::GLImageGLX(gfx::PluginWindowHandle window
)
49 : display_(base::MessagePumpForUI::GetDefaultXDisplay()),
55 GLImageGLX::~GLImageGLX() {
59 bool GLImageGLX::Initialize() {
60 if (!GLSurfaceGLX::IsTextureFromPixmapSupported()) {
61 LOG(ERROR
) << "GLX_EXT_texture_from_pixmap not supported.";
65 XWindowAttributes attributes
;
66 if (!XGetWindowAttributes(display_
, window_
, &attributes
)) {
67 LOG(ERROR
) << "XGetWindowAttributes failed for window " << window_
<< ".";
72 templ
.visualid
= XVisualIDFromVisual(attributes
.visual
);
74 scoped_ptr_malloc
<XVisualInfo
, ScopedPtrXFree
> visinfo(
75 XGetVisualInfo(display_
,
80 LOG(ERROR
) << "XGetVisualInfo failed for visual id " <<
81 templ
.visualid
<< ".";
85 LOG(ERROR
) << "XGetVisualInfo returned 0 elements.";
89 int config_attribs
[] = {
90 static_cast<int>(GLX_VISUAL_ID
),
91 static_cast<int>(visinfo
->visualid
),
92 GLX_DRAWABLE_TYPE
, GLX_PIXMAP_BIT
,
93 GLX_BIND_TO_TEXTURE_TARGETS_EXT
, GLX_TEXTURE_2D_EXT
,
94 BindToTextureFormat(visinfo
->depth
), GL_TRUE
,
98 scoped_ptr_malloc
<GLXFBConfig
, ScopedPtrXFree
> config(
99 glXChooseFBConfig(display_
,
100 DefaultScreen(display_
),
104 LOG(ERROR
) << "glXChooseFBConfig failed.";
108 LOG(ERROR
) << "glXChooseFBConfig returned 0 elements.";
112 // Create backing pixmap reference.
113 pixmap_
= XCompositeNameWindowPixmap(display_
, window_
);
118 unsigned int width
= 0;
119 unsigned int height
= 0;
121 unsigned int depth
= 0;
123 display_
, pixmap_
, &root
, &x
, &y
, &width
, &height
, &bw
, &depth
)) {
124 LOG(ERROR
) << "XGetGeometry failed for pixmap " << pixmap_
<< ".";
128 int pixmap_attribs
[] = {
129 GLX_TEXTURE_TARGET_EXT
, GLX_TEXTURE_2D_EXT
,
130 GLX_TEXTURE_FORMAT_EXT
, TextureFormat(visinfo
->depth
),
133 glx_pixmap_
= glXCreatePixmap(
139 LOG(ERROR
) << "glXCreatePixmap failed.";
143 size_
= gfx::Size(width
, height
);
147 void GLImageGLX::Destroy() {
149 glXDestroyGLXPixmap(display_
, glx_pixmap_
);
153 XFreePixmap(display_
, pixmap_
);
158 gfx::Size
GLImageGLX::GetSize() {
162 bool GLImageGLX::BindTexImage(unsigned target
) {
166 // Requires TEXTURE_2D target.
167 if (target
!= GL_TEXTURE_2D
)
170 glXBindTexImageEXT(display_
, glx_pixmap_
, GLX_FRONT_LEFT_EXT
, 0);
174 void GLImageGLX::ReleaseTexImage(unsigned target
) {
176 DCHECK_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
), target
);
178 glXReleaseTexImageEXT(display_
, glx_pixmap_
, GLX_FRONT_LEFT_EXT
);
181 void GLImageGLX::WillUseTexImage() {
184 void GLImageGLX::DidUseTexImage() {