From patchwork Tue Jul 19 08:32:32 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: alexandros.frantzis@linaro.org X-Patchwork-Id: 2753 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id E931D23F41 for ; Tue, 19 Jul 2011 08:32:38 +0000 (UTC) Received: from mail-qw0-f52.google.com (mail-qw0-f52.google.com [209.85.216.52]) by fiordland.canonical.com (Postfix) with ESMTP id 5AA04A18301 for ; Tue, 19 Jul 2011 08:32:38 +0000 (UTC) Received: by qwb8 with SMTP id 8so2753276qwb.11 for ; Tue, 19 Jul 2011 01:32:37 -0700 (PDT) Received: by 10.229.217.3 with SMTP id hk3mr6352084qcb.38.1311064356184; Tue, 19 Jul 2011 01:32:36 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.229.217.78 with SMTP id hl14cs78901qcb; Tue, 19 Jul 2011 01:32:35 -0700 (PDT) Received: by 10.68.1.38 with SMTP id 6mr7710530pbj.526.1311064354676; Tue, 19 Jul 2011 01:32:34 -0700 (PDT) Received: from adelie.canonical.com (adelie.canonical.com [91.189.90.139]) by mx.google.com with ESMTP id l20si14234384wfh.149.2011.07.19.01.32.33; Tue, 19 Jul 2011 01:32:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) client-ip=91.189.90.139; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.139 as permitted sender) smtp.mail=bounces@canonical.com Received: from loganberry.canonical.com ([91.189.90.37]) by adelie.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1Qj5jE-0005kr-RA for ; Tue, 19 Jul 2011 08:32:32 +0000 Received: from loganberry.canonical.com (localhost [127.0.0.1]) by loganberry.canonical.com (Postfix) with ESMTP id C6D882E8029 for ; Tue, 19 Jul 2011 08:32:32 +0000 (UTC) MIME-Version: 1.0 X-Launchpad-Project: glcompbench X-Launchpad-Branch: ~glcompbench-dev/glcompbench/trunk X-Launchpad-Message-Rationale: Subscriber X-Launchpad-Branch-Revision-Number: 48 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glcompbench-dev/glcompbench/trunk] Rev 48: Merge canvas, window and test for pixman-based compositing. Message-Id: <20110719083232.17286.88318.launchpad@loganberry.canonical.com> Date: Tue, 19 Jul 2011 08:32:32 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="13405"; Instance="initZopeless config overlay" X-Launchpad-Hash: 3b0ffce4f33028834c900877bd488a60bf82df7b Merge authors: Alexandros Frantzis (afrantzis) ------------------------------------------------------------ revno: 48 [merge] committer: Alexandros Frantzis branch nick: trunk timestamp: Tue 2011-07-19 11:29:50 +0300 message: Merge canvas, window and test for pixman-based compositing. added: src/composite-canvas-pixman.cc src/composite-canvas-pixman.h src/composite-test-pixman.cc src/composite-window-gl.cc src/composite-window-gl.h src/composite-window-pixman.cc src/composite-window-pixman.h modified: src/benchmark.h src/composite-canvas-egl.cc src/composite-canvas-egl.h src/composite-canvas-glx.cc src/composite-canvas-glx.h src/composite-canvas.cc src/composite-canvas.h src/composite-test-simple-base.cc src/composite-test-simple-brick.cc src/composite-test-simple-default.cc src/composite-test.cc src/composite-test.h src/composite-window-eglimage.h src/composite-window-glxpixmap.h src/composite-window-ximage.h src/composite-window.cc src/composite-window.h src/glcompbench.cc src/vbo.cc src/vbo.h src/wscript_build wscript --- lp:glcompbench https://code.launchpad.net/~glcompbench-dev/glcompbench/trunk You are subscribed to branch lp:glcompbench. To unsubscribe from this branch go to https://code.launchpad.net/~glcompbench-dev/glcompbench/trunk/+edit-subscription === modified file 'src/benchmark.h' --- src/benchmark.h 2011-06-22 11:35:50 +0000 +++ src/benchmark.h 2011-07-15 10:20:09 +0000 @@ -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 &tests() { return test_map_; } === modified file 'src/composite-canvas-egl.cc' --- src/composite-canvas-egl.cc 2011-06-24 15:51:40 +0000 +++ src/composite-canvas-egl.cc 2011-07-15 13:01:34 +0000 @@ -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' --- src/composite-canvas-egl.h 2011-06-24 15:51:40 +0000 +++ src/composite-canvas-egl.h 2011-07-15 13:01:34 +0000 @@ -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' --- src/composite-canvas-glx.cc 2011-06-24 15:51:40 +0000 +++ src/composite-canvas-glx.cc 2011-07-15 13:01:34 +0000 @@ -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' --- src/composite-canvas-glx.h 2011-06-24 15:51:40 +0000 +++ src/composite-canvas-glx.h 2011-07-15 13:01:34 +0000 @@ -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' --- src/composite-canvas-pixman.cc 1970-01-01 00:00:00 +0000 +++ src/composite-canvas-pixman.cc 2011-07-19 08:08:54 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#include +#include +#include + +#include "composite-canvas-pixman.h" +#include "composite-window-pixman.h" +#include "options.h" +#include "log.h" + +#include + +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(-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(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(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(-1)) { + shmdt(shm_info_.shmaddr); + XShmDetach(xdpy_, &shm_info_); + } + + pixman_image_ = 0; + gc_ = 0; + ximage_ = 0; + shm_info_.shmaddr = reinterpret_cast(-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' --- src/composite-canvas-pixman.h 1970-01-01 00:00:00 +0000 +++ src/composite-canvas-pixman.h 2011-07-18 15:00:13 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#ifndef COMPOSITE_CANVAS_PIXMAN_H_ +#define COMPOSITE_CANVAS_PIXMAN_H_ + +#include +#include "composite-canvas.h" + +#include +#include +#include + +class CompositeCanvasPixman: public CompositeCanvas +{ +public: + CompositeCanvasPixman() : + CompositeCanvas("pixman"), pixman_image_(0), gc_(0), ximage_(0), + use_shm_(false) + { shm_info_.shmaddr = reinterpret_cast(-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' --- src/composite-canvas.cc 2011-06-28 08:31:16 +0000 +++ src/composite-canvas.cc 2011-07-18 13:28:08 +0000 @@ -135,6 +135,23 @@ } /** + * Removes all windows from the list of tracked windows. + */ +void +CompositeCanvas::remove_all_windows() +{ + for(std::list::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& benchmarks, - std::list::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::const_iterator testIt = - Benchmark::tests().begin(); - testIt != Benchmark::tests().end(); - testIt++) + for (std::list::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::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::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' --- src/composite-canvas.h 2011-06-24 15:51:40 +0000 +++ src/composite-canvas.h 2011-07-18 13:28:08 +0000 @@ -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 &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 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' --- src/composite-test-pixman.cc 1970-01-01 00:00:00 +0000 +++ src/composite-test-pixman.cc 2011-07-18 12:38:37 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#include +#include +#include +#include +#include + +#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 &window_list) +{ + CompositeCanvasPixman *canvas_pixman = + static_cast(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::iterator iter = window_list.begin(); + iter != window_list.end(); ++iter) + { + CompositeWindow *comp_win = *iter; + pixman_image_t *pixman_image = reinterpret_cast(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' --- src/composite-test-simple-base.cc 2011-06-24 16:02:39 +0000 +++ src/composite-test-simple-base.cc 2011-07-15 13:08:25 +0000 @@ -21,6 +21,7 @@ * Jesse Barker */ +#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' --- src/composite-test-simple-brick.cc 2011-06-23 13:32:36 +0000 +++ src/composite-test-simple-brick.cc 2011-07-15 08:16:54 +0000 @@ -21,6 +21,7 @@ * Jesse Barker */ +#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' --- src/composite-test-simple-default.cc 2011-06-23 11:22:08 +0000 +++ src/composite-test-simple-default.cc 2011-07-15 08:16:54 +0000 @@ -21,6 +21,7 @@ * Jesse Barker */ +#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' --- src/composite-test.cc 2011-06-24 16:02:39 +0000 +++ src/composite-test.cc 2011-07-15 10:31:48 +0000 @@ -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::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' --- src/composite-test.h 2011-07-18 17:14:16 +0000 +++ src/composite-test.h 2011-07-19 08:29:50 +0000 @@ -27,19 +27,22 @@ #include #include #include +#include + #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 &window_list) { @@ -68,9 +71,13 @@ bool set_option_default(const std::string &opt, const std::string &val); const std::map &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 &window_list); std::string name_; std::map 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 &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' --- src/composite-window-eglimage.h 2011-02-07 18:41:00 +0000 +++ src/composite-window-eglimage.h 2011-07-15 08:16:54 +0000 @@ -28,14 +28,14 @@ #include "gl-headers.h" #include #include -#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' --- src/composite-window-gl.cc 1970-01-01 00:00:00 +0000 +++ src/composite-window-gl.cc 2011-07-15 08:16:54 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#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' --- src/composite-window-gl.h 1970-01-01 00:00:00 +0000 +++ src/composite-window-gl.h 2011-07-15 08:16:54 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#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' --- src/composite-window-glxpixmap.h 2011-02-07 18:00:40 +0000 +++ src/composite-window-glxpixmap.h 2011-07-15 08:16:54 +0000 @@ -26,14 +26,14 @@ #include #include -#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' --- src/composite-window-pixman.cc 1970-01-01 00:00:00 +0000 +++ src/composite-window-pixman.cc 2011-07-18 16:26:56 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#include +#include +#include + +#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(-1)) { + shmdt(shm_info_.shmaddr); + XShmDetach(xdpy_, &shm_info_); + } + + ximage_ = 0; + pixman_image_ = 0; + shm_info_.shmaddr = reinterpret_cast(-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(-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(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(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(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' --- src/composite-window-pixman.h 1970-01-01 00:00:00 +0000 +++ src/composite-window-pixman.h 2011-07-18 16:26:56 +0000 @@ -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 . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#ifndef COMPOSITE_WINDOW_PIXMAN_H_ +#define COMPOSITE_WINDOW_PIXMAN_H_ + +#include +#include +#include +#include + +#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(-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' --- src/composite-window-ximage.h 2011-02-07 18:35:50 +0000 +++ src/composite-window-ximage.h 2011-07-15 08:16:54 +0000 @@ -26,13 +26,13 @@ #include #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' --- src/composite-window.cc 2011-04-04 12:56:06 +0000 +++ src/composite-window.cc 2011-07-15 08:16:54 +0000 @@ -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' --- src/composite-window.h 2011-04-04 12:56:06 +0000 +++ src/composite-window.h 2011-07-15 08:16:54 +0000 @@ -26,7 +26,6 @@ #include #include -#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' --- src/glcompbench.cc 2011-06-24 15:51:40 +0000 +++ src/glcompbench.cc 2011-07-19 08:18:28 +0000 @@ -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 &canvas_list) +{ + const map &tests = Benchmark::tests(); + + for (map::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::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& benchmarks, + std::list::const_iterator &benchIt) +{ + benchIt++; + if (benchIt == benchmarks.end() && Options::run_forever) + benchIt = benchmarks.begin(); +} + + int main(int argc, char **argv) { + std::list 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 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 current_benchmarks; + + // Find continuous runs of benchmarks that use the same canvas + // and run them together + for (std::list::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::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' --- src/vbo.cc 2011-04-27 17:46:24 +0000 +++ src/vbo.cc 2011-07-15 13:03:49 +0000 @@ -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' --- src/vbo.h 2011-04-27 17:46:24 +0000 +++ src/vbo.h 2011-07-15 13:03:49 +0000 @@ -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 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 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 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(dataMap_.texcoordOffset); } const void* vertexOffset() const { return reinterpret_cast(dataMap_.vertexOffset); } === modified file 'src/wscript_build' --- src/wscript_build 2011-06-22 08:59:00 +0000 +++ src/wscript_build 2011-07-18 15:00:13 +0000 @@ -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' --- wscript 2011-06-28 08:38:53 +0000 +++ wscript 2011-07-18 15:00:13 +0000 @@ -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)