| Index: content/common/gpu/media/gles2_texture_to_egl_image_translator.cc
 | 
| ===================================================================
 | 
| --- content/common/gpu/media/gles2_texture_to_egl_image_translator.cc	(revision 120554)
 | 
| +++ content/common/gpu/media/gles2_texture_to_egl_image_translator.cc	(working copy)
 | 
| @@ -3,6 +3,7 @@
 | 
|  // found in the LICENSE file.
 | 
|  
 | 
|  #include "content/common/gpu/media/gles2_texture_to_egl_image_translator.h"
 | 
| +#include "ui/gfx/gl/gl_surface_egl.h"
 | 
|  
 | 
|  #include "base/logging.h"
 | 
|  
 | 
| @@ -13,12 +14,18 @@
 | 
|  static PFNEGLDESTROYIMAGEKHRPROC egl_destroy_image_khr =
 | 
|      reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(
 | 
|          eglGetProcAddress("eglDestroyImageKHR"));
 | 
| +static PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glegl_image_targettexture_2does =
 | 
| +    reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(
 | 
| +        eglGetProcAddress("glEGLImageTargetTexture2DOES"));
 | 
|  
 | 
|  static bool AreEGLExtensionsInitialized() {
 | 
| -  return (egl_create_image_khr && egl_destroy_image_khr);
 | 
| +  return (egl_create_image_khr && egl_destroy_image_khr &&
 | 
| +          glegl_image_targettexture_2does);
 | 
|  }
 | 
|  
 | 
| -Gles2TextureToEglImageTranslator::Gles2TextureToEglImageTranslator() {
 | 
| +Gles2TextureToEglImageTranslator::Gles2TextureToEglImageTranslator(
 | 
| +    bool use_backing_pixmaps)
 | 
| +    : use_backing_pixmaps_(use_backing_pixmaps) {
 | 
|    if (!AreEGLExtensionsInitialized()) {
 | 
|      LOG(DFATAL) << "Failed to get EGL extensions";
 | 
|      return;
 | 
| @@ -31,17 +38,45 @@
 | 
|  }
 | 
|  
 | 
|  EGLImageKHR Gles2TextureToEglImageTranslator::TranslateToEglImage(
 | 
| -    EGLDisplay egl_display, EGLContext egl_context, uint32 texture) {
 | 
| -  EGLint attrib = EGL_NONE;
 | 
| +    EGLDisplay egl_display, EGLContext egl_context,
 | 
| +    uint32 texture,
 | 
| +    const gfx::Size& dimensions) {
 | 
|    if (!egl_create_image_khr)
 | 
|      return EGL_NO_IMAGE_KHR;
 | 
| -  // Create an EGLImage
 | 
| -  EGLImageKHR hEglImage = egl_create_image_khr(
 | 
| -      egl_display,
 | 
| -      egl_context,
 | 
| -      EGL_GL_TEXTURE_2D_KHR,
 | 
| -      reinterpret_cast<EGLClientBuffer>(texture),
 | 
| -      &attrib);
 | 
| +  EGLImageKHR hEglImage;
 | 
| +  if (use_backing_pixmaps_) {
 | 
| +    if (!glegl_image_targettexture_2does)
 | 
| +      return EGL_NO_IMAGE_KHR;
 | 
| +
 | 
| +    EGLint image_attrs[] = { EGL_IMAGE_PRESERVED_KHR, 1 , EGL_NONE };
 | 
| +
 | 
| +    glActiveTexture(GL_TEXTURE0);
 | 
| +    glBindTexture(GL_TEXTURE_2D, texture);
 | 
| +
 | 
| +    Display* x_display = gfx::GLSurfaceEGL::GetNativeDisplay();
 | 
| +    Pixmap pixmap = XCreatePixmap(x_display, RootWindow(x_display, 0),
 | 
| +                                  dimensions.width(),
 | 
| +                                  dimensions.height(), 32);
 | 
| +
 | 
| +    hEglImage = egl_create_image_khr(egl_display,
 | 
| +                                     EGL_NO_CONTEXT,
 | 
| +                                     EGL_NATIVE_PIXMAP_KHR,
 | 
| +                                     (EGLClientBuffer)pixmap,
 | 
| +                                     image_attrs);
 | 
| +
 | 
| +    glegl_image_targettexture_2does(GL_TEXTURE_2D, hEglImage);
 | 
| +    bool inserted = eglimage_pixmap_.insert(std::make_pair(
 | 
| +                                            hEglImage, pixmap)).second;
 | 
| +    DCHECK(inserted);
 | 
| +  } else {
 | 
| +    EGLint attrib = EGL_NONE;
 | 
| +    // Create an EGLImage
 | 
| +    hEglImage = egl_create_image_khr(egl_display,
 | 
| +                                     egl_context,
 | 
| +                                     EGL_GL_TEXTURE_2D_KHR,
 | 
| +                                     reinterpret_cast<EGLClientBuffer>(texture),
 | 
| +                                     &attrib);
 | 
| +  }
 | 
|    CHECK(hEglImage) << "Failed to eglCreateImageKHR for " << texture
 | 
|                     << ", error: 0x" << std::hex << eglGetError();
 | 
|    return hEglImage;
 | 
| @@ -65,4 +100,13 @@
 | 
|      return;
 | 
|    }
 | 
|    egl_destroy_image_khr(egl_display, egl_image);
 | 
| +
 | 
| +  if (use_backing_pixmaps_) {
 | 
| +    ImagePixmap::iterator it = eglimage_pixmap_.find(egl_image);
 | 
| +    CHECK(it != eglimage_pixmap_.end());
 | 
| +    Pixmap pixmap = it->second;
 | 
| +    eglimage_pixmap_.erase(it);
 | 
| +    Display* x_display = gfx::GLSurfaceEGL::GetNativeDisplay();
 | 
| +    XFreePixmap(x_display, pixmap);
 | 
| +  }
 | 
|  }
 | 
| 
 |