| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ui/gl/gl_surface.h" | 5 #include "ui/gl/gl_surface.h" |
| 6 | 6 |
| 7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
| 8 #include "base/logging.h" | 8 #include "base/logging.h" |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
| 11 #include "third_party/mesa/src/include/GL/osmesa.h" | 11 #include "third_party/mesa/src/include/GL/osmesa.h" |
| 12 #include "ui/gl/gl_bindings.h" | 12 #include "ui/gl/gl_bindings.h" |
| 13 #include "ui/gl/gl_implementation.h" | 13 #include "ui/gl/gl_implementation.h" |
| 14 #include "ui/gl/gl_surface_egl.h" | 14 #include "ui/gl/gl_surface_egl.h" |
| 15 #include "ui/gl/gl_surface_glx.h" | 15 #include "ui/gl/gl_surface_glx.h" |
| 16 #include "ui/gl/gl_surface_osmesa.h" | 16 #include "ui/gl/gl_surface_osmesa.h" |
| 17 #include "ui/gl/gl_surface_stub.h" | 17 #include "ui/gl/gl_surface_stub.h" |
| 18 | 18 |
| 19 namespace gfx { | 19 namespace gfx { |
| 20 | 20 |
| 21 namespace { | |
| 22 Display* g_osmesa_display; | |
| 23 } // namespace | |
| 24 | |
| 25 // This OSMesa GL surface can use XLib to swap the contents of the buffer to a | 21 // This OSMesa GL surface can use XLib to swap the contents of the buffer to a |
| 26 // view. | 22 // view. |
| 27 class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa { | 23 class NativeViewGLSurfaceOSMesa : public GLSurfaceOSMesa { |
| 28 public: | 24 public: |
| 29 explicit NativeViewGLSurfaceOSMesa(gfx::AcceleratedWidget window); | 25 explicit NativeViewGLSurfaceOSMesa(gfx::AcceleratedWidget window); |
| 30 | 26 |
| 31 static bool InitializeOneOff(); | 27 static bool InitializeOneOff(); |
| 32 | 28 |
| 33 // Implement a subset of GLSurface. | 29 // Implement a subset of GLSurface. |
| 34 virtual bool Initialize() OVERRIDE; | 30 virtual bool Initialize() OVERRIDE; |
| 35 virtual void Destroy() OVERRIDE; | 31 virtual void Destroy() OVERRIDE; |
| 36 virtual bool Resize(const gfx::Size& new_size) OVERRIDE; | 32 virtual bool Resize(const gfx::Size& new_size) OVERRIDE; |
| 37 virtual bool IsOffscreen() OVERRIDE; | 33 virtual bool IsOffscreen() OVERRIDE; |
| 38 virtual bool SwapBuffers() OVERRIDE; | 34 virtual bool SwapBuffers() OVERRIDE; |
| 39 virtual std::string GetExtensions() OVERRIDE; | 35 virtual std::string GetExtensions() OVERRIDE; |
| 40 virtual bool PostSubBuffer(int x, int y, int width, int height) OVERRIDE; | 36 virtual bool PostSubBuffer(int x, int y, int width, int height) OVERRIDE; |
| 41 | 37 |
| 42 protected: | 38 protected: |
| 43 virtual ~NativeViewGLSurfaceOSMesa(); | 39 virtual ~NativeViewGLSurfaceOSMesa(); |
| 44 | 40 |
| 45 private: | 41 private: |
| 42 Display* xdisplay_; |
| 46 GC window_graphics_context_; | 43 GC window_graphics_context_; |
| 47 gfx::AcceleratedWidget window_; | 44 gfx::AcceleratedWidget window_; |
| 48 GC pixmap_graphics_context_; | 45 GC pixmap_graphics_context_; |
| 49 Pixmap pixmap_; | 46 Pixmap pixmap_; |
| 50 | 47 |
| 51 DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceOSMesa); | 48 DISALLOW_COPY_AND_ASSIGN(NativeViewGLSurfaceOSMesa); |
| 52 }; | 49 }; |
| 53 | 50 |
| 54 bool GLSurface::InitializeOneOffInternal() { | 51 bool GLSurface::InitializeOneOffInternal() { |
| 55 switch (GetGLImplementation()) { | 52 switch (GetGLImplementation()) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 73 break; | 70 break; |
| 74 default: | 71 default: |
| 75 break; | 72 break; |
| 76 } | 73 } |
| 77 | 74 |
| 78 return true; | 75 return true; |
| 79 } | 76 } |
| 80 | 77 |
| 81 NativeViewGLSurfaceOSMesa::NativeViewGLSurfaceOSMesa( | 78 NativeViewGLSurfaceOSMesa::NativeViewGLSurfaceOSMesa( |
| 82 gfx::AcceleratedWidget window) | 79 gfx::AcceleratedWidget window) |
| 83 : GLSurfaceOSMesa(OSMESA_BGRA, gfx::Size(1, 1)), | 80 : GLSurfaceOSMesa(OSMESA_BGRA, gfx::Size(1, 1)), |
| 84 window_graphics_context_(0), | 81 xdisplay_(base::MessagePumpForUI::GetDefaultXDisplay()), |
| 85 window_(window), | 82 window_graphics_context_(0), |
| 86 pixmap_graphics_context_(0), | 83 window_(window), |
| 87 pixmap_(0) { | 84 pixmap_graphics_context_(0), |
| 88 DCHECK(window); | 85 pixmap_(0) { |
| 86 DCHECK(xdisplay_); |
| 87 DCHECK(window_); |
| 89 } | 88 } |
| 90 | 89 |
| 90 // static |
| 91 bool NativeViewGLSurfaceOSMesa::InitializeOneOff() { | 91 bool NativeViewGLSurfaceOSMesa::InitializeOneOff() { |
| 92 static bool initialized = false; | 92 static bool initialized = false; |
| 93 if (initialized) | 93 if (initialized) |
| 94 return true; | 94 return true; |
| 95 | 95 |
| 96 g_osmesa_display = base::MessagePumpForUI::GetDefaultXDisplay(); | 96 if (!base::MessagePumpForUI::GetDefaultXDisplay()) { |
| 97 if (!g_osmesa_display) { | |
| 98 LOG(ERROR) << "XOpenDisplay failed."; | 97 LOG(ERROR) << "XOpenDisplay failed."; |
| 99 return false; | 98 return false; |
| 100 } | 99 } |
| 101 | 100 |
| 102 initialized = true; | 101 initialized = true; |
| 103 return true; | 102 return true; |
| 104 } | 103 } |
| 105 | 104 |
| 106 bool NativeViewGLSurfaceOSMesa::Initialize() { | 105 bool NativeViewGLSurfaceOSMesa::Initialize() { |
| 107 if (!GLSurfaceOSMesa::Initialize()) | 106 if (!GLSurfaceOSMesa::Initialize()) |
| 108 return false; | 107 return false; |
| 109 | 108 |
| 110 window_graphics_context_ = XCreateGC(g_osmesa_display, | 109 window_graphics_context_ = XCreateGC(xdisplay_, window_, 0, NULL); |
| 111 window_, | |
| 112 0, | |
| 113 NULL); | |
| 114 if (!window_graphics_context_) { | 110 if (!window_graphics_context_) { |
| 115 LOG(ERROR) << "XCreateGC failed."; | 111 LOG(ERROR) << "XCreateGC failed."; |
| 116 Destroy(); | 112 Destroy(); |
| 117 return false; | 113 return false; |
| 118 } | 114 } |
| 119 | 115 |
| 120 return true; | 116 return true; |
| 121 } | 117 } |
| 122 | 118 |
| 123 void NativeViewGLSurfaceOSMesa::Destroy() { | 119 void NativeViewGLSurfaceOSMesa::Destroy() { |
| 124 if (pixmap_graphics_context_) { | 120 if (pixmap_graphics_context_) { |
| 125 XFreeGC(g_osmesa_display, pixmap_graphics_context_); | 121 XFreeGC(xdisplay_, pixmap_graphics_context_); |
| 126 pixmap_graphics_context_ = NULL; | 122 pixmap_graphics_context_ = NULL; |
| 127 } | 123 } |
| 128 | 124 |
| 129 if (pixmap_) { | 125 if (pixmap_) { |
| 130 XFreePixmap(g_osmesa_display, pixmap_); | 126 XFreePixmap(xdisplay_, pixmap_); |
| 131 pixmap_ = 0; | 127 pixmap_ = 0; |
| 132 } | 128 } |
| 133 | 129 |
| 134 if (window_graphics_context_) { | 130 if (window_graphics_context_) { |
| 135 XFreeGC(g_osmesa_display, window_graphics_context_); | 131 XFreeGC(xdisplay_, window_graphics_context_); |
| 136 window_graphics_context_ = NULL; | 132 window_graphics_context_ = NULL; |
| 137 } | 133 } |
| 138 | 134 |
| 139 XSync(g_osmesa_display, False); | 135 XSync(xdisplay_, False); |
| 140 } | 136 } |
| 141 | 137 |
| 142 bool NativeViewGLSurfaceOSMesa::Resize(const gfx::Size& new_size) { | 138 bool NativeViewGLSurfaceOSMesa::Resize(const gfx::Size& new_size) { |
| 143 if (!GLSurfaceOSMesa::Resize(new_size)) | 139 if (!GLSurfaceOSMesa::Resize(new_size)) |
| 144 return false; | 140 return false; |
| 145 | 141 |
| 146 XWindowAttributes attributes; | 142 XWindowAttributes attributes; |
| 147 if (!XGetWindowAttributes(g_osmesa_display, window_, &attributes)) { | 143 if (!XGetWindowAttributes(xdisplay_, window_, &attributes)) { |
| 148 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; | 144 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; |
| 149 return false; | 145 return false; |
| 150 } | 146 } |
| 151 | 147 |
| 152 // Destroy the previous pixmap and graphics context. | 148 // Destroy the previous pixmap and graphics context. |
| 153 if (pixmap_graphics_context_) { | 149 if (pixmap_graphics_context_) { |
| 154 XFreeGC(g_osmesa_display, pixmap_graphics_context_); | 150 XFreeGC(xdisplay_, pixmap_graphics_context_); |
| 155 pixmap_graphics_context_ = NULL; | 151 pixmap_graphics_context_ = NULL; |
| 156 } | 152 } |
| 157 if (pixmap_) { | 153 if (pixmap_) { |
| 158 XFreePixmap(g_osmesa_display, pixmap_); | 154 XFreePixmap(xdisplay_, pixmap_); |
| 159 pixmap_ = 0; | 155 pixmap_ = 0; |
| 160 } | 156 } |
| 161 | 157 |
| 162 // Recreate a pixmap to hold the frame. | 158 // Recreate a pixmap to hold the frame. |
| 163 pixmap_ = XCreatePixmap(g_osmesa_display, | 159 pixmap_ = XCreatePixmap(xdisplay_, |
| 164 window_, | 160 window_, |
| 165 new_size.width(), | 161 new_size.width(), |
| 166 new_size.height(), | 162 new_size.height(), |
| 167 attributes.depth); | 163 attributes.depth); |
| 168 if (!pixmap_) { | 164 if (!pixmap_) { |
| 169 LOG(ERROR) << "XCreatePixmap failed."; | 165 LOG(ERROR) << "XCreatePixmap failed."; |
| 170 return false; | 166 return false; |
| 171 } | 167 } |
| 172 | 168 |
| 173 // Recreate a graphics context for the pixmap. | 169 // Recreate a graphics context for the pixmap. |
| 174 pixmap_graphics_context_ = XCreateGC(g_osmesa_display, pixmap_, 0, NULL); | 170 pixmap_graphics_context_ = XCreateGC(xdisplay_, pixmap_, 0, NULL); |
| 175 if (!pixmap_graphics_context_) { | 171 if (!pixmap_graphics_context_) { |
| 176 LOG(ERROR) << "XCreateGC failed"; | 172 LOG(ERROR) << "XCreateGC failed"; |
| 177 return false; | 173 return false; |
| 178 } | 174 } |
| 179 | 175 |
| 180 return true; | 176 return true; |
| 181 } | 177 } |
| 182 | 178 |
| 183 bool NativeViewGLSurfaceOSMesa::IsOffscreen() { | 179 bool NativeViewGLSurfaceOSMesa::IsOffscreen() { |
| 184 return false; | 180 return false; |
| 185 } | 181 } |
| 186 | 182 |
| 187 bool NativeViewGLSurfaceOSMesa::SwapBuffers() { | 183 bool NativeViewGLSurfaceOSMesa::SwapBuffers() { |
| 188 TRACE_EVENT2("gpu", "NativeViewGLSurfaceOSMesa:RealSwapBuffers", | 184 TRACE_EVENT2("gpu", "NativeViewGLSurfaceOSMesa:RealSwapBuffers", |
| 189 "width", GetSize().width(), | 185 "width", GetSize().width(), |
| 190 "height", GetSize().height()); | 186 "height", GetSize().height()); |
| 191 | 187 |
| 192 gfx::Size size = GetSize(); | 188 gfx::Size size = GetSize(); |
| 193 | 189 |
| 194 XWindowAttributes attributes; | 190 XWindowAttributes attributes; |
| 195 if (!XGetWindowAttributes(g_osmesa_display, window_, &attributes)) { | 191 if (!XGetWindowAttributes(xdisplay_, window_, &attributes)) { |
| 196 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; | 192 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; |
| 197 return false; | 193 return false; |
| 198 } | 194 } |
| 199 | 195 |
| 200 // Copy the frame into the pixmap. | 196 // Copy the frame into the pixmap. |
| 201 gfx::PutARGBImage(g_osmesa_display, | 197 gfx::PutARGBImage(xdisplay_, |
| 202 attributes.visual, | 198 attributes.visual, |
| 203 attributes.depth, | 199 attributes.depth, |
| 204 pixmap_, | 200 pixmap_, |
| 205 pixmap_graphics_context_, | 201 pixmap_graphics_context_, |
| 206 static_cast<const uint8*>(GetHandle()), | 202 static_cast<const uint8*>(GetHandle()), |
| 207 size.width(), | 203 size.width(), |
| 208 size.height()); | 204 size.height()); |
| 209 | 205 |
| 210 // Copy the pixmap to the window. | 206 // Copy the pixmap to the window. |
| 211 XCopyArea(g_osmesa_display, | 207 XCopyArea(xdisplay_, |
| 212 pixmap_, | 208 pixmap_, |
| 213 window_, | 209 window_, |
| 214 window_graphics_context_, | 210 window_graphics_context_, |
| 215 0, 0, | 211 0, |
| 216 size.width(), size.height(), | 212 0, |
| 217 0, 0); | 213 size.width(), |
| 214 size.height(), |
| 215 0, |
| 216 0); |
| 218 | 217 |
| 219 return true; | 218 return true; |
| 220 } | 219 } |
| 221 | 220 |
| 222 std::string NativeViewGLSurfaceOSMesa::GetExtensions() { | 221 std::string NativeViewGLSurfaceOSMesa::GetExtensions() { |
| 223 std::string extensions = gfx::GLSurfaceOSMesa::GetExtensions(); | 222 std::string extensions = gfx::GLSurfaceOSMesa::GetExtensions(); |
| 224 extensions += extensions.empty() ? "" : " "; | 223 extensions += extensions.empty() ? "" : " "; |
| 225 extensions += "GL_CHROMIUM_post_sub_buffer"; | 224 extensions += "GL_CHROMIUM_post_sub_buffer"; |
| 226 return extensions; | 225 return extensions; |
| 227 } | 226 } |
| 228 | 227 |
| 229 bool NativeViewGLSurfaceOSMesa::PostSubBuffer( | 228 bool NativeViewGLSurfaceOSMesa::PostSubBuffer( |
| 230 int x, int y, int width, int height) { | 229 int x, int y, int width, int height) { |
| 231 gfx::Size size = GetSize(); | 230 gfx::Size size = GetSize(); |
| 232 | 231 |
| 233 // Move (0,0) from lower-left to upper-left | 232 // Move (0,0) from lower-left to upper-left |
| 234 y = size.height() - y - height; | 233 y = size.height() - y - height; |
| 235 | 234 |
| 236 XWindowAttributes attributes; | 235 XWindowAttributes attributes; |
| 237 if (!XGetWindowAttributes(g_osmesa_display, window_, &attributes)) { | 236 if (!XGetWindowAttributes(xdisplay_, window_, &attributes)) { |
| 238 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; | 237 LOG(ERROR) << "XGetWindowAttributes failed for window " << window_ << "."; |
| 239 return false; | 238 return false; |
| 240 } | 239 } |
| 241 | 240 |
| 242 // Copy the frame into the pixmap. | 241 // Copy the frame into the pixmap. |
| 243 gfx::PutARGBImage(g_osmesa_display, | 242 gfx::PutARGBImage(xdisplay_, |
| 244 attributes.visual, | 243 attributes.visual, |
| 245 attributes.depth, | 244 attributes.depth, |
| 246 pixmap_, | 245 pixmap_, |
| 247 pixmap_graphics_context_, | 246 pixmap_graphics_context_, |
| 248 static_cast<const uint8*>(GetHandle()), | 247 static_cast<const uint8*>(GetHandle()), |
| 249 size.width(), | 248 size.width(), |
| 250 size.height(), | 249 size.height(), |
| 251 x, y, | 250 x, |
| 252 x, y, | 251 y, |
| 252 x, |
| 253 y, |
| 253 width, | 254 width, |
| 254 height); | 255 height); |
| 255 | 256 |
| 256 // Copy the pixmap to the window. | 257 // Copy the pixmap to the window. |
| 257 XCopyArea(g_osmesa_display, | 258 XCopyArea(xdisplay_, |
| 258 pixmap_, | 259 pixmap_, |
| 259 window_, | 260 window_, |
| 260 window_graphics_context_, | 261 window_graphics_context_, |
| 261 x, y, | 262 x, |
| 262 width, height, | 263 y, |
| 263 x, y); | 264 width, |
| 265 height, |
| 266 x, |
| 267 y); |
| 264 | 268 |
| 265 return true; | 269 return true; |
| 266 } | 270 } |
| 267 | 271 |
| 268 NativeViewGLSurfaceOSMesa::~NativeViewGLSurfaceOSMesa() { | 272 NativeViewGLSurfaceOSMesa::~NativeViewGLSurfaceOSMesa() { |
| 269 Destroy(); | 273 Destroy(); |
| 270 } | 274 } |
| 271 | 275 |
| 272 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( | 276 scoped_refptr<GLSurface> GLSurface::CreateViewGLSurface( |
| 273 gfx::AcceleratedWidget window) { | 277 gfx::AcceleratedWidget window) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 331 } | 335 } |
| 332 case kGLImplementationMockGL: | 336 case kGLImplementationMockGL: |
| 333 return new GLSurfaceStub; | 337 return new GLSurfaceStub; |
| 334 default: | 338 default: |
| 335 NOTREACHED(); | 339 NOTREACHED(); |
| 336 return NULL; | 340 return NULL; |
| 337 } | 341 } |
| 338 } | 342 } |
| 339 | 343 |
| 340 } // namespace gfx | 344 } // namespace gfx |
| OLD | NEW |