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 "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "ui/gl/gl_bindings.h"
12 #include "ui/gl/gl_image_glx.h"
13 #include "ui/gl/gl_surface_glx.h"
19 // scoped_ptr functor for XFree(). Use as follows:
20 // scoped_ptr<XVisualInfo, ScopedPtrXFree> foo(...);
21 // where "XVisualInfo" is any X type that is freed with XFree.
22 struct ScopedPtrXFree
{
23 void operator()(void* x
) const { ::XFree(x
); }
26 bool ValidFormat(unsigned internalformat
) {
27 switch (internalformat
) {
36 int TextureFormat(unsigned internalformat
) {
37 switch (internalformat
) {
39 return GLX_TEXTURE_FORMAT_RGB_EXT
;
41 return GLX_TEXTURE_FORMAT_RGBA_EXT
;
48 int BindToTextureFormat(unsigned internalformat
) {
49 switch (internalformat
) {
51 return GLX_BIND_TO_TEXTURE_RGB_EXT
;
53 return GLX_BIND_TO_TEXTURE_RGBA_EXT
;
60 unsigned PixmapDepth(unsigned internalformat
) {
61 switch (internalformat
) {
72 bool ActualPixmapGeometry(XID pixmap
, gfx::Size
* size
, unsigned* depth
) {
76 unsigned width_return
;
77 unsigned height_return
;
78 unsigned border_width_return
;
79 unsigned depth_return
;
80 if (!XGetGeometry(gfx::GetXDisplay(),
92 *size
= gfx::Size(width_return
, height_return
);
94 *depth
= depth_return
;
98 unsigned ActualPixmapDepth(XID pixmap
) {
100 if (!ActualPixmapGeometry(pixmap
, NULL
, &depth
))
106 gfx::Size
ActualPixmapSize(XID pixmap
) {
108 if (!ActualPixmapGeometry(pixmap
, &size
, NULL
))
114 } // namespace anonymous
116 GLImageGLX::GLImageGLX(const gfx::Size
& size
, unsigned internalformat
)
117 : glx_pixmap_(0), size_(size
), internalformat_(internalformat
) {
120 GLImageGLX::~GLImageGLX() {
121 DCHECK_EQ(0u, glx_pixmap_
);
124 bool GLImageGLX::Initialize(XID pixmap
) {
125 if (!GLSurfaceGLX::IsTextureFromPixmapSupported()) {
126 DVLOG(0) << "GLX_EXT_texture_from_pixmap not supported.";
130 if (!ValidFormat(internalformat_
)) {
131 DVLOG(0) << "Invalid format: " << internalformat_
;
135 DCHECK_EQ(PixmapDepth(internalformat_
), ActualPixmapDepth(pixmap
));
136 DCHECK_EQ(size_
.ToString(), ActualPixmapSize(pixmap
).ToString());
138 int config_attribs
[] = {
139 GLX_DRAWABLE_TYPE
, GLX_PIXMAP_BIT
,
140 GLX_BIND_TO_TEXTURE_TARGETS_EXT
, GLX_TEXTURE_2D_EXT
,
141 BindToTextureFormat(internalformat_
), GL_TRUE
,
143 int num_elements
= 0;
144 scoped_ptr
<GLXFBConfig
, ScopedPtrXFree
> config(
145 glXChooseFBConfig(gfx::GetXDisplay(),
146 DefaultScreen(gfx::GetXDisplay()),
150 DVLOG(0) << "glXChooseFBConfig failed.";
154 DVLOG(0) << "glXChooseFBConfig returned 0 elements.";
158 int pixmap_attribs
[] = {GLX_TEXTURE_TARGET_EXT
, GLX_TEXTURE_2D_EXT
,
159 GLX_TEXTURE_FORMAT_EXT
,
160 TextureFormat(internalformat_
), 0};
161 glx_pixmap_
= glXCreatePixmap(
162 gfx::GetXDisplay(), *config
.get(), pixmap
, pixmap_attribs
);
164 DVLOG(0) << "glXCreatePixmap failed.";
171 void GLImageGLX::Destroy(bool have_context
) {
173 glXDestroyGLXPixmap(gfx::GetXDisplay(), glx_pixmap_
);
178 gfx::Size
GLImageGLX::GetSize() { return size_
; }
180 bool GLImageGLX::BindTexImage(unsigned target
) {
184 // Requires TEXTURE_2D target.
185 if (target
!= GL_TEXTURE_2D
)
188 glXBindTexImageEXT(gfx::GetXDisplay(), glx_pixmap_
, GLX_FRONT_LEFT_EXT
, 0);
192 void GLImageGLX::ReleaseTexImage(unsigned target
) {
193 DCHECK_NE(0u, glx_pixmap_
);
194 DCHECK_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
), target
);
196 glXReleaseTexImageEXT(gfx::GetXDisplay(), glx_pixmap_
, GLX_FRONT_LEFT_EXT
);
199 bool GLImageGLX::CopyTexImage(unsigned target
) {
203 bool GLImageGLX::ScheduleOverlayPlane(gfx::AcceleratedWidget widget
,
205 OverlayTransform transform
,
206 const Rect
& bounds_rect
,
207 const RectF
& crop_rect
) {