OLD | NEW |
---|---|
(Empty) | |
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. | |
4 | |
5 extern "C" { | |
6 #include <X11/extensions/Xcomposite.h> | |
7 } | |
8 | |
9 #include "ui/gl/gl_image_glx.h" | |
10 | |
11 #include "base/basictypes.h" | |
12 #include "base/logging.h" | |
13 #include "base/memory/scoped_ptr.h" | |
14 #include "base/message_loop.h" | |
15 #include "ui/gl/gl_surface_glx.h" | |
16 | |
17 namespace gfx { | |
18 | |
19 namespace { | |
20 | |
21 // scoped_ptr functor for XFree(). Use as follows: | |
22 // scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...); | |
23 // where "XVisualInfo" is any X type that is freed with XFree. | |
24 class ScopedPtrXFree { | |
25 public: | |
26 void operator()(void* x) const { | |
27 ::XFree(x); | |
28 } | |
29 }; | |
30 | |
31 } // namespace anonymous | |
32 | |
33 GLImageGLX::GLImageGLX(gfx::PluginWindowHandle window) | |
34 : display_(base::MessagePumpForUI::GetDefaultXDisplay()), | |
35 pixmap_(XCompositeNameWindowPixmap(display_, window)), | |
36 glx_pixmap_(0) { | |
37 } | |
38 | |
39 bool GLImageGLX::Initialize() { | |
40 if (!GLSurfaceGLX::IsTextureFromPixmapSupported()) { | |
41 LOG(ERROR) << "GLX_EXT_texture_from_pixmap not supported."; | |
42 return false; | |
43 } | |
44 | |
45 XID root; | |
46 int x, y; | |
47 unsigned int width, height, border_width, depth; | |
piman
2012/10/12 22:05:11
nit: please initialize all local variables.
reveman
2012/10/13 05:25:53
Done.
| |
48 if (!XGetGeometry(display_, pixmap_, &root, &x, &y, &width, &height, | |
49 &border_width, &depth)) { | |
50 LOG(ERROR) << "XGetGeometry failed for pixmap " << pixmap_ << "."; | |
51 return false; | |
52 } | |
53 | |
54 int num_elements = 0; | |
55 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> configs( | |
56 glXGetFBConfigs(display_, | |
57 DefaultScreen(display_), | |
58 &num_elements)); | |
59 if (!configs.get()) { | |
60 LOG(ERROR) << "glXGetFBConfigs failed."; | |
61 return false; | |
62 } | |
63 if (!num_elements) { | |
64 LOG(ERROR) << "glXGetFBConfigs returned 0 elements."; | |
65 return false; | |
66 } | |
67 bool found = false; | |
68 int i; | |
piman
2012/10/12 22:05:11
nit move the = 0 initialization here.
reveman
2012/10/13 05:25:53
Done.
| |
69 for (i = 0; i < num_elements; ++i) { | |
70 int value; | |
piman
2012/10/12 22:05:11
nit: initialize
reveman
2012/10/13 05:25:53
Done.
| |
71 if (glXGetFBConfigAttrib( | |
72 display_, configs.get()[i], GLX_DRAWABLE_TYPE, &value)) { | |
73 LOG(ERROR) << "glXGetFBConfigAttrib failed."; | |
74 return false; | |
75 } | |
76 if (!(value & GLX_PIXMAP_BIT)) | |
77 continue; | |
78 if (glXGetFBConfigAttrib( | |
79 display_, configs.get()[i], GLX_BIND_TO_TEXTURE_TARGETS_EXT, | |
80 &value)) { | |
81 LOG(ERROR) << "glXGetFBConfigAttrib failed."; | |
82 return false; | |
83 } | |
84 if (!(value & GLX_TEXTURE_2D_BIT_EXT)) | |
85 continue; | |
86 if (glXGetFBConfigAttrib( | |
87 display_, configs.get()[i], (depth == 32) ? | |
88 GLX_BIND_TO_TEXTURE_RGBA_EXT : GLX_BIND_TO_TEXTURE_RGB_EXT, | |
piman
2012/10/12 22:05:11
so, techincally, we can have RGB windows in a 32 b
reveman
2012/10/13 05:25:53
Done.
| |
89 &value)) { | |
90 LOG(ERROR) << "glXGetFBConfigAttrib failed."; | |
91 return false; | |
92 } | |
93 if (value == GL_FALSE) | |
94 continue; | |
95 if (glXGetFBConfigAttrib( | |
96 display_, configs.get()[i], GLX_DOUBLEBUFFER, &value)) { | |
97 LOG(ERROR) << "glXGetFBConfigAttrib failed."; | |
98 return false; | |
99 } | |
100 // Avoid double buffered config. | |
101 if (value == GL_TRUE) | |
102 continue; | |
103 if (glXGetFBConfigAttrib( | |
104 display_, configs.get()[i], GLX_BUFFER_SIZE, &value)) { | |
105 LOG(ERROR) << "glXGetFBConfigAttrib failed."; | |
106 return false; | |
107 } | |
108 if (value < static_cast<int>(depth)) | |
109 continue; | |
110 | |
111 found = true; | |
112 break; | |
113 } | |
piman
2012/10/12 22:05:11
Can we replace all this by glXChooseFBConfig?
reveman
2012/10/13 05:25:53
Done.
| |
114 | |
115 if (!found) { | |
116 LOG(ERROR) << "Failed to find valid FBConfig for pixmap."; | |
117 return false; | |
118 } | |
119 | |
120 std::vector<int> attribs; | |
121 attribs.push_back(GLX_TEXTURE_TARGET_EXT); | |
122 attribs.push_back(GLX_TEXTURE_2D_EXT); | |
123 attribs.push_back(GLX_TEXTURE_FORMAT_EXT); | |
124 if (depth == 32) | |
125 attribs.push_back(GLX_TEXTURE_FORMAT_RGBA_EXT); | |
126 else | |
127 attribs.push_back(GLX_TEXTURE_FORMAT_RGB_EXT); | |
128 attribs.push_back(0); | |
piman
2012/10/12 22:05:11
Since the array is fixed size, can we just make th
reveman
2012/10/13 05:25:53
Done.
| |
129 | |
130 glx_pixmap_ = glXCreatePixmap( | |
131 display_, | |
132 configs.get()[i], | |
133 pixmap_, | |
134 &attribs.front()); | |
135 if (!glx_pixmap_) { | |
136 LOG(ERROR) << "glXCreatePixmap failed."; | |
137 return false; | |
138 } | |
139 | |
140 size_ = gfx::Size(width, height); | |
141 return true; | |
142 } | |
143 | |
144 void GLImageGLX::Destroy() { | |
145 if (glx_pixmap_) { | |
146 glXDestroyGLXPixmap(display_, glx_pixmap_); | |
147 glx_pixmap_ = 0; | |
148 } | |
149 if (pixmap_) { | |
150 XFreePixmap(display_, pixmap_); | |
151 pixmap_ = 0; | |
152 } | |
153 } | |
154 | |
155 gfx::Size GLImageGLX::GetSize() { | |
156 return size_; | |
157 } | |
158 | |
159 bool GLImageGLX::BindTexImage() { | |
160 if (!glx_pixmap_) | |
161 return false; | |
162 | |
163 glXBindTexImageEXT(display_, glx_pixmap_, GLX_FRONT_LEFT_EXT, 0); | |
164 return true; | |
165 } | |
166 | |
167 void GLImageGLX::ReleaseTexImage() { | |
168 if (!glx_pixmap_) | |
169 return; | |
170 | |
171 glXReleaseTexImageEXT(display_, glx_pixmap_, GLX_FRONT_LEFT_EXT); | |
172 } | |
173 | |
174 GLImageGLX::~GLImageGLX() { | |
175 Destroy(); | |
176 } | |
177 | |
178 } // namespace gfx | |
OLD | NEW |