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