=== added file 'src/composite-canvas-xrender.cc'
--- src/composite-canvas-xrender.cc	1970-01-01 00:00:00 +0000
+++ src/composite-canvas-xrender.cc	2011-08-03 17:13:02 +0000
@@ -0,0 +1,162 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * glcompbench is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with glcompbench.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *  Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ *  Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#include <string>
+#include <sstream>
+#include <cstdlib>
+
+#include "composite-canvas-xrender.h"
+#include "composite-window-xrender.h"
+#include "options.h"
+#include "log.h"
+
+#include <sys/shm.h>
+
+CompositeCanvasXRender::~CompositeCanvasXRender()
+{
+    release_resources();
+}
+
+bool
+CompositeCanvasXRender::have_xrender()
+{
+    int ignore, major, minor;
+    bool have_xrender = false;
+        
+    /* Check for the XShm extension */
+    if (XQueryExtension(xdpy_, "RENDER", &ignore, &ignore, &ignore)) {
+        if (XRenderQueryVersion(xdpy_, &major, &minor)) {
+            Log::debug("XRender extension version %d.%d\n",
+                       major, minor);
+            have_xrender = true;
+        }
+    }
+
+    return have_xrender;
+}
+
+bool
+CompositeCanvasXRender::ensure_xrender_picture()
+{
+    if (xrender_picture_)
+        return true;
+
+    if (!have_xrender())
+        return false;
+
+    XWindowAttributes canvas_attr;
+
+    if (!XGetWindowAttributes(xdpy_, canvas_, &canvas_attr)) {
+        Log::error("XGetWindowAttributes failed!\n");
+        return false;
+    }
+
+    /* TODO: should we free this when we are done? */
+    XRenderPictFormat *pict_format;
+        
+    pict_format = XRenderFindVisualFormat(xdpy_, canvas_attr.visual);
+    if (!pict_format) {
+        Log::error("XRenderFindVisualFormat failed!\n");
+        release_resources();
+        return false;
+    }
+
+    xrender_picture_ = XRenderCreatePicture(xdpy_, canvas_, pict_format,
+                                            0, NULL);
+    if (!xrender_picture_) {
+        Log::error("XRenderCreatePicture failed!\n");
+        release_resources();
+        return false;
+    }
+
+    return true;
+}
+
+XVisualInfo *
+CompositeCanvasXRender::get_canvas_xvisualinfo()
+{
+    int num_visuals;
+    XVisualInfo vis_tmpl;
+    XVisualInfo *vis_info;
+
+    vis_tmpl.depth = 32;
+    vis_tmpl.bits_per_rgb = 8;
+    vis_info = XGetVisualInfo(xdpy_, VisualDepthMask | VisualBitsPerRGBMask,
+                              &vis_tmpl, &num_visuals);
+    if (!vis_info) {
+        Log::error("Error: couldn't get X visual\n");
+        return 0;
+    }
+
+    return vis_info;
+}
+
+void
+CompositeCanvasXRender::reshape(int width, int height)
+{
+    CompositeCanvas::reshape(width, height);
+
+    release_resources();
+    ensure_xrender_picture();
+}
+
+bool
+CompositeCanvasXRender::make_current()
+{
+    return ensure_xrender_picture();
+}
+
+void
+CompositeCanvasXRender::release_resources()
+{
+    if (xrender_picture_)
+        XRenderFreePicture(xdpy_, xrender_picture_);
+
+    xrender_picture_ = 0;
+}
+
+CompositeWindow *
+CompositeCanvasXRender::create_window(Window win)
+{
+    return new CompositeWindowXRender(xdpy_, win);
+}
+
+void
+CompositeCanvasXRender::update_screen()
+{
+}
+
+std::string
+CompositeCanvasXRender::info_string()
+{
+    std::stringstream ss;
+    int major, minor;
+
+    ss << "    XRender ";
+    if (XRenderQueryVersion(xdpy_, &major, &minor))
+        ss << major << "." << minor << std::endl;
+    else
+        ss << "(Not Available)" << std::endl;
+
+    return ss.str();
+}

