From patchwork Tue Mar 20 16:35:16 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jesse Barker X-Patchwork-Id: 7365 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 0730223E01 for ; Tue, 20 Mar 2012 16:35:22 +0000 (UTC) Received: from mail-iy0-f180.google.com (mail-iy0-f180.google.com [209.85.210.180]) by fiordland.canonical.com (Postfix) with ESMTP id 5BF55A18115 for ; Tue, 20 Mar 2012 16:35:21 +0000 (UTC) Received: by iage36 with SMTP id e36so320650iag.11 for ; Tue, 20 Mar 2012 09:35:20 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf :content-type:mime-version:x-launchpad-project:x-launchpad-branch :x-launchpad-message-rationale:x-launchpad-branch-revision-number :x-launchpad-notification-type:to:from:subject:message-id:date :reply-to:sender:errors-to:precedence:x-generated-by :x-launchpad-hash:x-gm-message-state; bh=4elx+LwPktRstNjmWq2hPbSMK9lrmDwpX7+dEQY6Q7w=; b=krgRPHlQCVLVImOwrqB5hjpNhGT1bnSrRHmEtMayMpZg+M4SqjC1QbhggBf+kGIAVs UYJ9SpHbghcML13GlCQJOHKnBrIE8cFQyp0+/h16waWn+xFxL4G1t5Jmic0VjUW+4N19 Vkf/A/AUCDvHvd6xqVsyMMr7iXErb8vtn3yi8M3UB9OO+7RJgUBoxCf5blfO24ohQzuQ F209Nhpg7dmQNqYgVUTnfXgIlxHkctIs0sYWhUrI3bLBj0u0tskmbbk64uT+RrPJ89s0 qm5Z1LCX5+opR4KDIY8J0nvzgjWN6nctLrykWLDlBVUIzgvdFo951lngjmFXKVBO3uMV utyQ== Received: by 10.50.183.163 with SMTP id en3mr476200igc.12.1332261320776; Tue, 20 Mar 2012 09:35:20 -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.231.203.79 with SMTP id fh15csp5285ibb; Tue, 20 Mar 2012 09:35:19 -0700 (PDT) Received: by 10.216.134.24 with SMTP id r24mr253564wei.84.1332261317926; Tue, 20 Mar 2012 09:35:17 -0700 (PDT) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id 8si2118028wel.122.2012.03.20.09.35.16 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 20 Mar 2012 09:35:17 -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 1SA21k-0001Gf-Kt for ; Tue, 20 Mar 2012 16:35:16 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id 8B742E0109 for ; Tue, 20 Mar 2012 16:35:16 +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: 78 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glcompbench-dev/glcompbench/trunk] Rev 78: Merging lp:~glcompbench-dev/glcompbench/blur into trunk. Message-Id: <20120320163516.28801.74912.launchpad@ackee.canonical.com> Date: Tue, 20 Mar 2012 16:35:16 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="14969"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: cddf3a786473eb6da5e9cff1a318c8403e315399 X-Gm-Message-State: ALoCoQk2OMgDz2df2POnOd48YY+5Mg6GrRoJtrcfkScMSx/1cnZsrSABmPqZozs046UGBTaxFipi Merge authors: Jesse Barker (jesse-barker) Related merge proposals: https://code.launchpad.net/~glcompbench-dev/glcompbench/blur/+merge/98238 proposed by: Jesse Barker (jesse-barker) ------------------------------------------------------------ revno: 78 [merge] committer: Jesse Barker branch nick: trunk timestamp: Tue 2012-03-20 09:32:54 -0700 message: Merging lp:~glcompbench-dev/glcompbench/blur into trunk. This adds a new blur effect test, as well as some additional objects and new internal API changes to support it. added: data/background.png data/desktop-blur.frag data/desktop.frag data/desktop.vert data/window.png src/composite-test-simple-blur.cc src/render-object.cc src/render-object.h src/texture.cc src/texture.h modified: src/benchmark.cc src/benchmark.h src/composite-canvas.cc src/composite-test-default-options.cc src/composite-test-pixman.cc src/composite-test-simple-base.cc src/composite-test-simple-brick.cc src/composite-test-xrender.cc src/composite-test.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 === added file 'data/background.png' Binary files data/background.png 1970-01-01 00:00:00 +0000 and data/background.png 2012-03-01 23:28:36 +0000 differ === added file 'data/desktop-blur.frag' --- data/desktop-blur.frag 1970-01-01 00:00:00 +0000 +++ data/desktop-blur.frag 2012-02-02 22:12:48 +0000 @@ -0,0 +1,13 @@ +uniform sampler2D Texture0; + +varying vec2 TextureCoord; + +void main(void) +{ + vec4 result; + + $CONVOLUTION$ + + gl_FragColor = result; +} + === added file 'data/desktop.frag' --- data/desktop.frag 1970-01-01 00:00:00 +0000 +++ data/desktop.frag 2012-03-08 12:05:59 +0000 @@ -0,0 +1,10 @@ +uniform sampler2D MaterialTexture0; + +varying vec2 TextureCoord; + +void main(void) +{ + vec4 texel = texture2D(MaterialTexture0, TextureCoord); + gl_FragColor = vec4(texel.xyz, 0.5); +} + === added file 'data/desktop.vert' --- data/desktop.vert 1970-01-01 00:00:00 +0000 +++ data/desktop.vert 2012-02-02 22:12:48 +0000 @@ -0,0 +1,11 @@ +attribute vec2 position; +attribute vec2 texcoord; + +varying vec2 TextureCoord; + +void main(void) +{ + gl_Position = vec4(position, 0.0, 1.0); + + TextureCoord = texcoord; +} === added file 'data/window.png' Binary files data/window.png 1970-01-01 00:00:00 +0000 and data/window.png 2012-03-01 23:28:36 +0000 differ === modified file 'src/benchmark.cc' --- src/benchmark.cc 2011-06-22 11:35:50 +0000 +++ src/benchmark.cc 2012-03-09 03:58:54 +0000 @@ -28,6 +28,7 @@ using std::string; using std::vector; using std::map; +using std::list; std::map Benchmark::test_map_; @@ -113,12 +114,12 @@ } CompositeTest & -Benchmark::setup_test() +Benchmark::setup_test(list &window_list) { test_.reset_options(); load_options(); - test_.prepare_for_run(); + test_.prepare_for_run(window_list); return test_; } === modified file 'src/benchmark.h' --- src/benchmark.h 2011-07-15 10:20:09 +0000 +++ src/benchmark.h 2012-03-09 03:58:54 +0000 @@ -40,7 +40,7 @@ // test[:opt1=val1:opt2=val2...] Benchmark(const std::string &s); - CompositeTest &setup_test(); + CompositeTest &setup_test(std::list &window_list); void teardown_test(); CompositeTest &get_test() { return test_; } === modified file 'src/composite-canvas.cc' --- src/composite-canvas.cc 2011-09-21 13:57:01 +0000 +++ src/composite-canvas.cc 2012-03-09 03:58:54 +0000 @@ -633,7 +633,7 @@ benchIt++) { Benchmark *benchmark = *benchIt; - current_test_ = &benchmark->setup_test(); + current_test_ = &benchmark->setup_test(this->window_list_); if (!current_test_->name().empty()) { load_current_test_options(); === modified file 'src/composite-test-default-options.cc' --- src/composite-test-default-options.cc 2011-06-23 13:52:16 +0000 +++ src/composite-test-default-options.cc 2012-03-09 03:58:54 +0000 @@ -29,8 +29,10 @@ * Prepares the test for a test run. */ void -CompositeTestDefaultOptions::prepare_for_run() +CompositeTestDefaultOptions::prepare_for_run(std::list &window_list) { + CompositeTest::prepare_for_run(window_list); + const std::map &tests = Benchmark::tests(); for (std::list >::const_iterator iter = default_options_.begin(); === modified file 'src/composite-test-pixman.cc' --- src/composite-test-pixman.cc 2011-07-19 13:54:14 +0000 +++ src/composite-test-pixman.cc 2012-03-09 03:58:54 +0000 @@ -49,8 +49,10 @@ } void -CompositeTestPixman::prepare_for_run() +CompositeTestPixman::prepare_for_run(std::list &window_list) { + CompositeTest::prepare_for_run(window_list); + if (options_["filter"].value == "bilinear") pixman_filter_ = PIXMAN_FILTER_BILINEAR; else === modified file 'src/composite-test-simple-base.cc' --- src/composite-test-simple-base.cc 2011-12-05 19:01:24 +0000 +++ src/composite-test-simple-base.cc 2012-03-09 03:58:54 +0000 @@ -138,8 +138,10 @@ * Prepares the test for a test run. */ void -CompositeTestSimpleBase::prepare_for_run() +CompositeTestSimpleBase::prepare_for_run(std::list &window_list) { + CompositeTest::prepare_for_run(window_list); + vboData_.useBufferObject(options_["use-vbo"].value == "true"); program_.start(); === added file 'src/composite-test-simple-blur.cc' --- src/composite-test-simple-blur.cc 1970-01-01 00:00:00 +0000 +++ src/composite-test-simple-blur.cc 2012-03-20 16:24:50 +0000 @@ -0,0 +1,474 @@ +/* + * 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 "gl-headers.h" +#include "composite-test.h" +#include "options.h" +#include "log.h" +#include "util.h" +#include "render-object.h" +#include "texture.h" +#include "composite-window-ximage.h" + +using std::string; +using std::map; +using std::list; +using LibMatrix::vec2; + +// +// A RenderObject that blurs the target it is drawn to. +// +class RenderWindowBlur : public RenderObject +{ +public: + RenderWindowBlur(unsigned int passes, unsigned int radius, bool separable) : + RenderObject(), + passes_(passes), + radius_(radius), + separable_(separable), + window_contents_() {} + + virtual void init(Program& program) + { + RenderObject::init(program); + window_contents_.init(program); + } + + virtual void set_background(unsigned int background_texture) + { + window_contents_.set_background(background_texture); + } + + void refresh_window(unsigned int background_texture) + { + glClearColor(0.0, 0.0, 0.0, 0.0); + window_contents_.set_background(background_texture); + window_contents_.clear(); + } + + virtual void release() + { + window_contents_.release(); + RenderObject::release(); + } + + virtual void resize(const vec2& size) + { + RenderObject::resize(size); + window_contents_.resize(size); + } + + virtual void render_to(RenderObject& target) + { + if (separable_) { + Program& blur_program_h1 = blur_program_h(target.size().x()); + Program& blur_program_v1 = blur_program_v(target.size().y()); + + for (unsigned int i = 0; i < passes_; i++) { + render_from(target, blur_program_h1); + RenderObject::render_to(target, blur_program_v1); + } + } + else { + Program& blur_program1 = blur_program(target.size().x(), target.size().y()); + + for (unsigned int i = 0; i < passes_; i++) { + if (i % 2 == 0) + render_from(target, blur_program1); + else + RenderObject::render_to(target, blur_program1); + } + + if (passes_ % 2 == 1) + RenderObject::render_to(target); + } + + // Blend the window contents with the target texture. + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + window_contents_.position(position()); + window_contents_.render_to(target); + glDisable(GL_BLEND); + } + +private: + enum BlurDirection { + BlurDirectionHorizontal, + BlurDirectionVertical, + BlurDirectionBoth + }; + + void render_from(RenderObject& target, Program& program) + { + vec2 final_pos(pos_ + size_); + vec2 ll_tex(target.normalize_texcoord(pos_)); + vec2 ur_tex(target.normalize_texcoord(final_pos)); + + static const GLfloat position_blur[2 * 4] = { + -1.0, -1.0, + 1.0, -1.0, + -1.0, 1.0, + 1.0, 1.0, + }; + GLfloat texcoord_blur[2 * 4] = { + ll_tex.x(), ll_tex.y(), + ur_tex.x(), ll_tex.y(), + ll_tex.x(), ur_tex.y(), + ur_tex.x(), ur_tex.y(), + }; + + make_current(); + glBindTexture(GL_TEXTURE_2D, target.texture()); + draw_quad_with_program(position_blur, texcoord_blur, program); + } + + Program& blur_program(unsigned int w, unsigned int h) + { + /* + * If the size of the window has changed we must recreate + * the shader to contain the correct texture step values. + */ + if (blur_program_dim_.x() != w || blur_program_dim_.y() != h || + !blur_program_.ready()) + { + blur_program_dim_.x(w); + blur_program_dim_.y(h); + + blur_program_.release(); + + ShaderSource vtx_source; + ShaderSource frg_source; + create_blur_shaders(vtx_source, frg_source, radius_, + radius_ / 3.0, BlurDirectionBoth); + frg_source.add_const("TextureStepX", 1.0 / w); + frg_source.add_const("TextureStepY", 1.0 / h); + load_shaders_from_strings(blur_program_, vtx_source.str(), + frg_source.str()); + } + + return blur_program_; + } + + Program& blur_program_h(unsigned int w) + { + /* + * If the size of the window has changed we must recreate + * the shader to contain the correct texture step values. + */ + if (blur_program_dim_.x() != w || + !blur_program_h_.ready()) + { + blur_program_dim_.x(w); + + blur_program_h_.release(); + + ShaderSource vtx_source; + ShaderSource frg_source; + create_blur_shaders(vtx_source, frg_source, radius_, + radius_ / 3.0, BlurDirectionHorizontal); + frg_source.add_const("TextureStepX", 1.0 / w); + load_shaders_from_strings(blur_program_h_, vtx_source.str(), + frg_source.str()); + } + + return blur_program_h_; + } + + Program& blur_program_v(unsigned int h) + { + /* + * If the size of the window has changed we must recreate + * the shader to contain the correct texture step values. + */ + if (blur_program_dim_.y() != h || + !blur_program_v_.ready()) + { + blur_program_dim_.y(h); + + blur_program_v_.release(); + + ShaderSource vtx_source; + ShaderSource frg_source; + create_blur_shaders(vtx_source, frg_source, radius_, + radius_ / 3.0, BlurDirectionVertical); + frg_source.add_const("TextureStepY", 1.0 / h); + load_shaders_from_strings(blur_program_v_, vtx_source.str(), + frg_source.str()); + } + + return blur_program_v_; + } + + static void + create_blur_shaders(ShaderSource& vtx_source, ShaderSource& frg_source, + unsigned int radius, float sigma, BlurDirection direction); + LibMatrix::uvec2 blur_program_dim_; + Program blur_program_; + Program blur_program_h_; + Program blur_program_v_; + unsigned int passes_; + unsigned int radius_; + bool separable_; + RenderClearImage window_contents_; +}; + +void +RenderWindowBlur::create_blur_shaders(ShaderSource& vtx_source, + ShaderSource& frg_source, unsigned int radius, float sigma, + BlurDirection direction) +{ + vtx_source.append_file(GLCOMPBENCH_DATA_PATH"/desktop.vert"); + frg_source.append_file(GLCOMPBENCH_DATA_PATH"/desktop-blur.frag"); + + /* Don't let the gaussian curve become too narrow */ + if (sigma < 1.0) + sigma = 1.0; + + unsigned int side = 2 * radius + 1; + + for (unsigned int i = 0; i < radius + 1; i++) { + float s2 = 2.0 * sigma * sigma; + float k = 1.0 / std::sqrt(M_PI * s2) * std::exp( - (static_cast(i) * i) / s2); + std::stringstream ss_tmp; + ss_tmp << "Kernel" << i; + frg_source.add_const(ss_tmp.str(), k); + } + + std::stringstream ss; + ss << "result = " << std::endl; + + if (direction == BlurDirectionHorizontal) { + for (unsigned int i = 0; i < side; i++) { + int offset = static_cast(i - radius); + ss << "texture2D(Texture0, TextureCoord + vec2(" << + offset << ".0 * TextureStepX, 0.0)) * Kernel" << + std::abs(offset) << " +" << std::endl; + } + ss << "0.0 ;" << std::endl; + } + else if (direction == BlurDirectionVertical) { + for (unsigned int i = 0; i < side; i++) { + int offset = static_cast(i - radius); + ss << "texture2D(Texture0, TextureCoord + vec2(0.0, " << + offset << ".0 * TextureStepY)) * Kernel" << + std::abs(offset) << " +" << std::endl; + } + ss << "0.0 ;" << std::endl; + } + else if (direction == BlurDirectionBoth) { + for (unsigned int i = 0; i < side; i++) { + int ioffset = static_cast(i - radius); + for (unsigned int j = 0; j < side; j++) { + int joffset = static_cast(j - radius); + ss << "texture2D(Texture0, TextureCoord + vec2(" << + ioffset << ".0 * TextureStepX, " << + joffset << ".0 * TextureStepY))" << + " * Kernel" << std::abs(ioffset) << + " * Kernel" << std::abs(joffset) << " +" << std::endl; + } + } + ss << " 0.0;" << std::endl; + } + + frg_source.replace("$CONVOLUTION$", ss.str()); +} + +// +// Private structure used to avoid contaminating composite-test.h with all of +// the CompositeTestSimpleBlur internal classes. +// +struct BlurPrivate +{ + RenderScreen screen; + RenderClearImage desktop; + map windowMap; + int screen_width; + int screen_height; + double lastUpdateTime; + float window_scale_factor; + + BlurPrivate() : + desktop(GLCOMPBENCH_DATA_PATH"/background.png"), + screen_width(0), + screen_height(0), + lastUpdateTime(0), + window_scale_factor(0.4) {} + + ~BlurPrivate() {} +}; + +CompositeTestSimpleBlur::CompositeTestSimpleBlur() : + CompositeTestSimpleBase("blur", + GLCOMPBENCH_DATA_PATH"/desktop.vert", + GLCOMPBENCH_DATA_PATH"/desktop.frag") +{ + options_["use-vbo"] = CompositeTest::Option("use-vbo", "false", + "Whether to use VBOs for rendering [true,false]"); + options_["window-size"] = CompositeTest::Option("window-size", "0.5", + "a scaling factor for the window size (relative to screen screen size) [0.0 - 0.5]"); + options_["passes"] = CompositeTest::Option("passes", "1", + "the number of effect passes (effect dependent)"); + options_["blur-radius"] = CompositeTest::Option("blur-radius", "5", + "the blur effect radius (in pixels)"); + options_["separable"] = CompositeTest::Option("separable", "true", + "use separable convolution for the blur effect"); + priv_ = new BlurPrivate(); +} + +CompositeTestSimpleBlur::~CompositeTestSimpleBlur() +{ + for (map::iterator winIt = priv_->windowMap.begin(); + winIt != priv_->windowMap.end(); + winIt++) + { + RenderWindowBlur* ro = winIt->second; + delete ro; + } + delete priv_; +} + +// +// Width/height values used to compute buffer sizes are likely to generate +// errors in the GL implementation if they are not at least 1, so make sure we +// have sane values. +// +static void +clamp_size(vec2& size) +{ + if (size.x() < 1.0) + { + size.x(1.0); + } + if (size.y() < 1.0) + { + size.y(1.0); + } +} + +void +CompositeTestSimpleBlur::prepare_for_run(list& window_list) +{ + // See how our options tell us to behave... + priv_->window_scale_factor = Util::fromString(options_["window-size"].value); + unsigned int passes(Util::fromString(options_["passes"].value)); + unsigned int radius(Util::fromString(options_["blur-radius"].value)); + bool separable(options_["separable"].value == "true"); + + // Ensure we get a transparent clear color for all following operations + glClearColor(0.0, 0.0, 0.0, 0.0); + glDisable(GL_DEPTH_TEST); + glDepthMask(GL_FALSE); + + priv_->screen.init(program_); + priv_->desktop.init(program_); + + unsigned int visible_windows(num_visible_windows(window_list)); + float angular_step(2 * M_PI / visible_windows); + vec2 screen_size = priv_->screen.size(); + unsigned int i(0); + for(list::iterator iter = window_list.begin(); + iter != window_list.end(); + ++iter) + { + CompositeWindow* win = *iter; + if (!win->get_texture().is_valid()) + { + continue; + } + vec2 window_size(win->width(), win->height()); + window_size *= priv_->window_scale_factor; + clamp_size(window_size); + vec2 corner_offset(window_size / 2.0); + RenderWindowBlur* ro = new RenderWindowBlur(passes, radius, separable); + ro->init(program_); + ro->set_background(win->get_texture().i); + vec2 center(screen_size.x() * (0.5 + 0.25 * cos(i * angular_step)), + screen_size.y() * (0.5 + 0.25 * sin(i * angular_step))); + ro->position(center - corner_offset); + ro->resize(window_size); + priv_->windowMap.insert(make_pair(win->get_xwindow(), ro)); + i++; + } + // + // Ensure the screen is the current rendering target (it might have changed + // to a FBO in the previous steps). + // + priv_->screen.make_current(); +} + +void +CompositeTestSimpleBlur::reshape(int width, int height) +{ + CompositeTestSimpleBase::reshape(width, height); + vec2 screen_size(width, height); + priv_->screen.resize(screen_size); + priv_->desktop.resize(screen_size); +} + +void +CompositeTestSimpleBlur::draw(list &window_list) +{ + unsigned int visible_windows(num_visible_windows(window_list)); + float angular_step(2 * M_PI / visible_windows); + vec2 screen_size = priv_->screen.size(); + unsigned int i(0); + + // Ensure we get a transparent clear color for all following operations. + glClearColor(0.0, 0.0, 0.0, 0.0); + priv_->desktop.clear(); + + for(list::iterator cwIt = window_list.begin(); + cwIt != window_list.end(); + ++cwIt) + { + CompositeWindow* cw = *cwIt; + if (!cw->get_texture().is_valid()) + { + continue; + } + unsigned int winHandle(cw->get_xwindow()); + map::iterator roIt = priv_->windowMap.find(winHandle); + if (roIt == priv_->windowMap.end()) + { + Log::debug("Failed to find window 0x%x in window map\n", winHandle); + continue; + } + RenderWindowBlur* ro = roIt->second; + ro->refresh_window(cw->get_texture().i); + vec2 window_size(cw->width(), cw->height()); + window_size *= priv_->window_scale_factor; + clamp_size(window_size); + vec2 corner_offset(window_size / 2.0); + vec2 center(screen_size.x() * (0.5 + 0.25 * cos(i * angular_step)), + screen_size.y() * (0.5 + 0.25 * sin(i * angular_step))); + ro->position(center - corner_offset); + ro->resize(window_size); + ro->render_to(priv_->desktop); + i++; + } + + // Present the results to the screen. + priv_->desktop.render_to(priv_->screen); +} === modified file 'src/composite-test-simple-brick.cc' --- src/composite-test-simple-brick.cc 2011-09-05 15:23:11 +0000 +++ src/composite-test-simple-brick.cc 2012-03-09 03:58:54 +0000 @@ -37,9 +37,9 @@ const vec2 CompositeTestSimpleBrick::brickPct_(0.90, 0.85); void -CompositeTestSimpleBrick::prepare_for_run() +CompositeTestSimpleBrick::prepare_for_run(std::list &window_list) { - CompositeTestSimpleBase::prepare_for_run(); + CompositeTestSimpleBase::prepare_for_run(window_list); lightPos_ = LibMatrix::vec4(0.0, 1.0, 1.0, 0.0); === modified file 'src/composite-test-xrender.cc' --- src/composite-test-xrender.cc 2011-08-03 17:14:34 +0000 +++ src/composite-test-xrender.cc 2012-03-09 03:58:54 +0000 @@ -52,8 +52,10 @@ } void -CompositeTestXRender::prepare_for_run() +CompositeTestXRender::prepare_for_run(std::list &window_list) { + CompositeTest::prepare_for_run(window_list); + if (options_["filter"].value == "bilinear") xrender_filter_ = FilterBilinear; else === modified file 'src/composite-test.h' --- src/composite-test.h 2011-12-05 18:14:07 +0000 +++ src/composite-test.h 2012-03-09 03:58:54 +0000 @@ -45,7 +45,11 @@ virtual void init() {} virtual void deinit() {} - virtual void prepare_for_run() {} + virtual void prepare_for_run(std::list &window_list) + { + if (window_list.empty()) + return; + } virtual void draw(std::list &window_list) { (void)window_list; @@ -105,7 +109,7 @@ public: CompositeTestDefaultOptions() : CompositeTest("", "") {} - virtual void prepare_for_run(); + virtual void prepare_for_run(std::list &window_list); virtual bool set_option(const std::string &opt, const std::string &val); protected: @@ -121,7 +125,7 @@ virtual void init(); virtual void deinit(); - virtual void prepare_for_run(); + virtual void prepare_for_run(std::list &window_list); virtual void cleanup(); virtual void reshape(int width, int height); @@ -168,7 +172,7 @@ {} virtual void draw(std::list &window_list); - virtual void prepare_for_run(); + virtual void prepare_for_run(std::list &window_list); private: LibMatrix::vec4 lightPos_; static const LibMatrix::vec3 mortarColor_; @@ -187,7 +191,7 @@ virtual void init(); virtual void deinit(); - virtual void prepare_for_run(); + virtual void prepare_for_run(std::list &window_list); virtual void draw(std::list &window_list); private: @@ -202,7 +206,7 @@ virtual void init(); virtual void deinit(); - virtual void prepare_for_run(); + virtual void prepare_for_run(std::list &window_list); virtual void draw(std::list &window_list); private: @@ -225,4 +229,19 @@ virtual bool init_shaders(ShaderSource& vtx, ShaderSource& frg); }; +struct BlurPrivate; + +class CompositeTestSimpleBlur : public CompositeTestSimpleBase +{ + static const std::string fade_bias_name_; + BlurPrivate* priv_; +public: + CompositeTestSimpleBlur(); + ~CompositeTestSimpleBlur(); + + virtual void draw(std::list &window_list); + virtual void reshape(int width, int height); + virtual void prepare_for_run(std::list &window_list); +}; + #endif // COMPOSITE_TEST_H_ === modified file 'src/glcompbench.cc' --- src/glcompbench.cc 2012-02-17 11:51:23 +0000 +++ src/glcompbench.cc 2012-03-20 16:32:54 +0000 @@ -45,6 +45,7 @@ static const char *default_benchmarks[] = { "default", "fade", + "blur", "brick", "pixman", "xrender", @@ -195,6 +196,7 @@ Benchmark::register_test(*new CompositeTestDefaultOptions()); Benchmark::register_test(*new CompositeTestSimpleDefault()); + Benchmark::register_test(*new CompositeTestSimpleBlur()); Benchmark::register_test(*new CompositeTestSimpleFade()); Benchmark::register_test(*new CompositeTestSimpleBrick()); Benchmark::register_test(*new CompositeTestPixman()); === added file 'src/render-object.cc' --- src/render-object.cc 1970-01-01 00:00:00 +0000 +++ src/render-object.cc 2012-03-16 18:04:51 +0000 @@ -0,0 +1,282 @@ +/* + * Copyright © 2012 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 "log.h" +#include "render-object.h" +#include "shader-source.h" +#include "gl-headers.h" +#include "texture.h" + +using LibMatrix::vec2; +using std::string; + +bool +RenderObject::load_shaders_from_strings(Program &program, + const string &vtx_shader, const string &frg_shader) +{ + program.init(); + + Log::debug("Loading vertex shader:\n%s", vtx_shader.c_str()); + + program.addShader(GL_VERTEX_SHADER, vtx_shader); + if (!program.valid()) { + Log::error("Failed to add vertex shader:\n %s\n", "RenderObject: ", + program.errorMessage().c_str()); + program.release(); + return false; + } + + Log::debug("Loading fragment shader:\n%s", frg_shader.c_str()); + + program.addShader(GL_FRAGMENT_SHADER, frg_shader); + if (!program.valid()) { + Log::error("Failed to add fragment shader:\n %s\n", + program.errorMessage().c_str()); + program.release(); + return false; + } + + program.build(); + if (!program.ready()) { + Log::error("Failed to link program: %s\n", + program.errorMessage().c_str()); + program.release(); + return false; + } + + return true; +} + +void +RenderObject::init(Program& default_program) +{ + default_program_ = &default_program; + + // Create a texture to use as a render target + glGenTextures(1, &texture_); + glBindTexture(GL_TEXTURE_2D, texture_); + 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); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.x(), size_.y(), 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0); + + // Create a FBO + glGenFramebuffers(1, &fbo_); + glBindFramebuffer(GL_FRAMEBUFFER, fbo_); + glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, + GL_TEXTURE_2D, texture_, 0); + + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + texture_contents_invalid_ = true; +} + +void +RenderObject::release() +{ + // Release resources + if (texture_ != 0) + { + glDeleteTextures(1, &texture_); + texture_ = 0; + } + if (fbo_ != 0) + { + glDeleteFramebuffers(1, &fbo_); + fbo_ = 0; + } +} + +void +RenderObject::make_current() +{ + glBindFramebuffer(GL_FRAMEBUFFER, fbo_); + glViewport(0, 0, size_.x(), size_.y()); +} + +void +RenderObject::resize(const vec2& size) +{ + /// Recreate the backing texture with correct size + if (size_ != size) { + size_ = size; + glBindTexture(GL_TEXTURE_2D, texture_); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, size_.x(), size_.y(), 0, + GL_RGBA, GL_UNSIGNED_BYTE, 0); + texture_contents_invalid_ = true; + } + + if (texture_contents_invalid_) { + clear(); + texture_contents_invalid_ = false; + } +} + +void +RenderObject::clear() +{ + make_current(); + glClear(GL_COLOR_BUFFER_BIT); +} + +void +RenderObject::render_to(RenderObject& target) +{ + render_to(target, *default_program_); +} + +void +RenderObject::render_to(RenderObject& target, Program& program) +{ + vec2 anchor(pos_); + vec2 ll(pos_ - anchor); + vec2 ur(pos_ + size_ - anchor); + + /* Calculate new position according to rotation value */ + GLfloat position[2 * 4] = { + rotate_x(ll.x(), ll.y()) + anchor.x(), rotate_y(ll.x(), ll.y()) + anchor.y(), + rotate_x(ur.x(), ll.y()) + anchor.x(), rotate_y(ur.x(), ll.y()) + anchor.y(), + rotate_x(ll.x(), ur.y()) + anchor.x(), rotate_y(ll.x(), ur.y()) + anchor.y(), + rotate_x(ur.x(), ur.y()) + anchor.x(), rotate_y(ur.x(), ur.y()) + anchor.y(), + }; + + /* Normalize position and write back to array */ + for (unsigned int i = 0; i < 4; i++) { + unsigned int idx1(2 * i); + unsigned int idx2(2 * i + 1); + const vec2& v2(target.normalize_position(vec2(position[idx1], position[idx2]))); + position[idx1] = v2.x(); + position[idx2] = v2.y(); + } + + static const GLfloat texcoord[2 * 4] = { + 0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + 1.0, 1.0, + }; + + target.make_current(); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture_); + draw_quad_with_program(position, texcoord, program); +} + +void +RenderObject::draw_quad_with_program(const float *position, + const float *texcoord, Program &program) +{ + int pos_index = program["position"].location(); + int tex_index = program["texcoord"].location(); + + program.start(); + + glEnableVertexAttribArray(pos_index); + glEnableVertexAttribArray(tex_index); + glVertexAttribPointer(pos_index, 2, + GL_FLOAT, GL_FALSE, 0, position); + glVertexAttribPointer(tex_index, 2, + GL_FLOAT, GL_FALSE, 0, texcoord); + + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + + glDisableVertexAttribArray(tex_index); + glDisableVertexAttribArray(pos_index); + + program.stop(); +} + +RenderClearImage::RenderClearImage(const string& image_file) : + RenderObject(), background_texture_name_(image_file), + background_texture_(0), background_is_image_(false), + texcoord_(texcoord_window_) +{ + if (!background_texture_name_.empty()) + { + background_is_image_ = true; + texcoord_ = texcoord_image_; + } +} + +RenderClearImage::RenderClearImage() : + RenderObject(), + background_texture_(0), background_is_image_(false), + texcoord_(texcoord_window_) +{ +} + +void +RenderClearImage::init(Program& program) +{ + RenderObject::init(program); + if (background_is_image_) + { + // Load the image into a texture. + Texture::load(background_texture_name_, + &background_texture_, GL_LINEAR, GL_LINEAR, 0); + } +} + +void +RenderClearImage::set_background(unsigned int background_texture) +{ + background_texture_ = background_texture; +} + +void +RenderClearImage::clear() +{ + make_current(); + glClear(GL_COLOR_BUFFER_BIT); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, background_texture_); + + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + draw_quad_with_program(position_, texcoord_, *default_program_); + glDisable(GL_BLEND); +} + +const float RenderClearImage::position_[8] = { + -1.0, -1.0, + 1.0, -1.0, + -1.0, 1.0, + 1.0, 1.0, +}; +const float RenderClearImage::texcoord_image_[8] = { + 0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + 1.0, 1.0, +}; +const float RenderClearImage::texcoord_window_[8] = { + 0.0, 1.0, + 1.0, 1.0, + 0.0, 0.0, + 1.0, 0.0, +}; + === added file 'src/render-object.h' --- src/render-object.h 1970-01-01 00:00:00 +0000 +++ src/render-object.h 2012-03-16 18:04:51 +0000 @@ -0,0 +1,152 @@ +/* + * Copyright © 2012 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 RENDER_OBJECT_H_ +#define RENDER_OBJECT_H_ + +#include "vec.h" +#include "program.h" + +// +// A RenderObject represents a source and target of rendering +// operations. +// +class RenderObject +{ +public: + RenderObject() : + texture_(0), fbo_(0), rotation_rad_(0), + texture_contents_invalid_(true) {} + + // Public interfaces with default implementations + virtual void init(Program& default_program); + virtual void release(); + virtual void resize(const LibMatrix::vec2& size); + virtual void clear(); + virtual void render_to(RenderObject& target); + virtual void render_to(RenderObject& target, Program& program); + + // Public methods + void make_current(); + + // Get/set methods + void position(const LibMatrix::vec2& pos) { pos_ = pos; } + const LibMatrix::vec2& position() { return pos_; } + const LibMatrix::vec2& size() { return size_; } + unsigned int texture() { return texture_; } + + // Normalizes a position from [0, size] to [-1.0, 1.0] + LibMatrix::vec2 normalize_position(const LibMatrix::vec2& pos) + { + return pos * 2.0 / size_ - 1.0; + } + + // Normalizes a position from [0, size] to [0.0, 1.0] + LibMatrix::vec2 normalize_texcoord(const LibMatrix::vec2& pos) + { + return pos / size_; + } + + void rotation(float degrees) + { + rotation_rad_ = (M_PI * degrees / 180.0); + } + +protected: + static bool load_shaders_from_strings(Program& program, + const std::string& vtx_shader, const std::string& frg_shader); + static void draw_quad_with_program(const float *position, const float *texcoord, + Program &program); + + LibMatrix::vec2 pos_; + LibMatrix::vec2 size_; + unsigned int texture_; + unsigned int fbo_; + Program* default_program_; + +private: + float rotate_x(float x, float y) + { + return x * cos(rotation_rad_) - y * sin(rotation_rad_); + } + + float rotate_y(float x, float y) + { + return x * sin(rotation_rad_) + y * cos(rotation_rad_); + } + + float rotation_rad_; + bool texture_contents_invalid_; +}; + +// +// A RenderObject representing the screen. +// +// Rendering to this objects renders to the screen framebuffer. +// +class RenderScreen : public RenderObject +{ +public: + // Our own implementation of the init and release interfaces. + virtual void init(Program& program) { default_program_ = &program; } + virtual void release() {} +}; + +// +// A RenderObject with a background image. +// +// The image is drawn to the RenderObject automatically when the +// object is cleared, resized etc. The background texture for this object +// can either be an image loaded from a named file (in which case the texture +// name is created during the load), or it can be set from an existing texture +// object. +// +class RenderClearImage : public RenderObject +{ +public: + RenderClearImage(); + RenderClearImage(const std::string& image_file); + + // Our own implementation of the init interface. + virtual void init(Program& program); + + // Sets the background texture name. + void set_background(unsigned int background_texture); + + // "Clears" the object to the contents of the background texture. + void clear(); + +private: + std::string background_texture_name_; + unsigned int background_texture_; + bool background_is_image_; + // Vertex position is always the same for any rendering with this object, + // however, texture coordinates vary depending upon whether the texture + // came from a static image loaded from a file (for example) or a window + // system pixmap (inverted sense of y direction). + const float* texcoord_; + static const float position_[8]; + static const float texcoord_image_[8]; + static const float texcoord_window_[8]; +}; + +#endif // RENDER_OBJECT_H_ === added file 'src/texture.cc' --- src/texture.cc 1970-01-01 00:00:00 +0000 +++ src/texture.cc 2012-03-01 23:28:36 +0000 @@ -0,0 +1,201 @@ +/* + * Copyright © 2008 Ben Smith + * Copyright © 2010-2011 Linaro Limited + * + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. + * + * glmark2 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. + * + * glmark2 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 + * glmark2. If not, see . + * + * Authors: + * Ben Smith (original glmark benchmark) + * Alexandros Frantzis (glmark2) + */ +#include "texture.h" +#include "log.h" +#include "util.h" + +#include +#include +#include + +class PNGState +{ +public: + PNGState() : + png_(0), + info_(0), + rows_(0) {} + ~PNGState() + { + if (png_) + { + png_destroy_read_struct(&png_, &info_, 0); + } + } + bool gotData(const std::string& filename) + { + static const int png_transforms = PNG_TRANSFORM_STRIP_16 | + PNG_TRANSFORM_GRAY_TO_RGB | + PNG_TRANSFORM_PACKING | + PNG_TRANSFORM_EXPAND; + + Log::debug("Reading PNG file %s\n", filename.c_str()); + + const std::auto_ptr is_ptr(Util::get_resource(filename)); + if (!(*is_ptr)) { + Log::error("Cannot open file %s!\n", filename.c_str()); + return false; + } + + /* Set up all the libpng structs we need */ + png_ = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); + if (!png_) { + Log::error("Couldn't create libpng read struct\n"); + return false; + } + + info_ = png_create_info_struct(png_); + if (!info_) { + Log::error("Couldn't create libpng info struct\n"); + return false; + } + + /* Set up libpng error handling */ + if (setjmp(png_jmpbuf(png_))) { + Log::error("libpng error while reading file %s\n", filename.c_str()); + return false; + } + + /* Read the image information and data */ + png_set_read_fn(png_, reinterpret_cast(is_ptr.get()), png_read_fn); + + png_read_png(png_, info_, png_transforms, 0); + + rows_ = png_get_rows(png_, info_); + + return true; + } + unsigned int width() const { return png_get_image_width(png_, info_); } + unsigned int height() const { return png_get_image_height(png_, info_); } + unsigned int pixelBytes() const + { + if (png_get_color_type(png_, info_) == PNG_COLOR_TYPE_RGB) + { + return 3; + } + return 4; + } + const unsigned char* row(unsigned int idx) const { return rows_[idx]; } +private: + static void png_read_fn(png_structp png_ptr, png_bytep data, png_size_t length) + { + std::istream *is = reinterpret_cast(png_get_io_ptr(png_ptr)); + is->read(reinterpret_cast(data), length); + } + png_structp png_; + png_infop info_; + png_bytepp rows_; +}; + +class ImageData { + void resize(unsigned int w, unsigned int h, unsigned int b) + { + width = w; + height = h; + bpp = b; + delete [] pixels; + pixels = new unsigned char[bpp * width * height]; + } + +public: + ImageData() : pixels(0), width(0), height(0), bpp(0) {} + ~ImageData() { delete [] pixels; } + bool load_png(const std::string &filename); + + unsigned char *pixels; + unsigned int width; + unsigned int height; + unsigned int bpp; +}; + +bool +ImageData::load_png(const std::string &filename) +{ + PNGState png; + bool ret = png.gotData(filename); + if (!ret) + { + return ret; + } + + resize(png.width(), png.height(), png.pixelBytes()); + + Log::debug(" Height: %d Width: %d Bpp: %d\n", width, height, bpp); + + /* + * Copy the image data to a contiguous memory area suitable for texture + * upload. + */ + for (unsigned int i = 0; i < height; i++) { + memcpy(&pixels[bpp * width * i], + png.row(height - i - 1), + width * bpp); + } + + return ret; +} + +static void +setup_texture(GLuint *tex, ImageData &image, GLint min_filter, GLint mag_filter) +{ + GLenum format = image.bpp == 3 ? GL_RGB : GL_RGBA; + + glGenTextures(1, tex); + glBindTexture(GL_TEXTURE_2D, *tex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, min_filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, mag_filter); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(GL_TEXTURE_2D, 0, format, image.width, image.height, 0, + format, GL_UNSIGNED_BYTE, image.pixels); + + if ((min_filter != GL_NEAREST && min_filter != GL_LINEAR) || + (mag_filter != GL_NEAREST && mag_filter != GL_LINEAR)) + { + glGenerateMipmap(GL_TEXTURE_2D); + } +} + +bool +Texture::load(const std::string &filename, GLuint *pTexture, ...) +{ + ImageData image; + + if (!image.load_png(filename)) + return false; + + va_list ap; + va_start(ap, pTexture); + GLint arg; + + while ((arg = va_arg(ap, GLint)) != 0) { + GLint arg2 = va_arg(ap, GLint); + setup_texture(pTexture, image, arg, arg2); + pTexture++; + } + + va_end(ap); + + return true; +} === added file 'src/texture.h' --- src/texture.h 1970-01-01 00:00:00 +0000 +++ src/texture.h 2012-03-01 23:28:36 +0000 @@ -0,0 +1,37 @@ +/* + * Copyright © 2008 Ben Smith + * Copyright © 2010-2011 Linaro Limited + * + * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark. + * + * glmark2 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. + * + * glmark2 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 + * glmark2. If not, see . + * + * Authors: + * Ben Smith (original glmark benchmark) + * Alexandros Frantzis (glmark2) + */ +#ifndef GLMARK2_TEXTURE_H_ +#define GLMARK2_TEXTURE_H_ + +#include "gl-headers.h" + +#include + +class Texture +{ +public: + static bool load(const std::string &filename, GLuint *pTexture, ...); +}; + +#endif === modified file 'src/wscript_build' --- src/wscript_build 2011-12-12 13:18:23 +0000 +++ src/wscript_build 2012-03-01 23:28:36 +0000 @@ -49,7 +49,7 @@ source = common_sources + egl_sources, target = 'glcompbench-egl-gl', uselib = ['egl', 'gl'] + common_libs, - use = ['matrix'], + use = ['matrix', 'libpng12'], lib = ['m'], defines = ['USE_EGL', 'USE_GL'] ) @@ -60,7 +60,7 @@ source = common_sources + egl_sources, target = 'glcompbench-egl-es2', uselib = ['egl', 'glesv2'] + common_libs, - use = ['matrix-es2'], + use = ['matrix-es2', 'libpng12'], lib = ['m'], defines = ['USE_EGL', 'USE_GLES2'] ) @@ -71,7 +71,7 @@ source = common_sources + glx_sources, target = 'glcompbench-glx', uselib = ['gl'] + common_libs, - use = ['matrix'], + use = ['matrix', 'libpng12'], lib = ['m'], defines = ['USE_GLX', 'USE_GL'] ) @@ -82,7 +82,7 @@ source = common_sources + egl_sources + glx_sources, target = 'glcompbench', uselib = ['glproxy'] + common_libs, - use = ['matrix-glproxy'], + use = ['matrix-glproxy', 'libpng12'], lib = ['m'], defines = ['USE_EGL', 'USE_GLES2', 'USE_GLX', 'USE_GL', 'USE_GLPROXY'] ) === modified file 'wscript' --- wscript 2012-02-16 12:19:54 +0000 +++ wscript 2012-03-20 16:32:54 +0000 @@ -64,7 +64,7 @@ # Check required packages req_pkgs = [('x11', 'x11'), ('xdamage', 'xdamage'), ('xcomposite', 'xcomposite'), ('pixman-1', 'pixman'), - ('xext', 'xext'), ('xrender', 'xrender')] + ('xext', 'xext'), ('xrender', 'xrender'), ('libpng12', 'libpng12')] for (pkg, uselib) in req_pkgs: ctx.check_cfg(package = pkg, uselib_store = uselib, args = '--cflags --libs', mandatory = True)