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_image_glx.h"
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "ui/gl/gl_bindings.h"
14 #include "ui/gl/gl_surface_glx.h"
20 // scoped_ptr functor for XFree(). Use as follows:
21 // scoped_ptr<XVisualInfo, ScopedPtrXFree> foo(...);
22 // where "XVisualInfo" is any X type that is freed with XFree.
23 struct ScopedPtrXFree
{
24 void operator()(void* x
) const { ::XFree(x
); }
27 bool ValidFormat(unsigned internalformat
) {
28 switch (internalformat
) {
36 int TextureFormat(unsigned internalformat
) {
37 switch (internalformat
) {
39 return GLX_TEXTURE_FORMAT_RGBA_EXT
;
46 int BindToTextureFormat(unsigned internalformat
) {
47 switch (internalformat
) {
49 return GLX_BIND_TO_TEXTURE_RGBA_EXT
;
56 unsigned PixmapDepth(unsigned internalformat
) {
57 switch (internalformat
) {
66 bool ActualPixmapGeometry(XID pixmap
, gfx::Size
* size
, unsigned* depth
) {
70 unsigned width_return
;
71 unsigned height_return
;
72 unsigned border_width_return
;
73 unsigned depth_return
;
74 if (!XGetGeometry(gfx::GetXDisplay(),
86 *size
= gfx::Size(width_return
, height_return
);
88 *depth
= depth_return
;
92 unsigned ActualPixmapDepth(XID pixmap
) {
94 if (!ActualPixmapGeometry(pixmap
, NULL
, &depth
))
100 gfx::Size
ActualPixmapSize(XID pixmap
) {
102 if (!ActualPixmapGeometry(pixmap
, &size
, NULL
))
108 } // namespace anonymous
110 GLImageGLX::GLImageGLX(const gfx::Size
& size
, unsigned internalformat
)
111 : glx_pixmap_(0), size_(size
), internalformat_(internalformat
) {
114 GLImageGLX::~GLImageGLX() {
115 DCHECK_EQ(0u, glx_pixmap_
);
118 bool GLImageGLX::Initialize(XID pixmap
) {
119 if (!GLSurfaceGLX::IsTextureFromPixmapSupported()) {
120 DVLOG(0) << "GLX_EXT_texture_from_pixmap not supported.";
124 if (!ValidFormat(internalformat_
)) {
125 DVLOG(0) << "Invalid format: " << internalformat_
;
129 DCHECK_EQ(PixmapDepth(internalformat_
), ActualPixmapDepth(pixmap
));
130 DCHECK_EQ(size_
.ToString(), ActualPixmapSize(pixmap
).ToString());
132 int config_attribs
[] = {
133 GLX_DRAWABLE_TYPE
, GLX_PIXMAP_BIT
,
134 GLX_BIND_TO_TEXTURE_TARGETS_EXT
, GLX_TEXTURE_2D_EXT
,
135 BindToTextureFormat(internalformat_
), GL_TRUE
,
137 int num_elements
= 0;
138 scoped_ptr
<GLXFBConfig
, ScopedPtrXFree
> config(
139 glXChooseFBConfig(gfx::GetXDisplay(),
140 DefaultScreen(gfx::GetXDisplay()),
144 DVLOG(0) << "glXChooseFBConfig failed.";
148 DVLOG(0) << "glXChooseFBConfig returned 0 elements.";
152 int pixmap_attribs
[] = {GLX_TEXTURE_TARGET_EXT
, GLX_TEXTURE_2D_EXT
,
153 GLX_TEXTURE_FORMAT_EXT
,
154 TextureFormat(internalformat_
), 0};
155 glx_pixmap_
= glXCreatePixmap(
156 gfx::GetXDisplay(), *config
.get(), pixmap
, pixmap_attribs
);
158 DVLOG(0) << "glXCreatePixmap failed.";
165 void GLImageGLX::Destroy(bool have_context
) {
167 glXDestroyGLXPixmap(gfx::GetXDisplay(), glx_pixmap_
);
172 gfx::Size
GLImageGLX::GetSize() { return size_
; }
174 bool GLImageGLX::BindTexImage(unsigned target
) {
178 // Requires TEXTURE_2D target.
179 if (target
!= GL_TEXTURE_2D
)
182 glXBindTexImageEXT(gfx::GetXDisplay(), glx_pixmap_
, GLX_FRONT_LEFT_EXT
, 0);
186 void GLImageGLX::ReleaseTexImage(unsigned target
) {
187 DCHECK_NE(0u, glx_pixmap_
);
188 DCHECK_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
), target
);
190 glXReleaseTexImageEXT(gfx::GetXDisplay(), glx_pixmap_
, GLX_FRONT_LEFT_EXT
);
193 bool GLImageGLX::ScheduleOverlayPlane(gfx::AcceleratedWidget widget
,
195 OverlayTransform transform
,
196 const Rect
& bounds_rect
,
197 const RectF
& crop_rect
) {