=== modified file 'NEWS'
@@ -1,3 +1,8 @@
+glcompbench 2011.08 (20110818)
+==============================
+
+* Add xrender based compositing test.
+
glcompbench 2011.07 (20110719)
==============================
=== modified file 'doc/gl-composite-benchmark.1.in'
@@ -1,4 +1,4 @@
-.TH GL-COMPOSITE-BENCHMARK "1" "June 2011" "gl-composite-benchmark @appversion@"
+.TH GL-COMPOSITE-BENCHMARK "1" "August 2011" "gl-composite-benchmark @appversion@"
.SH NAME
.SH SYNOPSIS
.B gl-composite-benchmark [OPTIONS] [-- [GLCOMPBENCH_OPTIONS]]
=== modified file 'doc/glcompbench.1.in'
@@ -1,4 +1,4 @@
-.TH @APPNAME@ "1" "June 2011" "@appname@ @appversion@"
+.TH @APPNAME@ "1" "August 2011" "@appname@ @appversion@"
.SH NAME
@appname@ \- OpenGL (ES) 2.0 compositing benchmark
.SH SYNOPSIS
=== added file 'src/composite-canvas-xrender.cc'
@@ -0,0 +1,246 @@
+/*
+ * 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"
+
+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::have_xdbe()
+{
+ int major, minor;
+ bool have_xdbe = false;
+
+ /* Check for the Xdbe extension */
+ if (XdbeQueryExtension(xdpy_, &major, &minor)) {
+ Log::debug("Xdbe extension version %d.%d\n", major, minor);
+ have_xdbe = true;
+ }
+ else {
+ Log::info("** Xdbe extension not supported. You may experience flickering.\n");
+ }
+
+ return have_xdbe;
+}
+
+bool
+CompositeCanvasXRender::ensure_xdbe_back_buffer()
+{
+ XdbeScreenVisualInfo *xdbe_screen_vis_info;
+ XWindowAttributes canvas_attr;
+ int num_screens = 1;
+ bool dbe_visual_found = false;
+
+ if (xdbe_back_buffer_)
+ return true;
+
+ if (!have_xdbe())
+ return false;
+
+ /* Check if the canvas visual supports double-buffering */
+ if (!XGetWindowAttributes(xdpy_, canvas_, &canvas_attr)) {
+ Log::error("XGetWindowAttributes failed!\n");
+ return false;
+ }
+
+ xdbe_screen_vis_info = XdbeGetVisualInfo(xdpy_, &canvas_, &num_screens);
+ if (!xdbe_screen_vis_info || num_screens == 0) {
+ Log::error("XdbeGetVisualInfo failed!\n");
+ return false;
+ }
+
+ for (int i = 0; i < xdbe_screen_vis_info[0].count; i++) {
+ XdbeVisualInfo *vis_info = &xdbe_screen_vis_info[0].visinfo[i];
+ if (vis_info->visual == XVisualIDFromVisual(canvas_attr.visual)) {
+ dbe_visual_found = true;
+ break;
+ }
+ }
+
+ XdbeFreeVisualInfo(xdbe_screen_vis_info);
+
+ if (!dbe_visual_found) {
+ Log::info("** The window visual does not support double buffering."
+ " You may experience flickering!\n");
+ return false;
+ }
+
+ /* Allocate the back buffer */
+ xdbe_back_buffer_ = XdbeAllocateBackBufferName(xdpy_, canvas_,
+ XdbeBackground);
+ if (!xdbe_back_buffer_) {
+ Log::error("XdbeAllocateBufferName failed!\n");
+ return false;
+ }
+
+ return true;
+}
+
+bool
+CompositeCanvasXRender::ensure_xrender_picture()
+{
+ Drawable drawable;
+
+ if (xrender_picture_)
+ return true;
+
+ if (!have_xrender())
+ return false;
+
+ if (!ensure_xdbe_back_buffer())
+ drawable = canvas_;
+ else
+ drawable = xdbe_back_buffer_;
+
+ 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_, drawable, 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_);
+
+ if (xdbe_back_buffer_)
+ XdbeDeallocateBackBufferName(xdpy_, xdbe_back_buffer_);
+
+ xrender_picture_ = 0;
+ xdbe_back_buffer_ = 0;
+}
+
+CompositeWindow *
+CompositeCanvasXRender::create_window(Window win)
+{
+ return new CompositeWindowXRender(xdpy_, win);
+}
+
+void
+CompositeCanvasXRender::update_screen()
+{
+ if (xdbe_back_buffer_) {
+ XdbeSwapInfo swap_info = {canvas_, XdbeBackground};
+ XdbeSwapBuffers(xdpy_, &swap_info, 1);
+ }
+}
+
+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,64 @@
+/*
+ * 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>
+#include <X11/extensions/Xdbe.h>
+
+class CompositeCanvasXRender: public CompositeCanvas
+{
+public:
+ CompositeCanvasXRender() :
+ CompositeCanvas("xrender"), xrender_picture_(0), xdbe_back_buffer_(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 have_xdbe();
+ bool have_xrender();
+ bool ensure_xdbe_back_buffer();
+ bool ensure_xrender_picture();
+
+ Picture xrender_picture_;
+ XdbeBackBuffer xdbe_back_buffer_;
+};
+
+#endif /* COMPOSITE_CANVAS_XRENDER_H_ */
=== modified file 'src/composite-canvas.cc'
@@ -448,7 +448,7 @@
{
CompositeWindow *comp_win = *iter;
if (comp_win->get_texture().is_valid())
- comp_win->update_texture_from_pixmap(false);
+ comp_win->update_texture_from_pixmap();
}
}
=== 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_
=== modified file 'src/composite-window-eglimage.cc'
@@ -37,34 +37,44 @@
CompositeWindowEGLImage::~CompositeWindowEGLImage()
{
- if (egl_image_)
+ release_tfp();
+}
+
+void
+CompositeWindowEGLImage::release_tfp()
+{
+ if (egl_image_) {
eglDestroyImageKHR_(egl_display_, egl_image_);
+ egl_image_ = 0;
+ }
}
void
-CompositeWindowEGLImage::update_texture_from_pixmap(bool recreate)
+CompositeWindowEGLImage::update_texture()
{
+ CompositeWindowGL::update_texture();
+
const EGLint egl_image_attribs[] = {
EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
EGL_NONE
};
+ release_tfp();
+
+ egl_image_ = eglCreateImageKHR_(egl_display_, EGL_NO_CONTEXT,
+ EGL_NATIVE_PIXMAP_KHR,
+ reinterpret_cast<EGLClientBuffer>(pix_),
+ egl_image_attribs);
+
+ Log::debug(" => EGLImage <= %p\n", egl_image_);
+ Log::debug(" => eglError 0x%x\n", eglGetError());
+}
+
+void
+CompositeWindowEGLImage::update_texture_from_pixmap()
+{
Profiler::ScopedSamples scoped_tfp(CompositeWindow::get_profiler_tfp_pair());
- if (recreate) {
- if (egl_image_) {
- eglDestroyImageKHR_(egl_display_, egl_image_);
- egl_image_ = 0;
- }
- egl_image_ = eglCreateImageKHR_(egl_display_, EGL_NO_CONTEXT,
- EGL_NATIVE_PIXMAP_KHR,
- reinterpret_cast<EGLClientBuffer>(pix_),
- egl_image_attribs);
-
- Log::debug(" => EGLImage <= %p\n", egl_image_);
- Log::debug(" => eglError 0x%x\n", eglGetError());
- }
-
/* Update texture with new data */
eglWaitNative(EGL_CORE_NATIVE_ENGINE);
=== modified file 'src/composite-window-eglimage.h'
@@ -39,9 +39,11 @@
egl_image_(0), egl_display_(egl_display) {}
~CompositeWindowEGLImage();
- void update_texture_from_pixmap(bool recreate);
+ void update_texture();
+ void update_texture_from_pixmap();
private:
+ void release_tfp();
EGLImageKHR egl_image_;
EGLDisplay egl_display_;
};
=== modified file 'src/composite-window-gl.cc'
@@ -30,11 +30,9 @@
glDeleteTextures(1, &tex_);
}
-bool
+void
CompositeWindowGL::update_texture()
{
- bool ret = false;
-
if (!tex_ && attr_.map_state != 0) {
glGenTextures(1, &tex_);
@@ -45,14 +43,10 @@
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
Log::debug(" => texture <= 0x%x\n", (unsigned) tex_);
- ret = true;
}
else if (tex_ && attr_.map_state == 0) {
Log::debug(" => Deleting texture 0x%x\n", (unsigned) tex_);
glDeleteTextures(1, &tex_);
- tex_ = 0;
}
-
- return ret;
}
=== modified file 'src/composite-window-gl.h'
@@ -36,7 +36,7 @@
virtual ~CompositeWindowGL();
virtual Texture get_texture() { return CompositeWindow::Texture(tex_); }
- virtual bool update_texture();
+ virtual void update_texture();
protected:
GLuint tex_;
=== modified file 'src/composite-window-glxpixmap.cc'
@@ -52,24 +52,28 @@
}
void
-CompositeWindowGLXPixmap::update_texture_from_pixmap(bool recreate)
+CompositeWindowGLXPixmap::update_texture()
{
+ CompositeWindowGL::update_texture();
+
const int pixmap_attribs[] = {
GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT,
GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT,
None
};
+ release_tfp();
+ glx_pixmap_ = glXCreatePixmap(xdpy_, glx_fbconfig_, pix_,
+ pixmap_attribs);
+
+ Log::debug(" => GLXPixmap <= %p\n", glx_pixmap_);
+}
+
+void
+CompositeWindowGLXPixmap::update_texture_from_pixmap()
+{
Profiler::ScopedSamples scoped_tfp(CompositeWindow::get_profiler_tfp_pair());
- if (recreate) {
- release_tfp();
- glx_pixmap_ = glXCreatePixmap(xdpy_, glx_fbconfig_, pix_,
- pixmap_attribs);
-
- Log::debug(" => GLXPixmap <= %p\n", glx_pixmap_);
- }
-
/* Update texture with new data */
glXWaitX();
=== modified file 'src/composite-window-glxpixmap.h'
@@ -37,7 +37,8 @@
glx_fbconfig_ (glx_fbconfig), glx_pixmap_bound_(false) {}
~CompositeWindowGLXPixmap();
- void update_texture_from_pixmap(bool recreate);
+ void update_texture();
+ void update_texture_from_pixmap();
private:
void release_tfp();
=== modified file 'src/composite-window-pixman.cc'
@@ -188,31 +188,31 @@
}
void
-CompositeWindowPixman::update_texture_from_pixmap(bool recreate)
+CompositeWindowPixman::update_texture()
+{
+ release_resources();
+
+ if (use_shm_) {
+ if (!ensure_ximage_shm() || !ensure_pixman_image())
+ return;
+ }
+ else {
+ if (!ensure_ximage() || !ensure_pixman_image())
+ return;
+ }
+}
+
+void
+CompositeWindowPixman::update_texture_from_pixmap()
{
Profiler::ScopedSamples scoped_tfp(CompositeWindow::get_profiler_tfp_pair());
- if (recreate)
- release_resources();
-
if (use_shm_) {
- if (!ensure_ximage_shm() || !ensure_pixman_image())
- return;
-
XShmGetImage(xdpy_, pix_, ximage_, 0, 0, AllPlanes);
}
else {
- if (!ensure_ximage() || !ensure_pixman_image())
- return;
-
XGetSubImage(xdpy_, pix_, 0, 0, width_, height_, AllPlanes, ZPixmap,
ximage_, 0, 0);
}
}
-
-bool
-CompositeWindowPixman::update_texture()
-{
- return false;
-}
=== modified file 'src/composite-window-pixman.h'
@@ -47,8 +47,8 @@
return CompositeWindow::Texture(pixman_image_);
}
- bool update_texture();
- void update_texture_from_pixmap(bool recreate);
+ void update_texture();
+ void update_texture_from_pixmap();
private:
bool have_xshm();
=== modified file 'src/composite-window-ximage.cc'
@@ -36,23 +36,27 @@
}
void
-CompositeWindowXImage::update_texture_from_pixmap(bool recreate)
+CompositeWindowXImage::update_texture()
+{
+ CompositeWindowGL::update_texture();
+
+ glBindTexture(GL_TEXTURE_2D, tex_);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ width_, height_, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, NULL);
+}
+
+void
+CompositeWindowXImage::update_texture_from_pixmap()
{
Profiler::ScopedSamples scoped_tfp(CompositeWindow::get_profiler_tfp_pair());
- glBindTexture(GL_TEXTURE_2D, tex_);
-
- if (recreate) {
- glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
- width_, height_, 0,
- GL_RGBA, GL_UNSIGNED_BYTE, NULL);
- }
-
if (ximage_)
XDestroyImage(ximage_);
ximage_ = XGetImage(xdpy_, pix_, 0, 0, width_, height_, AllPlanes, ZPixmap);
if (ximage_) {
+ glBindTexture(GL_TEXTURE_2D, tex_);
/*
* Note that the data we get from the pixmap is BGRA but the texture
* expects RGBA, so what we are doing here is technically incorrect
=== modified file 'src/composite-window-ximage.h'
@@ -35,7 +35,8 @@
CompositeWindowGL(xdpy, win), ximage_(0) {}
~CompositeWindowXImage();
- void update_texture_from_pixmap(bool recreate);
+ void update_texture();
+ void update_texture_from_pixmap();
private:
XImage *ximage_;
=== 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.cc'
@@ -96,10 +96,10 @@
}
/* Create or delete texture if needed */
- update_tfp = update_texture() || update_tfp;
-
- if (update_tfp)
- update_texture_from_pixmap(true);
+ if (update_tfp) {
+ update_texture();
+ update_texture_from_pixmap();
+ }
/*
* We have to free the pixmap after calling update_texture_from_pixmap(),
@@ -123,5 +123,5 @@
if (damage_)
XDamageSubtract(xdpy_, damage_, None, None);
- update_texture_from_pixmap(false);
+ update_texture_from_pixmap();
}
=== modified file 'src/composite-window.h'
@@ -37,20 +37,27 @@
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;
- virtual bool update_texture() = 0;
- virtual void update_texture_from_pixmap(bool recreate) = 0;
+ /*
+ * Update the texture itself (whatever that happens
+ * to be, eg GL texture + TFP, pixman image)
+ */
+ virtual void update_texture() = 0;
+ /* Update the texture contents from the pixmap */
+ virtual void update_texture_from_pixmap() = 0;
protected:
Display *xdpy_;
=== 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'
@@ -4,7 +4,7 @@
out = 'build'
top = '.'
-VERSION = '2011.07'
+VERSION = '2011.08'
APPNAME = 'glcompbench'
def option_list_cb(option, opt, value, parser):
@@ -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)