Chromium Code Reviews| Index: chrome/browser/renderer_host/accelerated_surface_container_touch.cc |
| diff --git a/chrome/browser/renderer_host/accelerated_surface_container_touch.cc b/chrome/browser/renderer_host/accelerated_surface_container_touch.cc |
| index c621e14dfd06c9e593955d62602420036e6d7419..ab9daf3c269a2a978e087ac62bf40208277ce38b 100644 |
| --- a/chrome/browser/renderer_host/accelerated_surface_container_touch.cc |
| +++ b/chrome/browser/renderer_host/accelerated_surface_container_touch.cc |
| @@ -4,17 +4,65 @@ |
| #include "chrome/browser/renderer_host/accelerated_surface_container_touch.h" |
| +#include <X11/Xlib.h> |
| +#include <X11/extensions/Xcomposite.h> |
| + |
| +#include "base/memory/scoped_ptr.h" |
| #include "third_party/angle/include/EGL/egl.h" |
| #include "third_party/angle/include/EGL/eglext.h" |
| #include "ui/gfx/gl/gl_bindings.h" |
| +#include "ui/gfx/gl/gl_implementation.h" |
| #include "ui/gfx/gl/gl_surface_egl.h" |
| +#include "ui/gfx/gl/gl_surface_glx.h" |
| #include "ui/gfx/transform.h" |
| -AcceleratedSurfaceContainerTouch::AcceleratedSurfaceContainerTouch( |
| +namespace { |
| + |
| +class AcceleratedSurfaceContainerTouchEGL |
| + : public AcceleratedSurfaceContainerTouch { |
| + public: |
| + AcceleratedSurfaceContainerTouchEGL(ui::CompositorGL* compositor, |
| + const gfx::Size& size, |
| + uint64 surface_handle); |
| + // TextureGL implementation |
| + virtual void Draw(const ui::Transform& transform) OVERRIDE; |
| + |
| + private: |
| + ~AcceleratedSurfaceContainerTouchEGL(); |
| + |
| + void* image_; |
| + DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchEGL); |
| +}; |
| + |
| +class AcceleratedSurfaceContainerTouchGLX |
| + : public AcceleratedSurfaceContainerTouch { |
| + public: |
| + AcceleratedSurfaceContainerTouchGLX(ui::CompositorGL* compositor, |
| + const gfx::Size& size, |
| + uint64 surface_handle); |
| + // TextureGL implementation |
| + virtual void Draw(const ui::Transform& transform) OVERRIDE; |
| + |
| + private: |
| + ~AcceleratedSurfaceContainerTouchGLX(); |
| + |
| + XID pixmap_; |
| + XID glx_pixmap_; |
| + DISALLOW_COPY_AND_ASSIGN(AcceleratedSurfaceContainerTouchGLX); |
| +}; |
| + |
| +class ScopedPtrXFree { |
| + public: |
| + void operator()(void* x) const { |
| + ::XFree(x); |
| + } |
| +}; |
| + |
| +AcceleratedSurfaceContainerTouchEGL::AcceleratedSurfaceContainerTouchEGL( |
| ui::CompositorGL* compositor, |
| const gfx::Size& size, |
| uint64 surface_handle) |
| - : TextureGL(compositor, size), |
| + : AcceleratedSurfaceContainerTouch(compositor, size), |
| image_(NULL) { |
| compositor_->MakeCurrent(); |
| @@ -32,22 +80,16 @@ AcceleratedSurfaceContainerTouch::AcceleratedSurfaceContainerTouch( |
| glFlush(); |
| } |
| -AcceleratedSurfaceContainerTouch::~AcceleratedSurfaceContainerTouch() { |
| +AcceleratedSurfaceContainerTouchEGL::~AcceleratedSurfaceContainerTouchEGL() { |
| eglDestroyImageKHR(gfx::GLSurfaceEGL::GetDisplay(), image_); |
| glFlush(); |
| } |
| -void AcceleratedSurfaceContainerTouch::SetBitmap( |
| - const SkBitmap& bitmap, |
| - const gfx::Point& origin, |
| - const gfx::Size& overall_size) { |
| - NOTIMPLEMENTED(); |
| -} |
| - |
| -void AcceleratedSurfaceContainerTouch::Draw(const ui::Transform& transform) { |
| +void AcceleratedSurfaceContainerTouchEGL::Draw( |
| + const ui::Transform& transform) { |
| DCHECK(compositor_->program_no_swizzle()); |
| - // Texture from GPU is flipped horizontally. |
| + // Texture from GPU is flipped vertically. |
| ui::Transform flipped; |
| flipped.SetScaleY(-1.0); |
| flipped.SetTranslateY(size_.height()); |
| @@ -55,3 +97,134 @@ void AcceleratedSurfaceContainerTouch::Draw(const ui::Transform& transform) { |
| DrawInternal(*compositor_->program_no_swizzle(), flipped); |
| } |
| + |
| +AcceleratedSurfaceContainerTouchGLX::AcceleratedSurfaceContainerTouchGLX( |
| + ui::CompositorGL* compositor, |
| + const gfx::Size& size, |
| + uint64 surface_handle) |
| + : AcceleratedSurfaceContainerTouch(compositor, size), |
| + glx_pixmap_(0) { |
| + // Create pixmap from window. |
| + Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); |
| + int event_base, error_base; |
| + if (XCompositeQueryExtension(dpy, &event_base, &error_base)) { |
| + int major = 0, minor = 2; |
| + XCompositeQueryVersion(dpy, &major, &minor); |
| + if (major == 0 && minor < 2) { |
| + LOG(FATAL) << "Pixmap from window not supported."; |
| + } |
| + } |
| + pixmap_ = XCompositeNameWindowPixmap(dpy, surface_handle); |
| + |
| + // Wrap the pixmap in a GLXPixmap |
| + int screen = DefaultScreen(dpy); |
| + XWindowAttributes gwa; |
| + XGetWindowAttributes(dpy, RootWindow(dpy, screen), &gwa); |
| + unsigned int visualid = XVisualIDFromVisual(gwa.visual); |
| + |
| + int nfbconfigs, config; |
| + scoped_ptr_malloc<GLXFBConfig, ScopedPtrXFree> fbconfigs( |
| + glXGetFBConfigs(dpy, screen, &nfbconfigs)); |
| + |
| + for (config = 0; config < nfbconfigs; config++) { |
| + XVisualInfo* visinfo = glXGetVisualFromFBConfig( |
| + dpy, fbconfigs.get()[config]); |
| + if (!visinfo || visinfo->visualid != visualid) |
| + continue; |
| + |
| + int value; |
| + glXGetFBConfigAttrib(dpy, |
| + fbconfigs.get()[config], |
| + GLX_DRAWABLE_TYPE, |
| + &value); |
| + if (!(value & GLX_PIXMAP_BIT)) |
| + continue; |
| + |
| + glXGetFBConfigAttrib(dpy, |
| + fbconfigs.get()[config], |
| + GLX_BIND_TO_TEXTURE_TARGETS_EXT, |
| + &value); |
| + if (!(value & GLX_TEXTURE_2D_BIT_EXT)) |
| + continue; |
| + |
| + glXGetFBConfigAttrib(dpy, |
| + fbconfigs.get()[config], |
| + GLX_BIND_TO_TEXTURE_RGB_EXT, |
| + &value); |
| + if (value == GL_FALSE) |
| + continue; |
| + |
| + break; |
| + } |
| + |
| + const int pixmapAttribs[] = { |
| + GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, |
| + GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, |
| + 0 |
| + }; |
| + |
| + glx_pixmap_ = glXCreatePixmap( |
| + 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.
|
| + |
| + // Create texture. |
| + compositor_->MakeCurrent(); |
| + glGenTextures(1, &texture_id_); |
| + glBindTexture(GL_TEXTURE_2D, texture_id_); |
| + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); |
| + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); |
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); |
| + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); |
| +} |
| + |
| +AcceleratedSurfaceContainerTouchGLX::~AcceleratedSurfaceContainerTouchGLX() { |
| + Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); |
| + glXDestroyGLXPixmap(dpy, glx_pixmap_); |
| + XFreePixmap(dpy, pixmap_); |
| +} |
| + |
| +void AcceleratedSurfaceContainerTouchGLX::Draw( |
| + const ui::Transform& transform) { |
| + DCHECK(compositor_->program_no_swizzle()); |
| + Display* dpy = gfx::GLSurfaceGLX::GetDisplay(); |
| + |
| + glBindTexture(GL_TEXTURE_2D, texture_id_); |
| + glXBindTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT, NULL); |
| + DrawInternal(*compositor_->program_no_swizzle(), transform); |
| + glXReleaseTexImageEXT(dpy, glx_pixmap_, GLX_FRONT_LEFT_EXT); |
| +} |
| + |
| +} // namespace |
| + |
| +AcceleratedSurfaceContainerTouch::AcceleratedSurfaceContainerTouch( |
| + ui::CompositorGL* compositor, |
| + const gfx::Size& size) : |
| + TextureGL(compositor, size) { |
| +} |
| + |
| +// static |
| +AcceleratedSurfaceContainerTouch* |
| +AcceleratedSurfaceContainerTouch::CreateAcceleratedSurfaceContainer( |
| + ui::CompositorGL* compositor, |
| + const gfx::Size& size, |
| + uint64 surface_handle) { |
| + switch (gfx::GetGLImplementation()) { |
| + case gfx::kGLImplementationDesktopGL: |
| + return new AcceleratedSurfaceContainerTouchGLX(compositor, |
| + size, |
| + surface_handle); |
| + case gfx::kGLImplementationEGLGLES2: |
| + return new AcceleratedSurfaceContainerTouchEGL(compositor, |
| + size, |
| + surface_handle); |
| + default: |
| + NOTREACHED(); |
| + return NULL; |
| + } |
| +} |
| + |
| +void AcceleratedSurfaceContainerTouch::SetBitmap( |
| + const SkBitmap& bitmap, |
| + const gfx::Point& origin, |
| + const gfx::Size& overall_size) { |
| + NOTIMPLEMENTED(); |
| +} |