From patchwork Tue Aug 23 14:54:12 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jesse Barker X-Patchwork-Id: 3630 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 C1C4C23F36 for ; Tue, 23 Aug 2011 14:54:16 +0000 (UTC) Received: from mail-bw0-f52.google.com (mail-bw0-f52.google.com [209.85.214.52]) by fiordland.canonical.com (Postfix) with ESMTP id A261CA18791 for ; Tue, 23 Aug 2011 14:54:16 +0000 (UTC) Received: by mail-bw0-f52.google.com with SMTP id zs2so235097bkb.11 for ; Tue, 23 Aug 2011 07:54:16 -0700 (PDT) Received: by 10.204.13.81 with SMTP id b17mr1598969bka.278.1314111256241; Tue, 23 Aug 2011 07:54:16 -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.204.41.75 with SMTP id n11cs213997bke; Tue, 23 Aug 2011 07:54:15 -0700 (PDT) Received: by 10.216.67.78 with SMTP id i56mr820251wed.13.1314111253537; Tue, 23 Aug 2011 07:54:13 -0700 (PDT) Received: from indium.canonical.com (indium.canonical.com [91.189.90.7]) by mx.google.com with ESMTPS id t73si130098weq.79.2011.08.23.07.54.13 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 23 Aug 2011 07:54:13 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) client-ip=91.189.90.7; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of bounces@canonical.com designates 91.189.90.7 as permitted sender) smtp.mail=bounces@canonical.com Received: from ackee.canonical.com ([91.189.89.26]) by indium.canonical.com with esmtp (Exim 4.71 #1 (Debian)) id 1QvsMn-0005xz-1C for ; Tue, 23 Aug 2011 14:54:13 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id F0A34E0191 for ; Tue, 23 Aug 2011 14:54:12 +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: 56 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glcompbench-dev/glcompbench/trunk] Rev 56: Merge from trunk to keep current. Message-Id: <20110823145412.567.51843.launchpad@ackee.canonical.com> Date: Tue, 23 Aug 2011 14:54:12 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="13714"; Instance="initZopeless config overlay" X-Launchpad-Hash: d9297b62bb70fc585bb643f461c8cb3b983a84d3 Merge authors: Alexandros Frantzis (afrantzis) ------------------------------------------------------------ revno: 56 [merge] committer: Jesse Barker branch nick: brick2 timestamp: Tue 2011-08-23 07:34:04 -0700 message: Merge from trunk to keep current. added: src/composite-canvas-xrender.cc src/composite-canvas-xrender.h src/composite-test-xrender.cc src/composite-window-xrender.cc src/composite-window-xrender.h modified: NEWS doc/gl-composite-benchmark.1.in doc/glcompbench.1.in src/composite-canvas.cc src/composite-canvas.h src/composite-test.h src/composite-window-eglimage.cc src/composite-window-eglimage.h src/composite-window-gl.cc src/composite-window-gl.h src/composite-window-glxpixmap.cc src/composite-window-glxpixmap.h src/composite-window-pixman.cc src/composite-window-pixman.h src/composite-window-ximage.cc src/composite-window-ximage.h src/composite-window.cc src/composite-window.h src/glcompbench.cc 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 'NEWS' --- NEWS 2011-07-21 09:50:35 +0000 +++ NEWS 2011-08-18 07:56:25 +0000 @@ -1,3 +1,8 @@ +glcompbench 2011.08 (20110818) +============================== + +* Add xrender based compositing test. + glcompbench 2011.07 (20110719) ============================== === modified file 'doc/gl-composite-benchmark.1.in' --- doc/gl-composite-benchmark.1.in 2011-06-24 14:56:59 +0000 +++ doc/gl-composite-benchmark.1.in 2011-08-18 07:56:25 +0000 @@ -1,4 +1,4 @@ -.TH GL-COMPOSITE-BENCHMARK "1" "June 2011" "gl-composite-benchmark @appversion@" +.TH GL-COMPOSITE-BENCHMARK "1" "August 2011" "gl-composite-benchmark @appversion@" .SH NAME .SH SYNOPSIS .B gl-composite-benchmark [OPTIONS] [-- [GLCOMPBENCH_OPTIONS]] === modified file 'doc/glcompbench.1.in' --- doc/glcompbench.1.in 2011-06-24 14:56:59 +0000 +++ doc/glcompbench.1.in 2011-08-18 07:56:25 +0000 @@ -1,4 +1,4 @@ -.TH @APPNAME@ "1" "June 2011" "@appname@ @appversion@" +.TH @APPNAME@ "1" "August 2011" "@appname@ @appversion@" .SH NAME @appname@ \- OpenGL (ES) 2.0 compositing benchmark .SH SYNOPSIS === added file 'src/composite-canvas-xrender.cc' --- src/composite-canvas-xrender.cc 1970-01-01 00:00:00 +0000 +++ src/composite-canvas-xrender.cc 2011-08-17 14:15:49 +0000 @@ -0,0 +1,246 @@ +/* + * Copyright © 2011 Linaro Limited + * + * This file is part of glcompbench. + * + * glcompbench is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glcompbench is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with glcompbench. If not, see . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#include +#include +#include + +#include "composite-canvas-xrender.h" +#include "composite-window-xrender.h" +#include "options.h" +#include "log.h" + +CompositeCanvasXRender::~CompositeCanvasXRender() +{ + release_resources(); +} + +bool +CompositeCanvasXRender::have_xrender() +{ + int ignore, major, minor; + bool have_xrender = false; + + /* Check for the XShm extension */ + if (XQueryExtension(xdpy_, "RENDER", &ignore, &ignore, &ignore)) { + if (XRenderQueryVersion(xdpy_, &major, &minor)) { + Log::debug("XRender extension version %d.%d\n", + major, minor); + have_xrender = true; + } + } + + return have_xrender; +} + +bool +CompositeCanvasXRender::have_xdbe() +{ + int major, minor; + bool have_xdbe = false; + + /* Check for the Xdbe extension */ + if (XdbeQueryExtension(xdpy_, &major, &minor)) { + Log::debug("Xdbe extension version %d.%d\n", major, minor); + have_xdbe = true; + } + else { + Log::info("** Xdbe extension not supported. You may experience flickering.\n"); + } + + return have_xdbe; +} + +bool +CompositeCanvasXRender::ensure_xdbe_back_buffer() +{ + XdbeScreenVisualInfo *xdbe_screen_vis_info; + XWindowAttributes canvas_attr; + int num_screens = 1; + bool dbe_visual_found = false; + + if (xdbe_back_buffer_) + return true; + + if (!have_xdbe()) + return false; + + /* Check if the canvas visual supports double-buffering */ + if (!XGetWindowAttributes(xdpy_, canvas_, &canvas_attr)) { + Log::error("XGetWindowAttributes failed!\n"); + return false; + } + + xdbe_screen_vis_info = XdbeGetVisualInfo(xdpy_, &canvas_, &num_screens); + if (!xdbe_screen_vis_info || num_screens == 0) { + Log::error("XdbeGetVisualInfo failed!\n"); + return false; + } + + for (int i = 0; i < xdbe_screen_vis_info[0].count; i++) { + XdbeVisualInfo *vis_info = &xdbe_screen_vis_info[0].visinfo[i]; + if (vis_info->visual == XVisualIDFromVisual(canvas_attr.visual)) { + dbe_visual_found = true; + break; + } + } + + XdbeFreeVisualInfo(xdbe_screen_vis_info); + + if (!dbe_visual_found) { + Log::info("** The window visual does not support double buffering." + " You may experience flickering!\n"); + return false; + } + + /* Allocate the back buffer */ + xdbe_back_buffer_ = XdbeAllocateBackBufferName(xdpy_, canvas_, + XdbeBackground); + if (!xdbe_back_buffer_) { + Log::error("XdbeAllocateBufferName failed!\n"); + return false; + } + + return true; +} + +bool +CompositeCanvasXRender::ensure_xrender_picture() +{ + Drawable drawable; + + if (xrender_picture_) + return true; + + if (!have_xrender()) + return false; + + if (!ensure_xdbe_back_buffer()) + drawable = canvas_; + else + drawable = xdbe_back_buffer_; + + XWindowAttributes canvas_attr; + + if (!XGetWindowAttributes(xdpy_, canvas_, &canvas_attr)) { + Log::error("XGetWindowAttributes failed!\n"); + return false; + } + + /* TODO: should we free this when we are done? */ + XRenderPictFormat *pict_format; + + pict_format = XRenderFindVisualFormat(xdpy_, canvas_attr.visual); + if (!pict_format) { + Log::error("XRenderFindVisualFormat failed!\n"); + release_resources(); + return false; + } + + xrender_picture_ = XRenderCreatePicture(xdpy_, drawable, pict_format, + 0, NULL); + if (!xrender_picture_) { + Log::error("XRenderCreatePicture failed!\n"); + release_resources(); + return false; + } + + return true; +} + +XVisualInfo * +CompositeCanvasXRender::get_canvas_xvisualinfo() +{ + int num_visuals; + XVisualInfo vis_tmpl; + XVisualInfo *vis_info; + + vis_tmpl.depth = 32; + vis_tmpl.bits_per_rgb = 8; + vis_info = XGetVisualInfo(xdpy_, VisualDepthMask | VisualBitsPerRGBMask, + &vis_tmpl, &num_visuals); + if (!vis_info) { + Log::error("Error: couldn't get X visual\n"); + return 0; + } + + return vis_info; +} + +void +CompositeCanvasXRender::reshape(int width, int height) +{ + CompositeCanvas::reshape(width, height); + + release_resources(); + ensure_xrender_picture(); +} + +bool +CompositeCanvasXRender::make_current() +{ + return ensure_xrender_picture(); +} + +void +CompositeCanvasXRender::release_resources() +{ + if (xrender_picture_) + XRenderFreePicture(xdpy_, xrender_picture_); + + if (xdbe_back_buffer_) + XdbeDeallocateBackBufferName(xdpy_, xdbe_back_buffer_); + + xrender_picture_ = 0; + xdbe_back_buffer_ = 0; +} + +CompositeWindow * +CompositeCanvasXRender::create_window(Window win) +{ + return new CompositeWindowXRender(xdpy_, win); +} + +void +CompositeCanvasXRender::update_screen() +{ + if (xdbe_back_buffer_) { + XdbeSwapInfo swap_info = {canvas_, XdbeBackground}; + XdbeSwapBuffers(xdpy_, &swap_info, 1); + } +} + +std::string +CompositeCanvasXRender::info_string() +{ + std::stringstream ss; + int major, minor; + + ss << " XRender "; + if (XRenderQueryVersion(xdpy_, &major, &minor)) + ss << major << "." << minor << std::endl; + else + ss << "(Not Available)" << std::endl; + + return ss.str(); +} === added file 'src/composite-canvas-xrender.h' --- src/composite-canvas-xrender.h 1970-01-01 00:00:00 +0000 +++ src/composite-canvas-xrender.h 2011-08-17 14:15:49 +0000 @@ -0,0 +1,64 @@ +/* + * Copyright © 2011 Linaro Limited + * + * This file is part of glcompbench. + * + * glcompbench is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glcompbench is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with glcompbench. If not, see . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#ifndef COMPOSITE_CANVAS_XRENDER_H_ +#define COMPOSITE_CANVAS_XRENDER_H_ + +#include "composite-canvas.h" + +#include +#include +#include +#include + +class CompositeCanvasXRender: public CompositeCanvas +{ +public: + CompositeCanvasXRender() : + CompositeCanvas("xrender"), xrender_picture_(0), xdbe_back_buffer_(0) + {} + + virtual ~CompositeCanvasXRender(); + + std::string info_string(); + Picture xrender_picture() { return xrender_picture_; } + +protected: + XVisualInfo *get_canvas_xvisualinfo(); + bool make_current(); + void release_resources(); + CompositeWindow *create_window(Window win); + void update_screen(); + void reshape(int width, int height); + +private: + bool have_xdbe(); + bool have_xrender(); + bool ensure_xdbe_back_buffer(); + bool ensure_xrender_picture(); + + Picture xrender_picture_; + XdbeBackBuffer xdbe_back_buffer_; +}; + +#endif /* COMPOSITE_CANVAS_XRENDER_H_ */ === modified file 'src/composite-canvas.cc' --- src/composite-canvas.cc 2011-07-18 13:28:08 +0000 +++ src/composite-canvas.cc 2011-08-03 14:34:10 +0000 @@ -448,7 +448,7 @@ { CompositeWindow *comp_win = *iter; if (comp_win->get_texture().is_valid()) - comp_win->update_texture_from_pixmap(false); + comp_win->update_texture_from_pixmap(); } } === modified file 'src/composite-canvas.h' --- src/composite-canvas.h 2011-07-18 13:28:08 +0000 +++ src/composite-canvas.h 2011-08-03 17:00:15 +0000 @@ -52,6 +52,9 @@ virtual std::string info_string() { return std::string(); } const std::string &type() { return type_; } + Display *xdisplay() { return xdpy_; } + unsigned int width() { return width_; } + unsigned int height() { return height_; } protected: virtual XVisualInfo *get_canvas_xvisualinfo() = 0; === added file 'src/composite-test-xrender.cc' --- src/composite-test-xrender.cc 1970-01-01 00:00:00 +0000 +++ src/composite-test-xrender.cc 2011-08-03 17:14:34 +0000 @@ -0,0 +1,124 @@ +/* + * Copyright © 2011 Linaro Limited + * + * This file is part of glcompbench. + * + * glcompbench is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glcompbench is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with glcompbench. If not, see . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#include +#include + +#include "composite-test.h" +#include "composite-canvas-xrender.h" + +CompositeTestXRender::CompositeTestXRender() : + CompositeTest("xrender", "xrender") +{ + options_["filter"] = CompositeTest::Option("filter", "bilinear", + "Filter to use [nearest, bilinear]"); +} + +void +CompositeTestXRender::init() +{ + XRenderColor half_transparent = {0x7fff, 0x7fff, 0x7fff, 0x7fff}; + half_transparent_mask_ = XRenderCreateSolidFill(canvas_->xdisplay(), + &half_transparent); +} + +void +CompositeTestXRender::deinit() +{ + if (half_transparent_mask_) { + XRenderFreePicture(canvas_->xdisplay(), half_transparent_mask_); + half_transparent_mask_ = 0; + } +} + +void +CompositeTestXRender::prepare_for_run() +{ + if (options_["filter"].value == "bilinear") + xrender_filter_ = FilterBilinear; + else + xrender_filter_ = FilterNearest; +} + +void +CompositeTestXRender::draw(std::list &window_list) +{ + CompositeCanvasXRender *canvas_xrender = + static_cast(canvas_); + Display *xdpy = canvas_->xdisplay(); + + Picture dest_picture = canvas_xrender->xrender_picture(); + int dest_width = canvas_->width(); + int dest_height = canvas_->height(); + + /* Clear the screen with color matching GL {0.1, 0.1, 0.3, 1.0} */ + XRenderColor clear = {6554, 6554, 19661, 65535}; + + XRenderFillRectangle(xdpy, PictOpSrc, dest_picture, &clear, + 0, 0, dest_width, dest_height); + + /* Find out how many windows are visible and calculate the angular step */ + int visible_windows(num_visible_windows(window_list)); + float angular_step(2 * M_PI / visible_windows); + + /* Draw the windows in a circle using the calculated angular step */ + int i(0); + for(std::list::iterator iter = window_list.begin(); + iter != window_list.end(); ++iter) + { + CompositeWindow *comp_win = *iter; + Picture xrender_picture = static_cast(comp_win->get_texture().i); + if (xrender_picture) { + int width = comp_win->width(); + int height = comp_win->height(); + + /* Calculate the new position of the composited window center */ + int x0 = dest_width / 2 + cos(i * angular_step) * dest_width / 4; + int y0 = dest_height / 2 + sin(i * angular_step) * dest_height / 4; + + /* Calculate the new position of the upper left corner */ + x0 -= dest_width / 4; + y0 -= dest_height / 4; + + /* Scale the window to fit in dest_width/2 and dest_height/2 */ + XTransform xform = {{{0}}}; + xform.matrix[0][0] = XDoubleToFixed(2.0 * width / dest_width); + xform.matrix[1][1] = XDoubleToFixed(2.0 * height / dest_height); + xform.matrix[2][2] = XDoubleToFixed(1.0); + + XRenderSetPictureFilter(xdpy, xrender_picture, + xrender_filter_, NULL, 0); + XRenderSetPictureTransform(xdpy, xrender_picture, &xform); + + /* Draw the window Picture to the canvas Picture */ + XRenderComposite(xdpy, PictOpOver, xrender_picture, + half_transparent_mask_, dest_picture, + 0, 0, 0, 0, x0, y0, + dest_width / 2, dest_height / 2); + + i++; + } + } +} + + === modified file 'src/composite-test.h' --- src/composite-test.h 2011-07-19 08:29:50 +0000 +++ src/composite-test.h 2011-08-03 17:14:34 +0000 @@ -28,6 +28,7 @@ #include #include #include +#include #include "stack.h" #include "program.h" @@ -192,4 +193,20 @@ pixman_filter_t pixman_filter_; }; +class CompositeTestXRender : public CompositeTest +{ +public: + CompositeTestXRender(); + + virtual void init(); + virtual void deinit(); + virtual void prepare_for_run(); + virtual void draw(std::list &window_list); + +private: + Picture half_transparent_mask_; + const char *xrender_filter_; + +}; + #endif // COMPOSITE_TEST_H_ === modified file 'src/composite-window-eglimage.cc' --- src/composite-window-eglimage.cc 2011-04-04 12:56:06 +0000 +++ src/composite-window-eglimage.cc 2011-08-03 14:34:10 +0000 @@ -37,34 +37,44 @@ CompositeWindowEGLImage::~CompositeWindowEGLImage() { - if (egl_image_) + release_tfp(); +} + +void +CompositeWindowEGLImage::release_tfp() +{ + if (egl_image_) { eglDestroyImageKHR_(egl_display_, egl_image_); + egl_image_ = 0; + } } void -CompositeWindowEGLImage::update_texture_from_pixmap(bool recreate) +CompositeWindowEGLImage::update_texture() { + CompositeWindowGL::update_texture(); + const EGLint egl_image_attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_NONE }; + release_tfp(); + + egl_image_ = eglCreateImageKHR_(egl_display_, EGL_NO_CONTEXT, + EGL_NATIVE_PIXMAP_KHR, + reinterpret_cast(pix_), + egl_image_attribs); + + Log::debug(" => EGLImage <= %p\n", egl_image_); + Log::debug(" => eglError 0x%x\n", eglGetError()); +} + +void +CompositeWindowEGLImage::update_texture_from_pixmap() +{ Profiler::ScopedSamples scoped_tfp(CompositeWindow::get_profiler_tfp_pair()); - if (recreate) { - if (egl_image_) { - eglDestroyImageKHR_(egl_display_, egl_image_); - egl_image_ = 0; - } - egl_image_ = eglCreateImageKHR_(egl_display_, EGL_NO_CONTEXT, - EGL_NATIVE_PIXMAP_KHR, - reinterpret_cast(pix_), - egl_image_attribs); - - Log::debug(" => EGLImage <= %p\n", egl_image_); - Log::debug(" => eglError 0x%x\n", eglGetError()); - } - /* Update texture with new data */ eglWaitNative(EGL_CORE_NATIVE_ENGINE); === modified file 'src/composite-window-eglimage.h' --- src/composite-window-eglimage.h 2011-07-15 08:16:54 +0000 +++ src/composite-window-eglimage.h 2011-08-03 14:34:10 +0000 @@ -39,9 +39,11 @@ egl_image_(0), egl_display_(egl_display) {} ~CompositeWindowEGLImage(); - void update_texture_from_pixmap(bool recreate); + void update_texture(); + void update_texture_from_pixmap(); private: + void release_tfp(); EGLImageKHR egl_image_; EGLDisplay egl_display_; }; === modified file 'src/composite-window-gl.cc' --- src/composite-window-gl.cc 2011-07-15 08:16:54 +0000 +++ src/composite-window-gl.cc 2011-08-03 14:34:10 +0000 @@ -30,11 +30,9 @@ glDeleteTextures(1, &tex_); } -bool +void CompositeWindowGL::update_texture() { - bool ret = false; - if (!tex_ && attr_.map_state != 0) { glGenTextures(1, &tex_); @@ -45,14 +43,10 @@ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); Log::debug(" => texture <= 0x%x\n", (unsigned) tex_); - ret = true; } else if (tex_ && attr_.map_state == 0) { Log::debug(" => Deleting texture 0x%x\n", (unsigned) tex_); glDeleteTextures(1, &tex_); - tex_ = 0; } - - return ret; } === modified file 'src/composite-window-gl.h' --- src/composite-window-gl.h 2011-07-15 08:16:54 +0000 +++ src/composite-window-gl.h 2011-08-03 14:34:10 +0000 @@ -36,7 +36,7 @@ virtual ~CompositeWindowGL(); virtual Texture get_texture() { return CompositeWindow::Texture(tex_); } - virtual bool update_texture(); + virtual void update_texture(); protected: GLuint tex_; === modified file 'src/composite-window-glxpixmap.cc' --- src/composite-window-glxpixmap.cc 2011-07-20 09:17:11 +0000 +++ src/composite-window-glxpixmap.cc 2011-08-03 14:34:10 +0000 @@ -52,24 +52,28 @@ } void -CompositeWindowGLXPixmap::update_texture_from_pixmap(bool recreate) +CompositeWindowGLXPixmap::update_texture() { + CompositeWindowGL::update_texture(); + const int pixmap_attribs[] = { GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGBA_EXT, None }; + release_tfp(); + glx_pixmap_ = glXCreatePixmap(xdpy_, glx_fbconfig_, pix_, + pixmap_attribs); + + Log::debug(" => GLXPixmap <= %p\n", glx_pixmap_); +} + +void +CompositeWindowGLXPixmap::update_texture_from_pixmap() +{ Profiler::ScopedSamples scoped_tfp(CompositeWindow::get_profiler_tfp_pair()); - if (recreate) { - release_tfp(); - glx_pixmap_ = glXCreatePixmap(xdpy_, glx_fbconfig_, pix_, - pixmap_attribs); - - Log::debug(" => GLXPixmap <= %p\n", glx_pixmap_); - } - /* Update texture with new data */ glXWaitX(); === modified file 'src/composite-window-glxpixmap.h' --- src/composite-window-glxpixmap.h 2011-07-20 08:23:33 +0000 +++ src/composite-window-glxpixmap.h 2011-08-03 14:34:10 +0000 @@ -37,7 +37,8 @@ glx_fbconfig_ (glx_fbconfig), glx_pixmap_bound_(false) {} ~CompositeWindowGLXPixmap(); - void update_texture_from_pixmap(bool recreate); + void update_texture(); + void update_texture_from_pixmap(); private: void release_tfp(); === modified file 'src/composite-window-pixman.cc' --- src/composite-window-pixman.cc 2011-07-19 16:01:23 +0000 +++ src/composite-window-pixman.cc 2011-08-03 14:34:10 +0000 @@ -188,31 +188,31 @@ } void -CompositeWindowPixman::update_texture_from_pixmap(bool recreate) +CompositeWindowPixman::update_texture() +{ + release_resources(); + + if (use_shm_) { + if (!ensure_ximage_shm() || !ensure_pixman_image()) + return; + } + else { + if (!ensure_ximage() || !ensure_pixman_image()) + return; + } +} + +void +CompositeWindowPixman::update_texture_from_pixmap() { Profiler::ScopedSamples scoped_tfp(CompositeWindow::get_profiler_tfp_pair()); - if (recreate) - release_resources(); - if (use_shm_) { - if (!ensure_ximage_shm() || !ensure_pixman_image()) - return; - XShmGetImage(xdpy_, pix_, ximage_, 0, 0, AllPlanes); } else { - if (!ensure_ximage() || !ensure_pixman_image()) - return; - XGetSubImage(xdpy_, pix_, 0, 0, width_, height_, AllPlanes, ZPixmap, ximage_, 0, 0); } } - -bool -CompositeWindowPixman::update_texture() -{ - return false; -} === modified file 'src/composite-window-pixman.h' --- src/composite-window-pixman.h 2011-07-18 16:26:56 +0000 +++ src/composite-window-pixman.h 2011-08-03 14:34:10 +0000 @@ -47,8 +47,8 @@ return CompositeWindow::Texture(pixman_image_); } - bool update_texture(); - void update_texture_from_pixmap(bool recreate); + void update_texture(); + void update_texture_from_pixmap(); private: bool have_xshm(); === modified file 'src/composite-window-ximage.cc' --- src/composite-window-ximage.cc 2011-04-04 12:56:06 +0000 +++ src/composite-window-ximage.cc 2011-08-03 14:34:10 +0000 @@ -36,23 +36,27 @@ } void -CompositeWindowXImage::update_texture_from_pixmap(bool recreate) +CompositeWindowXImage::update_texture() +{ + CompositeWindowGL::update_texture(); + + glBindTexture(GL_TEXTURE_2D, tex_); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + width_, height_, 0, + GL_RGBA, GL_UNSIGNED_BYTE, NULL); +} + +void +CompositeWindowXImage::update_texture_from_pixmap() { Profiler::ScopedSamples scoped_tfp(CompositeWindow::get_profiler_tfp_pair()); - glBindTexture(GL_TEXTURE_2D, tex_); - - if (recreate) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, - width_, height_, 0, - GL_RGBA, GL_UNSIGNED_BYTE, NULL); - } - if (ximage_) XDestroyImage(ximage_); ximage_ = XGetImage(xdpy_, pix_, 0, 0, width_, height_, AllPlanes, ZPixmap); if (ximage_) { + glBindTexture(GL_TEXTURE_2D, tex_); /* * Note that the data we get from the pixmap is BGRA but the texture * expects RGBA, so what we are doing here is technically incorrect === modified file 'src/composite-window-ximage.h' --- src/composite-window-ximage.h 2011-07-15 08:16:54 +0000 +++ src/composite-window-ximage.h 2011-08-03 14:34:10 +0000 @@ -35,7 +35,8 @@ CompositeWindowGL(xdpy, win), ximage_(0) {} ~CompositeWindowXImage(); - void update_texture_from_pixmap(bool recreate); + void update_texture(); + void update_texture_from_pixmap(); private: XImage *ximage_; === added file 'src/composite-window-xrender.cc' --- src/composite-window-xrender.cc 1970-01-01 00:00:00 +0000 +++ src/composite-window-xrender.cc 2011-08-03 17:05:08 +0000 @@ -0,0 +1,91 @@ +/* + * Copyright © 2011 Linaro Limited + * + * This file is part of glcompbench. + * + * glcompbench is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glcompbench is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with glcompbench. If not, see . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#include +#include +#include + +#include "composite-window-xrender.h" +#include "log.h" + +CompositeWindowXRender::~CompositeWindowXRender() +{ + release_resources(); +} + +void +CompositeWindowXRender::release_resources() +{ + if (xrender_picture_) + XRenderFreePicture(xdpy_, xrender_picture_); + + xrender_picture_ = 0; +} + +bool +CompositeWindowXRender::ensure_xrender_picture() +{ + if (xrender_picture_) + return true; + + XWindowAttributes win_attr; + + if (!XGetWindowAttributes(xdpy_, win_, &win_attr)) { + Log::error("XGetWindowAttributes failed!\n"); + return false; + } + + /* TODO: should we free this when we are done? */ + XRenderPictFormat *pict_format; + + pict_format = XRenderFindVisualFormat(xdpy_, win_attr.visual); + if (!pict_format) { + Log::error("XRenderFindVisualFormat failed!\n"); + release_resources(); + return false; + } + + xrender_picture_ = XRenderCreatePicture(xdpy_, win_, pict_format, + 0, NULL); + if (!xrender_picture_) { + Log::error("XRenderCreatePicture failed!\n"); + release_resources(); + return false; + } + + return true; +} + +void +CompositeWindowXRender::update_texture() +{ + release_resources(); + ensure_xrender_picture(); +} + +void +CompositeWindowXRender::update_texture_from_pixmap() +{ + Profiler::ScopedSamples scoped_tfp(CompositeWindow::get_profiler_tfp_pair()); +} + === added file 'src/composite-window-xrender.h' --- src/composite-window-xrender.h 1970-01-01 00:00:00 +0000 +++ src/composite-window-xrender.h 2011-08-03 17:05:08 +0000 @@ -0,0 +1,56 @@ +/* + * Copyright © 2011 Linaro Limited + * + * This file is part of glcompbench. + * + * glcompbench is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * glcompbench is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with glcompbench. If not, see . + * + * Authors: + * Alexandros Frantzis + * Jesse Barker + */ + +#ifndef COMPOSITE_WINDOW_PIXMAN_H_ +#define COMPOSITE_WINDOW_PIXMAN_H_ + +#include +#include + +#include "composite-window.h" +#include "options.h" + +class CompositeWindowXRender : public CompositeWindow +{ +public: + CompositeWindowXRender(Display *xdpy, Window win) : + CompositeWindow(xdpy, win), xrender_picture_(0) {} + + ~CompositeWindowXRender(); + + CompositeWindow::Texture get_texture() + { + return CompositeWindow::Texture(xrender_picture_); + } + + void update_texture(); + void update_texture_from_pixmap(); + +private: + bool ensure_xrender_picture(); + void release_resources(); + + Picture xrender_picture_; +}; + +#endif === modified file 'src/composite-window.cc' --- src/composite-window.cc 2011-07-15 08:16:54 +0000 +++ src/composite-window.cc 2011-08-03 14:34:10 +0000 @@ -96,10 +96,10 @@ } /* Create or delete texture if needed */ - update_tfp = update_texture() || update_tfp; - - if (update_tfp) - update_texture_from_pixmap(true); + if (update_tfp) { + update_texture(); + update_texture_from_pixmap(); + } /* * We have to free the pixmap after calling update_texture_from_pixmap(), @@ -123,5 +123,5 @@ if (damage_) XDamageSubtract(xdpy_, damage_, None, None); - update_texture_from_pixmap(false); + update_texture_from_pixmap(); } === modified file 'src/composite-window.h' --- src/composite-window.h 2011-07-15 08:16:54 +0000 +++ src/composite-window.h 2011-08-03 17:02:08 +0000 @@ -37,20 +37,27 @@ union Texture { Texture(void *p): p(p) {} - Texture(unsigned int i): i(i) {} + Texture(long unsigned int i): i(i) {} bool is_valid() { return p != 0 && i != 0; } void *p; - unsigned int i; + long unsigned int i; }; virtual ~CompositeWindow(); void update(); void handle_damage(); Window get_xwindow(); + unsigned int width() { return width_; } + unsigned int height() { return height_; } virtual Texture get_texture() = 0; - virtual bool update_texture() = 0; - virtual void update_texture_from_pixmap(bool recreate) = 0; + /* + * Update the texture itself (whatever that happens + * to be, eg GL texture + TFP, pixman image) + */ + virtual void update_texture() = 0; + /* Update the texture contents from the pixmap */ + virtual void update_texture_from_pixmap() = 0; protected: Display *xdpy_; === modified file 'src/glcompbench.cc' --- src/glcompbench.cc 2011-07-19 08:18:28 +0000 +++ src/glcompbench.cc 2011-08-04 10:49:59 +0000 @@ -29,6 +29,7 @@ #include "composite-canvas-glx.h" #endif #include "composite-canvas-pixman.h" +#include "composite-canvas-xrender.h" #include "composite-test.h" #include "benchmark.h" @@ -39,6 +40,7 @@ "default", "brick", "pixman", + "xrender", NULL }; @@ -135,6 +137,7 @@ { std::list canvas_list; canvas_list.push_back(new CompositeCanvasPixman()); + canvas_list.push_back(new CompositeCanvasXRender()); #ifdef USE_EGL canvas_list.push_back(new CompositeCanvasEGL()); @@ -156,6 +159,7 @@ Benchmark::register_test(*new CompositeTestSimpleDefault()); Benchmark::register_test(*new CompositeTestSimpleBrick()); Benchmark::register_test(*new CompositeTestPixman()); + Benchmark::register_test(*new CompositeTestXRender()); // Assign a compatible canvas to each test assign_canvas_to_tests(canvas_list); === modified file 'src/wscript_build' --- src/wscript_build 2011-07-18 15:00:13 +0000 +++ src/wscript_build 2011-08-03 17:03:48 +0000 @@ -6,7 +6,7 @@ glx_sources = ['composite-canvas-glx.cc', 'composite-window-glxpixmap.cc'] egl_sources = ['composite-canvas-egl.cc', 'composite-window-eglimage.cc'] -common_libs = ['x11', 'xdamage', 'xcomposite', 'pixman', 'xext'] +common_libs = ['x11', 'xdamage', 'xcomposite', 'pixman', 'xext', 'xrender'] if bld.env.BUILD_EGL_GL or bld.env.BUILD_GLX: bld( === modified file 'wscript' --- wscript 2011-07-21 09:50:35 +0000 +++ wscript 2011-08-18 07:56:25 +0000 @@ -4,7 +4,7 @@ out = 'build' top = '.' -VERSION = '2011.07' +VERSION = '2011.08' APPNAME = 'glcompbench' def option_list_cb(option, opt, value, parser): @@ -63,7 +63,7 @@ # Check required packages req_pkgs = [('x11', 'x11'), ('xdamage', 'xdamage'), ('xcomposite', 'xcomposite'), ('pixman-1', 'pixman'), - ('xext', 'xext')] + ('xext', 'xext'), ('xrender', 'xrender')] for (pkg, uselib) in req_pkgs: ctx.check_cfg(package = pkg, uselib_store = uselib, args = '--cflags --libs', mandatory = True)