| Index: x11/real_x_connection.cc
 | 
| diff --git a/x11/real_x_connection.cc b/x11/real_x_connection.cc
 | 
| index 1155e242d586765ba732649e43b577e2825a9393..9dfd87714defb215dfd170a4444d512b365b78f8 100644
 | 
| --- a/x11/real_x_connection.cc
 | 
| +++ b/x11/real_x_connection.cc
 | 
| @@ -15,6 +15,7 @@ extern "C" {
 | 
|  #include <X11/extensions/sync.h>
 | 
|  #include <X11/extensions/Xcomposite.h>
 | 
|  #include <X11/extensions/Xdamage.h>
 | 
| +#include <X11/extensions/Xrender.h>
 | 
|  #include <X11/Xatom.h>
 | 
|  #include <X11/Xlib-xcb.h>
 | 
|  #include <X11/Xutil.h>
 | 
| @@ -1344,6 +1345,137 @@ bool RealXConnection::QueryPointerPosition(Point* absolute_pos_out) {
 | 
|    return true;
 | 
|  }
 | 
|  
 | 
| +bool RealXConnection::RenderQueryExtension() {
 | 
| +  int render_event, render_error;
 | 
| +  return XRenderQueryExtension(display_, &render_event, &render_error);
 | 
| +}
 | 
| +
 | 
| +XPicture RealXConnection::RenderCreatePicture(XDrawable drawable, int depth) {
 | 
| +  XRenderPictFormat *format;
 | 
| +  XRenderPictureAttributes pa;
 | 
| +
 | 
| +  format = XRenderFindStandardFormat(
 | 
| +      display_,
 | 
| +      depth == 24 ? PictStandardRGB24 : PictStandardARGB32);
 | 
| +  pa.repeat = True;
 | 
| +  XPicture r = XRenderCreatePicture(display_, drawable, format, CPRepeat, &pa);
 | 
| +  return r;
 | 
| +}
 | 
| +
 | 
| +XPixmap RealXConnection::CreatePixmapFromContainer(
 | 
| +    const ImageContainer& container) {
 | 
| +  Size size = container.size();
 | 
| +  int data_size = size.width * size.height * 4;
 | 
| +
 | 
| +  // XDestroyImage will free() this.
 | 
| +  char* pixmap_data = static_cast<char*>(malloc(data_size));
 | 
| +
 | 
| +  // Premultiply the RGB channels.
 | 
| +  memcpy(pixmap_data, container.data(), data_size);
 | 
| +  for (int i = 0; i < size.width * size.height; i++) {
 | 
| +     pixmap_data[i*4+0] = pixmap_data[i*4+0] * pixmap_data[i*4+3] / 255;
 | 
| +     pixmap_data[i*4+1] = pixmap_data[i*4+1] * pixmap_data[i*4+3] / 255;
 | 
| +     pixmap_data[i*4+2] = pixmap_data[i*4+2] * pixmap_data[i*4+3] / 255;
 | 
| +  }
 | 
| +
 | 
| +  XPixmap pixmap = XCreatePixmap(display_, root_, size.width, size.height, 32);
 | 
| +
 | 
| +  XImage* image = XCreateImage(
 | 
| +      display_,
 | 
| +      DefaultVisual(display_, DefaultScreen(display_)),
 | 
| +      32,  // depth
 | 
| +      ZPixmap,
 | 
| +      0,   // offset
 | 
| +      pixmap_data,
 | 
| +      size.width, size.height,
 | 
| +      32,  // bitmap_pad
 | 
| +      0);  // bytes_per_line
 | 
| +
 | 
| +  GC gc = XCreateGC(display_, pixmap, 0, NULL);
 | 
| +  if (!gc) {
 | 
| +    XDestroyImage(image);
 | 
| +    XFreePixmap(display_, pixmap);
 | 
| +    return None;
 | 
| +  }
 | 
| +
 | 
| +  XPutImage(display_,
 | 
| +            pixmap,
 | 
| +            gc,
 | 
| +            image,
 | 
| +            0, 0,  // src x,y
 | 
| +            0, 0,  // dst x,y
 | 
| +            size.width, size.height);
 | 
| +  XDestroyImage(image);
 | 
| +
 | 
| +  XFreeGC(display_, gc);
 | 
| +
 | 
| +  return pixmap;
 | 
| +}
 | 
| +
 | 
| +void RealXConnection::RenderComposite(bool blend,
 | 
| +                                      XPicture src,
 | 
| +                                      XPicture mask,
 | 
| +                                      XPicture dst,
 | 
| +                                      const Point& srcpos,
 | 
| +                                      const Point& maskpos,
 | 
| +                                      const Matrix4& transform,
 | 
| +                                      const Size& size) {
 | 
| +  Point dstpos(transform[3][0], transform[3][1]);
 | 
| +
 | 
| +  // Don't use transform/filtering all the time,
 | 
| +  // there are performance implications in doing so.
 | 
| +  if (size != Size(transform[0][0], transform[1][1])) {
 | 
| +    XTransform xform = {{{XDoubleToFixed(size.width/float(transform[0][0])),
 | 
| +                          XDoubleToFixed(transform[1][0]),
 | 
| +                          XDoubleToFixed(transform[2][0])},
 | 
| +                         {XDoubleToFixed(transform[0][1]),
 | 
| +                          XDoubleToFixed(size.height/float(transform[1][1])),
 | 
| +                          XDoubleToFixed(transform[2][1])},
 | 
| +                         {XDoubleToFixed(0.0),
 | 
| +                          XDoubleToFixed(0.0),
 | 
| +                          XDoubleToFixed(1.0)}}};
 | 
| +    XRenderSetPictureTransform(display_, src, &xform);
 | 
| +    XRenderSetPictureFilter(display_, src, FilterBilinear, 0, 0);
 | 
| +  }
 | 
| +
 | 
| +  int op = blend ? PictOpOver : PictOpSrc;
 | 
| +  XRenderComposite(display_,
 | 
| +                   op,
 | 
| +                   src,
 | 
| +                   mask,
 | 
| +                   dst,
 | 
| +                   static_cast<int>(srcpos.x),  static_cast<int>(srcpos.y),
 | 
| +                   static_cast<int>(maskpos.x), static_cast<int>(maskpos.y),
 | 
| +                   static_cast<int>(dstpos.x),  static_cast<int>(dstpos.y),
 | 
| +                   static_cast<int>(transform[0][0]),
 | 
| +                   static_cast<int>(transform[1][1]));
 | 
| +}
 | 
| +
 | 
| +bool RealXConnection::RenderFreePicture(XPicture pict) {
 | 
| +  XRenderFreePicture(display_, pict);
 | 
| +  return true;
 | 
| +}
 | 
| +
 | 
| +void RealXConnection::RenderFillRectangle(XPicture dst,
 | 
| +                                          float red,
 | 
| +                                          float green,
 | 
| +                                          float blue,
 | 
| +                                          const Point& pos,
 | 
| +                                          const Size& size) {
 | 
| +  XRenderColor c;
 | 
| +
 | 
| +  c.red = red * 0xffff;
 | 
| +  c.green = green * 0xffff;
 | 
| +  c.blue = blue * 0xffff;
 | 
| +  c.alpha = 0xffff;
 | 
| +  XRenderFillRectangle(display_,
 | 
| +                       PictOpSrc,
 | 
| +                       dst,
 | 
| +                       &c,
 | 
| +                       pos.x, pos.y,
 | 
| +                       size.width, size.height);
 | 
| +}
 | 
| +
 | 
|  void RealXConnection::Free(void* item) {
 | 
|    XFree(item);
 | 
|  }
 | 
| 
 |