=== added file 'src/composite-canvas-xrender.h'
--- src/composite-canvas-xrender.h	1970-01-01 00:00:00 +0000
+++ src/composite-canvas-xrender.h	2011-08-03 17:13:02 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * glcompbench is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with glcompbench.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *  Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ *  Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#ifndef COMPOSITE_CANVAS_XRENDER_H_
+#define COMPOSITE_CANVAS_XRENDER_H_
+
+#include "composite-canvas.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/Xrender.h>
+
+class CompositeCanvasXRender: public CompositeCanvas
+{
+public:
+    CompositeCanvasXRender() :
+        CompositeCanvas("xrender"), xrender_picture_(0) {}
+
+    virtual ~CompositeCanvasXRender();
+
+    std::string info_string();
+    Picture xrender_picture() { return xrender_picture_; }
+
+protected:
+    XVisualInfo *get_canvas_xvisualinfo();
+    bool make_current();
+    void release_resources();
+    CompositeWindow *create_window(Window win);
+    void update_screen();
+    void reshape(int width, int height);
+
+private:
+    bool ensure_xrender_picture();
+    bool have_xrender();
+
+    Picture xrender_picture_;
+};
+
+#endif /* COMPOSITE_CANVAS_XRENDER_H_ */

=== modified file 'src/composite-canvas.h'
--- src/composite-canvas.h	2011-07-18 13:28:08 +0000
+++ src/composite-canvas.h	2011-08-03 17:00:15 +0000
@@ -52,6 +52,9 @@
     virtual std::string info_string() { return std::string(); }
     
     const std::string &type() { return type_; }
+    Display *xdisplay() { return xdpy_; }
+    unsigned int width() { return width_; }
+    unsigned int height() { return height_; }
 
 protected:
     virtual XVisualInfo *get_canvas_xvisualinfo() = 0;

=== added file 'src/composite-test-xrender.cc'
--- src/composite-test-xrender.cc	1970-01-01 00:00:00 +0000
+++ src/composite-test-xrender.cc	2011-08-03 17:14:34 +0000
@@ -0,0 +1,124 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * glcompbench is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with glcompbench.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *  Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ *  Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#include <X11/extensions/Xrender.h>
+#include <cmath>
+
+#include "composite-test.h"
+#include "composite-canvas-xrender.h"
+
+CompositeTestXRender::CompositeTestXRender() :
+    CompositeTest("xrender", "xrender")
+{
+    options_["filter"] = CompositeTest::Option("filter", "bilinear",
+                                               "Filter to use [nearest, bilinear]");
+}
+
+void
+CompositeTestXRender::init()
+{
+    XRenderColor half_transparent = {0x7fff, 0x7fff, 0x7fff, 0x7fff};
+    half_transparent_mask_ = XRenderCreateSolidFill(canvas_->xdisplay(),
+                                                    &half_transparent);
+}
+
+void
+CompositeTestXRender::deinit()
+{
+    if (half_transparent_mask_) {
+        XRenderFreePicture(canvas_->xdisplay(), half_transparent_mask_);
+        half_transparent_mask_ = 0;
+    }
+}
+
+void
+CompositeTestXRender::prepare_for_run()
+{
+    if (options_["filter"].value == "bilinear")
+        xrender_filter_ = FilterBilinear;
+    else
+        xrender_filter_ = FilterNearest;
+}
+
+void
+CompositeTestXRender::draw(std::list<CompositeWindow *> &window_list)
+{
+    CompositeCanvasXRender *canvas_xrender =
+        static_cast<CompositeCanvasXRender *>(canvas_);
+    Display *xdpy = canvas_->xdisplay();
+
+    Picture dest_picture = canvas_xrender->xrender_picture();
+    int dest_width = canvas_->width();
+    int dest_height = canvas_->height();
+
+    /* Clear the screen with color matching GL {0.1, 0.1, 0.3, 1.0} */
+    XRenderColor clear = {6554, 6554, 19661, 65535};
+
+    XRenderFillRectangle(xdpy, PictOpSrc, dest_picture, &clear,
+                         0, 0, dest_width, dest_height);
+
+    /* Find out how many windows are visible and calculate the angular step */
+    int visible_windows(num_visible_windows(window_list));
+    float angular_step(2 * M_PI / visible_windows);
+
+    /* Draw the windows in a circle using the calculated angular step */
+    int i(0);
+    for(std::list<CompositeWindow*>::iterator iter = window_list.begin();
+        iter != window_list.end(); ++iter)
+    {
+        CompositeWindow *comp_win = *iter;
+        Picture xrender_picture = static_cast<Picture>(comp_win->get_texture().i);
+        if (xrender_picture) {
+            int width = comp_win->width();
+            int height = comp_win->height();
+
+            /* Calculate the new position of the composited window center */
+            int x0 = dest_width / 2 + cos(i * angular_step) * dest_width / 4;
+            int y0 = dest_height / 2 + sin(i * angular_step) * dest_height / 4;
+
+            /* Calculate the new position of the upper left corner */
+            x0 -= dest_width / 4;
+            y0 -= dest_height / 4;
+
+            /* Scale the window to fit in dest_width/2 and dest_height/2 */
+            XTransform xform = {{{0}}};
+            xform.matrix[0][0] = XDoubleToFixed(2.0 * width / dest_width);
+            xform.matrix[1][1] = XDoubleToFixed(2.0 * height / dest_height);
+            xform.matrix[2][2] = XDoubleToFixed(1.0);
+
+            XRenderSetPictureFilter(xdpy, xrender_picture,
+                                    xrender_filter_, NULL, 0);
+            XRenderSetPictureTransform(xdpy, xrender_picture, &xform);
+
+            /* Draw the window Picture to the canvas Picture */
+            XRenderComposite(xdpy, PictOpOver, xrender_picture,
+                             half_transparent_mask_, dest_picture,
+                             0, 0, 0, 0, x0, y0,
+                             dest_width / 2, dest_height / 2);
+
+            i++;
+        }
+    }
+}
+
+

