Index: ui/gl/gl_surface_glx.cc |
diff --git a/ui/gl/gl_surface_glx.cc b/ui/gl/gl_surface_glx.cc |
index a5609cd8e23cf35e0b20a3506d0150e3c9bf53ee..5cc4fe1313db6af5c070808354a1a987d1e1e93f 100644 |
--- a/ui/gl/gl_surface_glx.cc |
+++ b/ui/gl/gl_surface_glx.cc |
@@ -321,4 +321,150 @@ PbufferGLSurfaceGLX::~PbufferGLSurfaceGLX() { |
Destroy(); |
} |
+PixmapGLSurfaceGLX::PixmapGLSurfaceGLX(XID pixmap) |
+ : config_(NULL), |
+ pixmap_(pixmap), |
+ glx_pixmap_(0) { |
+} |
+ |
+bool PixmapGLSurfaceGLX::Initialize() { |
+ DCHECK(pixmap_); |
+ |
+ XID root; |
+ int x, y; |
+ unsigned int width, height, border_width, depth; |
+ if (!XGetGeometry(g_display, pixmap_, &root, &x, &y, &width, &height, |
+ &border_width, &depth)) { |
+ LOG(ERROR) << "XGetGeometry failed for pixmap " << pixmap_ << "."; |
+ return false; |
+ } |
+ size_ = gfx::Size(width, height); |
+ |
+ int num_elements = 0; |
+ scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> configs( |
+ glXGetFBConfigs(g_display, |
+ DefaultScreen(g_display), |
+ &num_elements)); |
+ if (!configs.get()) { |
+ LOG(ERROR) << "glXGetFBConfigs failed."; |
+ return false; |
+ } |
+ if (!num_elements) { |
+ LOG(ERROR) << "glXGetFBConfigs returned 0 elements."; |
+ return false; |
+ } |
+ bool found = false; |
+ int i; |
+ for (i = 0; i < num_elements; ++i) { |
+ int value; |
+ if (glXGetFBConfigAttrib( |
+ g_display, configs.get()[i], GLX_DRAWABLE_TYPE, &value)) { |
+ LOG(ERROR) << "glXGetFBConfigAttrib failed."; |
+ return false; |
+ } |
+ if (!(value & GLX_PIXMAP_BIT)) |
+ continue; |
+ if (glXGetFBConfigAttrib( |
+ g_display, configs.get()[i], GLX_BIND_TO_TEXTURE_TARGETS_EXT, |
+ &value)) { |
+ LOG(ERROR) << "glXGetFBConfigAttrib failed."; |
+ return false; |
+ } |
+ if (!(value & GLX_TEXTURE_2D_BIT_EXT)) |
+ continue; |
+ if (glXGetFBConfigAttrib( |
+ g_display, configs.get()[i], (depth == 32) ? |
+ GLX_BIND_TO_TEXTURE_RGBA_EXT : GLX_BIND_TO_TEXTURE_RGB_EXT, |
+ &value)) { |
+ LOG(ERROR) << "glXGetFBConfigAttrib failed."; |
+ return false; |
+ } |
+ if (value == GL_FALSE) |
+ continue; |
+ if (glXGetFBConfigAttrib( |
+ g_display, configs.get()[i], GLX_DOUBLEBUFFER, &value)) { |
+ LOG(ERROR) << "glXGetFBConfigAttrib failed."; |
+ return false; |
+ } |
+ // Avoid double buffered config. |
+ if (value == GL_TRUE) |
+ continue; |
+ if (glXGetFBConfigAttrib( |
+ g_display, configs.get()[i], GLX_BUFFER_SIZE, &value)) { |
+ LOG(ERROR) << "glXGetFBConfigAttrib failed."; |
+ return false; |
+ } |
+ if (value < static_cast<int>(depth)) |
+ continue; |
+ |
+ found = true; |
+ break; |
+ } |
+ |
+ if (!found) { |
+ LOG(ERROR) << "Failed to find valid FBConfig for pixmap."; |
+ return false; |
+ } |
+ |
+ config_ = configs.get()[i]; |
+ |
+ std::vector<int> attribs; |
+ attribs.push_back(GLX_TEXTURE_TARGET_EXT); |
+ attribs.push_back(GLX_TEXTURE_2D_EXT); |
+ attribs.push_back(GLX_TEXTURE_FORMAT_EXT); |
+ if (depth == 32) |
+ attribs.push_back(GLX_TEXTURE_FORMAT_RGBA_EXT); |
+ else |
+ attribs.push_back(GLX_TEXTURE_FORMAT_RGB_EXT); |
+ attribs.push_back(0); |
+ |
+ glx_pixmap_ = glXCreatePixmap( |
+ g_display, static_cast<GLXFBConfig>(config_), pixmap_, &attribs.front()); |
+ if (!glx_pixmap_) { |
+ Destroy(); |
+ LOG(ERROR) << "glXCreatePixmap failed."; |
+ return false; |
+ } |
+ |
+ return true; |
+} |
+ |
+void PixmapGLSurfaceGLX::Destroy() { |
+ if (glx_pixmap_) { |
+ glXDestroyGLXPixmap(g_display, glx_pixmap_); |
+ glx_pixmap_ = 0; |
+ } |
+ |
+ config_ = NULL; |
+} |
+ |
+bool PixmapGLSurfaceGLX::IsOffscreen() { |
+ return true; |
+} |
+ |
+bool PixmapGLSurfaceGLX::SwapBuffers() { |
+ NOTREACHED() << "Attempted to call SwapBuffers on a pixmap."; |
+ return false; |
+} |
+ |
+gfx::Size PixmapGLSurfaceGLX::GetSize() { |
+ return size_; |
+} |
+ |
+void* PixmapGLSurfaceGLX::GetHandle() { |
+ return reinterpret_cast<void*>(glx_pixmap_); |
+} |
+ |
+void* PixmapGLSurfaceGLX::GetShareHandle() { |
+ return reinterpret_cast<void*>(pixmap_); |
+} |
+ |
+void* PixmapGLSurfaceGLX::GetConfig() { |
+ return config_; |
+} |
+ |
+PixmapGLSurfaceGLX::~PixmapGLSurfaceGLX() { |
+ Destroy(); |
+} |
+ |
} // namespace gfx |