Chromium Code Reviews| 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::Transform& transform) 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::Transform& transform) 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::GetDisplay(), EGL_NO_CONTEXT, | 70 gfx::GLSurfaceEGL::GetDisplay(), 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::GetDisplay(), image_); | 84 eglDestroyImageKHR(gfx::GLSurfaceEGL::GetDisplay(), image_); |
| 37 glFlush(); | 85 glFlush(); |
| 38 } | 86 } |
| 39 | 87 |
| 40 void AcceleratedSurfaceContainerTouch::SetBitmap( | 88 void AcceleratedSurfaceContainerTouchEGL::Draw( |
| 41 const SkBitmap& bitmap, | 89 const ui::Transform& transform) { |
| 42 const gfx::Point& origin, | |
| 43 const gfx::Size& overall_size) { | |
| 44 NOTIMPLEMENTED(); | |
| 45 } | |
| 46 | |
| 47 void AcceleratedSurfaceContainerTouch::Draw(const ui::Transform& transform) { | |
| 48 DCHECK(compositor_->program_no_swizzle()); | 90 DCHECK(compositor_->program_no_swizzle()); |
| 49 | 91 |
| 50 // Texture from GPU is flipped horizontally. | 92 // Texture from GPU is flipped vertically. |
| 51 ui::Transform flipped; | 93 ui::Transform flipped; |
| 52 flipped.SetScaleY(-1.0); | 94 flipped.SetScaleY(-1.0); |
| 53 flipped.SetTranslateY(size_.height()); | 95 flipped.SetTranslateY(size_.height()); |
| 54 flipped.ConcatTransform(transform); | 96 flipped.ConcatTransform(transform); |
| 55 | 97 |
| 56 DrawInternal(*compositor_->program_no_swizzle(), flipped); | 98 DrawInternal(*compositor_->program_no_swizzle(), flipped); |
| 57 } | 99 } |
| 100 | |
| 101 AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX( | |
| 102 ui::CompositorGL* compositor, | |
| 103 const gfx::Size& size, | |
| 104 uint64 surface_handle) | |
| 105 : AcceleratedSurfaceContainerTouch(compositor, size), | |
| 106 glx_pixmap_(0) { | |
| 107 // Create pixmap from window. | |
| 108 Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); | |
| 109 int event_base, error_base; | |
| 110 if (XCompositeQueryExtension(dpy, &event_base, &error_base)) { | |
| 111 int major = 0, minor = 2; | |
| 112 XCompositeQueryVersion(dpy, &major, &minor); | |
| 113 if (major == 0 && minor < 2) { | |
| 114 LOG(FATAL) << "Pixmap from window not supported."; | |
| 115 } | |
| 116 } | |
| 117 pixmap_ = XCompositeNameWindowPixmap(dpy, surface_handle); | |
| 118 | |
| 119 // Wrap the pixmap in a GLXPixmap | |
| 120 int screen = DefaultScreen(dpy); | |
| 121 XWindowAttributes gwa; | |
| 122 XGetWindowAttributes(dpy, RootWindow(dpy, screen), &gwa); | |
| 123 unsigned int visualid = XVisualIDFromVisual(gwa.visual); | |
| 124 | |
| 125 int nfbconfigs, config; | |
| 126 scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> fbconfigs( | |
| 127 glXGetFBConfigs(dpy, screen, &nfbconfigs)); | |
| 128 | |
| 129 for (config = 0; config < nfbconfigs; config++) { | |
| 130 XVisualInfo* visinfo = glXGetVisualFromFBConfig( | |
| 131 dpy, fbconfigs.get()[config]); | |
| 132 if (!visinfo || visinfo->visualid != visualid) | |
| 133 continue; | |
| 134 | |
| 135 int value; | |
| 136 glXGetFBConfigAttrib(dpy, | |
| 137 fbconfigs.get()[config], | |
| 138 GLX_DRAWABLE_TYPE, | |
| 139 &value); | |
| 140 if (!(value & GLX_PIXMAP_BIT)) | |
| 141 continue; | |
| 142 | |
| 143 glXGetFBConfigAttrib(dpy, | |
| 144 fbconfigs.get()[config], | |
| 145 GLX_BIND_TO_TEXTURE_TARGETS_EXT, | |
| 146 &value); | |
| 147 if (!(value & GLX_TEXTURE_2D_BIT_EXT)) | |
| 148 continue; | |
| 149 | |
| 150 glXGetFBConfigAttrib(dpy, | |
| 151 fbconfigs.get()[config], | |
| 152 GLX_BIND_TO_TEXTURE_RGB_EXT, | |
| 153 &value); | |
| 154 if (value == GL_FALSE) | |
| 155 continue; | |
| 156 | |
| 157 break; | |
| 158 } | |
| 159 | |
| 160 const int pixmapAttribs[] = { | |
| 161 GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, | |
| 162 GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, | |
| 163 0 | |
| 164 }; | |
| 165 | |
| 166 glx_pixmap_ = glXCreatePixmap( | |
| 167 dpy, fbconfigs.get()[config], pixmap_, pixmapAttribs); | |
|
apatrick_chromium
2011/07/21 21:03:02
This will be out of bounds if there is no suitable
jonathan.backer
2011/07/22 13:12:40
Done.
| |
| 168 | |
| 169 // Create texture. | |
| 170 compositor_->MakeCurrent(); | |
| 171 glGenTextures(1, &texture_id_); | |
| 172 glBindTexture(GL_TEXTURE_2D, texture_id_); | |
| 173 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | |
| 174 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | |
| 175 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); | |
| 176 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); | |
| 177 } | |
| 178 | |
| 179 AcceleratedSurfaceContainerTouchGLX::~AcceleratedSurfaceContainerTouchGLX() { | |
| 180 Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); | |
| 181 glXDestroyGLXPixmap(dpy, glx_pixmap_); | |
| 182 XFreePixmap(dpy, pixmap_); | |
| 183 } | |
| 184 | |
| 185 void AcceleratedSurfaceContainerTouchGLX::Draw( | |
| 186 const ui::Transform& transform) { | |
| 187 DCHECK(compositor_->program_no_swizzle()); | |
| 188 Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); | |
| 189 | |
| 190 glBindTexture(GL_TEXTURE_2D, texture_id_); | |
| 191 glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL); | |
| 192 DrawInternal(*compositor_->program_no_swizzle(), transform); | |
| 193 glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT); | |
| 194 } | |
| 195 | |
| 196 } // namespace | |
| 197 | |
| 198 AcceleratedSurfaceContainerTouch::AcceleratedSurfaceContainerTouch( | |
| 199 ui::CompositorGL* compositor, | |
| 200 const gfx::Size& size) : | |
| 201 TextureGL(compositor, size) { | |
| 202 } | |
| 203 | |
| 204 // static | |
| 205 AcceleratedSurfaceContainerTouch* | |
| 206 AcceleratedSurfaceContainerTouch::CreateAcceleratedSurfaceContainer( | |
| 207 ui::CompositorGL* compositor, | |
| 208 const gfx::Size& size, | |
| 209 uint64 surface_handle) { | |
| 210 switch (gfx::GetGLImplementation()) { | |
| 211 case gfx::kGLImplementationDesktopGL: | |
| 212 return new AcceleratedSurfaceContainerTouchGLX(compositor, | |
| 213 size, | |
| 214 surface_handle); | |
| 215 case gfx::kGLImplementationEGLGLES2: | |
| 216 return new AcceleratedSurfaceContainerTouchEGL(compositor, | |
| 217 size, | |
| 218 surface_handle); | |
| 219 default: | |
| 220 NOTREACHED(); | |
| 221 return NULL; | |
| 222 } | |
| 223 } | |
| 224 | |
| 225 void AcceleratedSurfaceContainerTouch::SetBitmap( | |
| 226 const SkBitmap& bitmap, | |
| 227 const gfx::Point& origin, | |
| 228 const gfx::Size& overall_size) { | |
| 229 NOTIMPLEMENTED(); | |
| 230 } | |
| OLD | NEW |