=== modified file 'src/composite-test.h'
--- src/composite-test.h	2011-07-19 08:29:50 +0000
+++ src/composite-test.h	2011-08-03 17:14:34 +0000
@@ -28,6 +28,7 @@
 #include <list>
 #include <map>
 #include <pixman.h>
+#include <X11/extensions/Xrender.h>
 
 #include "stack.h"
 #include "program.h"
@@ -192,4 +193,20 @@
     pixman_filter_t pixman_filter_;
 };
 
+class CompositeTestXRender : public CompositeTest
+{
+public:
+    CompositeTestXRender();
+
+    virtual void init();
+    virtual void deinit();
+    virtual void prepare_for_run();
+    virtual void draw(std::list<CompositeWindow*> &window_list);
+
+private:
+    Picture half_transparent_mask_;
+    const char *xrender_filter_;
+    
+};
+
 #endif // COMPOSITE_TEST_H_

=== added file 'src/composite-window-xrender.cc'
--- src/composite-window-xrender.cc	1970-01-01 00:00:00 +0000
+++ src/composite-window-xrender.cc	2011-08-03 17:05:08 +0000
@@ -0,0 +1,91 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * glcompbench is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with glcompbench.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *  Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ *  Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/Xrender.h>
+
+#include "composite-window-xrender.h"
+#include "log.h"
+
+CompositeWindowXRender::~CompositeWindowXRender()
+{
+    release_resources();
+}
+
+void
+CompositeWindowXRender::release_resources()
+{
+    if (xrender_picture_)
+        XRenderFreePicture(xdpy_, xrender_picture_);
+
+    xrender_picture_ = 0;
+}
+
+bool
+CompositeWindowXRender::ensure_xrender_picture()
+{
+    if (xrender_picture_)
+        return true;
+
+    XWindowAttributes win_attr;
+
+    if (!XGetWindowAttributes(xdpy_, win_, &win_attr)) {
+        Log::error("XGetWindowAttributes failed!\n");
+        return false;
+    }
+
+    /* TODO: should we free this when we are done? */
+    XRenderPictFormat *pict_format;
+        
+    pict_format = XRenderFindVisualFormat(xdpy_, win_attr.visual);
+    if (!pict_format) {
+        Log::error("XRenderFindVisualFormat failed!\n");
+        release_resources();
+        return false;
+    }
+
+    xrender_picture_ = XRenderCreatePicture(xdpy_, win_, pict_format,
+                                            0, NULL);
+    if (!xrender_picture_) {
+        Log::error("XRenderCreatePicture failed!\n");
+        release_resources();
+        return false;
+    }
+
+    return true;
+}
+
+void
+CompositeWindowXRender::update_texture()
+{
+    release_resources();
+    ensure_xrender_picture();
+}
+
+void
+CompositeWindowXRender::update_texture_from_pixmap()
+{
+    Profiler::ScopedSamples scoped_tfp(CompositeWindow::get_profiler_tfp_pair());
+}
+

