OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "chrome/browser/renderer_host/accelerated_surface_container_touch.h" | 5 #include "chrome/browser/renderer_host/accelerated_surface_container_touch.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/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "third_party/angle/include/EGL/egl.h" | 11 #include "third_party/angle/include/EGL/egl.h" |
12 #include "third_party/angle/include/EGL/eglext.h" | 12 #include "third_party/angle/include/EGL/eglext.h" |
13 #include "ui/gfx/gl/gl_bindings.h" | 13 #include "ui/gfx/gl/gl_bindings.h" |
14 #include "ui/gfx/gl/gl_implementation.h" | 14 #include "ui/gfx/gl/gl_implementation.h" |
15 #include "ui/gfx/gl/gl_surface_egl.h" | 15 #include "ui/gfx/gl/gl_surface_egl.h" |
16 #include "ui/gfx/gl/gl_surface_glx.h" | 16 #include "ui/gfx/gl/gl_surface_glx.h" |
17 #include "ui/gfx/rect.h" | 17 #include "ui/gfx/rect.h" |
18 #include "ui/gfx/transform.h" | 18 #include "ui/gfx/transform.h" |
19 | 19 |
20 namespace { | 20 namespace { |
21 | 21 |
22 class AcceleratedSurfaceContainerTouchEGL | 22 class AcceleratedSurfaceContainerTouchEGL |
23 : public AcceleratedSurfaceContainerTouch { | 23 : public AcceleratedSurfaceContainerTouch { |
24 public: | 24 public: |
25 AcceleratedSurfaceContainerTouchEGL(const gfx::Size& size, | 25 AcceleratedSurfaceContainerTouchEGL(const gfx::Size& size, |
26 uint64 surface_handle); | 26 uint64 surface_id); |
27 // TextureGL implementation | 27 // TextureGL implementation |
28 virtual void Draw(const ui::TextureDrawParams& params, | 28 virtual void Draw(const ui::TextureDrawParams& params, |
29 const gfx::Rect& clip_bounds_in_texture) OVERRIDE; | 29 const gfx::Rect& clip_bounds_in_texture) OVERRIDE; |
30 | 30 |
31 private: | 31 private: |
32 ~AcceleratedSurfaceContainerTouchEGL(); | 32 ~AcceleratedSurfaceContainerTouchEGL(); |
33 | 33 |
34 void* image_; | 34 void* image_; |
35 | 35 |
36 DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchEGL); | 36 DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchEGL); |
37 }; | 37 }; |
38 | 38 |
39 class AcceleratedSurfaceContainerTouchGLX | 39 class AcceleratedSurfaceContainerTouchGLX |
40 : public AcceleratedSurfaceContainerTouch { | 40 : public AcceleratedSurfaceContainerTouch { |
41 public: | 41 public: |
42 AcceleratedSurfaceContainerTouchGLX(const gfx::Size& size, | 42 AcceleratedSurfaceContainerTouchGLX(const gfx::Size& size, |
43 uint64 surface_handle); | 43 uint64 surface_id); |
44 // TextureGL implementation | 44 // TextureGL implementation |
45 virtual void Draw(const ui::TextureDrawParams& params, | 45 virtual void Draw(const ui::TextureDrawParams& params, |
46 const gfx::Rect& clip_bounds_in_texture) OVERRIDE; | 46 const gfx::Rect& clip_bounds_in_texture) OVERRIDE; |
47 | 47 |
48 private: | 48 private: |
49 ~AcceleratedSurfaceContainerTouchGLX(); | 49 ~AcceleratedSurfaceContainerTouchGLX(); |
50 | 50 |
51 XID pixmap_; | 51 XID pixmap_; |
52 XID glx_pixmap_; | 52 XID glx_pixmap_; |
53 | 53 |
54 DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchGLX); | 54 DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchGLX); |
55 }; | 55 }; |
56 | 56 |
| 57 class AcceleratedSurfaceContainerTouchGLXShm |
| 58 : public AcceleratedSurfaceContainerTouch { |
| 59 public: |
| 60 AcceleratedSurfaceContainerTouchGLXShm(const gfx::Size& size, |
| 61 uint64 surface_handle); |
| 62 // TextureGL implementation |
| 63 virtual void Draw(const ui::TextureDrawParams& params, |
| 64 const gfx::Rect& clip_bounds_in_texture) OVERRIDE; |
| 65 |
| 66 virtual uint64 id() const OVERRIDE; |
| 67 |
| 68 // Some implementations of this class use shared memory, this the handle |
| 69 // to the shared buffer, which is part of the surface container. |
| 70 virtual TransportDIB::Handle handle() const OVERRIDE; |
| 71 |
| 72 private: |
| 73 ~AcceleratedSurfaceContainerTouchGLXShm(); |
| 74 |
| 75 uint64 id_; |
| 76 scoped_ptr<TransportDIB> shared_mem_; |
| 77 |
| 78 DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchGLXShm); |
| 79 }; |
| 80 |
57 class ScopedPtrXFree { | 81 class ScopedPtrXFree { |
58 public: | 82 public: |
59 void operator()(void* x) const { | 83 void operator()(void* x) const { |
60 ::XFree(x); | 84 ::XFree(x); |
61 } | 85 } |
62 }; | 86 }; |
63 | 87 |
64 AcceleratedSurfaceContainerTouchEGL::AcceleratedSurfaceContainerTouchEGL( | 88 AcceleratedSurfaceContainerTouchEGL::AcceleratedSurfaceContainerTouchEGL( |
65 const gfx::Size& size, | 89 const gfx::Size& size, |
66 uint64 surface_handle) | 90 uint64 surface_id) |
67 : AcceleratedSurfaceContainerTouch(size), | 91 : AcceleratedSurfaceContainerTouch(size, surface_id), |
68 image_(NULL) { | 92 image_(NULL) { |
69 ui::SharedResources* instance = ui::SharedResources::GetInstance(); | 93 ui::SharedResources* instance = ui::SharedResources::GetInstance(); |
70 DCHECK(instance); | 94 DCHECK(instance); |
71 instance->MakeSharedContextCurrent(); | 95 instance->MakeSharedContextCurrent(); |
72 | 96 |
73 image_ = eglCreateImageKHR( | 97 image_ = eglCreateImageKHR( |
74 gfx::GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT, | 98 gfx::GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT, |
75 EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<void*>(surface_handle), NULL); | 99 EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<void*>(surface_id), NULL); |
76 | 100 |
77 glGenTextures(1, &texture_id_); | 101 glGenTextures(1, &texture_id_); |
78 glBindTexture(GL_TEXTURE_2D, texture_id_); | 102 glBindTexture(GL_TEXTURE_2D, texture_id_); |
79 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 103 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
80 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 104 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
81 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 105 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
82 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 106 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
83 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_); | 107 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_); |
84 glFlush(); | 108 glFlush(); |
85 } | 109 } |
(...skipping 23 matching lines...) Expand all Loading... |
109 | 133 |
110 modified_params.transform = flipped; | 134 modified_params.transform = flipped; |
111 | 135 |
112 DrawInternal(*instance->program_no_swizzle(), | 136 DrawInternal(*instance->program_no_swizzle(), |
113 modified_params, | 137 modified_params, |
114 clip_bounds_in_texture); | 138 clip_bounds_in_texture); |
115 } | 139 } |
116 | 140 |
117 AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX( | 141 AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX( |
118 const gfx::Size& size, | 142 const gfx::Size& size, |
119 uint64 surface_handle) | 143 uint64 surface_id) |
120 : AcceleratedSurfaceContainerTouch(size), | 144 : AcceleratedSurfaceContainerTouch(size, surface_id), |
121 pixmap_(0), | 145 pixmap_(0), |
122 glx_pixmap_(0) { | 146 glx_pixmap_(0) { |
123 ui::SharedResources* instance = ui::SharedResources::GetInstance(); | 147 ui::SharedResources* instance = ui::SharedResources::GetInstance(); |
124 DCHECK(instance); | 148 DCHECK(instance); |
125 instance->MakeSharedContextCurrent(); | 149 instance->MakeSharedContextCurrent(); |
126 | 150 |
127 // Create pixmap from window. | 151 // Create pixmap from window. |
| 152 // We receive a window here rather than a pixmap directly because drivers |
| 153 // require (or required) that the pixmap used to create the GL texture be |
| 154 // created in the same process as the texture. |
128 Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); | 155 Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); |
129 int event_base, error_base; | 156 int event_base, error_base; |
130 if (XCompositeQueryExtension(dpy, &event_base, &error_base)) { | 157 if (XCompositeQueryExtension(dpy, &event_base, &error_base)) { |
131 int major = 0, minor = 2; | 158 int major = 0, minor = 2; |
132 XCompositeQueryVersion(dpy, &major, &minor); | 159 XCompositeQueryVersion(dpy, &major, &minor); |
133 if (major == 0 && minor < 2) { | 160 if (major == 0 && minor < 2) { |
134 LOG(ERROR) << "Pixmap from window not supported."; | 161 LOG(ERROR) << "Pixmap from window not supported."; |
135 return; | 162 return; |
136 } | 163 } |
137 } | 164 } |
138 pixmap_ = XCompositeNameWindowPixmap(dpy, surface_handle); | 165 pixmap_ = XCompositeNameWindowPixmap(dpy, surface_id); |
139 | 166 |
140 // Wrap the pixmap in a GLXPixmap | 167 // Wrap the pixmap in a GLXPixmap |
141 int screen = DefaultScreen(dpy); | 168 int screen = DefaultScreen(dpy); |
142 XWindowAttributes gwa; | 169 XWindowAttributes gwa; |
143 XGetWindowAttributes(dpy, RootWindow(dpy, screen), &gwa); | 170 XGetWindowAttributes(dpy, RootWindow(dpy, screen), &gwa); |
144 unsigned int visualid = XVisualIDFromVisual(gwa.visual); | 171 unsigned int visualid = XVisualIDFromVisual(gwa.visual); |
145 | 172 |
146 int nfbconfigs, config; | 173 int nfbconfigs, config; |
147 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> fbconfigs( | 174 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> fbconfigs( |
148 glXGetFBConfigs(dpy, screen, &nfbconfigs)); | 175 glXGetFBConfigs(dpy, screen, &nfbconfigs)); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
224 Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); | 251 Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); |
225 | 252 |
226 glBindTexture(GL_TEXTURE_2D, texture_id_); | 253 glBindTexture(GL_TEXTURE_2D, texture_id_); |
227 glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL); | 254 glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL); |
228 DrawInternal(*instance->program_no_swizzle(), | 255 DrawInternal(*instance->program_no_swizzle(), |
229 params, | 256 params, |
230 clip_bounds_in_texture); | 257 clip_bounds_in_texture); |
231 glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT); | 258 glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT); |
232 } | 259 } |
233 | 260 |
| 261 AcceleratedSurfaceContainerTouchGLXShm::AcceleratedSurfaceContainerTouchGLXShm( |
| 262 const gfx::Size& size, |
| 263 uint64 surface_id) |
| 264 : AcceleratedSurfaceContainerTouch(size, surface_id), |
| 265 id_(0), |
| 266 shared_mem_(0) { |
| 267 static uint32 next_id = 1; |
| 268 |
| 269 ui::SharedResources* instance = ui::SharedResources::GetInstance(); |
| 270 DCHECK(instance); |
| 271 instance->MakeSharedContextCurrent(); |
| 272 |
| 273 // We expect to make the id here, so don't want the other end giving us one |
| 274 DCHECK_EQ(surface_id, static_cast<uint64>(0)); |
| 275 |
| 276 // It's possible that this ID gneration could clash with IDs from other |
| 277 // AcceleratedSurfaceContainerTouch* objects, however we should never have |
| 278 // ids active from more than one type at the same time, so we have free |
| 279 // reign of the id namespace. |
| 280 shared_mem_.reset( |
| 281 TransportDIB::Create(size.width() * size.height() * 4, // GL_RGBA=4 B/px |
| 282 next_id)); |
| 283 id_ = next_id++; |
| 284 |
| 285 // Create texture. |
| 286 glGenTextures(1, &texture_id_); |
| 287 glBindTexture(GL_TEXTURE_2D, texture_id_); |
| 288 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 289 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 290 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 291 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 292 } |
| 293 |
| 294 AcceleratedSurfaceContainerTouchGLXShm:: |
| 295 ~AcceleratedSurfaceContainerTouchGLXShm() { |
| 296 } |
| 297 |
| 298 uint64 AcceleratedSurfaceContainerTouchGLXShm::id() const { |
| 299 return id_; |
| 300 } |
| 301 |
| 302 |
| 303 TransportDIB::Handle AcceleratedSurfaceContainerTouchGLXShm::handle() const { |
| 304 if (shared_mem_.get()) |
| 305 return shared_mem_->handle(); |
| 306 else |
| 307 return TransportDIB::DefaultHandleValue(); |
| 308 } |
| 309 |
| 310 |
| 311 void AcceleratedSurfaceContainerTouchGLXShm::Draw( |
| 312 const ui::TextureDrawParams& params, |
| 313 const gfx::Rect& clip_bounds_in_texture) { |
| 314 ui::SharedResources* instance = ui::SharedResources::GetInstance(); |
| 315 DCHECK(instance); |
| 316 |
| 317 if (shared_mem_.get()) { |
| 318 glBindTexture(GL_TEXTURE_2D, texture_id_); |
| 319 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, |
| 320 size_.width(), size_.height(), 0, |
| 321 GL_RGBA, GL_UNSIGNED_BYTE, shared_mem_->memory()); |
| 322 |
| 323 ui::TextureDrawParams modified_params = params; |
| 324 |
| 325 // Texture from GPU is flipped vertically. |
| 326 ui::Transform flipped; |
| 327 flipped.SetScaleY(-1.0); |
| 328 flipped.SetTranslateY(size_.height()); |
| 329 flipped.ConcatTransform(params.transform); |
| 330 |
| 331 modified_params.transform = flipped; |
| 332 |
| 333 DrawInternal(*instance->program_no_swizzle(), |
| 334 modified_params, |
| 335 clip_bounds_in_texture); |
| 336 } |
| 337 } |
| 338 |
234 } // namespace | 339 } // namespace |
235 | 340 |
236 AcceleratedSurfaceContainerTouch::AcceleratedSurfaceContainerTouch( | 341 AcceleratedSurfaceContainerTouch::AcceleratedSurfaceContainerTouch( |
237 const gfx::Size& size) : TextureGL(size) { | 342 const gfx::Size& size, |
| 343 uint64 surface_id) : TextureGL(size) { |
| 344 id_ = surface_id; |
| 345 } |
| 346 |
| 347 uint64 AcceleratedSurfaceContainerTouch::id() const { |
| 348 return id_; |
| 349 } |
| 350 |
| 351 TransportDIB::Handle AcceleratedSurfaceContainerTouch::handle() const { |
| 352 return TransportDIB::DefaultHandleValue(); |
238 } | 353 } |
239 | 354 |
240 // static | 355 // static |
241 AcceleratedSurfaceContainerTouch* | 356 AcceleratedSurfaceContainerTouch* |
242 AcceleratedSurfaceContainerTouch::CreateAcceleratedSurfaceContainer( | 357 AcceleratedSurfaceContainerTouch::CreateAcceleratedSurfaceContainer( |
243 const gfx::Size& size, | 358 const gfx::Size& size, |
244 uint64 surface_handle) { | 359 uint64 surface_id) { |
245 switch (gfx::GetGLImplementation()) { | 360 switch (gfx::GetGLImplementation()) { |
246 case gfx::kGLImplementationDesktopGL: | 361 case gfx::kGLImplementationDesktopGL: |
247 return new AcceleratedSurfaceContainerTouchGLX(size, | 362 return new AcceleratedSurfaceContainerTouchGLXShm(size, |
248 surface_handle); | 363 surface_id); |
249 case gfx::kGLImplementationEGLGLES2: | 364 case gfx::kGLImplementationEGLGLES2: |
250 return new AcceleratedSurfaceContainerTouchEGL(size, | 365 return new AcceleratedSurfaceContainerTouchEGL(size, |
251 surface_handle); | 366 surface_id); |
252 default: | 367 default: |
253 NOTREACHED(); | 368 NOTREACHED(); |
254 return NULL; | 369 return NULL; |
255 } | 370 } |
256 } | 371 } |
257 | 372 |
258 void AcceleratedSurfaceContainerTouch::SetCanvas( | 373 void AcceleratedSurfaceContainerTouch::SetCanvas( |
259 const SkCanvas& canvas, | 374 const SkCanvas& canvas, |
260 const gfx::Point& origin, | 375 const gfx::Point& origin, |
261 const gfx::Size& overall_size) { | 376 const gfx::Size& overall_size) { |
262 NOTREACHED(); | 377 NOTREACHED(); |
263 } | 378 } |
OLD | NEW |