=== modified file 'src/benchmark.h'
@@ -43,6 +43,8 @@
CompositeTest &setup_test();
void teardown_test();
+ CompositeTest &get_test() { return test_; }
+
static void register_test(CompositeTest &test);
static CompositeTest &get_test_by_name(const std::string &name);
static const std::map<std::string, CompositeTest *> &tests() { return test_map_; }
=== modified file 'src/composite-canvas-egl.cc'
@@ -256,6 +256,20 @@
return true;
}
+void
+CompositeCanvasEGL::release_resources()
+{
+ eglMakeCurrent(egl_display_, EGL_NO_SURFACE, EGL_NO_SURFACE,
+ EGL_NO_CONTEXT);
+ eglDestroySurface(egl_display_, egl_surface_);
+ eglDestroyContext(egl_display_, egl_context_);
+ eglTerminate(egl_display_);
+
+ egl_display_ = 0;
+ egl_config_ = 0;
+ egl_context_ = 0;
+ egl_surface_ = 0;
+}
CompositeWindow *
CompositeCanvasEGL::create_window(Window win)
=== modified file 'src/composite-canvas-egl.h'
@@ -31,7 +31,7 @@
{
public:
CompositeCanvasEGL() :
- CompositeCanvas(),
+ CompositeCanvas("gl"),
egl_display_(0), egl_config_(0),
egl_context_(0), egl_surface_(0),
use_accel_tfp_(false) {}
@@ -41,6 +41,7 @@
protected:
XVisualInfo *get_canvas_xvisualinfo();
bool make_current();
+ void release_resources();
CompositeWindow *create_window(Window win);
void update_screen();
=== modified file 'src/composite-canvas-glx.cc'
@@ -201,6 +201,13 @@
return true;
}
+void
+CompositeCanvasGLX::release_resources()
+{
+ glx_fbconfig_ = 0;
+ glXDestroyContext(xdpy_, glx_context_);
+ glx_context_ = 0;
+}
CompositeWindow *
CompositeCanvasGLX::create_window(Window win)
=== modified file 'src/composite-canvas-glx.h'
@@ -31,7 +31,7 @@
{
public:
CompositeCanvasGLX() :
- CompositeCanvas(),
+ CompositeCanvas("gl"),
glx_fbconfig_(0), glx_context_(0),
use_accel_tfp_(false) {}
@@ -40,6 +40,7 @@
protected:
XVisualInfo *get_canvas_xvisualinfo();
bool make_current();
+ void release_resources();
CompositeWindow *create_window(Window win);
void update_screen();
=== added file 'src/composite-canvas-pixman.cc'
@@ -0,0 +1,254 @@
+/*
+ * 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-pixman.h"
+#include "composite-window-pixman.h"
+#include "options.h"
+#include "log.h"
+
+#include <sys/shm.h>
+
+CompositeCanvasPixman::~CompositeCanvasPixman()
+{
+ release_resources();
+}
+
+bool
+CompositeCanvasPixman::have_xshm()
+{
+ int ignore, major, minor;
+ Bool pixmaps;
+ bool have_xshm = false;
+
+ /* Check for the XShm extension */
+ if (XQueryExtension(xdpy_, "MIT-SHM", &ignore, &ignore, &ignore)) {
+ if (XShmQueryVersion(xdpy_, &major, &minor, &pixmaps) == True) {
+ Log::debug("XShm extension version %d.%d %s shared pixmaps\n",
+ major, minor, (pixmaps == True) ? "with" : "without");
+ have_xshm = true;
+ }
+ }
+
+ if (!have_xshm && Options::use_accel_tfp) {
+ Log::info("*** Accelerated TFP requested but X Server doesn't support XSHM\n",
+ " Using normal XImage transfer mechanism.");
+ }
+
+ return have_xshm;
+}
+
+bool
+CompositeCanvasPixman::ensure_ximage_shm()
+{
+ XWindowAttributes canvas_attr;
+
+ if (!XGetWindowAttributes(xdpy_, canvas_, &canvas_attr)) {
+ Log::error("XGetWindowAttributes failed!\n");
+ return false;
+ }
+
+ ximage_ = XShmCreateImage(xdpy_, canvas_attr.visual, canvas_attr.depth,
+ ZPixmap, 0, &shm_info_, width_, height_);
+ if (!ximage_) {
+ Log::error("XCreateImage failed!\n");
+ return false;
+ }
+
+ /* Get shared memory from the system */
+ shm_info_.shmid = shmget(IPC_PRIVATE, ximage_->bytes_per_line * ximage_->height,
+ IPC_CREAT | 0777);
+ if (shm_info_.shmid < 0) {
+ Log::error("shmget failed!\n");
+ release_resources();
+ return false;
+ }
+
+ /* Attach shared memory to process address space and set it as RW */
+ shm_info_.readOnly = False;
+ shm_info_.shmaddr = (char *)shmat(shm_info_.shmid, 0, 0);
+ if (shm_info_.shmaddr == reinterpret_cast<char *>(-1)) {
+ Log::error("shmat failed!\n");
+ release_resources();
+ return false;
+ }
+
+ /* Set shared memory as the pixel data for the XImage*/
+ ximage_->data = shm_info_.shmaddr;
+
+ /* Attach shared memory to X Server */
+ if (!XShmAttach(xdpy_, &shm_info_)) {
+ Log::error("XShmAttach failed!\n");
+ release_resources();
+ return false;
+ }
+
+ return true;
+}
+
+bool
+CompositeCanvasPixman::ensure_ximage()
+{
+ XWindowAttributes canvas_attr;
+
+ if (!XGetWindowAttributes(xdpy_, canvas_, &canvas_attr)) {
+ Log::error("XGetWindowAttributes failed!\n");
+ return false;
+ }
+
+ char *pixel_data = reinterpret_cast<char *>(calloc(4 * width_ * height_, 1));
+
+ ximage_ = XCreateImage(xdpy_, canvas_attr.visual, canvas_attr.depth,
+ ZPixmap, 0, pixel_data, width_, height_, 32, 0);
+ if (!ximage_) {
+ Log::error("XCreateImage failed!\n");
+ return false;
+ }
+
+ return true;
+}
+
+bool
+CompositeCanvasPixman::ensure_pixman_image()
+{
+ if (pixman_image_)
+ return true;
+
+ bool have_ximage;
+
+ if (use_shm_)
+ have_ximage = ensure_ximage_shm();
+ else
+ have_ximage = ensure_ximage();
+
+ if (!have_ximage)
+ return false;
+
+ gc_ = XCreateGC(xdpy_, canvas_, 0, 0);
+ if (!gc_) {
+ Log::error("XCreateGC failed!\n");
+ release_resources();
+ return false;
+ }
+
+ pixman_image_ = pixman_image_create_bits(PIXMAN_a8r8g8b8, width_, height_,
+ reinterpret_cast<uint32_t *>(ximage_->data),
+ 4 * width_);
+ if (!pixman_image_) {
+ Log::error("XCreateImage failed!\n");
+ release_resources();
+ return false;
+ }
+
+ return true;
+}
+
+XVisualInfo *
+CompositeCanvasPixman::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
+CompositeCanvasPixman::reshape(int width, int height)
+{
+ CompositeCanvas::reshape(width, height);
+
+ release_resources();
+ ensure_pixman_image();
+}
+
+bool
+CompositeCanvasPixman::make_current()
+{
+ use_shm_ = have_xshm() && Options::use_accel_tfp;
+
+ return ensure_pixman_image();
+}
+
+void
+CompositeCanvasPixman::release_resources()
+{
+ if (pixman_image_)
+ pixman_image_unref(pixman_image_);
+
+ if (gc_)
+ XFreeGC(xdpy_, gc_);
+
+ if (ximage_)
+ XDestroyImage(ximage_);
+
+ if (shm_info_.shmaddr != reinterpret_cast<char *>(-1)) {
+ shmdt(shm_info_.shmaddr);
+ XShmDetach(xdpy_, &shm_info_);
+ }
+
+ pixman_image_ = 0;
+ gc_ = 0;
+ ximage_ = 0;
+ shm_info_.shmaddr = reinterpret_cast<char *>(-1);
+}
+
+CompositeWindow *
+CompositeCanvasPixman::create_window(Window win)
+{
+ return new CompositeWindowPixman(xdpy_, win);
+}
+
+void
+CompositeCanvasPixman::update_screen()
+{
+ if (use_shm_) {
+ XShmPutImage(xdpy_, canvas_, gc_, ximage_, 0, 0, 0, 0, width_,
+ height_, False);
+ }
+ else {
+ XPutImage(xdpy_, canvas_, gc_, ximage_, 0, 0, 0, 0, width_, height_);
+ }
+}
+
+std::string
+CompositeCanvasPixman::info_string()
+{
+ std::stringstream ss;
+
+ ss << " Pixman " << pixman_version_string() << std::endl;
+
+ return ss.str();
+}
=== added file 'src/composite-canvas-pixman.h'
@@ -0,0 +1,68 @@
+/*
+ * 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_PIXMAN_H_
+#define COMPOSITE_CANVAS_PIXMAN_H_
+
+#include <pixman.h>
+#include "composite-canvas.h"
+
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/extensions/XShm.h>
+
+class CompositeCanvasPixman: public CompositeCanvas
+{
+public:
+ CompositeCanvasPixman() :
+ CompositeCanvas("pixman"), pixman_image_(0), gc_(0), ximage_(0),
+ use_shm_(false)
+ { shm_info_.shmaddr = reinterpret_cast<char *>(-1); }
+
+ virtual ~CompositeCanvasPixman();
+
+ std::string info_string();
+ pixman_image_t *pixman_image() { return pixman_image_; }
+
+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_pixman_image();
+ bool ensure_ximage();
+ bool ensure_ximage_shm();
+ bool have_xshm();
+
+ pixman_image_t *pixman_image_;
+ GC gc_;
+ XImage *ximage_;
+ bool use_shm_;
+ XShmSegmentInfo shm_info_;
+};
+
+#endif /* COMPOSITE_CANVAS_PIXMAN_H_ */
=== modified file 'src/composite-canvas.cc'
@@ -135,6 +135,23 @@
}
/**
+ * Removes all windows from the list of tracked windows.
+ */
+void
+CompositeCanvas::remove_all_windows()
+{
+ for(std::list<CompositeWindow*>::iterator iter = window_list_.begin();
+ iter != window_list_.end(); ++iter)
+ {
+ delete *iter;
+ }
+
+ window_list_.clear();
+
+ return;
+}
+
+/**
* Updates a window.
*
* @param win the Window XID
@@ -349,7 +366,7 @@
XEvent event;
bool needs_redraw(false);
Window window(0);
- Profiler::ScopedSamples xevent_scoped(profiler_xevent_pair_);
+ Profiler::ScopedSamples xevent_scoped(CompositeCanvas::profiler_xevent_pair());
if (Options::idle_redraw && !XPending(xdpy_))
return true;
@@ -430,7 +447,7 @@
iter != window_list_.end(); ++iter)
{
CompositeWindow *comp_win = *iter;
- if (comp_win->get_texture())
+ if (comp_win->get_texture().is_valid())
comp_win->update_texture_from_pixmap(false);
}
}
@@ -438,7 +455,14 @@
void
CompositeCanvas::benchmark_init()
{
- profiler_cycle_pair_.sample_start();
+ // Ensure that the profiler pairs have been created
+ CompositeCanvas::profiler_cycle_pair();
+ CompositeCanvas::profiler_xevent_pair();
+ CompositeCanvas::profiler_draw_pair();
+ CompositeCanvas::profiler_screen_update_pair();
+
+ Profiler::instance().reset();
+ CompositeCanvas::profiler_cycle_pair().sample_start();
}
void
@@ -450,10 +474,10 @@
Profiler &profiler = Profiler::instance();
- profiler_cycle_pair_.sample_end();
- profiler_cycle_pair_.sample_start();
+ CompositeCanvas::profiler_cycle_pair().sample_end();
+ CompositeCanvas::profiler_cycle_pair().sample_start();
- profiler_cycle_pair_.get_stats(stats);
+ CompositeCanvas::profiler_cycle_pair().get_stats(stats);
// Each iteration is 3 seconds of compositing by the current test object.
// When we complete an iteration, reset the count and tell the caller.
@@ -500,15 +524,6 @@
}
}
-static void
-next_benchmark(std::list<Benchmark*>& benchmarks,
- std::list<Benchmark*>::iterator &benchIt)
-{
- benchIt++;
- if (benchIt == benchmarks.end() && Options::run_forever)
- benchIt = benchmarks.begin();
-}
-
/******************
* Public methods *
******************/
@@ -551,6 +566,24 @@
}
/**
+ * Deinitializes the canvas.
+ */
+void
+CompositeCanvas::deinit()
+{
+ remove_all_windows();
+ release_resources();
+
+ XDestroyWindow(xdpy_, canvas_);
+ XCloseDisplay(xdpy_);
+
+ xdpy_ = 0;
+ canvas_ = 0;
+ width_ = 0;
+ height_ = 0;
+}
+
+/**
* Runs a list of tests.
*
* @param benchmarks the list of benchmarks to run
@@ -572,19 +605,18 @@
XMapWindow(xdpy_, canvas_);
- // Initialize all tests so that the benchmarking is not biased by
+ // Initialize tests to run so that the benchmarking is not biased by
// setup time (loading and building shaders, etc.)
- for (std::map<std::string, CompositeTest*>::const_iterator testIt =
- Benchmark::tests().begin();
- testIt != Benchmark::tests().end();
- testIt++)
+ for (std::list<Benchmark *>::iterator benchIt = benchmarks.begin();
+ benchIt != benchmarks.end();
+ benchIt++)
{
- CompositeTest* curTest = testIt->second;
- if (!curTest) {
- Log::error("Found a NULL test pointer!\n");
+ Benchmark *benchmark = *benchIt;
+ if (!benchmark) {
+ Log::error("Found a NULL benchmark pointer!\n");
return;
}
- curTest->init();
+ benchmark->get_test().init();
}
benchmark_init();
@@ -593,14 +625,14 @@
for (std::list<Benchmark *>::iterator benchIt = benchmarks.begin();
benchIt != benchmarks.end();
- next_benchmark(benchmarks, benchIt))
+ benchIt++)
{
Benchmark *benchmark = *benchIt;
current_test_ = &benchmark->setup_test();
if (!current_test_->name().empty()) {
load_current_test_options();
- reshape(width_, height_);
+ current_test_->reshape(width_, height_);
Log::info("Running test: '%s'\n", current_test_->name().c_str());
while (true) {
@@ -609,12 +641,12 @@
update_all_textures();
if (Options::draw) {
- profiler_draw_pair_.sample_start();
+ CompositeCanvas::profiler_draw_pair().sample_start();
current_test_->draw(this->window_list_);
- profiler_draw_pair_.sample_end();
- profiler_screen_update_pair_.sample_start();
+ CompositeCanvas::profiler_draw_pair().sample_end();
+ CompositeCanvas::profiler_screen_update_pair().sample_start();
update_screen();
- profiler_screen_update_pair_.sample_end();
+ CompositeCanvas::profiler_screen_update_pair().sample_end();
}
benchmark_update(next_iteration);
@@ -628,5 +660,18 @@
benchmark->teardown_test();
}
+
+ // Deinitialize tests
+ for (std::list<Benchmark *>::iterator benchIt = benchmarks.begin();
+ benchIt != benchmarks.end();
+ benchIt++)
+ {
+ Benchmark *benchmark = *benchIt;
+ if (!benchmark) {
+ Log::error("Found a NULL benchmark pointer!\n");
+ return;
+ }
+ benchmark->get_test().deinit();
+ }
}
=== modified file 'src/composite-canvas.h'
@@ -40,29 +40,33 @@
class CompositeCanvas
{
public:
- CompositeCanvas():
+ CompositeCanvas(const std::string &type):
xdpy_(0), root_(0), canvas_(0), damage_event_(0),
- current_test_(0), iterations_(0), width_(0), height_(0),
- profiler_cycle_pair_("cycle"),
- profiler_xevent_pair_("xevent"),
- profiler_draw_pair_("draw"),
- profiler_screen_update_pair_("screen-update")
+ width_(0), height_(0),
+ current_test_(0), iterations_(0), type_(type)
{}
bool init();
+ void deinit();
void run_tests(std::list<Benchmark*> &benchmarks);
virtual std::string info_string() { return std::string(); }
+
+ const std::string &type() { return type_; }
protected:
virtual XVisualInfo *get_canvas_xvisualinfo() = 0;
virtual bool make_current() = 0;
+ virtual void release_resources() = 0;
virtual CompositeWindow *create_window(Window win) = 0;
virtual void update_screen() = 0;
+ virtual void reshape(int width, int height);
Display *xdpy_;
Window root_;
Window canvas_;
int damage_event_;
+ unsigned int width_;
+ unsigned int height_;
std::list<CompositeWindow*> window_list_;
CompositeTest *current_test_;
@@ -71,8 +75,8 @@
CompositeWindow *find_window(Window win);
void add_window(Window win);
void remove_window(Window win);
+ void remove_all_windows();
void update_window(Window win);
- void reshape(int width, int height);
Window create_canvas_x_window(const char *name, int x, int y,
int width, int height,
XVisualInfo *vis_info);
@@ -87,15 +91,35 @@
void sample_point(int i);
void load_current_test_options();
unsigned int iterations_;
- unsigned int width_;
- unsigned int height_;
double current_test_duration_;
unsigned int current_test_iterations_;
- Profiler::PointPair profiler_cycle_pair_;
- Profiler::PointPair profiler_xevent_pair_;
- Profiler::PointPair profiler_draw_pair_;
- Profiler::PointPair profiler_screen_update_pair_;
+ std::string type_;
+
+ static Profiler::PointPair &profiler_cycle_pair()
+ {
+ static Profiler::PointPair profiler_cycle_pair_("cycle");
+ return profiler_cycle_pair_;
+ }
+
+ static Profiler::PointPair &profiler_xevent_pair()
+ {
+ static Profiler::PointPair profiler_xevent_pair_("xevent");
+ return profiler_xevent_pair_;
+ }
+
+ static Profiler::PointPair &profiler_draw_pair()
+ {
+ static Profiler::PointPair profiler_draw_pair_("draw");
+ return profiler_draw_pair_;
+ }
+
+ static Profiler::PointPair &profiler_screen_update_pair()
+ {
+ static Profiler::PointPair profiler_screen_update_pair_("screen-update");
+ return profiler_screen_update_pair_;
+ }
+
};
=== added file 'src/composite-test-pixman.cc'
@@ -0,0 +1,128 @@
+/*
+ * 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 <pixman.h>
+#include <sstream>
+#include <fstream>
+#include <cstring>
+#include <cstdlib>
+
+#include "composite-test.h"
+#include "composite-canvas-pixman.h"
+#include "options.h"
+#include "log.h"
+
+CompositeTestPixman::CompositeTestPixman() :
+ CompositeTest("pixman", "pixman")
+{
+ options_["filter"] = CompositeTest::Option("filter", "bilinear",
+ "Filter to use [nearest, bilinear]");
+}
+
+void
+CompositeTestPixman::init()
+{
+ pixman_color_t half_transparent = {0x7fff, 0x7fff, 0x7fff, 0x7fff};
+ half_transparent_mask_ = pixman_image_create_solid_fill(&half_transparent);
+}
+
+void
+CompositeTestPixman::deinit()
+{
+ if (half_transparent_mask_)
+ pixman_image_unref(half_transparent_mask_);
+}
+
+void
+CompositeTestPixman::prepare_for_run()
+{
+ if (options_["filter"].value == "bilinear")
+ pixman_filter_ = PIXMAN_FILTER_BILINEAR;
+ else
+ pixman_filter_ = PIXMAN_FILTER_NEAREST;
+}
+
+void
+CompositeTestPixman::draw(std::list<CompositeWindow *> &window_list)
+{
+ CompositeCanvasPixman *canvas_pixman =
+ static_cast<CompositeCanvasPixman *>(canvas_);
+
+ pixman_image_t *dest_image = canvas_pixman->pixman_image();
+ int dest_width = pixman_image_get_width(dest_image);
+ int dest_height = pixman_image_get_height(dest_image);
+
+ /* Clear the screen with color matching GL {0.1, 0.1, 0.3, 1.0} */
+ pixman_color_t clear = {6554, 6554, 19661, 65535};
+
+ pixman_box32_t box;
+ box.x1 = box.y1 = 0;
+ box.x2 = dest_width > 0 ? dest_width - 1 : 0;
+ box.y2 = dest_height > 0 ? dest_height - 1 : 0;
+
+ pixman_image_fill_boxes(PIXMAN_OP_SRC, dest_image, &clear, 1, &box);
+
+ /* 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;
+ pixman_image_t *pixman_image = reinterpret_cast<pixman_image_t *>(comp_win->get_texture().p);
+ if (pixman_image) {
+ int width = pixman_image_get_width(pixman_image);
+ int height = pixman_image_get_height(pixman_image);
+
+ /* 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 */
+ pixman_transform_t xform;
+
+ pixman_image_set_filter(pixman_image, pixman_filter_, NULL, 0);
+ pixman_transform_init_scale(&xform,
+ pixman_double_to_fixed(2.0 * width / dest_width),
+ pixman_double_to_fixed(2.0 * height / dest_height));
+ pixman_image_set_transform(pixman_image, &xform);
+
+ /* Draw the image to the canvas image */
+ pixman_image_composite32(PIXMAN_OP_OVER, pixman_image,
+ half_transparent_mask_, dest_image,
+ 0, 0, 0, 0, x0, y0,
+ dest_width / 2, dest_height / 2);
+
+ i++;
+ }
+ }
+}
+
+
=== modified file 'src/composite-test-simple-base.cc'
@@ -21,6 +21,7 @@
* Jesse Barker <jesse.barker@linaro.org>
*/
+#include "gl-headers.h"
#include "composite-test.h"
#include "options.h"
#include "log.h"
@@ -37,7 +38,7 @@
CompositeTestSimpleBase::CompositeTestSimpleBase(const std::string& test_name,
const std::string& vs_filename,
const std::string& fs_filename)
- : CompositeTest(test_name), vs_filename_(vs_filename),
+ : CompositeTest(test_name, "gl"), vs_filename_(vs_filename),
fs_filename_(fs_filename)
{
options_["use-vbo"] = CompositeTest::Option("use-vbo", "true",
@@ -47,6 +48,9 @@
void
CompositeTestSimpleBase::init()
{
+ if (initialized_)
+ return;
+
// Initialize shader sources from input files
if (!gotSource(vs_filename_, vertex_shader_))
{
@@ -111,6 +115,8 @@
vboData_.addTexCoord(vec2(0, 0));
vboData_.genBufferObject();
+
+ initialized_ = true;
}
/**
@@ -153,3 +159,18 @@
{
program_.stop();
}
+
+void
+CompositeTestSimpleBase::deinit()
+{
+ if (!initialized_)
+ return;
+
+ vertex_shader_.clear();
+ fragment_shader_.clear();
+ vboData_.release();
+ program_.release();
+ vertexIndex_ = 0;
+ texcoordIndex_ = 0;
+ initialized_ = false;
+}
=== modified file 'src/composite-test-simple-brick.cc'
@@ -21,6 +21,7 @@
* Jesse Barker <jesse.barker@linaro.org>
*/
+#include "gl-headers.h"
#include "composite-test.h"
#include "options.h"
#include "log.h"
@@ -75,7 +76,7 @@
iter != window_list.end(); ++iter)
{
CompositeWindow *comp_win = *iter;
- GLuint tex = comp_win->get_texture();
+ GLuint tex = comp_win->get_texture().i;
if (tex) {
model_view_matrix.push();
model_view_matrix.translate(cos(angular_step * i),
=== modified file 'src/composite-test-simple-default.cc'
@@ -21,6 +21,7 @@
* Jesse Barker <jesse.barker@linaro.org>
*/
+#include "gl-headers.h"
#include "composite-test.h"
#include "options.h"
#include "log.h"
@@ -56,7 +57,7 @@
iter != window_list.end(); ++iter)
{
CompositeWindow *comp_win = *iter;
- GLuint tex = comp_win->get_texture();
+ GLuint tex = comp_win->get_texture().i;
if (tex) {
model_view_matrix.push();
model_view_matrix.translate(cos(angular_step * i),
=== modified file 'src/composite-test.cc'
@@ -28,8 +28,8 @@
using std::string;
using std::map;
-CompositeTest::CompositeTest(const string& test_name) :
- name_(test_name)
+CompositeTest::CompositeTest(const string& test_name, const string& type) :
+ name_(test_name), type_(type), initialized_(false), canvas_(0)
{
options_["duration"] = CompositeTest::Option("duration", "3.0",
"The duration of each iteration in seconds");
@@ -52,7 +52,7 @@
for(std::list<CompositeWindow*>::iterator iter = window_list.begin();
iter != window_list.end(); iter++)
{
- if ((*iter)->get_texture())
+ if ((*iter)->get_texture().is_valid())
count++;
}
=== modified file 'src/composite-test.h'
@@ -27,19 +27,22 @@
#include <string>
#include <list>
#include <map>
+#include <pixman.h>
+
#include "stack.h"
#include "program.h"
#include "composite-window.h"
#include "vbo.h"
-class composite_data;
+class CompositeCanvas;
class CompositeTest
{
public:
- CompositeTest(const std::string& test_name);
+ CompositeTest(const std::string& test_name, const std::string &type);
virtual void init() {}
+ virtual void deinit() {}
virtual void prepare_for_run() {}
virtual void draw(std::list<CompositeWindow*> &window_list)
{
@@ -68,9 +71,13 @@
bool set_option_default(const std::string &opt, const std::string &val);
const std::map<std::string, Option> &options() { return options_; }
+ const std::string &type() { return type_; }
+ void set_canvas(CompositeCanvas *canvas) { canvas_ = canvas; }
+ CompositeCanvas *canvas() { return canvas_; }
+
static CompositeTest &dummy()
{
- static CompositeTest dummy_test("");
+ static CompositeTest dummy_test("", "");
return dummy_test;
}
@@ -86,12 +93,15 @@
int num_visible_windows(std::list<CompositeWindow *> &window_list);
std::string name_;
std::map<std::string, Option> options_;
+ std::string type_;
+ bool initialized_;
+ CompositeCanvas *canvas_;
};
class CompositeTestDefaultOptions : public CompositeTest
{
public:
- CompositeTestDefaultOptions() : CompositeTest("") {}
+ CompositeTestDefaultOptions() : CompositeTest("", "") {}
virtual void prepare_for_run();
virtual bool set_option(const std::string &opt, const std::string &val);
@@ -108,6 +118,7 @@
const std::string& fs_filename);
virtual void init();
+ virtual void deinit();
virtual void prepare_for_run();
virtual void cleanup();
virtual void reshape(int width, int height);
@@ -166,4 +177,19 @@
static const std::string lightPosName_;
};
+class CompositeTestPixman : public CompositeTest
+{
+public:
+ CompositeTestPixman();
+
+ virtual void init();
+ virtual void deinit();
+ virtual void prepare_for_run();
+ virtual void draw(std::list<CompositeWindow*> &window_list);
+
+private:
+ pixman_image_t *half_transparent_mask_;
+ pixman_filter_t pixman_filter_;
+};
+
#endif // COMPOSITE_TEST_H_
=== modified file 'src/composite-window-eglimage.h'
@@ -28,14 +28,14 @@
#include "gl-headers.h"
#include <EGL/egl.h>
#include <EGL/eglext.h>
-#include "composite-window.h"
+#include "composite-window-gl.h"
-class CompositeWindowEGLImage : public CompositeWindow
+class CompositeWindowEGLImage : public CompositeWindowGL
{
public:
CompositeWindowEGLImage(Display *xdpy, Window win,
EGLDisplay egl_display) :
- CompositeWindow(xdpy, win),
+ CompositeWindowGL(xdpy, win),
egl_image_(0), egl_display_(egl_display) {}
~CompositeWindowEGLImage();
=== added file 'src/composite-window-gl.cc'
@@ -0,0 +1,58 @@
+/*
+ * 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 "composite-window-gl.h"
+#include "log.h"
+
+CompositeWindowGL::~CompositeWindowGL()
+{
+ if (tex_)
+ glDeleteTextures(1, &tex_);
+}
+
+bool
+CompositeWindowGL::update_texture()
+{
+ bool ret = false;
+
+ if (!tex_ && attr_.map_state != 0) {
+ glGenTextures(1, &tex_);
+
+ glBindTexture(GL_TEXTURE_2D, tex_);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ 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;
+}
+
=== added file 'src/composite-window-gl.h'
@@ -0,0 +1,45 @@
+/*
+ * 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_GL_H_
+#define COMPOSITE_WINDOW_GL_H_
+
+#include "gl-headers.h"
+#include "composite-window.h"
+
+class CompositeWindowGL : public CompositeWindow
+{
+public:
+ CompositeWindowGL(Display *xdpy, Window win) :
+ CompositeWindow(xdpy, win), tex_(0) {}
+
+ virtual ~CompositeWindowGL();
+
+ virtual Texture get_texture() { return CompositeWindow::Texture(tex_); }
+ virtual bool update_texture();
+
+protected:
+ GLuint tex_;
+};
+
+#endif /* COMPOSITE_WINDOW_GL_H_ */
=== modified file 'src/composite-window-glxpixmap.h'
@@ -26,14 +26,14 @@
#include <X11/Xlib.h>
#include <GL/glx.h>
-#include "composite-window.h"
+#include "composite-window-gl.h"
-class CompositeWindowGLXPixmap : public CompositeWindow
+class CompositeWindowGLXPixmap : public CompositeWindowGL
{
public:
CompositeWindowGLXPixmap(Display *xdpy, Window win,
GLXFBConfig glx_fbconfig) :
- CompositeWindow(xdpy, win), glx_pixmap_(0),
+ CompositeWindowGL(xdpy, win), glx_pixmap_(0),
glx_fbconfig_ (glx_fbconfig) {}
~CompositeWindowGLXPixmap();
=== added file 'src/composite-window-pixman.cc'
@@ -0,0 +1,201 @@
+/*
+ * 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 <cstdlib>
+
+#include "gl-headers.h"
+
+#include "composite-window-pixman.h"
+#include "log.h"
+
+CompositeWindowPixman::~CompositeWindowPixman()
+{
+ release_resources();
+}
+
+void
+CompositeWindowPixman::release_resources()
+{
+ if (ximage_)
+ XDestroyImage(ximage_);
+
+ if (pixman_image_)
+ pixman_image_unref(pixman_image_);
+
+ if (shm_info_.shmaddr != reinterpret_cast<char *>(-1)) {
+ shmdt(shm_info_.shmaddr);
+ XShmDetach(xdpy_, &shm_info_);
+ }
+
+ ximage_ = 0;
+ pixman_image_ = 0;
+ shm_info_.shmaddr = reinterpret_cast<char *>(-1);
+}
+
+bool
+CompositeWindowPixman::have_xshm()
+{
+ int ignore, major, minor;
+ Bool pixmaps;
+ bool have_xshm = false;
+
+ if (XQueryExtension(xdpy_, "MIT-SHM", &ignore, &ignore, &ignore)
+ && XShmQueryVersion(xdpy_, &major, &minor, &pixmaps) == True)
+ {
+ have_xshm = true;
+ }
+
+ return have_xshm;
+}
+
+bool
+CompositeWindowPixman::ensure_ximage_shm()
+{
+ if (ximage_)
+ return true;
+
+ XWindowAttributes win_attr;
+
+ if (!XGetWindowAttributes(xdpy_, win_, &win_attr)) {
+ Log::error("XGetWindowAttributes failed!\n");
+ return false;
+ }
+
+ ximage_ = XShmCreateImage(xdpy_, win_attr.visual, win_attr.depth,
+ ZPixmap, 0, &shm_info_, width_, height_);
+ if (!ximage_) {
+ Log::error("XCreateImage failed!\n");
+ return false;
+ }
+
+ /* Get shared memory from the system */
+ shm_info_.shmid = shmget(IPC_PRIVATE, ximage_->bytes_per_line * ximage_->height,
+ IPC_CREAT | 0777);
+ if (shm_info_.shmid < 0) {
+ Log::error("shmget failed!\n");
+ release_resources();
+ return false;
+ }
+
+ /* Attach shared memory to process address space and set it as RW */
+ shm_info_.readOnly = False;
+ shm_info_.shmaddr = (char *)shmat(shm_info_.shmid, 0, 0);
+ if (shm_info_.shmaddr == reinterpret_cast<char *>(-1)) {
+ Log::error("shmat failed!\n");
+ release_resources();
+ return false;
+ }
+
+ /* Set shared memory as the pixel data for the XImage*/
+ ximage_->data = shm_info_.shmaddr;
+
+ /* Attach shared memory to X Server */
+ if (!XShmAttach(xdpy_, &shm_info_)) {
+ Log::error("XShmAttach failed!\n");
+ release_resources();
+ return false;
+ }
+
+ return true;
+}
+
+bool
+CompositeWindowPixman::ensure_ximage()
+{
+ if (ximage_)
+ return true;
+
+ XWindowAttributes win_attr;
+
+ if (!XGetWindowAttributes(xdpy_, win_, &win_attr)) {
+ Log::error("XGetWindowAttributes failed!\n");
+ return false;
+ }
+
+ char *pixel_data = reinterpret_cast<char *>(calloc(4 * width_ * height_, 1));
+
+ ximage_ = XCreateImage(xdpy_, win_attr.visual, win_attr.depth,
+ ZPixmap, 0, pixel_data, width_, height_, 32, 0);
+ if (!ximage_) {
+ Log::error("XCreateImage failed!\n");
+ return false;
+ }
+
+ return true;
+}
+
+bool
+CompositeWindowPixman::ensure_pixman_image()
+{
+ if (pixman_image_)
+ return true;
+
+ pixman_format_code_t format =
+ static_cast<pixman_format_code_t>(
+ PIXMAN_FORMAT(ximage_->bits_per_pixel,
+ PIXMAN_TYPE_ARGB,
+ ximage_->depth - 24, 8, 8, 8));
+
+ if (!pixman_format_supported_source(format)) {
+ Log::debug("Source pixmap format is not supported by pixman!");
+ }
+ else {
+ pixman_image_ = pixman_image_create_bits(format, width_, height_,
+ reinterpret_cast<uint32_t *>(ximage_->data),
+ width_ * 4);
+ }
+
+ return pixman_image_ != 0;
+}
+
+void
+CompositeWindowPixman::update_texture_from_pixmap(bool recreate)
+{
+ 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;
+}
=== added file 'src/composite-window-pixman.h'
@@ -0,0 +1,66 @@
+/*
+ * 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/XShm.h>
+#include <sys/shm.h>
+#include <pixman.h>
+
+#include "composite-window.h"
+#include "options.h"
+
+class CompositeWindowPixman : public CompositeWindow
+{
+public:
+ CompositeWindowPixman(Display *xdpy, Window win) :
+ CompositeWindow(xdpy, win), pixman_image_(0), ximage_(0),
+ use_shm_(have_xshm() && Options::use_accel_tfp)
+ { shm_info_.shmaddr = reinterpret_cast<char *>(-1); }
+
+ ~CompositeWindowPixman();
+
+ CompositeWindow::Texture get_texture()
+ {
+ return CompositeWindow::Texture(pixman_image_);
+ }
+
+ bool update_texture();
+ void update_texture_from_pixmap(bool recreate);
+
+private:
+ bool have_xshm();
+ bool ensure_ximage();
+ bool ensure_ximage_shm();
+ bool ensure_pixman_image();
+ void release_resources();
+
+ pixman_image_t *pixman_image_;
+ XImage *ximage_;
+ bool use_shm_;
+ XShmSegmentInfo shm_info_;
+};
+
+#endif
=== modified file 'src/composite-window-ximage.h'
@@ -26,13 +26,13 @@
#include <X11/Xlib.h>
#include "gl-headers.h"
-#include "composite-window.h"
+#include "composite-window-gl.h"
-class CompositeWindowXImage : public CompositeWindow
+class CompositeWindowXImage : public CompositeWindowGL
{
public:
CompositeWindowXImage(Display *xdpy, Window win) :
- CompositeWindow(xdpy, win), ximage_(0) {}
+ CompositeWindowGL(xdpy, win), ximage_(0) {}
~CompositeWindowXImage();
void update_texture_from_pixmap(bool recreate);
=== modified file 'src/composite-window.cc'
@@ -36,9 +36,6 @@
if (damage_)
XDamageDestroy(xdpy_, damage_);
-
- if (tex_)
- glDeleteTextures(1, &tex_);
}
/**
@@ -50,7 +47,7 @@
int x, y;
unsigned int width, height, border;
Window root;
- bool update_texture = false;
+ bool update_tfp = false;
Pixmap pix_to_free = None;
Log::debug("Composite: Updating window 0x%x\n", (unsigned)win_);
@@ -78,7 +75,7 @@
if (!pix_ && attr_.map_state != 0) {
pix_ = XCompositeNameWindowPixmap(xdpy_, win_);
Log::debug(" => Pixmap <= 0x%x\n", (unsigned) pix_);
- update_texture = true;
+ update_tfp = true;
}
else if (pix_ && attr_.map_state == 0) {
Log::debug(" => Destroying Pixmap 0x%x\n", (unsigned) pix_);
@@ -99,25 +96,9 @@
}
/* Create or delete texture if needed */
- if (!tex_ && attr_.map_state != 0) {
- glGenTextures(1, &tex_);
-
- glBindTexture(GL_TEXTURE_2D, tex_);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-
- Log::debug(" => texture <= 0x%x\n", (unsigned) tex_);
- update_texture = true;
- }
- else if (tex_ && attr_.map_state == 0) {
- Log::debug(" => Deleting texture 0x%x\n", (unsigned) tex_);
- glDeleteTextures(1, &tex_);
- tex_ = 0;
- }
-
- if (update_texture)
+ update_tfp = update_texture() || update_tfp;
+
+ if (update_tfp)
update_texture_from_pixmap(true);
/*
@@ -136,12 +117,6 @@
return win_;
}
-GLuint
-CompositeWindow::get_texture()
-{
- return tex_;
-}
-
void
CompositeWindow::handle_damage()
{
=== modified file 'src/composite-window.h'
@@ -26,7 +26,6 @@
#include <X11/Xlib.h>
#include <X11/extensions/Xdamage.h>
-#include "gl-headers.h"
#include "profiler.h"
class CompositeWindow
@@ -34,14 +33,23 @@
public:
CompositeWindow(Display *xdpy, Window win) :
xdpy_(xdpy), win_(win), pix_(0), damage_(0),
- tex_(0), width_(0), height_(0), depth_(0) {}
+ width_(0), height_(0), depth_(0) {}
+
+ union Texture {
+ Texture(void *p): p(p) {}
+ Texture(unsigned int i): i(i) {}
+ bool is_valid() { return p != 0 && i != 0; }
+ void *p;
+ unsigned int i;
+ };
virtual ~CompositeWindow();
void update();
void handle_damage();
Window get_xwindow();
- GLuint get_texture();
+ virtual Texture get_texture() = 0;
+ virtual bool update_texture() = 0;
virtual void update_texture_from_pixmap(bool recreate) = 0;
protected:
@@ -50,7 +58,6 @@
Pixmap pix_;
Damage damage_;
XWindowAttributes attr_;
- GLuint tex_;
unsigned int width_;
unsigned int height_;
=== modified file 'src/glcompbench.cc'
@@ -28,6 +28,7 @@
#elif USE_GLX
#include "composite-canvas-glx.h"
#endif
+#include "composite-canvas-pixman.h"
#include "composite-test.h"
#include "benchmark.h"
@@ -37,6 +38,7 @@
static const char *default_benchmarks[] = {
"default",
"brick",
+ "pixman",
NULL
};
@@ -91,13 +93,53 @@
}
}
+void
+assign_canvas_to_tests(std::list<CompositeCanvas *> &canvas_list)
+{
+ const map<string, CompositeTest *> &tests = Benchmark::tests();
+
+ for (map<string, CompositeTest *>::const_iterator test_iter = tests.begin();
+ test_iter != tests.end();
+ test_iter++)
+
+ {
+ CompositeTest *test = test_iter->second;
+ if (test->type().empty())
+ continue;
+
+ for (std::list<CompositeCanvas *>::const_iterator iter = canvas_list.begin();
+ iter != canvas_list.end();
+ iter++)
+ {
+ CompositeCanvas *canvas = *iter;
+ if (canvas->type() == test->type()) {
+ test->set_canvas(canvas);
+ break;
+ }
+ }
+ }
+}
+
+static void
+next_benchmark(std::list<Benchmark*>& benchmarks,
+ std::list<Benchmark*>::const_iterator &benchIt)
+{
+ benchIt++;
+ if (benchIt == benchmarks.end() && Options::run_forever)
+ benchIt = benchmarks.begin();
+}
+
+
int
main(int argc, char **argv)
{
+ std::list<CompositeCanvas *> canvas_list;
+ canvas_list.push_back(new CompositeCanvasPixman());
+
#ifdef USE_EGL
- CompositeCanvasEGL canvas;
+ canvas_list.push_back(new CompositeCanvasEGL());
#elif USE_GLX
- CompositeCanvasGLX canvas;
+ canvas_list.push_back(new CompositeCanvasGLX());
#endif
std::list<Benchmark*> benchmarks;
@@ -113,6 +155,10 @@
Benchmark::register_test(*new CompositeTestDefaultOptions());
Benchmark::register_test(*new CompositeTestSimpleDefault());
Benchmark::register_test(*new CompositeTestSimpleBrick());
+ Benchmark::register_test(*new CompositeTestPixman());
+
+ // Assign a compatible canvas to each test
+ assign_canvas_to_tests(canvas_list);
if (Options::list_tests) {
list_tests();
@@ -125,15 +171,54 @@
else
add_custom_benchmarks(benchmarks);
- canvas.init();
Log::info("=======================================================\n");
Log::info(" glcompbench %s\n", GLCOMPBENCH_VERSION);
- Log::info("=======================================================\n");
- Log::info("%s", canvas.info_string().c_str());
- Log::info("=======================================================\n");
-
- canvas.run_tests(benchmarks);
+
+ CompositeCanvas *canvas = 0;
+ std::list<Benchmark *> current_benchmarks;
+
+ // Find continuous runs of benchmarks that use the same canvas
+ // and run them together
+ for (std::list<Benchmark *>::const_iterator iter = benchmarks.begin();
+ iter != benchmarks.end();
+ next_benchmark(benchmarks, iter))
+ {
+ Benchmark *benchmark = *iter;
+ CompositeCanvas *test_canvas = benchmark->get_test().canvas();
+
+ // Check the canvas of the next benchmark (if any)
+ std::list<Benchmark *>::const_iterator next_iter = iter;
+ next_iter++;
+ CompositeCanvas *next_canvas = next_iter == benchmarks.end() ? 0 :
+ (*next_iter)->get_test().canvas();
+
+ // If we have a change in canvas, deinit the previous one
+ // and init the new
+ if (test_canvas != canvas && test_canvas != 0) {
+ if (canvas)
+ canvas->deinit();
+ canvas = test_canvas;
+ canvas->init();
+ Log::info("=======================================================\n");
+ Log::info("%s", canvas->info_string().c_str());
+ Log::info("=======================================================\n");
+ }
+
+ current_benchmarks.push_back(benchmark);
+
+ // We should run the current benchmarks if we have reached the end
+ // or the next benchmark will cause a change to a new valid canvas
+ bool should_run = canvas &&
+ (next_iter == benchmarks.end() ||
+ (next_canvas != 0 && next_canvas != canvas));
+
+ if (should_run) {
+ canvas->run_tests(current_benchmarks);
+ current_benchmarks.clear();
+ }
+
+ }
return 0;
}
=== modified file 'src/vbo.cc'
@@ -257,3 +257,14 @@
glDrawElements(GL_TRIANGLES, indexData_.count(), GL_UNSIGNED_SHORT,
indexOffset());
}
+
+void
+VertexBufferData::release()
+{
+ vertexData_.clear();
+ texcoordData_.clear();
+ indexData_.clear();
+ glDeleteBuffers(2, &bufferObjects_[0]);
+ useBufferObjects_ = false;
+ isMutable_ = false;
+}
=== modified file 'src/vbo.h'
@@ -36,6 +36,7 @@
void addVertex(const LibMatrix::vec3& v) { vertexVec_.push_back(v); }
unsigned int count() const { return vertexVec_.size(); }
const LibMatrix::vec3* data() const { return vertexVec_.data(); }
+ void clear() { vertexVec_.clear(); }
private:
std::vector<LibMatrix::vec3> vertexVec_;
};
@@ -49,6 +50,7 @@
void addIndex(const unsigned short i) { indexVec_.push_back(i); }
unsigned int count() const { return indexVec_.size(); }
const unsigned short* data() { return indexVec_.data(); }
+ void clear() { indexVec_.clear(); }
private:
std::vector<unsigned short> indexVec_;
};
@@ -62,6 +64,7 @@
void addTexCoord(const LibMatrix::vec2& t) { texcoordVec_.push_back(t); }
unsigned int count() const { return texcoordVec_.size(); }
const LibMatrix::vec2* data() const { return texcoordVec_.data(); }
+ void clear() { texcoordVec_.clear(); }
private:
std::vector<LibMatrix::vec2> texcoordVec_;
};
@@ -105,6 +108,8 @@
void unbind();
// Draw the object(s) described by the current data.
void draw();
+ // Release all resources held by this object
+ void release();
// Used to specifiy pointers to glVertexAttribPointer(), etc.
const void* texcoordOffset() const { return reinterpret_cast<const void*>(dataMap_.texcoordOffset); }
const void* vertexOffset() const { return reinterpret_cast<const void*>(dataMap_.vertexOffset); }
=== modified file 'src/wscript_build'
@@ -6,6 +6,8 @@
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']
+
if bld.env.BUILD_EGL_GL or bld.env.BUILD_GLX:
bld(
features = ['cxx', 'cxxstlib'],
@@ -33,7 +35,7 @@
features = ['cxx', 'cprogram'],
source = common_sources + egl_sources,
target = 'glcompbench-egl-gl',
- uselib = ['egl', 'gl', 'x11', 'xdamage', 'xcomposite'],
+ uselib = ['egl', 'gl'] + common_libs,
use = ['matrix'],
lib = ['m'],
defines = ['USE_EGL', 'USE_GL']
@@ -44,7 +46,7 @@
features = ['cxx', 'cprogram'],
source = common_sources + egl_sources,
target = 'glcompbench-egl-es2',
- uselib = ['egl', 'glesv2', 'x11', 'xdamage', 'xcomposite'],
+ uselib = ['egl', 'glesv2'] + common_libs,
use = ['matrix-es2'],
lib = ['m'],
defines = ['USE_EGL', 'USE_GLES2']
@@ -55,7 +57,7 @@
features = ['cxx', 'cprogram'],
source = common_sources + glx_sources,
target = 'glcompbench-glx',
- uselib = ['gl', 'x11', 'xdamage', 'xcomposite'],
+ uselib = ['gl'] + common_libs,
use = ['matrix'],
lib = ['m'],
defines = ['USE_GLX', 'USE_GL']
=== modified file 'wscript'
@@ -61,7 +61,9 @@
ctx.check_cxx(function_name = func, header_name = header, uselib = uselib, mandatory = True)
# Check required packages
- req_pkgs = [('x11', 'x11'), ('xdamage', 'xdamage'), ('xcomposite', 'xcomposite')]
+ req_pkgs = [('x11', 'x11'), ('xdamage', 'xdamage'),
+ ('xcomposite', 'xcomposite'), ('pixman-1', 'pixman'),
+ ('xext', 'xext')]
for (pkg, uselib) in req_pkgs:
ctx.check_cfg(package = pkg, uselib_store = uselib, args = '--cflags --libs',
mandatory = True)