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 |