| 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 #include "ui/gl/gl_image_glx.h" | 
|  | 6 | 
|  | 7 #include "base/basictypes.h" | 
|  | 8 #include "base/logging.h" | 
|  | 9 #include "base/memory/scoped_ptr.h" | 
|  | 10 #include "ui/gl/gl_surface.h" | 
|  | 11 | 
|  | 12 namespace gfx { | 
|  | 13 | 
|  | 14 namespace { | 
|  | 15 | 
|  | 16 // scoped_ptr functor for XFree(). Use as follows: | 
|  | 17 //   scoped_ptr_malloc<XVisualInfo, ScopedPtrXFree> foo(...); | 
|  | 18 // where "XVisualInfo" is any X type that is freed with XFree. | 
|  | 19 class ScopedPtrXFree { | 
|  | 20  public: | 
|  | 21   void operator()(void* x) const { | 
|  | 22     ::XFree(x); | 
|  | 23   } | 
|  | 24 }; | 
|  | 25 | 
|  | 26 }  // namespace anonymous | 
|  | 27 | 
|  | 28 | 
|  | 29 PixmapGLImageGLX::PixmapGLImageGLX() | 
|  | 30   : display_(NULL), | 
|  | 31     pixmap_(0), | 
|  | 32     glx_pixmap_(0) { | 
|  | 33 } | 
|  | 34 | 
|  | 35 bool PixmapGLImageGLX::Initialize(GLSurface* compatible_surface) { | 
|  | 36   display_ = static_cast<Display*>(compatible_surface->GetDisplay()); | 
|  | 37   return true; | 
|  | 38 } | 
|  | 39 | 
|  | 40 void PixmapGLImageGLX::Destroy() { | 
|  | 41   pixmap_ = 0; | 
|  | 42   if (glx_pixmap_) { | 
|  | 43     glXDestroyGLXPixmap(display_, glx_pixmap_); | 
|  | 44     glx_pixmap_ = 0; | 
|  | 45   } | 
|  | 46 } | 
|  | 47 | 
|  | 48 gfx::Size PixmapGLImageGLX::GetSize() { | 
|  | 49   return size_; | 
|  | 50 } | 
|  | 51 | 
|  | 52 bool PixmapGLImageGLX::RebindPixmap(GLuint pixmap) { | 
|  | 53   XID glx_pixmap = glx_pixmap_; | 
|  | 54 | 
|  | 55   if (pixmap && pixmap != pixmap_) { | 
|  | 56     XID root; | 
|  | 57     int x, y; | 
|  | 58     unsigned int width, height, border_width, depth; | 
|  | 59     if (!XGetGeometry(display_, pixmap, &root, &x, &y, &width, &height, | 
|  | 60                       &border_width, &depth)) { | 
|  | 61       LOG(ERROR) << "XGetGeometry failed for pixmap " << pixmap << "."; | 
|  | 62       return false; | 
|  | 63     } | 
|  | 64     size_ = gfx::Size(width, height); | 
|  | 65 | 
|  | 66     int num_elements = 0; | 
|  | 67     scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> configs( | 
|  | 68         glXGetFBConfigs(display_, | 
|  | 69                         DefaultScreen(display_), | 
|  | 70                         &num_elements)); | 
|  | 71     if (!configs.get()) { | 
|  | 72       LOG(ERROR) << "glXGetFBConfigs failed."; | 
|  | 73       return false; | 
|  | 74     } | 
|  | 75     if (!num_elements) { | 
|  | 76       LOG(ERROR) << "glXGetFBConfigs returned 0 elements."; | 
|  | 77       return false; | 
|  | 78     } | 
|  | 79     bool found = false; | 
|  | 80     int i; | 
|  | 81     for (i = 0; i < num_elements; ++i) { | 
|  | 82       int value; | 
|  | 83       if (glXGetFBConfigAttrib( | 
|  | 84               display_, configs.get()[i], GLX_DRAWABLE_TYPE, &value)) { | 
|  | 85         LOG(ERROR) << "glXGetFBConfigAttrib failed."; | 
|  | 86         return false; | 
|  | 87       } | 
|  | 88       if (!(value & GLX_PIXMAP_BIT)) | 
|  | 89         continue; | 
|  | 90       if (glXGetFBConfigAttrib( | 
|  | 91               display_, configs.get()[i], GLX_BIND_TO_TEXTURE_TARGETS_EXT, | 
|  | 92               &value)) { | 
|  | 93         LOG(ERROR) << "glXGetFBConfigAttrib failed."; | 
|  | 94         return false; | 
|  | 95       } | 
|  | 96       if (!(value & GLX_TEXTURE_2D_BIT_EXT)) | 
|  | 97         continue; | 
|  | 98       if (glXGetFBConfigAttrib( | 
|  | 99               display_, configs.get()[i], (depth == 32) ? | 
|  | 100               GLX_BIND_TO_TEXTURE_RGBA_EXT : GLX_BIND_TO_TEXTURE_RGB_EXT, | 
|  | 101               &value)) { | 
|  | 102         LOG(ERROR) << "glXGetFBConfigAttrib failed."; | 
|  | 103         return false; | 
|  | 104       } | 
|  | 105       if (value == GL_FALSE) | 
|  | 106         continue; | 
|  | 107       if (glXGetFBConfigAttrib( | 
|  | 108               display_, configs.get()[i], GLX_DOUBLEBUFFER, &value)) { | 
|  | 109         LOG(ERROR) << "glXGetFBConfigAttrib failed."; | 
|  | 110         return false; | 
|  | 111       } | 
|  | 112       // Avoid double buffered config. | 
|  | 113       if (value == GL_TRUE) | 
|  | 114         continue; | 
|  | 115       if (glXGetFBConfigAttrib( | 
|  | 116               display_, configs.get()[i], GLX_BUFFER_SIZE, &value)) { | 
|  | 117         LOG(ERROR) << "glXGetFBConfigAttrib failed."; | 
|  | 118         return false; | 
|  | 119       } | 
|  | 120       if (value < static_cast<int>(depth)) | 
|  | 121         continue; | 
|  | 122 | 
|  | 123       found = true; | 
|  | 124       break; | 
|  | 125     } | 
|  | 126 | 
|  | 127     if (!found) { | 
|  | 128       LOG(ERROR) << "Failed to find valid FBConfig for pixmap."; | 
|  | 129       return false; | 
|  | 130     } | 
|  | 131 | 
|  | 132     std::vector<int> attribs; | 
|  | 133     attribs.push_back(GLX_TEXTURE_TARGET_EXT); | 
|  | 134     attribs.push_back(GLX_TEXTURE_2D_EXT); | 
|  | 135     attribs.push_back(GLX_TEXTURE_FORMAT_EXT); | 
|  | 136     if (depth == 32) | 
|  | 137       attribs.push_back(GLX_TEXTURE_FORMAT_RGBA_EXT); | 
|  | 138     else | 
|  | 139       attribs.push_back(GLX_TEXTURE_FORMAT_RGB_EXT); | 
|  | 140     attribs.push_back(0); | 
|  | 141 | 
|  | 142     glx_pixmap = glXCreatePixmap( | 
|  | 143         display_, | 
|  | 144         configs.get()[i], | 
|  | 145         pixmap, | 
|  | 146         &attribs.front()); | 
|  | 147     if (!glx_pixmap) { | 
|  | 148       LOG(ERROR) << "glXCreatePixmap failed."; | 
|  | 149       return false; | 
|  | 150     } | 
|  | 151   } | 
|  | 152 | 
|  | 153   // Release currently bound pixmap from texture. | 
|  | 154   if (glx_pixmap_) | 
|  | 155     glXReleaseTexImageEXT(display_, glx_pixmap_, GLX_FRONT_LEFT_EXT); | 
|  | 156 | 
|  | 157   pixmap_ = pixmap; | 
|  | 158   glx_pixmap_ = glx_pixmap; | 
|  | 159 | 
|  | 160   // Bind new pixmap to texture. | 
|  | 161   if (glx_pixmap_) | 
|  | 162     glXBindTexImageEXT(display_, glx_pixmap_, GLX_FRONT_LEFT_EXT, 0); | 
|  | 163 | 
|  | 164   return true; | 
|  | 165 } | 
|  | 166 | 
|  | 167 PixmapGLImageGLX::~PixmapGLImageGLX() { | 
|  | 168   Destroy(); | 
|  | 169 } | 
|  | 170 | 
|  | 171 }  // namespace gfx | 
| OLD | NEW | 
|---|