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 bool ValidFormat(unsigned internalformat
) {
20 switch (internalformat
) {
29 int TextureFormat(unsigned internalformat
) {
30 switch (internalformat
) {
32 return GLX_TEXTURE_FORMAT_RGB_EXT
;
34 return GLX_TEXTURE_FORMAT_RGBA_EXT
;
41 int BindToTextureFormat(unsigned internalformat
) {
42 switch (internalformat
) {
44 return GLX_BIND_TO_TEXTURE_RGB_EXT
;
46 return GLX_BIND_TO_TEXTURE_RGBA_EXT
;
53 unsigned PixmapDepth(unsigned internalformat
) {
54 switch (internalformat
) {
65 bool ActualPixmapGeometry(XID pixmap
, gfx::Size
* size
, unsigned* depth
) {
69 unsigned width_return
;
70 unsigned height_return
;
71 unsigned border_width_return
;
72 unsigned depth_return
;
73 if (!XGetGeometry(gfx::GetXDisplay(),
85 *size
= gfx::Size(width_return
, height_return
);
87 *depth
= depth_return
;
91 unsigned ActualPixmapDepth(XID pixmap
) {
93 if (!ActualPixmapGeometry(pixmap
, NULL
, &depth
))
99 gfx::Size
ActualPixmapSize(XID pixmap
) {
101 if (!ActualPixmapGeometry(pixmap
, &size
, NULL
))
107 } // namespace anonymous
109 GLImageGLX::GLImageGLX(const gfx::Size
& size
, unsigned internalformat
)
110 : glx_pixmap_(0), size_(size
), internalformat_(internalformat
) {
113 GLImageGLX::~GLImageGLX() {
114 DCHECK_EQ(0u, glx_pixmap_
);
117 bool GLImageGLX::Initialize(XID pixmap
) {
118 if (!GLSurfaceGLX::IsTextureFromPixmapSupported()) {
119 DVLOG(0) << "GLX_EXT_texture_from_pixmap not supported.";
123 if (!ValidFormat(internalformat_
)) {
124 DVLOG(0) << "Invalid format: " << internalformat_
;
128 DCHECK_EQ(PixmapDepth(internalformat_
), ActualPixmapDepth(pixmap
));
129 DCHECK_EQ(size_
.ToString(), ActualPixmapSize(pixmap
).ToString());
131 int config_attribs
[] = {
132 GLX_DRAWABLE_TYPE
, GLX_PIXMAP_BIT
,
133 GLX_BIND_TO_TEXTURE_TARGETS_EXT
, GLX_TEXTURE_2D_EXT
,
134 BindToTextureFormat(internalformat_
), GL_TRUE
,
136 int num_elements
= 0;
137 gfx::XScopedPtr
<GLXFBConfig
> config(
138 glXChooseFBConfig(gfx::GetXDisplay(), DefaultScreen(gfx::GetXDisplay()),
139 config_attribs
, &num_elements
));
141 DVLOG(0) << "glXChooseFBConfig failed.";
145 DVLOG(0) << "glXChooseFBConfig returned 0 elements.";
149 int pixmap_attribs
[] = {GLX_TEXTURE_TARGET_EXT
, GLX_TEXTURE_2D_EXT
,
150 GLX_TEXTURE_FORMAT_EXT
,
151 TextureFormat(internalformat_
), 0};
152 glx_pixmap_
= glXCreatePixmap(
153 gfx::GetXDisplay(), *config
.get(), pixmap
, pixmap_attribs
);
155 DVLOG(0) << "glXCreatePixmap failed.";
162 void GLImageGLX::Destroy(bool have_context
) {
164 glXDestroyGLXPixmap(gfx::GetXDisplay(), glx_pixmap_
);
169 gfx::Size
GLImageGLX::GetSize() { return size_
; }
171 unsigned GLImageGLX::GetInternalFormat() { return internalformat_
; }
173 bool GLImageGLX::BindTexImage(unsigned target
) {
177 // Requires TEXTURE_2D target.
178 if (target
!= GL_TEXTURE_2D
)
181 glXBindTexImageEXT(gfx::GetXDisplay(), glx_pixmap_
, GLX_FRONT_LEFT_EXT
, 0);
185 void GLImageGLX::ReleaseTexImage(unsigned target
) {
186 DCHECK_NE(0u, glx_pixmap_
);
187 DCHECK_EQ(static_cast<GLenum
>(GL_TEXTURE_2D
), target
);
189 glXReleaseTexImageEXT(gfx::GetXDisplay(), glx_pixmap_
, GLX_FRONT_LEFT_EXT
);
192 bool GLImageGLX::CopyTexSubImage(unsigned target
,
198 bool GLImageGLX::ScheduleOverlayPlane(gfx::AcceleratedWidget widget
,
200 OverlayTransform transform
,
201 const Rect
& bounds_rect
,
202 const RectF
& crop_rect
) {