NaCl: Update revision in DEPS, r12770 -> r12773
[chromium-blink-merge.git] / ui / gl / gl_image_glx.cc
blobc7b2522eb38b79484455a781dd8a4251f807bec0
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.
5 extern "C" {
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"
18 namespace gfx {
20 namespace {
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 {
26 public:
27 void operator()(void* x) const {
28 ::XFree(x);
32 int BindToTextureFormat(int depth) {
33 if (depth == 32)
34 return GLX_BIND_TO_TEXTURE_RGBA_EXT;
36 return GLX_BIND_TO_TEXTURE_RGB_EXT;
39 int TextureFormat(int depth) {
40 if (depth == 32)
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()),
50 window_(window),
51 pixmap_(0),
52 glx_pixmap_(0) {
55 GLImageGLX::~GLImageGLX() {
56 Destroy();
59 bool GLImageGLX::Initialize() {
60 if (!GLSurfaceGLX::IsTextureFromPixmapSupported()) {
61 LOG(ERROR) << "GLX_EXT_texture_from_pixmap not supported.";
62 return false;
65 XWindowAttributes attributes;
66 if (!XGetWindowAttributes(display_, window_, &attributes)) {
67 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << ".";
68 return false;
71 XVisualInfo templ;
72 templ.visualid = XVisualIDFromVisual(attributes.visual);
73 int num_visinfo = 0;
74 scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> visinfo(
75 XGetVisualInfo(display_,
76 VisualIDMask,
77 &templ,
78 &num_visinfo));
79 if (!visinfo.get()) {
80 LOG(ERROR) << "XGetVisualInfo failed for visual id " <<
81 templ.visualid << ".";
82 return false;
84 if (!num_visinfo) {
85 LOG(ERROR) << "XGetVisualInfo returned 0 elements.";
86 return false;
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,
97 int num_elements = 0;
98 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> config(
99 glXChooseFBConfig(display_,
100 DefaultScreen(display_),
101 config_attribs,
102 &num_elements));
103 if (!config.get()) {
104 LOG(ERROR) << "glXChooseFBConfig failed.";
105 return false;
107 if (!num_elements) {
108 LOG(ERROR) << "glXChooseFBConfig returned 0 elements.";
109 return false;
112 // Create backing pixmap reference.
113 pixmap_ = XCompositeNameWindowPixmap(display_, window_);
115 XID root = 0;
116 int x = 0;
117 int y = 0;
118 unsigned int width = 0;
119 unsigned int height = 0;
120 unsigned int bw = 0;
121 unsigned int depth = 0;
122 if (!XGetGeometry(
123 display_, pixmap_, &root, &x, &y, &width, &height, &bw, &depth)) {
124 LOG(ERROR) << "XGetGeometry failed for pixmap " << pixmap_ << ".";
125 return false;
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(
134 display_,
135 *config.get(),
136 pixmap_,
137 pixmap_attribs);
138 if (!glx_pixmap_) {
139 LOG(ERROR) << "glXCreatePixmap failed.";
140 return false;
143 size_ = gfx::Size(width, height);
144 return true;
147 void GLImageGLX::Destroy() {
148 if (glx_pixmap_) {
149 glXDestroyGLXPixmap(display_, glx_pixmap_);
150 glx_pixmap_ = 0;
152 if (pixmap_) {
153 XFreePixmap(display_, pixmap_);
154 pixmap_ = 0;
158 gfx::Size GLImageGLX::GetSize() {
159 return size_;
162 bool GLImageGLX::BindTexImage(unsigned target) {
163 if (!glx_pixmap_)
164 return false;
166 // Requires TEXTURE_2D target.
167 if (target != GL_TEXTURE_2D)
168 return false;
170 glXBindTexImageEXT(display_, glx_pixmap_, GLX_FRONT_LEFT_EXT, 0);
171 return true;
174 void GLImageGLX::ReleaseTexImage(unsigned target) {
175 DCHECK(glx_pixmap_);
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() {
187 } // namespace gfx