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> |
| 8 #include <X11/extensions/Xcomposite.h> |
| 9 |
| 10 #include "base/memory/scoped_ptr.h" |
7 #include "third_party/angle/include/EGL/egl.h" | 11 #include "third_party/angle/include/EGL/egl.h" |
8 #include "third_party/angle/include/EGL/eglext.h" | 12 #include "third_party/angle/include/EGL/eglext.h" |
9 #include "ui/gfx/gl/gl_bindings.h" | 13 #include "ui/gfx/gl/gl_bindings.h" |
| 14 #include "ui/gfx/gl/gl_implementation.h" |
10 #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" |
11 #include "ui/gfx/transform.h" | 17 #include "ui/gfx/transform.h" |
12 | 18 |
13 AcceleratedSurfaceContainerTouch::AcceleratedSurfaceContainerTouch( | 19 namespace { |
| 20 |
| 21 class AcceleratedSurfaceContainerTouchEGL |
| 22 : public AcceleratedSurfaceContainerTouch { |
| 23 public: |
| 24 AcceleratedSurfaceContainerTouchEGL(ui::CompositorGL* compositor, |
| 25 const gfx::Size& size, |
| 26 uint64 surface_handle); |
| 27 // TextureGL implementation |
| 28 virtual void Draw(const ui::TextureDrawParams& params) OVERRIDE; |
| 29 |
| 30 private: |
| 31 ~AcceleratedSurfaceContainerTouchEGL(); |
| 32 |
| 33 void* image_; |
| 34 DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchEGL); |
| 35 }; |
| 36 |
| 37 class AcceleratedSurfaceContainerTouchGLX |
| 38 : public AcceleratedSurfaceContainerTouch { |
| 39 public: |
| 40 AcceleratedSurfaceContainerTouchGLX(ui::CompositorGL* compositor, |
| 41 const gfx::Size& size, |
| 42 uint64 surface_handle); |
| 43 // TextureGL implementation |
| 44 virtual void Draw(const ui::TextureDrawParams& params) OVERRIDE; |
| 45 |
| 46 private: |
| 47 ~AcceleratedSurfaceContainerTouchGLX(); |
| 48 |
| 49 XID pixmap_; |
| 50 XID glx_pixmap_; |
| 51 DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchGLX); |
| 52 }; |
| 53 |
| 54 class ScopedPtrXFree { |
| 55 public: |
| 56 void operator()(void* x) const { |
| 57 ::XFree(x); |
| 58 } |
| 59 }; |
| 60 |
| 61 AcceleratedSurfaceContainerTouchEGL::AcceleratedSurfaceContainerTouchEGL( |
14 ui::CompositorGL* compositor, | 62 ui::CompositorGL* compositor, |
15 const gfx::Size& size, | 63 const gfx::Size& size, |
16 uint64 surface_handle) | 64 uint64 surface_handle) |
17 : TextureGL(compositor, size), | 65 : AcceleratedSurfaceContainerTouch(compositor, size), |
18 image_(NULL) { | 66 image_(NULL) { |
19 compositor_->MakeCurrent(); | 67 compositor_->MakeCurrent(); |
20 | 68 |
21 image_ = eglCreateImageKHR( | 69 image_ = eglCreateImageKHR( |
22 gfx::GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT, | 70 gfx::GLSurfaceEGL::GetHardwareDisplay(), EGL_NO_CONTEXT, |
23 EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<void*>(surface_handle), NULL); | 71 EGL_NATIVE_PIXMAP_KHR, reinterpret_cast<void*>(surface_handle), NULL); |
24 | 72 |
25 glGenTextures(1, &texture_id_); | 73 glGenTextures(1, &texture_id_); |
26 glBindTexture(GL_TEXTURE_2D, texture_id_); | 74 glBindTexture(GL_TEXTURE_2D, texture_id_); |
27 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | 75 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
28 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | 76 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
29 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | 77 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
30 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | 78 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
31 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_); | 79 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, image_); |
32 glFlush(); | 80 glFlush(); |
33 } | 81 } |
34 | 82 |
35 AcceleratedSurfaceContainerTouch::~AcceleratedSurfaceContainerTouch() { | 83 AcceleratedSurfaceContainerTouchEGL::~AcceleratedSurfaceContainerTouchEGL() { |
36 eglDestroyImageKHR(gfx::GLSurfaceEGL::GetHardwareDisplay(), image_); | 84 eglDestroyImageKHR(gfx::GLSurfaceEGL::GetHardwareDisplay(), image_); |
37 glFlush(); | 85 glFlush(); |
38 } | 86 } |
39 | 87 |
40 void AcceleratedSurfaceContainerTouch::SetBitmap( | 88 void AcceleratedSurfaceContainerTouchEGL::Draw( |
41 const SkBitmap& bitmap, | |
42 const gfx::Point& origin, | |
43 const gfx::Size& overall_size) { | |
44 NOTIMPLEMENTED(); | |
45 } | |
46 | |
47 void AcceleratedSurfaceContainerTouch::Draw( | |
48 const ui::TextureDrawParams& params) { | 89 const ui::TextureDrawParams& params) { |
49 DCHECK(compositor_->program_no_swizzle()); | 90 DCHECK(compositor_->program_no_swizzle()); |
50 | 91 |
51 ui::TextureDrawParams modified_params = params; | 92 ui::TextureDrawParams modified_params = params; |
52 | 93 |
53 // Texture from GPU is flipped horizontally. | 94 // Texture from GPU is flipped vertically. |
54 ui::Transform flipped; | 95 ui::Transform flipped; |
55 flipped.SetScaleY(-1.0); | 96 flipped.SetScaleY(-1.0); |
56 flipped.SetTranslateY(size_.height()); | 97 flipped.SetTranslateY(size_.height()); |
57 flipped.ConcatTransform(params.transform); | 98 flipped.ConcatTransform(params.transform); |
58 | 99 |
59 modified_params.transform = flipped; | 100 modified_params.transform = flipped; |
60 | 101 |
61 DrawInternal(*compositor_->program_no_swizzle(), modified_params); | 102 DrawInternal(*compositor_->program_no_swizzle(), modified_params); |
62 } | 103 } |
| 104 |
| 105 AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX( |
| 106 ui::CompositorGL* compositor, |
| 107 const gfx::Size& size, |
| 108 uint64 surface_handle) |
| 109 : AcceleratedSurfaceContainerTouch(compositor, size), |
| 110 pixmap_(0), |
| 111 glx_pixmap_(0) { |
| 112 // Create pixmap from window. |
| 113 Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); |
| 114 int event_base, error_base; |
| 115 if (XCompositeQueryExtension(dpy, &event_base, &error_base)) { |
| 116 int major = 0, minor = 2; |
| 117 XCompositeQueryVersion(dpy, &major, &minor); |
| 118 if (major == 0 && minor < 2) { |
| 119 LOG(ERROR) << "Pixmap from window not supported."; |
| 120 return; |
| 121 } |
| 122 } |
| 123 pixmap_ = XCompositeNameWindowPixmap(dpy, surface_handle); |
| 124 |
| 125 // Wrap the pixmap in a GLXPixmap |
| 126 int screen = DefaultScreen(dpy); |
| 127 XWindowAttributes gwa; |
| 128 XGetWindowAttributes(dpy, RootWindow(dpy, screen), &gwa); |
| 129 unsigned int visualid = XVisualIDFromVisual(gwa.visual); |
| 130 |
| 131 int nfbconfigs, config; |
| 132 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> fbconfigs( |
| 133 glXGetFBConfigs(dpy, screen, &nfbconfigs)); |
| 134 |
| 135 for (config = 0; config < nfbconfigs; config++) { |
| 136 XVisualInfo* visinfo = glXGetVisualFromFBConfig( |
| 137 dpy, fbconfigs.get()[config]); |
| 138 if (!visinfo || visinfo->visualid != visualid) |
| 139 continue; |
| 140 |
| 141 int value; |
| 142 glXGetFBConfigAttrib(dpy, |
| 143 fbconfigs.get()[config], |
| 144 GLX_DRAWABLE_TYPE, |
| 145 &value); |
| 146 if (!(value & GLX_PIXMAP_BIT)) |
| 147 continue; |
| 148 |
| 149 glXGetFBConfigAttrib(dpy, |
| 150 fbconfigs.get()[config], |
| 151 GLX_BIND_TO_TEXTURE_TARGETS_EXT, |
| 152 &value); |
| 153 if (!(value & GLX_TEXTURE_2D_BIT_EXT)) |
| 154 continue; |
| 155 |
| 156 glXGetFBConfigAttrib(dpy, |
| 157 fbconfigs.get()[config], |
| 158 GLX_BIND_TO_TEXTURE_RGB_EXT, |
| 159 &value); |
| 160 if (value == GL_FALSE) |
| 161 continue; |
| 162 |
| 163 break; |
| 164 } |
| 165 |
| 166 if (config == nfbconfigs) { |
| 167 LOG(ERROR) |
| 168 << "Could not find configuration suitable for binding a pixmap " |
| 169 << "as a texture."; |
| 170 return; |
| 171 } |
| 172 |
| 173 const int pixmapAttribs[] = { |
| 174 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, |
| 175 GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, |
| 176 0 |
| 177 }; |
| 178 |
| 179 glx_pixmap_ = glXCreatePixmap( |
| 180 dpy, fbconfigs.get()[config], pixmap_, pixmapAttribs); |
| 181 |
| 182 // Create texture. |
| 183 compositor_->MakeCurrent(); |
| 184 glGenTextures(1, &texture_id_); |
| 185 glBindTexture(GL_TEXTURE_2D, texture_id_); |
| 186 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| 187 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| 188 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| 189 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| 190 } |
| 191 |
| 192 AcceleratedSurfaceContainerTouchGLX::~AcceleratedSurfaceContainerTouchGLX() { |
| 193 Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); |
| 194 if (glx_pixmap_) |
| 195 glXDestroyGLXPixmap(dpy, glx_pixmap_); |
| 196 if (pixmap_) |
| 197 XFreePixmap(dpy, pixmap_); |
| 198 } |
| 199 |
| 200 void AcceleratedSurfaceContainerTouchGLX::Draw( |
| 201 const ui::TextureDrawParams& params) { |
| 202 DCHECK(compositor_->program_no_swizzle()); |
| 203 Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); |
| 204 |
| 205 glBindTexture(GL_TEXTURE_2D, texture_id_); |
| 206 glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL); |
| 207 DrawInternal(*compositor_->program_no_swizzle(), params); |
| 208 glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT); |
| 209 } |
| 210 |
| 211 } // namespace |
| 212 |
| 213 AcceleratedSurfaceContainerTouch::AcceleratedSurfaceContainerTouch( |
| 214 ui::CompositorGL* compositor, |
| 215 const gfx::Size& size) : |
| 216 TextureGL(compositor, size) { |
| 217 } |
| 218 |
| 219 // static |
| 220 AcceleratedSurfaceContainerTouch* |
| 221 AcceleratedSurfaceContainerTouch::CreateAcceleratedSurfaceContainer( |
| 222 ui::CompositorGL* compositor, |
| 223 const gfx::Size& size, |
| 224 uint64 surface_handle) { |
| 225 switch (gfx::GetGLImplementation()) { |
| 226 case gfx::kGLImplementationDesktopGL: |
| 227 return new AcceleratedSurfaceContainerTouchGLX(compositor, |
| 228 size, |
| 229 surface_handle); |
| 230 case gfx::kGLImplementationEGLGLES2: |
| 231 return new AcceleratedSurfaceContainerTouchEGL(compositor, |
| 232 size, |
| 233 surface_handle); |
| 234 default: |
| 235 NOTREACHED(); |
| 236 return NULL; |
| 237 } |
| 238 } |
| 239 |
| 240 void AcceleratedSurfaceContainerTouch::SetBitmap( |
| 241 const SkBitmap& bitmap, |
| 242 const gfx::Point& origin, |
| 243 const gfx::Size& overall_size) { |
| 244 NOTREACHED(); |
| 245 } |
OLD | NEW |