=== added file 'src/composite-canvas-xrender.cc'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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'
@@ -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)