 Chromium Code Reviews
 Chromium Code Reviews Issue 6793005:
  Add the xrender backend to the window manager.  (Closed) 
  Base URL: ssh://gitrw.chromium.org:9222/window_manager.git@master
    
  
    Issue 6793005:
  Add the xrender backend to the window manager.  (Closed) 
  Base URL: ssh://gitrw.chromium.org:9222/window_manager.git@master| Index: x11/real_x_connection.cc | 
| diff --git a/x11/real_x_connection.cc b/x11/real_x_connection.cc | 
| index 1155e242d586765ba732649e43b577e2825a9393..3a8cbac68696f927b703847cbebc70bee8f7d88f 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,130 @@ 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) { | 
| 
Daniel Erat
2011/04/04 21:16:35
nit: make this be a reference instead of a pointer
 
marcheu
2011/04/05 00:23:40
Done.
 | 
| + Size size = container->GetSize(); | 
| + 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, Point srcpos, Point maskpos, | 
| 
Daniel Erat
2011/04/04 21:16:35
use const references for non-POD types, and use se
 
marcheu
2011/04/05 00:23:40
Done.
 | 
| + Matrix4 transform, 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.width != transform[0][0]) || (size.height != transform[1][1])) { | 
| 
Daniel Erat
2011/04/04 21:16:35
might be simpler as this (may require static_casts
 
marcheu
2011/04/05 00:23:40
Done.
 | 
| + 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, | 
| + int(srcpos.x), (int)(srcpos.y), | 
| 
Daniel Erat
2011/04/04 21:16:35
nit: use static_cast (also, you're mixing int() an
 
marcheu
2011/04/05 00:23:40
Done.
 | 
| + int(maskpos.x), int(maskpos.y), | 
| + int(dstpos.x), (int)(dstpos.y), | 
| + int(transform[0][0]), int(transform[1][1])); | 
| +} | 
| + | 
| +void RealXConnection::RenderFreePicture(XPicture pict) { | 
| + XRenderFreePicture(display_, pict); | 
| +} | 
| + | 
| +void RealXConnection::RenderFillRectangle(XPicture dst, | 
| + float red, | 
| + float green, | 
| + float blue, | 
| + Point pos, | 
| 
Daniel Erat
2011/04/04 21:16:35
const Point&, const Size&
 
marcheu
2011/04/05 00:23:40
Done.
 | 
| + 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); | 
| } |