| 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);
|
| }
|
|
|