| 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 "content/browser/renderer_host/image_transport_client.h" | 5 #include "content/browser/renderer_host/image_transport_client.h" |
| 6 | 6 |
| 7 #include <X11/Xlib.h> | 7 #include <X11/Xlib.h> |
| 8 #include <X11/extensions/Xcomposite.h> | 8 #include <X11/extensions/Xcomposite.h> |
| 9 | 9 |
| 10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 } | 42 } |
| 43 | 43 |
| 44 class ImageTransportClientEGL : public ImageTransportClient { | 44 class ImageTransportClientEGL : public ImageTransportClient { |
| 45 public: | 45 public: |
| 46 ImageTransportClientEGL(ImageTransportFactory* factory, const gfx::Size& size) | 46 ImageTransportClientEGL(ImageTransportFactory* factory, const gfx::Size& size) |
| 47 : ImageTransportClient(true, size), | 47 : ImageTransportClient(true, size), |
| 48 factory_(factory), | 48 factory_(factory), |
| 49 image_(NULL) { | 49 image_(NULL) { |
| 50 } | 50 } |
| 51 | 51 |
| 52 virtual ~ImageTransportClientEGL() { | 52 virtual bool Initialize(uint64* surface_handle) OVERRIDE { |
| 53 scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent()); | |
| 54 if (image_) | |
| 55 eglDestroyImageKHR(gfx::GLSurfaceEGL::GetHardwareDisplay(), image_); | |
| 56 unsigned int texture = texture_id(); | |
| 57 if (texture) | |
| 58 glDeleteTextures(1, &texture); | |
| 59 glFlush(); | |
| 60 } | |
| 61 | |
| 62 virtual bool Initialize(uint64* surface_handle) { | |
| 63 scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent()); | 53 scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent()); |
| 64 image_ = eglCreateImageKHR( | 54 image_ = eglCreateImageKHR( |
| 65 gfx::GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT, | 55 gfx::GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT, |
| 66 EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<void*>(*surface_handle), NULL); | 56 EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<void*>(*surface_handle), NULL); |
| 67 if (!image_) | 57 if (!image_) |
| 68 return false; | 58 return false; |
| 69 set_texture_id(CreateTexture()); | 59 set_texture_id(CreateTexture()); |
| 70 glBindTexture(GL_TEXTURE_2D, texture_id()); | 60 glBindTexture(GL_TEXTURE_2D, texture_id()); |
| 71 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_); | 61 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_); |
| 72 glFlush(); | 62 glFlush(); |
| 73 return true; | 63 return true; |
| 74 } | 64 } |
| 75 | 65 |
| 76 virtual void Update() { } | 66 virtual void Update() OVERRIDE {} |
| 77 virtual TransportDIB::Handle Handle() const { | 67 virtual TransportDIB::Handle Handle() const OVERRIDE { |
| 78 return TransportDIB::DefaultHandleValue(); | 68 return TransportDIB::DefaultHandleValue(); |
| 79 } | 69 } |
| 80 | 70 |
| 71 protected: |
| 72 virtual ~ImageTransportClientEGL() { |
| 73 scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent()); |
| 74 if (image_) |
| 75 eglDestroyImageKHR(gfx::GLSurfaceEGL::GetHardwareDisplay(), image_); |
| 76 unsigned int texture = texture_id(); |
| 77 if (texture) |
| 78 glDeleteTextures(1, &texture); |
| 79 glFlush(); |
| 80 } |
| 81 |
| 81 private: | 82 private: |
| 82 ImageTransportFactory* factory_; | 83 ImageTransportFactory* factory_; |
| 83 EGLImageKHR image_; | 84 EGLImageKHR image_; |
| 84 }; | 85 }; |
| 85 | 86 |
| 86 class ImageTransportClientGLX : public ImageTransportClient { | 87 class ImageTransportClientGLX : public ImageTransportClient { |
| 87 public: | 88 public: |
| 88 ImageTransportClientGLX(ImageTransportFactory* factory, const gfx::Size& size) | 89 ImageTransportClientGLX(ImageTransportFactory* factory, const gfx::Size& size) |
| 89 : ImageTransportClient(false, size), | 90 : ImageTransportClient(false, size), |
| 90 factory_(factory), | 91 factory_(factory), |
| 91 pixmap_(0), | 92 pixmap_(0), |
| 92 glx_pixmap_(0), | 93 glx_pixmap_(0), |
| 93 acquired_(false) { | 94 acquired_(false) { |
| 94 } | 95 } |
| 95 | 96 |
| 96 virtual ~ImageTransportClientGLX() { | 97 virtual bool Initialize(uint64* surface_handle) OVERRIDE { |
| 97 scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent()); | |
| 98 Display* dpy = base::MessagePumpForUI::GetDefaultXDisplay(); | |
| 99 if (glx_pixmap_) { | |
| 100 if (acquired_) | |
| 101 glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT); | |
| 102 glXDestroyGLXPixmap(dpy, glx_pixmap_); | |
| 103 } | |
| 104 if (pixmap_) | |
| 105 XFreePixmap(dpy, pixmap_); | |
| 106 unsigned int texture = texture_id(); | |
| 107 if (texture) | |
| 108 glDeleteTextures(1, &texture); | |
| 109 glFlush(); | |
| 110 } | |
| 111 | |
| 112 virtual bool Initialize(uint64* surface_handle) { | |
| 113 TRACE_EVENT0("renderer_host", "ImageTransportClientGLX::Initialize"); | 98 TRACE_EVENT0("renderer_host", "ImageTransportClientGLX::Initialize"); |
| 114 Display* dpy = base::MessagePumpForUI::GetDefaultXDisplay(); | 99 Display* dpy = base::MessagePumpForUI::GetDefaultXDisplay(); |
| 115 | 100 |
| 116 scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent()); | 101 scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent()); |
| 117 if (!InitializeOneOff(dpy)) | 102 if (!InitializeOneOff(dpy)) |
| 118 return false; | 103 return false; |
| 119 | 104 |
| 120 // Create pixmap from window. | 105 // Create pixmap from window. |
| 121 // We receive a window here rather than a pixmap directly because drivers | 106 // We receive a window here rather than a pixmap directly because drivers |
| 122 // require (or required) that the pixmap used to create the GL texture be | 107 // require (or required) that the pixmap used to create the GL texture be |
| 123 // created in the same process as the texture. | 108 // created in the same process as the texture. |
| 124 pixmap_ = XCompositeNameWindowPixmap(dpy, *surface_handle); | 109 pixmap_ = XCompositeNameWindowPixmap(dpy, *surface_handle); |
| 125 | 110 |
| 126 const int pixmapAttribs[] = { | 111 const int pixmapAttribs[] = { |
| 127 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, | 112 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, |
| 128 GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, | 113 GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, |
| 129 0 | 114 0 |
| 130 }; | 115 }; |
| 131 | 116 |
| 132 glx_pixmap_ = glXCreatePixmap(dpy, fbconfig_.Get(), pixmap_, pixmapAttribs); | 117 glx_pixmap_ = glXCreatePixmap(dpy, fbconfig_.Get(), pixmap_, pixmapAttribs); |
| 133 | 118 |
| 134 set_texture_id(CreateTexture()); | 119 set_texture_id(CreateTexture()); |
| 135 glFlush(); | 120 glFlush(); |
| 136 return true; | 121 return true; |
| 137 } | 122 } |
| 138 | 123 |
| 139 virtual void Update() { | 124 virtual void Update() OVERRIDE { |
| 140 TRACE_EVENT0("renderer_host", "ImageTransportClientGLX::Update"); | 125 TRACE_EVENT0("renderer_host", "ImageTransportClientGLX::Update"); |
| 141 Display* dpy = base::MessagePumpForUI::GetDefaultXDisplay(); | 126 Display* dpy = base::MessagePumpForUI::GetDefaultXDisplay(); |
| 142 scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent()); | 127 scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent()); |
| 143 glBindTexture(GL_TEXTURE_2D, texture_id()); | 128 glBindTexture(GL_TEXTURE_2D, texture_id()); |
| 144 if (acquired_) | 129 if (acquired_) |
| 145 glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT); | 130 glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT); |
| 146 glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL); | 131 glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL); |
| 147 acquired_ = true; | 132 acquired_ = true; |
| 148 glFlush(); | 133 glFlush(); |
| 149 } | 134 } |
| 150 | 135 |
| 151 virtual TransportDIB::Handle Handle() const { | 136 virtual TransportDIB::Handle Handle() const OVERRIDE { |
| 152 return TransportDIB::DefaultHandleValue(); | 137 return TransportDIB::DefaultHandleValue(); |
| 153 } | 138 } |
| 154 | 139 |
| 140 protected: |
| 141 virtual ~ImageTransportClientGLX() { |
| 142 scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent()); |
| 143 Display* dpy = base::MessagePumpForUI::GetDefaultXDisplay(); |
| 144 if (glx_pixmap_) { |
| 145 if (acquired_) |
| 146 glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT); |
| 147 glXDestroyGLXPixmap(dpy, glx_pixmap_); |
| 148 } |
| 149 if (pixmap_) |
| 150 XFreePixmap(dpy, pixmap_); |
| 151 unsigned int texture = texture_id(); |
| 152 if (texture) |
| 153 glDeleteTextures(1, &texture); |
| 154 glFlush(); |
| 155 } |
| 156 |
| 155 private: | 157 private: |
| 156 static bool InitializeOneOff(Display* dpy) { | 158 static bool InitializeOneOff(Display* dpy) { |
| 157 static bool initialized = false; | 159 static bool initialized = false; |
| 158 if (initialized) | 160 if (initialized) |
| 159 return true; | 161 return true; |
| 160 | 162 |
| 161 int event_base, error_base; | 163 int event_base, error_base; |
| 162 if (XCompositeQueryExtension(dpy, &event_base, &error_base)) { | 164 if (XCompositeQueryExtension(dpy, &event_base, &error_base)) { |
| 163 int major = 0, minor = 2; | 165 int major = 0, minor = 2; |
| 164 XCompositeQueryVersion(dpy, &major, &minor); | 166 XCompositeQueryVersion(dpy, &major, &minor); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 LAZY_INSTANCE_INITIALIZER; | 232 LAZY_INSTANCE_INITIALIZER; |
| 231 | 233 |
| 232 class ImageTransportClientOSMesa : public ImageTransportClient { | 234 class ImageTransportClientOSMesa : public ImageTransportClient { |
| 233 public: | 235 public: |
| 234 ImageTransportClientOSMesa(ImageTransportFactory* factory, | 236 ImageTransportClientOSMesa(ImageTransportFactory* factory, |
| 235 const gfx::Size& size) | 237 const gfx::Size& size) |
| 236 : ImageTransportClient(false, size), | 238 : ImageTransportClient(false, size), |
| 237 factory_(factory) { | 239 factory_(factory) { |
| 238 } | 240 } |
| 239 | 241 |
| 240 virtual ~ImageTransportClientOSMesa() { | 242 virtual bool Initialize(uint64* surface_handle) OVERRIDE { |
| 241 unsigned int texture = texture_id(); | |
| 242 if (texture) { | |
| 243 scoped_ptr<gfx::ScopedMakeCurrent> bind( | |
| 244 factory_->GetScopedMakeCurrent()); | |
| 245 glDeleteTextures(1, &texture); | |
| 246 glFlush(); | |
| 247 } | |
| 248 } | |
| 249 | |
| 250 virtual bool Initialize(uint64* surface_handle) { | |
| 251 // We expect to make the handle here, so don't want the other end giving us | 243 // We expect to make the handle here, so don't want the other end giving us |
| 252 // one. | 244 // one. |
| 253 DCHECK_EQ(*surface_handle, static_cast<uint64>(0)); | 245 DCHECK_EQ(*surface_handle, static_cast<uint64>(0)); |
| 254 | 246 |
| 255 // It's possible that this ID gneration could clash with IDs from other | 247 // It's possible that this ID gneration could clash with IDs from other |
| 256 // AcceleratedSurfaceContainerTouch* objects, however we should never have | 248 // AcceleratedSurfaceContainerTouch* objects, however we should never have |
| 257 // ids active from more than one type at the same time, so we have free | 249 // ids active from more than one type at the same time, so we have free |
| 258 // reign of the id namespace. | 250 // reign of the id namespace. |
| 259 *surface_handle = next_handle_++; | 251 *surface_handle = next_handle_++; |
| 260 | 252 |
| 261 shared_mem_.reset( | 253 shared_mem_.reset( |
| 262 TransportDIB::Create(size().GetArea() * 4, // GL_RGBA=4 B/px | 254 TransportDIB::Create(size().GetArea() * 4, // GL_RGBA=4 B/px |
| 263 *surface_handle)); | 255 *surface_handle)); |
| 264 if (!shared_mem_.get()) | 256 if (!shared_mem_.get()) |
| 265 return false; | 257 return false; |
| 266 | 258 |
| 267 scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent()); | 259 scoped_ptr<gfx::ScopedMakeCurrent> bind(factory_->GetScopedMakeCurrent()); |
| 268 set_texture_id(CreateTexture()); | 260 set_texture_id(CreateTexture()); |
| 269 glFlush(); | 261 glFlush(); |
| 270 return true; | 262 return true; |
| 271 } | 263 } |
| 272 | 264 |
| 273 virtual void Update() { | 265 virtual void Update() OVERRIDE { |
| 274 glBindTexture(GL_TEXTURE_2D, texture_id()); | 266 glBindTexture(GL_TEXTURE_2D, texture_id()); |
| 275 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, | 267 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, |
| 276 size().width(), size().height(), 0, | 268 size().width(), size().height(), 0, |
| 277 GL_RGBA, GL_UNSIGNED_BYTE, shared_mem_->memory()); | 269 GL_RGBA, GL_UNSIGNED_BYTE, shared_mem_->memory()); |
| 278 glFlush(); | 270 glFlush(); |
| 279 } | 271 } |
| 280 | 272 |
| 281 virtual TransportDIB::Handle Handle() const { return shared_mem_->handle(); } | 273 virtual TransportDIB::Handle Handle() const OVERRIDE { |
| 274 return shared_mem_->handle(); |
| 275 } |
| 276 |
| 277 protected: |
| 278 virtual ~ImageTransportClientOSMesa() { |
| 279 unsigned int texture = texture_id(); |
| 280 if (texture) { |
| 281 scoped_ptr<gfx::ScopedMakeCurrent> bind( |
| 282 factory_->GetScopedMakeCurrent()); |
| 283 glDeleteTextures(1, &texture); |
| 284 glFlush(); |
| 285 } |
| 286 } |
| 282 | 287 |
| 283 private: | 288 private: |
| 284 ImageTransportFactory* factory_; | 289 ImageTransportFactory* factory_; |
| 285 scoped_ptr<TransportDIB> shared_mem_; | 290 scoped_ptr<TransportDIB> shared_mem_; |
| 286 static uint32 next_handle_; | 291 static uint32 next_handle_; |
| 287 }; | 292 }; |
| 288 uint32 ImageTransportClientOSMesa::next_handle_ = 0; | 293 uint32 ImageTransportClientOSMesa::next_handle_ = 0; |
| 289 | 294 |
| 290 } // anonymous namespace | 295 } // anonymous namespace |
| 291 | 296 |
| 292 ImageTransportClient* ImageTransportClient::Create( | 297 ImageTransportClient* ImageTransportClient::Create( |
| 293 ImageTransportFactory* factory, | 298 ImageTransportFactory* factory, |
| 294 const gfx::Size& size) { | 299 const gfx::Size& size) { |
| 295 switch (gfx::GetGLImplementation()) { | 300 switch (gfx::GetGLImplementation()) { |
| 296 case gfx::kGLImplementationOSMesaGL: | 301 case gfx::kGLImplementationOSMesaGL: |
| 297 return new ImageTransportClientOSMesa(factory, size); | 302 return new ImageTransportClientOSMesa(factory, size); |
| 298 case gfx::kGLImplementationDesktopGL: | 303 case gfx::kGLImplementationDesktopGL: |
| 299 return new ImageTransportClientGLX(factory, size); | 304 return new ImageTransportClientGLX(factory, size); |
| 300 case gfx::kGLImplementationEGLGLES2: | 305 case gfx::kGLImplementationEGLGLES2: |
| 301 return new ImageTransportClientEGL(factory, size); | 306 return new ImageTransportClientEGL(factory, size); |
| 302 default: | 307 default: |
| 303 NOTREACHED(); | 308 NOTREACHED(); |
| 304 return NULL; | 309 return NULL; |
| 305 } | 310 } |
| 306 } | 311 } |
| OLD | NEW |