=== added file 'src/composite-window-xrender.h'
--- src/composite-window-xrender.h	1970-01-01 00:00:00 +0000
+++ src/composite-window-xrender.h	2011-08-03 17:05:08 +0000
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2011 Linaro Limited
+ *
+ * This file is part of glcompbench.
+ *
+ * glcompbench is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * glcompbench is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with glcompbench.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Authors:
+ *  Alexandros Frantzis <alexandros.frantzis@linaro.org>
+ *  Jesse Barker <jesse.barker@linaro.org>
+ */
+
+#ifndef COMPOSITE_WINDOW_PIXMAN_H_
+#define COMPOSITE_WINDOW_PIXMAN_H_
+
+#include <X11/Xlib.h>
+#include <X11/extensions/Xrender.h>
+
+#include "composite-window.h"
+#include "options.h"
+
+class CompositeWindowXRender : public CompositeWindow
+{
+public:
+    CompositeWindowXRender(Display *xdpy, Window win) :
+        CompositeWindow(xdpy, win), xrender_picture_(0) {}
+
+    ~CompositeWindowXRender();
+
+    CompositeWindow::Texture get_texture()
+    {
+        return CompositeWindow::Texture(xrender_picture_);
+    }
+
+    void update_texture();
+    void update_texture_from_pixmap();
+
+private:
+    bool ensure_xrender_picture();
+    void release_resources();
+
+    Picture xrender_picture_;
+};
+
+#endif

=== modified file 'src/composite-window.h'
--- src/composite-window.h	2011-08-03 14:34:10 +0000
+++ src/composite-window.h	2011-08-03 17:02:08 +0000
@@ -37,16 +37,18 @@
 
     union Texture {
         Texture(void *p): p(p) {}
-        Texture(unsigned int i): i(i) {}
+        Texture(long unsigned int i): i(i) {}
         bool is_valid() { return p != 0 && i != 0; }
         void *p;
-        unsigned int i;
+        long unsigned int i;
     };
 
     virtual ~CompositeWindow();
     void update();
     void handle_damage();
     Window get_xwindow();
+    unsigned int width() { return width_; }
+    unsigned int height() { return height_; }
 
     virtual Texture get_texture() = 0;
     /* 

=== modified file 'src/glcompbench.cc'
--- src/glcompbench.cc	2011-07-19 08:18:28 +0000
+++ src/glcompbench.cc	2011-08-04 10:49:59 +0000
@@ -29,6 +29,7 @@
 #include "composite-canvas-glx.h"
 #endif
 #include "composite-canvas-pixman.h"
+#include "composite-canvas-xrender.h"
 
 #include "composite-test.h"
 #include "benchmark.h"
@@ -39,6 +40,7 @@
     "default",
     "brick",
     "pixman",
+    "xrender",
     NULL
 };
 
@@ -135,6 +137,7 @@
 {
     std::list<CompositeCanvas *> canvas_list;
     canvas_list.push_back(new CompositeCanvasPixman());
+    canvas_list.push_back(new CompositeCanvasXRender());
 
 #ifdef USE_EGL
     canvas_list.push_back(new CompositeCanvasEGL());
@@ -156,6 +159,7 @@
     Benchmark::register_test(*new CompositeTestSimpleDefault());
     Benchmark::register_test(*new CompositeTestSimpleBrick());
     Benchmark::register_test(*new CompositeTestPixman());
+    Benchmark::register_test(*new CompositeTestXRender());
 
     // Assign a compatible canvas to each test
     assign_canvas_to_tests(canvas_list);

=== modified file 'src/wscript_build'
--- src/wscript_build	2011-07-18 15:00:13 +0000
+++ src/wscript_build	2011-08-03 17:03:48 +0000
@@ -6,7 +6,7 @@
 glx_sources = ['composite-canvas-glx.cc', 'composite-window-glxpixmap.cc']
 egl_sources = ['composite-canvas-egl.cc', 'composite-window-eglimage.cc']
 
-common_libs = ['x11', 'xdamage', 'xcomposite', 'pixman', 'xext']
+common_libs = ['x11', 'xdamage', 'xcomposite', 'pixman', 'xext', 'xrender']
 
 if bld.env.BUILD_EGL_GL or bld.env.BUILD_GLX:
     bld(

=== modified file 'wscript'
--- wscript	2011-07-21 09:50:35 +0000
+++ wscript	2011-08-03 17:03:48 +0000
@@ -63,7 +63,7 @@
     # Check required packages
     req_pkgs = [('x11', 'x11'), ('xdamage', 'xdamage'),
                 ('xcomposite', 'xcomposite'), ('pixman-1', 'pixman'),
-                ('xext', 'xext')]
+                ('xext', 'xext'), ('xrender', 'xrender')]
     for (pkg, uselib) in req_pkgs:
         ctx.check_cfg(package = pkg, uselib_store = uselib, args = '--cflags --libs',
                 mandatory = True)

