From patchwork Fri Jan 27 22:29:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jesse Barker X-Patchwork-Id: 6429 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 C42FF23E16 for ; Fri, 27 Jan 2012 22:29:16 +0000 (UTC) Received: from mail-bk0-f52.google.com (mail-bk0-f52.google.com [209.85.214.52]) by fiordland.canonical.com (Postfix) with ESMTP id 84A07A1805A for ; Fri, 27 Jan 2012 22:29:16 +0000 (UTC) Received: by bkar19 with SMTP id r19so2406883bka.11 for ; Fri, 27 Jan 2012 14:29:16 -0800 (PST) Received: by 10.205.134.129 with SMTP id ic1mr3895648bkc.92.1327703356158; Fri, 27 Jan 2012 14:29:16 -0800 (PST) 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.130.220 with SMTP id u28cs86993bks; Fri, 27 Jan 2012 14:29:15 -0800 (PST) Received: by 10.180.19.97 with SMTP id d1mr13945393wie.12.1327703355376; Fri, 27 Jan 2012 14:29:15 -0800 (PST) Received: from indium.canonical.com (indium.canonical.com. [91.189.90.7]) by mx.google.com with ESMTPS id n10si8791530wie.24.2012.01.27.14.29.15 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 27 Jan 2012 14:29:15 -0800 (PST) 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 1RquIF-0008II-48 for ; Fri, 27 Jan 2012 22:29:15 +0000 Received: from ackee.canonical.com (localhost [127.0.0.1]) by ackee.canonical.com (Postfix) with ESMTP id 0F4D7E01BB for ; Fri, 27 Jan 2012 22:29:15 +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: 75 X-Launchpad-Notification-Type: branch-revision To: Linaro Patch Tracker From: noreply@launchpad.net Subject: [Branch ~glcompbench-dev/glcompbench/trunk] Rev 75: Merge of lp:~glcompbench-dev/glcompbench/libmatrix-util. Message-Id: <20120127222915.8576.68759.launchpad@ackee.canonical.com> Date: Fri, 27 Jan 2012 22:29:15 -0000 Reply-To: noreply@launchpad.net Sender: bounces@canonical.com Errors-To: bounces@canonical.com Precedence: bulk X-Generated-By: Launchpad (canonical.com); Revision="14727"; Instance="launchpad-lazr.conf" X-Launchpad-Hash: 39c38b395a39d51f1050eaef907d9a39e61bc989 Merge authors: Jesse Barker (jesse-barker) Related merge proposals: https://code.launchpad.net/~glcompbench-dev/glcompbench/libmatrix-util/+merge/90329 proposed by: Jesse Barker (jesse-barker) ------------------------------------------------------------ revno: 75 [merge] committer: Jesse Barker branch nick: trunk timestamp: Fri 2012-01-27 14:26:02 -0800 message: Merge of lp:~glcompbench-dev/glcompbench/libmatrix-util. Updates glcompbench to reflect the latest lp:libmatrix, which, in and of itself, conslidates code previously duplicated between glcompbench and glmark2 into libmatrix. removed: src/log.cc src/log.h src/shader-source.cc src/shader-source.h src/util.cc src/util.h added: src/libmatrix/gl-if.h src/libmatrix/log.cc src/libmatrix/log.h src/libmatrix/shader-source.cc src/libmatrix/shader-source.h src/libmatrix/test/basic-global-const.vert src/libmatrix/test/basic.frag src/libmatrix/test/basic.vert src/libmatrix/test/const_vec_test.cc src/libmatrix/test/const_vec_test.h src/libmatrix/test/shader_source_test.cc src/libmatrix/test/shader_source_test.h src/libmatrix/test/transpose_test.cc src/libmatrix/test/transpose_test.h src/libmatrix/util.cc src/libmatrix/util.h modified: src/glcompbench.cc src/libmatrix/Makefile src/libmatrix/mat.h src/libmatrix/program.cc src/libmatrix/program.h src/libmatrix/test/inverse_test.cc src/libmatrix/test/inverse_test.h src/libmatrix/test/libmatrix_test.cc src/libmatrix/test/libmatrix_test.h src/libmatrix/test/options.cc src/libmatrix/vec.h --- 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/glcompbench.cc' --- src/glcompbench.cc 2011-12-12 13:16:47 +0000 +++ src/glcompbench.cc 2012-01-27 22:21:17 +0000 @@ -40,6 +40,7 @@ #include "benchmark.h" #include "options.h" #include "log.h" +#include "util.h" static const char *default_benchmarks[] = { "default", @@ -148,6 +149,9 @@ if (!Options::parse_args(argc, argv)) return 1; + // Initialize Log class + Log::init(Util::appname_from_path(argv[0]), Options::show_debug); + if (Options::show_help || Options::backend == Options::BACKEND_NONE) { Options::print_help(); === modified file 'src/libmatrix/Makefile' --- src/libmatrix/Makefile 2011-06-22 08:59:00 +0000 +++ src/libmatrix/Makefile 2012-01-26 19:36:28 +0000 @@ -1,11 +1,14 @@ CXXFLAGS = -Wall -Werror -pedantic -O3 LIBMATRIX = libmatrix.a -LIBSRCS = mat.cc program.cc +LIBSRCS = mat.cc program.cc log.cc util.cc shader-source.cc LIBOBJS = $(LIBSRCS:.cc=.o) TESTDIR = test LIBMATRIX_TESTS = $(TESTDIR)/libmatrix_test TESTSRCS = $(TESTDIR)/options.cc \ + $(TESTDIR)/const_vec_test.cc \ $(TESTDIR)/inverse_test.cc \ + $(TESTDIR)/transpose_test.cc \ + $(TESTDIR)/shader_source_test.cc \ $(TESTDIR)/libmatrix_test.cc TESTOBJS = $(TESTSRCS:.cc=.o) @@ -16,15 +19,21 @@ # Main library targets here. mat.o : mat.cc mat.h vec.h program.o: program.cc program.h mat.h vec.h -libmatrix.a : mat.o mat.h stack.h vec.h program.o program.h +log.o: log.cc log.h +util.o: util.cc util.h +shader-source.o: shader-source.cc shader-source.h mat.h vec.h +libmatrix.a : mat.o stack.h program.o log.o util.o shader-source.o $(AR) -r $@ $(LIBOBJS) # Tests and execution targets here. $(TESTDIR)/options.o: $(TESTDIR)/options.cc $(TESTDIR)/libmatrix_test.h -$(TESTDIR)/libmatrix_test.o: $(TESTDIR)/libmatrix_test.cc $(TESTDIR)/libmatrix_test.h $(TESTDIR)/inverse_test.h +$(TESTDIR)/libmatrix_test.o: $(TESTDIR)/libmatrix_test.cc $(TESTDIR)/libmatrix_test.h $(TESTDIR)/inverse_test.h $(TESTDIR)/transpose_test.h +$(TESTDIR)/const_vec_test.o: $(TESTDIR)/const_vec_test.cc $(TESTDIR)/const_vec_test.h $(TESTDIR)/libmatrix_test.h vec.h $(TESTDIR)/inverse_test.o: $(TESTDIR)/inverse_test.cc $(TESTDIR)/inverse_test.h $(TESTDIR)/libmatrix_test.h mat.h -$(TESTDIR)/libmatrix_test: $(TESTDIR)/options.o $(TESTDIR)/libmatrix_test.o $(TESTDIR)/inverse_test.o libmatrix.a - $(CXX) -o $@ $? +$(TESTDIR)/transpose_test.o: $(TESTDIR)/transpose_test.cc $(TESTDIR)/transpose_test.h $(TESTDIR)/libmatrix_test.h mat.h +$(TESTDIR)/shader_source_test.o: $(TESTDIR)/shader_source_test.cc $(TESTDIR)/shader_source_test.h $(TESTDIR)/libmatrix_test.h shader-source.h +$(TESTDIR)/libmatrix_test: $(TESTOBJS) libmatrix.a + $(CXX) -o $@ $^ run_tests: $(LIBMATRIX_TESTS) $(LIBMATRIX_TESTS) clean : === added file 'src/libmatrix/gl-if.h' --- src/libmatrix/gl-if.h 1970-01-01 00:00:00 +0000 +++ src/libmatrix/gl-if.h 2012-01-26 19:36:28 +0000 @@ -0,0 +1,18 @@ +// +// Copyright (c) 2012 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#ifndef GL_IF_H_ +#define GL_IF_H_ +// Inclusion abstraction to provide project specific interface headers for +// whatever flavor of OpenGL(|ES) is appropriate. For core libmatrix, this +// is GLEW. +#include "gl-headers.h" +#endif // GL_IF_H_ === added file 'src/libmatrix/log.cc' --- src/libmatrix/log.cc 1970-01-01 00:00:00 +0000 +++ src/libmatrix/log.cc 2012-01-27 22:21:17 +0000 @@ -0,0 +1,178 @@ +// +// Copyright (c) 2010-2012 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Alexandros Frantzis +// Jesse Barker +// +#include +#include +#include +#include +#include +#include "log.h" + +#ifdef ANDROID +#include +#endif + +using std::string; + +const string Log::continuation_prefix("\x10"); +string Log::appname_; +bool Log::do_debug_(false); + +#ifndef ANDROID + +static const string terminal_color_normal("\033[0m"); +static const string terminal_color_red("\033[1;31m"); +static const string terminal_color_cyan("\033[36m"); +static const string terminal_color_yellow("\033[33m"); +static const string empty; + +static void +print_prefixed_message(std::ostream& stream, const string& color, const string& prefix, + const string& fmt, va_list ap) +{ + va_list aq; + + /* Estimate message size */ + va_copy(aq, ap); + int msg_size = vsnprintf(NULL, 0, fmt.c_str(), aq); + va_end(aq); + + /* Create the buffer to hold the message */ + char *buf = new char[msg_size + 1]; + + /* Store the message in the buffer */ + va_copy(aq, ap); + vsnprintf(buf, msg_size + 1, fmt.c_str(), aq); + va_end(aq); + + /* + * Print the message lines prefixed with the supplied prefix. + * If the target stream is a terminal make the prefix colored. + */ + string linePrefix; + if (!prefix.empty()) + { + static const string colon(": "); + string start_color; + string end_color; + if (!color.empty()) + { + start_color = color; + end_color = terminal_color_normal; + } + linePrefix = start_color + prefix + end_color + colon; + } + + std::string line; + std::stringstream ss(buf); + + while(std::getline(ss, line)) { + /* + * If this line is a continuation of a previous log message + * just print the line plainly. + */ + if (line[0] == Log::continuation_prefix[0]) { + stream << line.c_str() + 1; + } + else { + /* Normal line, emit the prefix. */ + stream << linePrefix << line; + } + + /* Only emit a newline if the original message has it. */ + if (!(ss.rdstate() & std::stringstream::eofbit)) + stream << std::endl; + } + + delete[] buf; +} + +void +Log::info(const char *fmt, ...) +{ + static const string infoprefix("Info"); + static const string& infocolor(isatty(fileno(stdout)) ? terminal_color_cyan : empty); + va_list ap; + va_start(ap, fmt); + if (do_debug_) + print_prefixed_message(std::cout, infocolor, infoprefix, fmt, ap); + else + print_prefixed_message(std::cout, empty, empty, fmt, ap); + va_end(ap); +} + +void +Log::debug(const char *fmt, ...) +{ + static const string dbgprefix("Debug"); + static const string& dbgcolor(isatty(fileno(stdout)) ? terminal_color_yellow : empty); + if (!do_debug_) + return; + va_list ap; + va_start(ap, fmt); + print_prefixed_message(std::cout, dbgcolor, dbgprefix, fmt, ap); + va_end(ap); +} + +void +Log::error(const char *fmt, ...) +{ + static const string errprefix("Error"); + static const string& errcolor(isatty(fileno(stderr)) ? terminal_color_red : empty); + va_list ap; + va_start(ap, fmt); + print_prefixed_message(std::cerr, errcolor, errprefix, fmt, ap); + va_end(ap); +} + +void +Log::flush() +{ + std::cout.flush(); + std::cerr.flush(); +} +#else +void +Log::info(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + __android_log_vprint(ANDROID_LOG_INFO, appname_.c_str(), fmt, ap); + va_end(ap); +} + +void +Log::debug(const char *fmt, ...) +{ + if (!do_debug_) + return; + va_list ap; + va_start(ap, fmt); + __android_log_vprint(ANDROID_LOG_DEBUG, appname_.c_str(), fmt, ap); + va_end(ap); +} + +void +Log::error(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + __android_log_vprint(ANDROID_LOG_ERROR, appname_.c_str(), fmt, ap); + va_end(ap); +} + +void +Log::flush() +{ +} + +#endif === added file 'src/libmatrix/log.h' --- src/libmatrix/log.h 1970-01-01 00:00:00 +0000 +++ src/libmatrix/log.h 2012-01-27 22:21:17 +0000 @@ -0,0 +1,46 @@ +// +// Copyright (c) 2010-2012 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Alexandros Frantzis +// Jesse Barker +// +#ifndef LOG_H_ +#define LOG_H_ + +#include + +class Log +{ +public: + static void init(const std::string& appname, bool do_debug = false) + { + appname_ = appname; + do_debug_ = do_debug; + } + // Emit an informational message + static void info(const char *fmt, ...); + // Emit a debugging message + static void debug(const char *fmt, ...); + // Emit an error message + static void error(const char *fmt, ...); + // Explicit flush of the log buffer + static void flush(); + // A prefix constant that informs the logging infrastructure that the log + // message is a continuation of a previous log message to be put on the + // same line. + static const std::string continuation_prefix; +private: + // A constant for identifying the log messages as originating from a + // particular application. + static std::string appname_; + // Indicates whether debug level messages should generate any output + static bool do_debug_; +}; + +#endif /* LOG_H_ */ === modified file 'src/libmatrix/mat.h' --- src/libmatrix/mat.h 2011-06-22 08:59:00 +0000 +++ src/libmatrix/mat.h 2012-01-26 19:36:28 +0000 @@ -46,6 +46,11 @@ // However, the internal data representation is column-major, so when using // the raw data access member to treat the data as a singly-dimensioned array, // it does not have to be transposed. +// +// A template class for creating, managing and operating on a 2x2 matrix +// of any type you like (intended for built-in types, but as long as it +// supports the basic arithmetic and assignment operators, any type should +// work). template class tmat2 { @@ -70,6 +75,7 @@ } ~tmat2() {} + // Reset this to the identity matrix. void setIdentity() { m_[0] = 1; @@ -78,6 +84,7 @@ m_[3] = 1; } + // Transpose this. Return a reference to this. tmat2& transpose() { T tmp_val = m_[1]; @@ -86,11 +93,16 @@ return *this; } + // Compute the determinant of this and return it. T determinant() { return (m_[0] * m_[3]) - (m_[2] * m_[1]); } + // Invert this. Return a reference to this. + // + // NOTE: If this is non-invertible, we will + // throw to avoid undefined behavior. tmat2& inverse() throw(std::runtime_error) { T d(determinant()); @@ -109,6 +121,8 @@ return *this; } + // Print the elements of the matrix to standard out. + // Really only useful for debug and test. void print() const { static const int precision(6); @@ -126,8 +140,12 @@ std::cout << " |" << std::endl; } + // Allow raw data access for API calls and the like. + // For example, it is valid to pass a tmat2 into a call to + // the OpenGL command "glUniformMatrix2fv()". operator const T*() const { return &m_[0];} + // Test if 'rhs' is equal to this. bool operator==(const tmat2& rhs) const { return m_[0] == rhs.m_[0] && @@ -136,11 +154,13 @@ m_[3] == rhs.m_[3]; } + // Test if 'rhs' is not equal to this. bool operator!=(const tmat2& rhs) const { return !(*this == rhs); } + // A direct assignment of 'rhs' to this. Return a reference to this. tmat2& operator=(const tmat2& rhs) { if (this != &rhs) @@ -153,6 +173,7 @@ return *this; } + // Add another matrix to this. Return a reference to this. tmat2& operator+=(const tmat2& rhs) { m_[0] += rhs.m_[0]; @@ -162,11 +183,13 @@ return *this; } + // Add another matrix to a copy of this. Return the copy. const tmat2 operator+(const tmat2& rhs) { return tmat2(*this) += rhs; } + // Subtract another matrix from this. Return a reference to this. tmat2& operator-=(const tmat2& rhs) { m_[0] -= rhs.m_[0]; @@ -176,11 +199,13 @@ return *this; } + // Subtract another matrix from a copy of this. Return the copy. const tmat2 operator-(const tmat2& rhs) { return tmat2(*this) += rhs; } + // Multiply this by another matrix. Return a reference to this. tmat2& operator*=(const tmat2& rhs) { T c0r0((m_[0] * rhs.m_[0]) + (m_[2] * rhs.m_[1])); @@ -194,11 +219,13 @@ return *this; } + // Multiply a copy of this by another matrix. Return the copy. const tmat2 operator*(const tmat2& rhs) { return tmat2(*this) *= rhs; } + // Multiply this by a scalar. Return a reference to this. tmat2& operator*=(const T& rhs) { m_[0] *= rhs; @@ -208,11 +235,13 @@ return *this; } + // Multiply a copy of this by a scalar. Return the copy. const tmat2 operator*(const T& rhs) { return tmat2(*this) *= rhs; } + // Divide this by a scalar. Return a reference to this. tmat2& operator/=(const T& rhs) { m_[0] /= rhs; @@ -222,11 +251,15 @@ return *this; } + // Divide a copy of this by a scalar. Return the copy. const tmat2 operator/(const T& rhs) { return tmat2(*this) /= rhs; } + // Use an instance of the ArrayProxy class to support double-indexed + // references to a matrix (i.e., m[1][1]). See comments above the + // ArrayProxy definition for more details. ArrayProxy operator[](int index) { return ArrayProxy(&m_[index]); @@ -240,12 +273,16 @@ T m_[4]; }; +// Multiply a scalar and a matrix just like the member operator, but allow +// the scalar to be the left-hand operand. template const tmat2 operator*(const T& lhs, const tmat2& rhs) { return tmat2(rhs) * lhs; } +// Multiply a copy of a vector and a matrix (matrix is right-hand operand). +// Return the copy. template const tvec2 operator*(const tvec2& lhs, const tmat2& rhs) { @@ -254,6 +291,8 @@ return tvec2(x,y); } +// Multiply a copy of a vector and a matrix (matrix is left-hand operand). +// Return the copy. template const tvec2 operator*(const tmat2& lhs, const tvec2& rhs) { @@ -262,6 +301,7 @@ return tvec2(x, y); } +// Compute the outer product of two vectors. Return the resultant matrix. template const tmat2 outer(const tvec2& a, const tvec2& b) { @@ -273,6 +313,10 @@ return product; } +// A template class for creating, managing and operating on a 3x3 matrix +// of any type you like (intended for built-in types, but as long as it +// supports the basic arithmetic and assignment operators, any type should +// work). template class tmat3 { @@ -294,8 +338,8 @@ m_[8] = m.m_[8]; } tmat3(const T& c0r0, const T& c0r1, const T& c0r2, - const T& c1r0, const T& c1r1, const T& c1r2, - const T& c2r0, const T& c2r1, const T& c2r2) + const T& c1r0, const T& c1r1, const T& c1r2, + const T& c2r0, const T& c2r1, const T& c2r2) { m_[0] = c0r0; m_[1] = c0r1; @@ -309,6 +353,7 @@ } ~tmat3() {} + // Reset this to the identity matrix. void setIdentity() { m_[0] = 1; @@ -322,6 +367,7 @@ m_[8] = 1; } + // Transpose this. Return a reference to this. tmat3& transpose() { T tmp_val = m_[1]; @@ -336,6 +382,7 @@ return *this; } + // Compute the determinant of this and return it. T determinant() { tmat2 minor0(m_[4], m_[5], m_[7], m_[8]); @@ -346,6 +393,10 @@ (m_[6] * minor6.determinant()); } + // Invert this. Return a reference to this. + // + // NOTE: If this is non-invertible, we will + // throw to avoid undefined behavior. tmat3& inverse() throw(std::runtime_error) { T d(determinant()); @@ -374,6 +425,8 @@ return *this; } + // Print the elements of the matrix to standard out. + // Really only useful for debug and test. void print() const { static const int precision(6); @@ -403,8 +456,12 @@ std::cout << " |" << std::endl; } + // Allow raw data access for API calls and the like. + // For example, it is valid to pass a tmat3 into a call to + // the OpenGL command "glUniformMatrix3fv()". operator const T*() const { return &m_[0];} + // Test if 'rhs' is equal to this. bool operator==(const tmat3& rhs) const { return m_[0] == rhs.m_[0] && @@ -418,11 +475,13 @@ m_[8] == rhs.m_[8]; } + // Test if 'rhs' is not equal to this. bool operator!=(const tmat3& rhs) const { return !(*this == rhs); } + // A direct assignment of 'rhs' to this. Return a reference to this. tmat3& operator=(const tmat3& rhs) { if (this != &rhs) @@ -440,6 +499,7 @@ return *this; } + // Add another matrix to this. Return a reference to this. tmat3& operator+=(const tmat3& rhs) { m_[0] += rhs.m_[0]; @@ -454,11 +514,13 @@ return *this; } + // Add another matrix to a copy of this. Return the copy. const tmat3 operator+(const tmat3& rhs) { return tmat3(*this) += rhs; } + // Subtract another matrix from this. Return a reference to this. tmat3& operator-=(const tmat3& rhs) { m_[0] -= rhs.m_[0]; @@ -473,11 +535,13 @@ return *this; } + // Subtract another matrix from a copy of this. Return the copy. const tmat3 operator-(const tmat3& rhs) { return tmat3(*this) -= rhs; } + // Multiply this by another matrix. Return a reference to this. tmat3& operator*=(const tmat3& rhs) { T c0r0((m_[0] * rhs.m_[0]) + (m_[3] * rhs.m_[1]) + (m_[6] * rhs.m_[2])); @@ -501,11 +565,13 @@ return *this; } + // Multiply a copy of this by another matrix. Return the copy. const tmat3 operator*(const tmat3& rhs) { return tmat3(*this) *= rhs; } + // Multiply this by a scalar. Return a reference to this. tmat3& operator*=(const T& rhs) { m_[0] *= rhs; @@ -520,11 +586,13 @@ return *this; } + // Multiply a copy of this by a scalar. Return the copy. const tmat3 operator*(const T& rhs) { return tmat3(*this) *= rhs; } + // Divide this by a scalar. Return a reference to this. tmat3& operator/=(const T& rhs) { m_[0] /= rhs; @@ -539,11 +607,15 @@ return *this; } + // Divide a copy of this by a scalar. Return the copy. const tmat3 operator/(const T& rhs) { return tmat3(*this) /= rhs; } + // Use an instance of the ArrayProxy class to support double-indexed + // references to a matrix (i.e., m[1][1]). See comments above the + // ArrayProxy definition for more details. ArrayProxy operator[](int index) { return ArrayProxy(&m_[index]); @@ -557,12 +629,16 @@ T m_[9]; }; +// Multiply a scalar and a matrix just like the member operator, but allow +// the scalar to be the left-hand operand. template const tmat3 operator*(const T& lhs, const tmat3& rhs) { return tmat3(rhs) * lhs; } +// Multiply a copy of a vector and a matrix (matrix is right-hand operand). +// Return the copy. template const tvec3 operator*(const tvec3& lhs, const tmat3& rhs) { @@ -572,6 +648,8 @@ return tvec3(x, y, z); } +// Multiply a copy of a vector and a matrix (matrix is left-hand operand). +// Return the copy. template const tvec3 operator*(const tmat3& lhs, const tvec3& rhs) { @@ -581,6 +659,7 @@ return tvec3(x, y, z); } +// Compute the outer product of two vectors. Return the resultant matrix. template const tmat3 outer(const tvec3& a, const tvec3& b) { @@ -597,6 +676,10 @@ return product; } +// A template class for creating, managing and operating on a 4x4 matrix +// of any type you like (intended for built-in types, but as long as it +// supports the basic arithmetic and assignment operators, any type should +// work). template class tmat4 { @@ -626,6 +709,7 @@ } ~tmat4() {} + // Reset this to the identity matrix. void setIdentity() { m_[0] = 1; @@ -646,6 +730,7 @@ m_[15] = 1; } + // Transpose this. Return a reference to this. tmat4& transpose() { T tmp_val = m_[1]; @@ -669,6 +754,7 @@ return *this; } + // Compute the determinant of this and return it. T determinant() { tmat3 minor0(m_[5], m_[6], m_[7], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]); @@ -681,6 +767,10 @@ (m_[12] * minor12.determinant()); } + // Invert this. Return a reference to this. + // + // NOTE: If this is non-invertible, we will + // throw to avoid undefined behavior. tmat4& inverse() throw(std::runtime_error) { T d(determinant()); @@ -726,6 +816,8 @@ return *this; } + // Print the elements of the matrix to standard out. + // Really only useful for debug and test. void print() const { static const int precision(6); @@ -771,8 +863,12 @@ std::cout << " |" << std::endl; } + // Allow raw data access for API calls and the like. + // For example, it is valid to pass a tmat4 into a call to + // the OpenGL command "glUniformMatrix4fv()". operator const T*() const { return &m_[0];} + // Test if 'rhs' is equal to this. bool operator==(const tmat4& rhs) const { return m_[0] == rhs.m_[0] && @@ -793,11 +889,13 @@ m_[15] == rhs.m_[15]; } + // Test if 'rhs' is not equal to this. bool operator!=(const tmat4& rhs) const { return !(*this == rhs); } + // A direct assignment of 'rhs' to this. Return a reference to this. tmat4& operator=(const tmat4& rhs) { if (this != &rhs) @@ -822,6 +920,7 @@ return *this; } + // Add another matrix to this. Return a reference to this. tmat4& operator+=(const tmat4& rhs) { m_[0] += rhs.m_[0]; @@ -843,11 +942,13 @@ return *this; } + // Add another matrix to a copy of this. Return the copy. const tmat4 operator+(const tmat4& rhs) { return tmat4(*this) += rhs; } + // Subtract another matrix from this. Return a reference to this. tmat4& operator-=(const tmat4& rhs) { m_[0] -= rhs.m_[0]; @@ -869,11 +970,13 @@ return *this; } + // Subtract another matrix from a copy of this. Return the copy. const tmat4 operator-(const tmat4& rhs) { return tmat4(*this) -= rhs; } + // Multiply this by another matrix. Return a reference to this. tmat4& operator*=(const tmat4& rhs) { T c0r0((m_[0] * rhs.m_[0]) + (m_[4] * rhs.m_[1]) + (m_[8] * rhs.m_[2]) + (m_[12] * rhs.m_[3])); @@ -911,11 +1014,13 @@ return *this; } + // Multiply a copy of this by another matrix. Return the copy. const tmat4 operator*(const tmat4& rhs) { return tmat4(*this) *= rhs; } + // Multiply this by a scalar. Return a reference to this. tmat4& operator*=(const T& rhs) { m_[0] *= rhs; @@ -937,11 +1042,13 @@ return *this; } + // Multiply a copy of this by a scalar. Return the copy. const tmat4 operator*(const T& rhs) { return tmat4(*this) *= rhs; } + // Divide this by a scalar. Return a reference to this. tmat4& operator/=(const T& rhs) { m_[0] /= rhs; @@ -963,11 +1070,15 @@ return *this; } + // Divide a copy of this by a scalar. Return the copy. const tmat4 operator/(const T& rhs) { return tmat4(*this) /= rhs; } + // Use an instance of the ArrayProxy class to support double-indexed + // references to a matrix (i.e., m[1][1]). See comments above the + // ArrayProxy definition for more details. ArrayProxy operator[](int index) { return ArrayProxy(&m_[index]); @@ -981,12 +1092,16 @@ T m_[16]; }; +// Multiply a scalar and a matrix just like the member operator, but allow +// the scalar to be the left-hand operand. template const tmat4 operator*(const T& lhs, const tmat4& rhs) { return tmat4(rhs) * lhs; } +// Multiply a copy of a vector and a matrix (matrix is right-hand operand). +// Return the copy. template const tvec4 operator*(const tvec4& lhs, const tmat4& rhs) { @@ -997,6 +1112,8 @@ return tvec4(x, y, z, w); } +// Multiply a copy of a vector and a matrix (matrix is left-hand operand). +// Return the copy. template const tvec4 operator*(const tmat4& lhs, const tvec4& rhs) { @@ -1007,6 +1124,7 @@ return tvec4(x, y, z, w); } +// Compute the outer product of two vectors. Return the resultant matrix. template const tmat4 outer(const tvec4& a, const tvec4& b) { === modified file 'src/libmatrix/program.cc' --- src/libmatrix/program.cc 2011-09-05 15:23:11 +0000 +++ src/libmatrix/program.cc 2012-01-26 19:36:28 +0000 @@ -1,5 +1,5 @@ // -// Copyright (c) 2011 Linaro Limited +// Copyright (c) 2011-2012 Linaro Limited // // All rights reserved. This program and the accompanying materials // are made available under the terms of the MIT License which accompanies @@ -8,16 +8,15 @@ // // Contributors: // Jesse Barker - original implementation. -// Alexandros Frantzis - local changes for better integration with glcompbench +// Alexandros Frantzis - local integration changes // #include #include #include #include #include -#include "gl-headers.h" +#include "gl-if.h" #include "program.h" -#include "log.h" using std::string; using LibMatrix::mat4; @@ -25,27 +24,6 @@ using LibMatrix::vec3; using LibMatrix::vec4; -bool -gotSource(const string& filename, string& source) -{ - using std::ifstream; - ifstream inputFile(filename.c_str()); - if (!inputFile) - { - std::cerr << "Failed to open \"" << filename << "\"" << std::endl; - return false; - } - - string curLine; - while (getline(inputFile, curLine)) - { - source += curLine; - source += '\n'; - } - - return true; -} - Shader::Shader(unsigned int type, const string& source) : handle_(0), type_(type), === modified file 'src/libmatrix/program.h' --- src/libmatrix/program.h 2011-09-05 15:23:11 +0000 +++ src/libmatrix/program.h 2012-01-26 19:36:28 +0000 @@ -1,5 +1,5 @@ // -// Copyright (c) 2011 Linaro Limited +// Copyright (c) 2011-2012 Linaro Limited // // All rights reserved. This program and the accompanying materials // are made available under the terms of the MIT License which accompanies @@ -8,6 +8,7 @@ // // Contributors: // Jesse Barker - original implementation. +// Alexandros Frantzis - local integration changes // #ifndef PROGRAM_H_ #define PROGRAM_H_ @@ -161,7 +162,4 @@ bool valid_; }; -// Handy utility for extracting shader source from a named file -bool gotSource(const std::string& filename, std::string& sourceOut); - #endif // PROGRAM_H_ === added file 'src/libmatrix/shader-source.cc' --- src/libmatrix/shader-source.cc 1970-01-01 00:00:00 +0000 +++ src/libmatrix/shader-source.cc 2012-01-26 19:36:28 +0000 @@ -0,0 +1,615 @@ +// +// Copyright (c) 2010-2012 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Alexandros Frantzis +// Jesse Barker +// +#include +#include + +#include "shader-source.h" +#include "log.h" +#include "vec.h" +#include "util.h" + +/** + * Holds default precision values for all shader types + * (even the unknown type, which is hardwired to default precision values) + */ +std::vector +ShaderSource::default_precision_(ShaderSource::ShaderTypeUnknown + 1); + +/** + * Loads the contents of a file into a string. + * + * @param filename the name of the file + * @param str the string to put the contents of the file into + */ +bool +ShaderSource::load_file(const std::string& filename, std::string& str) +{ + std::auto_ptr is_ptr(Util::get_resource(filename)); + std::istream& inputFile(*is_ptr); + + if (!inputFile) + { + Log::error("Failed to open \"%s\"\n", filename.c_str()); + return false; + } + + std::string curLine; + while (getline(inputFile, curLine)) + { + str += curLine; + str += '\n'; + } + + return true; +} + + +/** + * Appends a string to the shader source. + * + * @param str the string to append + */ +void +ShaderSource::append(const std::string &str) +{ + source_ << str; +} + +/** + * Appends the contents of a file to the shader source. + * + * @param filename the name of the file to append + */ +void +ShaderSource::append_file(const std::string &filename) +{ + std::string source; + if (load_file(filename, source)) + source_ << source; +} + +/** + * Replaces a string in the source with another string. + * + * @param remove the string to replace + * @param insert the string to replace with + */ +void +ShaderSource::replace(const std::string &remove, const std::string &insert) +{ + std::string::size_type pos = 0; + std::string str(source_.str()); + + while ((pos = str.find(remove, pos)) != std::string::npos) { + str.replace(pos, remove.size(), insert); + pos++; + } + + source_.clear(); + source_.str(str); +} + +/** + * Replaces a string in the source with the contents of a file. + * + * @param remove the string to replace + * @param filename the name of the file to read from + */ +void +ShaderSource::replace_with_file(const std::string &remove, const std::string &filename) +{ + std::string source; + if (load_file(filename, source)) + replace(remove, source); +} + +/** + * Adds a string (usually containing a constant definition) at + * global (per shader) scope. + * + * The string is placed after any default precision qualifiers. + * + * @param str the string to add + */ +void +ShaderSource::add_global(const std::string &str) +{ + std::string::size_type pos = 0; + std::string source(source_.str()); + + /* Find the last precision qualifier */ + pos = source.rfind("precision"); + + if (pos != std::string::npos) { + /* + * Find the next #endif line of a preprocessor block that contains + * the precision qualifier. + */ + std::string::size_type pos_if = source.find("#if", pos); + std::string::size_type pos_endif = source.find("#endif", pos); + + if (pos_endif != std::string::npos && pos_endif < pos_if) + pos = pos_endif; + + /* Go to the next line */ + pos = source.find("\n", pos); + if (pos != std::string::npos) + pos++; + } + else + pos = 0; + + source.insert(pos, str); + + source_.clear(); + source_.str(source); +} + +/** + * Adds a string (usually containing a constant definition) at + * global (per shader) scope. + * + * The string is placed after any default precision qualifiers. + * + * @param function the function to add the string into + * @param str the string to add + */ +void +ShaderSource::add_local(const std::string &str, const std::string &function) +{ + std::string::size_type pos = 0; + std::string source(source_.str()); + + /* Find the function */ + pos = source.find(function); + pos = source.find('{', pos); + + /* Go to the next line */ + pos = source.find("\n", pos); + if (pos != std::string::npos) + pos++; + + source.insert(pos, str); + + source_.clear(); + source_.str(source); +} + +/** + * Adds a string (usually containing a constant definition) to a shader source + * + * If the function parameter is empty, the string will be added to global + * scope, after any precision definitions. + * + * @param str the string to add + * @param function if not empty, the function to add the string into + */ +void +ShaderSource::add(const std::string &str, const std::string &function) +{ + if (!function.empty()) + add_local(str, function); + else + add_global(str); +} + +/** + * Adds a float constant definition. + * + * @param name the name of the constant + * @param f the value of the constant + * @param function if not empty, the function to put the definition in + */ +void +ShaderSource::add_const(const std::string &name, float f, + const std::string &function) +{ + std::stringstream ss; + + ss << "const float " << name << " = " << std::fixed << f << ";" << std::endl; + + add(ss.str(), function); +} + +/** + * Adds a float array constant definition. + * + * Note that various GLSL versions (including ES) don't support + * array constants. + * + * @param name the name of the constant + * @param v the value of the constant + * @param function if not empty, the function to put the definition in + */ +void +ShaderSource::add_const(const std::string &name, std::vector &array, + const std::string &function) +{ + std::stringstream ss; + + ss << "const float " << name << "[" << array.size() << "] = {" << std::fixed; + for(std::vector::const_iterator iter = array.begin(); + iter != array.end(); + iter++) + { + ss << *iter; + if (iter + 1 != array.end()) + ss << ", " << std::endl; + } + + ss << "};" << std::endl; + + add(ss.str(), function); +} + +/** + * Adds a vec2 constant definition. + * + * @param name the name of the constant + * @param v the value of the constant + * @param function if not empty, the function to put the definition in + */ +void +ShaderSource::add_const(const std::string &name, const LibMatrix::vec2 &v, + const std::string &function) +{ + std::stringstream ss; + + ss << "const vec2 " << name << " = vec2(" << std::fixed; + ss << v.x() << ", " << v.y() << ");" << std::endl; + + add(ss.str(), function); +} + +/** + * Adds a vec3 constant definition. + * + * @param name the name of the constant + * @param v the value of the constant + * @param function if not empty, the function to put the definition in + */ +void +ShaderSource::add_const(const std::string &name, const LibMatrix::vec3 &v, + const std::string &function) +{ + std::stringstream ss; + + ss << "const vec3 " << name << " = vec3(" << std::fixed; + ss << v.x() << ", " << v.y() << ", " << v.z() << ");" << std::endl; + + add(ss.str(), function); +} + +/** + * Adds a vec4 constant definition. + * + * @param name the name of the constant + * @param v the value of the constant + * @param function if not empty, the function to put the definition in + */ +void +ShaderSource::add_const(const std::string &name, const LibMatrix::vec4 &v, + const std::string &function) +{ + std::stringstream ss; + + ss << "const vec4 " << name << " = vec4(" << std::fixed; + ss << v.x() << ", " << v.y() << ", " << v.z() << ", " << v.w() << ");" << std::endl; + + add(ss.str(), function); +} + +/** + * Adds a mat3 constant definition. + * + * @param name the name of the constant + * @param v the value of the constant + * @param function if not empty, the function to put the definition in + */ +void +ShaderSource::add_const(const std::string &name, const LibMatrix::mat3 &m, + const std::string &function) +{ + std::stringstream ss; + + ss << "const mat3 " << name << " = mat3(" << std::fixed; + ss << m[0][0] << ", " << m[1][0] << ", " << m[2][0] << "," << std::endl; + ss << m[0][1] << ", " << m[1][1] << ", " << m[2][1] << "," << std::endl; + ss << m[0][2] << ", " << m[1][2] << ", " << m[2][2] << std::endl; + ss << ");" << std::endl; + + add(ss.str(), function); +} + +/** + * Adds a float array declaration and initialization. + * + * @param name the name of the array + * @param array the array values + * @param init_function the function to put the initialization in + * @param decl_function if not empty, the function to put the declaration in + */ +void +ShaderSource::add_array(const std::string &name, std::vector &array, + const std::string &init_function, + const std::string &decl_function) +{ + if (init_function.empty() || name.empty()) + return; + + std::stringstream ss; + ss << "float " << name << "[" << array.size() << "];" << std::endl; + + std::string decl(ss.str()); + + ss.clear(); + ss.str(""); + ss << std::fixed; + + for(std::vector::const_iterator iter = array.begin(); + iter != array.end(); + iter++) + { + ss << name << "[" << iter - array.begin() << "] = " << *iter << ";" << std::endl; + } + + add(ss.str(), init_function); + + add(decl, decl_function); +} + +/** + * Gets the ShaderType for this ShaderSource. + * + * If the ShaderType is unknown, an attempt is made to infer + * the type from the shader source contents. + * + * @return the ShaderType + */ +ShaderSource::ShaderType +ShaderSource::type() +{ + /* Try to infer the type from the source contents */ + if (type_ == ShaderSource::ShaderTypeUnknown) { + std::string source(source_.str()); + + if (source.find("gl_FragColor") != std::string::npos) + type_ = ShaderSource::ShaderTypeFragment; + else if (source.find("gl_Position") != std::string::npos) + type_ = ShaderSource::ShaderTypeVertex; + else + Log::debug("Cannot infer shader type from contents. Leaving it Unknown.\n"); + } + + return type_; +} + +/** + * Helper function that emits a precision statement. + * + * @param ss the stringstream to add the statement to + * @param val the precision value + * @param type_str the variable type to apply the precision value to + */ +void +ShaderSource::emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val, + const std::string& type_str) +{ + static const char *precision_map[] = { + "lowp", "mediump", "highp", NULL + }; + + if (val == ShaderSource::PrecisionValueHigh) { + if (type_ == ShaderSource::ShaderTypeFragment) + ss << "#ifdef GL_FRAGMENT_PRECISION_HIGH" << std::endl; + + ss << "precision highp " << type_str << ";" << std::endl; + + if (type_ == ShaderSource::ShaderTypeFragment) { + ss << "#else" << std::endl; + ss << "precision mediump " << type_str << ";" << std::endl; + ss << "#endif" << std::endl; + } + } + else if (val >= 0 && val < ShaderSource::PrecisionValueDefault) { + ss << "precision " << precision_map[val] << " "; + ss << type_str << ";" << std::endl; + } + + /* There is no default precision in the fragment shader, so set it to mediump */ + if (val == ShaderSource::PrecisionValueDefault + && type_str == "float" && type_ == ShaderSource::ShaderTypeFragment) + { + ss << "precision mediump float;" << std::endl; + } +} + +/** + * Gets a string containing the complete shader source. + * + * Precision statements are applied at this point. + * + * @return the shader source + */ +std::string +ShaderSource::str() +{ + /* Decide which precision values to use */ + ShaderSource::Precision precision; + + /* Ensure we have tried to infer the type from the contents */ + type(); + + if (precision_has_been_set_) + precision = precision_; + else + precision = default_precision(type_); + + /* Create the precision statements */ + std::stringstream ss; + + emit_precision(ss, precision.int_precision, "int"); + emit_precision(ss, precision.float_precision, "float"); + emit_precision(ss, precision.sampler2d_precision, "sampler2D"); + emit_precision(ss, precision.samplercube_precision, "samplerCube"); + + std::string precision_str(ss.str()); + if (!precision_str.empty()) { + precision_str.insert(0, "#ifdef GL_ES\n"); + precision_str.insert(precision_str.size(), "#endif\n"); + } + + return precision_str + source_.str(); +} + +/** + * Sets the precision that will be used for this shader. + * + * This overrides any default values set with ShaderSource::default_*_precision(). + * + * @param precision the precision to set + */ +void +ShaderSource::precision(const ShaderSource::Precision& precision) +{ + precision_ = precision; + precision_has_been_set_ = true; +} + +/** + * Gets the precision that will be used for this shader. + * + * @return the precision + */ +const ShaderSource::Precision& +ShaderSource::precision() +{ + return precision_; +} + +/** + * Sets the default precision that will be used for a shaders type. + * + * If type is ShaderTypeUnknown the supplied precision is used for all + * shader types. + * + * This can be overriden per ShaderSource object by using ::precision(). + * + * @param precision the default precision to set + * @param type the ShaderType to use the precision for + */ +void +ShaderSource::default_precision(const ShaderSource::Precision& precision, + ShaderSource::ShaderType type) +{ + if (type < 0 || type > ShaderSource::ShaderTypeUnknown) + type = ShaderSource::ShaderTypeUnknown; + + if (type == ShaderSource::ShaderTypeUnknown) { + for (size_t i = 0; i < ShaderSource::ShaderTypeUnknown; i++) + default_precision_[i] = precision; + } + else { + default_precision_[type] = precision; + } +} + +/** + * Gets the default precision that will be used for a shader type. + * + * It is valid to use a type of ShaderTypeUnknown. This will always + * return a Precision with default values. + * + * @param type the ShaderType to get the precision of + * + * @return the precision + */ +const ShaderSource::Precision& +ShaderSource::default_precision(ShaderSource::ShaderType type) +{ + if (type < 0 || type > ShaderSource::ShaderTypeUnknown) + type = ShaderSource::ShaderTypeUnknown; + + return default_precision_[type]; +} + +/**************************************** + * ShaderSource::Precision constructors * + ****************************************/ + +/** + * Creates a ShaderSource::Precision with default precision values. + */ +ShaderSource::Precision::Precision() : + int_precision(ShaderSource::PrecisionValueDefault), + float_precision(ShaderSource::PrecisionValueDefault), + sampler2d_precision(ShaderSource::PrecisionValueDefault), + samplercube_precision(ShaderSource::PrecisionValueDefault) +{ +} + +/** + * Creates a ShaderSource::Precision using the supplied precision values. + */ +ShaderSource::Precision::Precision(ShaderSource::PrecisionValue int_p, + ShaderSource::PrecisionValue float_p, + ShaderSource::PrecisionValue sampler2d_p, + ShaderSource::PrecisionValue samplercube_p) : + int_precision(int_p), float_precision(float_p), + sampler2d_precision(sampler2d_p), samplercube_precision(samplercube_p) +{ +} + +/** + * Creates a ShaderSource::Precision from a string representation of + * precision values. + * + * The string format is: + * ",,," + * + * Each precision value is one of "high", "medium", "low" or "default". + * + * @param precision_values the string representation of the precision values + */ +ShaderSource::Precision::Precision(const std::string& precision_values) : + int_precision(ShaderSource::PrecisionValueDefault), + float_precision(ShaderSource::PrecisionValueDefault), + sampler2d_precision(ShaderSource::PrecisionValueDefault), + samplercube_precision(ShaderSource::PrecisionValueDefault) +{ + std::vector elems; + + Util::split(precision_values, ',', elems); + + for (size_t i = 0; i < elems.size() && i < 4; i++) { + const std::string& pstr(elems[i]); + ShaderSource::PrecisionValue pval; + + if (pstr == "high") + pval = ShaderSource::PrecisionValueHigh; + else if (pstr == "medium") + pval = ShaderSource::PrecisionValueMedium; + else if (pstr == "low") + pval = ShaderSource::PrecisionValueLow; + else + pval = ShaderSource::PrecisionValueDefault; + + switch(i) { + case 0: int_precision = pval; break; + case 1: float_precision = pval; break; + case 2: sampler2d_precision = pval; break; + case 3: samplercube_precision = pval; break; + default: break; + } + } +} === added file 'src/libmatrix/shader-source.h' --- src/libmatrix/shader-source.h 1970-01-01 00:00:00 +0000 +++ src/libmatrix/shader-source.h 2012-01-26 19:36:28 +0000 @@ -0,0 +1,103 @@ +// +// Copyright (c) 2010-2012 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Alexandros Frantzis +// Jesse Barker +// +#include +#include +#include +#include "vec.h" +#include "mat.h" + +/** + * Helper class for loading and manipulating shader sources. + */ +class ShaderSource +{ +public: + enum ShaderType { + ShaderTypeVertex, + ShaderTypeFragment, + ShaderTypeUnknown + }; + + ShaderSource(ShaderType type = ShaderTypeUnknown) : + precision_has_been_set_(false), type_(type) {} + ShaderSource(const std::string &filename, ShaderType type = ShaderTypeUnknown) : + precision_has_been_set_(false), type_(type) { append_file(filename); } + + void append(const std::string &str); + void append_file(const std::string &filename); + + void replace(const std::string &remove, const std::string &insert); + void replace_with_file(const std::string &remove, const std::string &filename); + + void add(const std::string &str, const std::string &function = ""); + + void add_const(const std::string &name, float f, + const std::string &function = ""); + void add_const(const std::string &name, std::vector &f, + const std::string &function = ""); + void add_const(const std::string &name, const LibMatrix::vec2 &v, + const std::string &function = ""); + void add_const(const std::string &name, const LibMatrix::vec3 &v, + const std::string &function = ""); + void add_const(const std::string &name, const LibMatrix::vec4 &v, + const std::string &function = ""); + void add_const(const std::string &name, const LibMatrix::mat3 &m, + const std::string &function = ""); + + void add_array(const std::string &name, std::vector &array, + const std::string &init_function, + const std::string &decl_function = ""); + + ShaderType type(); + std::string str(); + + enum PrecisionValue { + PrecisionValueLow, + PrecisionValueMedium, + PrecisionValueHigh, + PrecisionValueDefault + }; + + struct Precision { + Precision(); + Precision(PrecisionValue int_p, PrecisionValue float_p, + PrecisionValue sampler2d_p, PrecisionValue samplercube_p); + Precision(const std::string& list); + + PrecisionValue int_precision; + PrecisionValue float_precision; + PrecisionValue sampler2d_precision; + PrecisionValue samplercube_precision; + }; + + void precision(const Precision& precision); + const Precision& precision(); + + static void default_precision(const Precision& precision, + ShaderType type = ShaderTypeUnknown); + static const Precision& default_precision(ShaderType type); + +private: + void add_global(const std::string &str); + void add_local(const std::string &str, const std::string &function); + bool load_file(const std::string& filename, std::string& str); + void emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val, + const std::string& type_str); + + std::stringstream source_; + Precision precision_; + bool precision_has_been_set_; + ShaderType type_; + + static std::vector default_precision_; +}; === added file 'src/libmatrix/test/basic-global-const.vert' --- src/libmatrix/test/basic-global-const.vert 1970-01-01 00:00:00 +0000 +++ src/libmatrix/test/basic-global-const.vert 2012-01-26 19:36:28 +0000 @@ -0,0 +1,15 @@ +const vec4 ConstantColor = vec4(1.000000, 1.000000, 1.000000, 1.000000); +attribute vec3 position; + +uniform mat4 modelview; +uniform mat4 projection; + +varying vec4 color; + +void +main(void) +{ + vec4 curVertex = vec4(position, 1.0); + gl_Position = projection * modelview * curVertex; + color = ConstantColor; +} === added file 'src/libmatrix/test/basic.frag' --- src/libmatrix/test/basic.frag 1970-01-01 00:00:00 +0000 +++ src/libmatrix/test/basic.frag 2012-01-26 19:36:28 +0000 @@ -0,0 +1,7 @@ +varying vec4 color; + +void +main(void) +{ + gl_FragColor = color; +} === added file 'src/libmatrix/test/basic.vert' --- src/libmatrix/test/basic.vert 1970-01-01 00:00:00 +0000 +++ src/libmatrix/test/basic.vert 2012-01-26 19:36:28 +0000 @@ -0,0 +1,14 @@ +attribute vec3 position; + +uniform mat4 modelview; +uniform mat4 projection; + +varying vec4 color; + +void +main(void) +{ + vec4 curVertex = vec4(position, 1.0); + gl_Position = projection * modelview * curVertex; + color = ConstantColor; +} === added file 'src/libmatrix/test/const_vec_test.cc' --- src/libmatrix/test/const_vec_test.cc 1970-01-01 00:00:00 +0000 +++ src/libmatrix/test/const_vec_test.cc 2012-01-26 19:36:28 +0000 @@ -0,0 +1,60 @@ +// +// Copyright (c) 2011 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#include +#include "libmatrix_test.h" +#include "const_vec_test.h" +#include "../vec.h" + +using LibMatrix::vec2; +using LibMatrix::vec3; +using LibMatrix::vec4; +using std::cout; +using std::endl; + +void +Vec2TestConstOperator::run(const Options& options) +{ + const vec2 a(1.0, 1.0); + const vec2 b(2.0, 2.0); + vec2 aplusb(a + b); + vec2 aminusb(a - b); + vec2 atimesb(a * b); + vec2 adivb(a / b); + const float s(2.5); + vec2 stimesb(s * b); +} + +void +Vec3TestConstOperator::run(const Options& options) +{ + const vec3 a(1.0, 1.0, 1.0); + const vec3 b(2.0, 2.0, 2.0); + vec3 aplusb(a + b); + vec3 aminusb(a - b); + vec3 atimesb(a * b); + vec3 adivb(a / b); + const float s(2.5); + vec3 stimesb(s * b); +} + +void +Vec4TestConstOperator::run(const Options& options) +{ + const vec4 a(1.0, 1.0, 1.0, 1.0); + const vec4 b(2.0, 2.0, 2.0, 2.0); + vec4 aplusb(a + b); + vec4 aminusb(a - b); + vec4 atimesb(a * b); + vec4 adivb(a / b); + const float s(2.5); + vec4 stimesb(s * b); +} === added file 'src/libmatrix/test/const_vec_test.h' --- src/libmatrix/test/const_vec_test.h 1970-01-01 00:00:00 +0000 +++ src/libmatrix/test/const_vec_test.h 2012-01-26 19:36:28 +0000 @@ -0,0 +1,39 @@ +// +// Copyright (c) 2011 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#ifndef CONST_VEC_TEST_H_ +#define CONST_VEC_TEST_H_ + +class MatrixTest; +class Options; + +class Vec2TestConstOperator : public MatrixTest +{ +public: + Vec2TestConstOperator() : MatrixTest("vec2::const") {} + virtual void run(const Options& options); +}; + +class Vec3TestConstOperator : public MatrixTest +{ +public: + Vec3TestConstOperator() : MatrixTest("vec3::const") {} + virtual void run(const Options& options); +}; + +class Vec4TestConstOperator : public MatrixTest +{ +public: + Vec4TestConstOperator() : MatrixTest("vec4::const") {} + virtual void run(const Options& options); +}; + +#endif // CONST_VEC_TEST_H_ === modified file 'src/libmatrix/test/inverse_test.cc' --- src/libmatrix/test/inverse_test.cc 2011-06-22 08:59:00 +0000 +++ src/libmatrix/test/inverse_test.cc 2012-01-26 19:36:28 +0000 @@ -1,3 +1,14 @@ +// +// Copyright (c) 2010 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// #include #include "libmatrix_test.h" #include "inverse_test.h" === modified file 'src/libmatrix/test/inverse_test.h' --- src/libmatrix/test/inverse_test.h 2011-06-22 08:59:00 +0000 +++ src/libmatrix/test/inverse_test.h 2012-01-26 19:36:28 +0000 @@ -1,3 +1,14 @@ +// +// Copyright (c) 2010 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// #ifndef INVERSE_TEST_H_ #define INVERSE_TEST_H_ === modified file 'src/libmatrix/test/libmatrix_test.cc' --- src/libmatrix/test/libmatrix_test.cc 2011-06-22 08:59:00 +0000 +++ src/libmatrix/test/libmatrix_test.cc 2012-01-26 19:36:28 +0000 @@ -14,6 +14,9 @@ #include #include "libmatrix_test.h" #include "inverse_test.h" +#include "transpose_test.h" +#include "const_vec_test.h" +#include "shader_source_test.h" using std::cerr; using std::cout; @@ -35,12 +38,20 @@ testVec.push_back(new MatrixTest2x2Inverse()); testVec.push_back(new MatrixTest3x3Inverse()); testVec.push_back(new MatrixTest4x4Inverse()); + testVec.push_back(new MatrixTest2x2Transpose()); + testVec.push_back(new MatrixTest3x3Transpose()); + testVec.push_back(new MatrixTest4x4Transpose()); + testVec.push_back(new ShaderSourceBasic()); for (vector::iterator testIt = testVec.begin(); testIt != testVec.end(); testIt++) { MatrixTest* curTest = *testIt; + if (testOptions.beVerbose()) + { + cout << "Running test " << curTest->name() << endl; + } curTest->run(testOptions); if (!curTest->passed()) { === modified file 'src/libmatrix/test/libmatrix_test.h' --- src/libmatrix/test/libmatrix_test.h 2011-06-22 08:59:00 +0000 +++ src/libmatrix/test/libmatrix_test.h 2012-01-26 19:36:28 +0000 @@ -1,3 +1,14 @@ +// +// Copyright (c) 2010 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// #ifndef LIBMATRIX_TEST_H_ #define LIBMATRIX_TEST_H_ === modified file 'src/libmatrix/test/options.cc' --- src/libmatrix/test/options.cc 2011-06-22 08:59:00 +0000 +++ src/libmatrix/test/options.cc 2012-01-26 19:36:28 +0000 @@ -1,3 +1,14 @@ +// +// Copyright (c) 2010 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// #include #include #include @@ -21,6 +32,15 @@ int c = getopt_long(argc, argv, "", long_options, &option_index); while (c != -1) { + // getopt_long() returns '?' and prints an "unrecognized option" error + // to stderr if it does not recognize an option. Just trigger + // the help/usage message, stop processing and get out. + if (c == '?') + { + show_help_ = true; + break; + } + std::string optname(long_options[option_index].name); if (optname == verbose_name_) === added file 'src/libmatrix/test/shader_source_test.cc' --- src/libmatrix/test/shader_source_test.cc 1970-01-01 00:00:00 +0000 +++ src/libmatrix/test/shader_source_test.cc 2012-01-26 19:36:28 +0000 @@ -0,0 +1,49 @@ +// +// Copyright (c) 2012 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#include +#include "libmatrix_test.h" +#include "shader_source_test.h" +#include "../shader-source.h" +#include "../vec.h" + +using std::string; +using LibMatrix::vec4; + +void +ShaderSourceBasic::run(const Options& options) +{ + static const string vtx_shader_filename("test/basic.vert"); + + ShaderSource vtx_source(vtx_shader_filename); + ShaderSource vtx_source2(vtx_shader_filename); + + pass_ = (vtx_source.str() == vtx_source2.str()); +} + +void +ShaderSourceAddConstGlobal::run(const Options& options) +{ + // Load the original shader source. + static const string src_shader_filename("test/basic.vert"); + ShaderSource src_shader(src_shader_filename); + + // Add constant at global scope + static const vec4 constantColor(1.0, 1.0, 1.0, 1.0); + src_shader.add_const("ConstantColor", constantColor); + + // Load the pre-modified shader + static const string result_shader_filename("test/basic-global-const.vert"); + ShaderSource result_shader(result_shader_filename); + + // Compare the output strings to confirm the results. + pass_ = (src_shader.str() == result_shader.str()); +} === added file 'src/libmatrix/test/shader_source_test.h' --- src/libmatrix/test/shader_source_test.h 1970-01-01 00:00:00 +0000 +++ src/libmatrix/test/shader_source_test.h 2012-01-26 19:36:28 +0000 @@ -0,0 +1,32 @@ +// +// Copyright (c) 2012 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#ifndef SHADER_SOURCE_TEST_H_ +#define SHADER_SOURCE_TEST_H_ + +class MatrixTest; +class Options; + +class ShaderSourceBasic : public MatrixTest +{ +public: + ShaderSourceBasic() : MatrixTest("ShaderSource::basic") {} + virtual void run(const Options& options); +}; + +class ShaderSourceAddConstGlobal : public MatrixTest +{ +public: + ShaderSourceAddConstGlobal() : MatrixTest("ShaderSource::AddConstGlobal") {} + virtual void run(const Options& options); +}; + +#endif // SHADER_SOURCE_TEST_H === added file 'src/libmatrix/test/transpose_test.cc' --- src/libmatrix/test/transpose_test.cc 1970-01-01 00:00:00 +0000 +++ src/libmatrix/test/transpose_test.cc 2012-01-26 19:36:28 +0000 @@ -0,0 +1,297 @@ +// +// Copyright (c) 2010 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#include +#include "libmatrix_test.h" +#include "transpose_test.h" +#include "../mat.h" + +using LibMatrix::mat2; +using LibMatrix::mat3; +using LibMatrix::mat4; +using std::cout; +using std::endl; + +void +MatrixTest2x2Transpose::run(const Options& options) +{ + // First, a simple test to ensure that the transpose of the identity is + // the identity. + if (options.beVerbose()) + { + cout << endl << "Assertion 1: Transpose of the identity is the identity." << endl << endl; + } + + mat2 m; + + if (options.beVerbose()) + { + cout << "Starting with mat2 (should be identity): " << endl << endl; + m.print(); + } + + m.transpose(); + + if (options.beVerbose()) + { + cout << endl << "Transpose of identity (should be identity): " << endl << endl; + m.print(); + } + + mat2 mi; + if (m != mi) + { + // FAIL! Transpose of the identity is the identity. + return; + } + + // At this point, we have 2 identity matrices. + // Next, set an element in the matrix and transpose twice. We should see + // the original matrix (with i,j set). + if (options.beVerbose()) + { + cout << endl << "Assertion 2: Transposing a matrix twice yields the original matrix." << endl << endl; + } + + m[0][1] = 6.3; + + if (options.beVerbose()) + { + cout << "Matrix should now have (0, 1) == 6.300000" << endl << endl; + m.print(); + } + + mi = m; + + m.transpose().transpose(); + + if (options.beVerbose()) + { + cout << endl << "Matrix should now have (0, 1) == 6.300000" << endl << endl; + m.print(); + } + + if (m != mi) + { + // FAIL! Transposing the same matrix twice should yield the original. + return; + } + + // Next, reset mi back to the identity. Set element element j,i in this + // matrix and transpose m. They should now be equal. + if (options.beVerbose()) + { + cout << endl << "Assertion 3: Transpose of matrix (i,j) == x is equal to matrix (j,i) == x." << endl << endl; + } + + mi.setIdentity(); + mi[1][0] = 6.3; + + m.transpose(); + + if (options.beVerbose()) + { + cout << "Matrix should now have (1, 0) == 6.300000" << endl << endl; + m.print(); + cout << endl; + } + + if (m == mi) + { + pass_ = true; + } + + // FAIL! Transposing the same matrix twice should yield the original. +} + +void +MatrixTest3x3Transpose::run(const Options& options) +{ + // First, a simple test to ensure that the transpose of the identity is + // the identity. + if (options.beVerbose()) + { + cout << endl << "Assertion 1: Transpose of the identity is the identity." << endl << endl; + } + + mat3 m; + + if (options.beVerbose()) + { + cout << "Starting with mat2 (should be identity): " << endl << endl; + m.print(); + } + + m.transpose(); + + if (options.beVerbose()) + { + cout << endl << "Transpose of identity (should be identity): " << endl << endl; + m.print(); + } + + mat3 mi; + if (m != mi) + { + // FAIL! Transpose of the identity is the identity. + return; + } + + // At this point, we have 2 identity matrices. + // Next, set an element in the matrix and transpose twice. We should see + // the original matrix (with i,j set). + if (options.beVerbose()) + { + cout << endl << "Assertion 2: Transposing a matrix twice yields the original matrix." << endl << endl; + } + + m[0][1] = 6.3; + + if (options.beVerbose()) + { + cout << "Matrix should now have (0, 1) == 6.300000" << endl << endl; + m.print(); + } + + mi = m; + + m.transpose().transpose(); + + if (options.beVerbose()) + { + cout << endl << "Matrix should now have (0, 1) == 6.300000" << endl << endl; + m.print(); + } + + if (m != mi) + { + // FAIL! Transposing the same matrix twice should yield the original. + return; + } + + // Next, reset mi back to the identity. Set element element j,i in this + // matrix and transpose m. They should now be equal. + if (options.beVerbose()) + { + cout << endl << "Assertion 3: Transpose of matrix (i,j) == x is equal to matrix (j,i) == x." << endl << endl; + } + + mi.setIdentity(); + mi[1][0] = 6.3; + + m.transpose(); + + if (options.beVerbose()) + { + cout << "Matrix should now have (1, 0) == 6.300000" << endl << endl; + m.print(); + cout << endl; + } + + if (m == mi) + { + pass_ = true; + } + + // FAIL! Transposing the same matrix twice should yield the original. +} + +void +MatrixTest4x4Transpose::run(const Options& options) +{ + // First, a simple test to ensure that the transpose of the identity is + // the identity. + if (options.beVerbose()) + { + cout << endl << "Assertion 1: Transpose of the identity is the identity." << endl << endl; + } + + mat4 m; + + if (options.beVerbose()) + { + cout << "Starting with mat2 (should be identity): " << endl << endl; + m.print(); + } + + m.transpose(); + + if (options.beVerbose()) + { + cout << endl << "Transpose of identity (should be identity): " << endl << endl; + m.print(); + } + + mat4 mi; + if (m != mi) + { + // FAIL! Transpose of the identity is the identity. + return; + } + + // At this point, we have 2 identity matrices. + // Next, set an element in the matrix and transpose twice. We should see + // the original matrix (with i,j set). + if (options.beVerbose()) + { + cout << endl << "Assertion 2: Transposing a matrix twice yields the original matrix." << endl << endl; + } + + m[0][1] = 6.3; + + if (options.beVerbose()) + { + cout << "Matrix should now have (0, 1) == 6.300000" << endl << endl; + m.print(); + } + + mi = m; + + m.transpose().transpose(); + + if (options.beVerbose()) + { + cout << endl << "Matrix should now have (0, 1) == 6.300000" << endl << endl; + m.print(); + } + + if (m != mi) + { + // FAIL! Transposing the same matrix twice should yield the original. + return; + } + + // Next, reset mi back to the identity. Set element element j,i in this + // matrix and transpose m. They should now be equal. + if (options.beVerbose()) + { + cout << endl << "Assertion 3: Transpose of matrix (i,j) == x is equal to matrix (j,i) == x." << endl << endl; + } + + mi.setIdentity(); + mi[1][0] = 6.3; + + m.transpose(); + + if (options.beVerbose()) + { + cout << "Matrix should now have (1, 0) == 6.300000" << endl << endl; + m.print(); + cout << endl; + } + + if (m == mi) + { + pass_ = true; + } + + // FAIL! Transposing the same matrix twice should yield the original. +} === added file 'src/libmatrix/test/transpose_test.h' --- src/libmatrix/test/transpose_test.h 1970-01-01 00:00:00 +0000 +++ src/libmatrix/test/transpose_test.h 2012-01-26 19:36:28 +0000 @@ -0,0 +1,38 @@ +// +// Copyright (c) 2010 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Jesse Barker - original implementation. +// +#ifndef TRANSPOSE_TEST_H_ +#define TRANSPOSE_TEST_H_ + +class MatrixTest; +class Options; + +class MatrixTest2x2Transpose : public MatrixTest +{ +public: + MatrixTest2x2Transpose() : MatrixTest("mat2::transpose") {} + virtual void run(const Options& options); +}; + +class MatrixTest3x3Transpose : public MatrixTest +{ +public: + MatrixTest3x3Transpose() : MatrixTest("mat3::transpose") {} + virtual void run(const Options& options); +}; + +class MatrixTest4x4Transpose : public MatrixTest +{ +public: + MatrixTest4x4Transpose() : MatrixTest("mat4::transpose") {} + virtual void run(const Options& options); +}; +#endif // TRANSPOSE_TEST_H_ === added file 'src/libmatrix/util.cc' --- src/libmatrix/util.cc 1970-01-01 00:00:00 +0000 +++ src/libmatrix/util.cc 2012-01-27 22:21:17 +0000 @@ -0,0 +1,165 @@ +// +// Copyright (c) 2010-2011 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Alexandros Frantzis +// Jesse Barker +// +#include +#include +#include +#ifdef ANDROID +#include +#else +#include +#endif + +#include "log.h" +#include "util.h" + +/** + * Splits a string using a delimiter + * + * @param s the string to split + * @param delim the delimitir to use + * @param elems the string vector to populate + */ +void +Util::split(const std::string &s, char delim, std::vector &elems) +{ + std::stringstream ss(s); + + std::string item; + while(std::getline(ss, item, delim)) + elems.push_back(item); +} + +uint64_t +Util::get_timestamp_us() +{ + struct timeval tv; + gettimeofday(&tv, NULL); + uint64_t now = static_cast(tv.tv_sec) * 1000000 + + static_cast(tv.tv_usec); + return now; +} + +std::string +Util::appname_from_path(const std::string& path) +{ + std::string::size_type slashPos = path.rfind("/"); + std::string::size_type startPos(0); + if (slashPos != std::string::npos) + { + startPos = slashPos + 1; + } + return std::string(path, startPos, std::string::npos); +} + +#ifndef ANDROID + +std::istream * +Util::get_resource(const std::string &path) +{ + std::ifstream *ifs = new std::ifstream(path.c_str()); + + return static_cast(ifs); +} + +void +Util::list_files(const std::string& dirName, std::vector& fileVec) +{ + DIR* dir = opendir(dirName.c_str()); + if (!dir) + { + Log::error("Failed to open models directory '%s'\n", dirName.c_str()); + return; + } + + struct dirent* entry = readdir(dir); + while (entry) + { + std::string pathname(dirName + "/"); + pathname += std::string(entry->d_name); + // Skip '.' and '..' + if (entry->d_name[0] != '.') + { + fileVec.push_back(pathname); + } + entry = readdir(dir); + } + closedir(dir); +} + +#else + +AAssetManager *Util::android_asset_manager = 0; + +void +Util::android_set_asset_manager(AAssetManager *asset_manager) +{ + Util::android_asset_manager = asset_manager; +} + +AAssetManager * +Util::android_get_asset_manager() +{ + return Util::android_asset_manager; +} + +std::istream * +Util::get_resource(const std::string &path) +{ + std::string path2(path); + /* Remove leading '/' from path name, it confuses the AssetManager */ + if (path2.size() > 0 && path2[0] == '/') + path2.erase(0, 1); + + std::stringstream *ss = new std::stringstream; + AAsset *asset = AAssetManager_open(Util::android_asset_manager, + path2.c_str(), AASSET_MODE_RANDOM); + if (asset) { + ss->write(reinterpret_cast(AAsset_getBuffer(asset)), + AAsset_getLength(asset)); + Log::debug("Load asset %s\n", path2.c_str()); + AAsset_close(asset); + } + else { + Log::error("Couldn't load asset %s\n", path2.c_str()); + } + + return static_cast(ss); +} + +void +Util::list_files(const std::string& dirName, std::vector& fileVec) +{ + AAssetManager *mgr(Util::android_get_asset_manager()); + std::string dir_name(dirName); + + /* Remove leading '/' from path, it confuses the AssetManager */ + if (dir_name.size() > 0 && dir_name[0] == '/') + dir_name.erase(0, 1); + + AAssetDir* dir = AAssetManager_openDir(mgr, dir_name.c_str()); + if (!dir) + { + Log::error("Failed to open models directory '%s'\n", dir_name.c_str()); + return; + } + + const char *filename(0); + while ((filename = AAssetDir_getNextFileName(dir)) != 0) + { + std::string pathname(dir_name + "/"); + pathname += std::string(filename); + fileVec.push_back(pathname); + } + AAssetDir_close(dir); +} +#endif === added file 'src/libmatrix/util.h' --- src/libmatrix/util.h 1970-01-01 00:00:00 +0000 +++ src/libmatrix/util.h 2012-01-27 22:21:17 +0000 @@ -0,0 +1,71 @@ +// +// Copyright (c) 2010-2011 Linaro Limited +// +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the MIT License which accompanies +// this distribution, and is available at +// http://www.opensource.org/licenses/mit-license.php +// +// Contributors: +// Alexandros Frantzis +// Jesse Barker +// +#ifndef UTIL_H_ +#define UTIL_H_ + +#include +#include +#include +#include +#include + +#ifdef ANDROID +#include +#endif + +struct Util { + static void split(const std::string &s, char delim, std::vector &elems); + static uint64_t get_timestamp_us(); + static std::istream *get_resource(const std::string &path); + static void list_files(const std::string& dirName, std::vector& fileVec); + template static void dispose_pointer_vector(std::vector &vec) + { + for (typename std::vector::const_iterator iter = vec.begin(); + iter != vec.end(); + iter++) + { + delete *iter; + } + + vec.clear(); + } + template + static T + fromString(const std::string& asString) + { + std::stringstream ss(asString); + T retVal; + ss >> retVal; + return retVal; + } + + template + static std::string + toString(const T t) + { + std::stringstream ss; + ss << t; + return ss.str(); + } + static std::string + appname_from_path(const std::string& path); + +#ifdef ANDROID + static void android_set_asset_manager(AAssetManager *asset_manager); + static AAssetManager *android_get_asset_manager(void); +private: + static AAssetManager *android_asset_manager; +#endif +}; + +#endif /* UTIL_H */ === modified file 'src/libmatrix/vec.h' --- src/libmatrix/vec.h 2011-01-17 18:15:21 +0000 +++ src/libmatrix/vec.h 2012-01-26 19:36:28 +0000 @@ -1,5 +1,5 @@ // -// Copyright (c) 2010 Linaro Limited +// Copyright (c) 2010-2011 Linaro Limited // // All rights reserved. This program and the accompanying materials // are made available under the terms of the MIT License which accompanies @@ -17,6 +17,10 @@ namespace LibMatrix { +// A template class for creating, managing and operating on a 2-element vector +// of any type you like (intended for built-in types, but as long as it +// supports the basic arithmetic and assignment operators, any type should +// work). template class tvec2 { @@ -24,10 +28,10 @@ tvec2() : x_(0), y_(0) {} - tvec2(T t) : + tvec2(const T t) : x_(t), y_(t) {} - tvec2(T x, T y) : + tvec2(const T x, const T y) : x_(x), y_(y) {} tvec2(const tvec2& v) : @@ -35,18 +39,26 @@ y_(v.y_) {} ~tvec2() {} + // Print the elements of the vector to standard out. + // Really only useful for debug and test. void print() const { std::cout << "| " << x_ << " " << y_ << " |" << std::endl; } + + // Allow raw data access for API calls and the like. + // For example, it is valid to pass a tvec2 into a call to + // the OpenGL command "glUniform2fv()". operator const T*() const { return &x_;} + // Get and set access members for the individual elements. const T x() const { return x_; } const T y() const { return y_; } void x(const T& val) { x_ = val; } void y(const T& val) { y_ = val; } + // A direct assignment of 'rhs' to this. Return a reference to this. tvec2& operator=(const tvec2& rhs) { if (this != &rhs) @@ -57,6 +69,7 @@ return *this; } + // Divide this by a scalar. Return a reference to this. tvec2& operator/=(const T& rhs) { x_ /= rhs; @@ -64,11 +77,29 @@ return *this; } - const tvec2 operator/(const T& rhs) - { - return tvec2(*this) /= rhs; - } - + // Divide a copy of this by a scalar. Return the copy. + const tvec2 operator/(const T& rhs) const + { + return tvec2(*this) /= rhs; + } + + // Component-wise divide of this by another vector. + // Return a reference to this. + tvec2& operator/=(const tvec2& rhs) + { + x_ /= rhs.x_; + y_ /= rhs.y_; + return *this; + } + + // Component-wise divide of a copy of this by another vector. + // Return the copy. + const tvec2 operator/(const tvec2& rhs) const + { + return tvec2(*this) /= rhs; + } + + // Multiply this by a scalar. Return a reference to this. tvec2& operator*=(const T& rhs) { x_ *= rhs; @@ -76,11 +107,29 @@ return *this; } - const tvec2 operator*(const T& rhs) - { - return tvec2(*this) *= rhs; - } - + // Multiply a copy of this by a scalar. Return the copy. + const tvec2 operator*(const T& rhs) const + { + return tvec2(*this) *= rhs; + } + + // Component-wise multiply of this by another vector. + // Return a reference to this. + tvec2& operator*=(const tvec2& rhs) + { + x_ *= rhs.x_; + y_ *= rhs.y_; + return *this; + } + + // Component-wise multiply of a copy of this by another vector. + // Return the copy. + const tvec2 operator*(const tvec2& rhs) const + { + return tvec2(*this) *= rhs; + } + + // Add a scalar to this. Return a reference to this. tvec2& operator+=(const T& rhs) { x_ += rhs; @@ -88,11 +137,14 @@ return *this; } - const tvec2 operator+(const T& rhs) + // Add a scalar to a copy of this. Return the copy. + const tvec2 operator+(const T& rhs) const { return tvec2(*this) += rhs; } + // Component-wise addition of another vector to this. + // Return a reference to this. tvec2& operator+=(const tvec2& rhs) { x_ += rhs.x_; @@ -100,11 +152,14 @@ return *this; } - const tvec2 operator+(const tvec2& rhs) + // Component-wise addition of another vector to a copy of this. + // Return the copy. + const tvec2 operator+(const tvec2& rhs) const { return tvec2(*this) += rhs; } + // Subtract a scalar from this. Return a reference to this. tvec2& operator-=(const T& rhs) { x_ -= rhs; @@ -112,11 +167,14 @@ return *this; } - const tvec2 operator-(const T& rhs) + // Subtract a scalar from a copy of this. Return the copy. + const tvec2 operator-(const T& rhs) const { return tvec2(*this) -= rhs; } + // Component-wise subtraction of another vector from this. + // Return a reference to this. tvec2& operator-=(const tvec2& rhs) { x_ -= rhs.x_; @@ -124,16 +182,20 @@ return *this; } - const tvec2 operator-(const tvec2& rhs) + // Component-wise subtraction of another vector from a copy of this. + // Return the copy. + const tvec2 operator-(const tvec2& rhs) const { return tvec2(*this) -= rhs; } + // Compute the length of this and return it. float length() const { return sqrt(dot(*this, *this)); } + // Make this a unit vector. void normalize() { float l = length(); @@ -141,6 +203,7 @@ y_ /= l; } + // Compute the dot product of two vectors. static T dot(const tvec2& v1, const tvec2& v2) { return (v1.x_ * v2.x_) + (v1.y_ * v2.y_); @@ -151,6 +214,10 @@ T y_; }; +// A template class for creating, managing and operating on a 3-element vector +// of any type you like (intended for built-in types, but as long as it +// supports the basic arithmetic and assignment operators, any type should +// work). template class tvec3 { @@ -159,11 +226,11 @@ x_(0), y_(0), z_(0) {} - tvec3(T t) : + tvec3(const T t) : x_(t), y_(t), z_(t) {} - tvec3(T x, T y, T z) : + tvec3(const T x, const T y, const T z) : x_(x), y_(y), z_(z) {} @@ -173,12 +240,19 @@ z_(v.z_) {} ~tvec3() {} + // Print the elements of the vector to standard out. + // Really only useful for debug and test. void print() const { std::cout << "| " << x_ << " " << y_ << " " << z_ << " |" << std::endl; } + + // Allow raw data access for API calls and the like. + // For example, it is valid to pass a tvec3 into a call to + // the OpenGL command "glUniform3fv()". operator const T*() const { return &x_;} + // Get and set access members for the individual elements. const T x() const { return x_; } const T y() const { return y_; } const T z() const { return z_; } @@ -187,6 +261,7 @@ void y(const T& val) { y_ = val; } void z(const T& val) { z_ = val; } + // A direct assignment of 'rhs' to this. Return a reference to this. tvec3& operator=(const tvec3& rhs) { if (this != &rhs) @@ -198,6 +273,7 @@ return *this; } + // Divide this by a scalar. Return a reference to this. tvec3& operator/=(const T& rhs) { x_ /= rhs; @@ -206,11 +282,30 @@ return *this; } - const tvec3 operator/(const T& rhs) - { - return tvec3(*this) /= rhs; - } - + // Divide a copy of this by a scalar. Return the copy. + const tvec3 operator/(const T& rhs) const + { + return tvec3(*this) /= rhs; + } + + // Component-wise divide of this by another vector. + // Return a reference to this. + tvec3& operator/=(const tvec3& rhs) + { + x_ /= rhs.x_; + y_ /= rhs.y_; + z_ /= rhs.z_; + return *this; + } + + // Component-wise divide of a copy of this by another vector. + // Return the copy. + const tvec3 operator/(const tvec3& rhs) const + { + return tvec3(*this) /= rhs; + } + + // Multiply this by a scalar. Return a reference to this. tvec3& operator*=(const T& rhs) { x_ *= rhs; @@ -219,11 +314,30 @@ return *this; } - const tvec3 operator*(const T& rhs) - { - return tvec3(*this) *= rhs; - } - + // Multiply a copy of this by a scalar. Return the copy. + const tvec3 operator*(const T& rhs) const + { + return tvec3(*this) *= rhs; + } + + // Component-wise multiply of this by another vector. + // Return a reference to this. + tvec3& operator*=(const tvec3& rhs) + { + x_ *= rhs.x_; + y_ *= rhs.y_; + z_ *= rhs.z_; + return *this; + } + + // Component-wise multiply of a copy of this by another vector. + // Return the copy. + const tvec3 operator*(const tvec3& rhs) const + { + return tvec3(*this) *= rhs; + } + + // Add a scalar to this. Return a reference to this. tvec3& operator+=(const T& rhs) { x_ += rhs; @@ -232,11 +346,14 @@ return *this; } - const tvec3 operator+(const T& rhs) + // Add a scalar to a copy of this. Return the copy. + const tvec3 operator+(const T& rhs) const { return tvec3(*this) += rhs; } + // Component-wise addition of another vector to this. + // Return a reference to this. tvec3& operator+=(const tvec3& rhs) { x_ += rhs.x_; @@ -245,11 +362,14 @@ return *this; } - const tvec3 operator+(const tvec3& rhs) + // Component-wise addition of another vector to a copy of this. + // Return the copy. + const tvec3 operator+(const tvec3& rhs) const { return tvec3(*this) += rhs; } + // Subtract a scalar from this. Return a reference to this. tvec3& operator-=(const T& rhs) { x_ -= rhs; @@ -258,11 +378,14 @@ return *this; } - const tvec3 operator-(const T& rhs) + // Subtract a scalar from a copy of this. Return the copy. + const tvec3 operator-(const T& rhs) const { return tvec3(*this) -= rhs; } + // Component-wise subtraction of another vector from this. + // Return a reference to this. tvec3& operator-=(const tvec3& rhs) { x_ -= rhs.x_; @@ -271,16 +394,20 @@ return *this; } - const tvec3 operator-(const tvec3& rhs) + // Component-wise subtraction of another vector from a copy of this. + // Return the copy. + const tvec3 operator-(const tvec3& rhs) const { return tvec3(*this) -= rhs; } + // Compute the length of this and return it. float length() const { return sqrt(dot(*this, *this)); } + // Make this a unit vector. void normalize() { float l = length(); @@ -289,11 +416,13 @@ z_ /= l; } + // Compute the dot product of two vectors. static T dot(const tvec3& v1, const tvec3& v2) { return (v1.x_ * v2.x_) + (v1.y_ * v2.y_) + (v1.z_ * v2.z_); } + // Compute the cross product of two vectors. static tvec3 cross(const tvec3& u, const tvec3& v) { return tvec3((u.y_ * v.z_) - (u.z_ * v.y_), @@ -307,6 +436,10 @@ T z_; }; +// A template class for creating, managing and operating on a 4-element vector +// of any type you like (intended for built-in types, but as long as it +// supports the basic arithmetic and assignment operators, any type should +// work). template class tvec4 { @@ -316,12 +449,12 @@ y_(0), z_(0), w_(0) {} - tvec4(T t) : + tvec4(const T t) : x_(t), y_(t), z_(t), w_(t) {} - tvec4(T x, T y, T z, T w) : + tvec4(const T x, const T y, const T z, const T w) : x_(x), y_(y), z_(z), @@ -333,12 +466,19 @@ w_(v.w_) {} ~tvec4() {} + // Print the elements of the vector to standard out. + // Really only useful for debug and test. void print() const { std::cout << "| " << x_ << " " << y_ << " " << z_ << " " << w_ << " |" << std::endl; } + + // Allow raw data access for API calls and the like. + // For example, it is valid to pass a tvec4 into a call to + // the OpenGL command "glUniform4fv()". operator const T*() const { return &x_;} + // Get and set access members for the individual elements. const T x() const { return x_; } const T y() const { return y_; } const T z() const { return z_; } @@ -349,6 +489,7 @@ void z(const T& val) { z_ = val; } void w(const T& val) { w_ = val; } + // A direct assignment of 'rhs' to this. Return a reference to this. tvec4& operator=(const tvec4& rhs) { if (this != &rhs) @@ -361,6 +502,7 @@ return *this; } + // Divide this by a scalar. Return a reference to this. tvec4& operator/=(const T& rhs) { x_ /= rhs; @@ -370,11 +512,31 @@ return *this; } - const tvec4 operator/(const T& rhs) - { - return tvec4(*this) /= rhs; - } - + // Divide a copy of this by a scalar. Return the copy. + const tvec4 operator/(const T& rhs) const + { + return tvec4(*this) /= rhs; + } + + // Component-wise divide of this by another vector. + // Return a reference to this. + tvec4& operator/=(const tvec4& rhs) + { + x_ /= rhs.x_; + y_ /= rhs.y_; + z_ /= rhs.z_; + w_ /= rhs.w_; + return *this; + } + + // Component-wise divide of a copy of this by another vector. + // Return the copy. + const tvec4 operator/(const tvec4& rhs) const + { + return tvec4(*this) /= rhs; + } + + // Multiply this by a scalar. Return a reference to this. tvec4& operator*=(const T& rhs) { x_ *= rhs; @@ -384,11 +546,31 @@ return *this; } - const tvec4 operator*(const T& rhs) - { - return tvec4(*this) *= rhs; - } - + // Multiply a copy of this by a scalar. Return the copy. + const tvec4 operator*(const T& rhs) const + { + return tvec4(*this) *= rhs; + } + + // Component-wise multiply of this by another vector. + // Return a reference to this. + tvec4& operator*=(const tvec4& rhs) + { + x_ *= rhs.x_; + y_ *= rhs.y_; + z_ *= rhs.z_; + w_ *= rhs.w_; + return *this; + } + + // Component-wise multiply of a copy of this by another vector. + // Return the copy. + const tvec4 operator*(const tvec4& rhs) const + { + return tvec4(*this) *= rhs; + } + + // Add a scalar to this. Return a reference to this. tvec4& operator+=(const T& rhs) { x_ += rhs; @@ -398,11 +580,14 @@ return *this; } - const tvec4 operator+(const T& rhs) + // Add a scalar to a copy of this. Return the copy. + const tvec4 operator+(const T& rhs) const { return tvec4(*this) += rhs; } + // Component-wise addition of another vector to this. + // Return a reference to this. tvec4& operator+=(const tvec4& rhs) { x_ += rhs.x_; @@ -412,11 +597,14 @@ return *this; } - const tvec4 operator+(const tvec4& rhs) + // Component-wise addition of another vector to a copy of this. + // Return the copy. + const tvec4 operator+(const tvec4& rhs) const { return tvec4(*this) += rhs; } + // Subtract a scalar from this. Return a reference to this. tvec4& operator-=(const T& rhs) { x_ -= rhs; @@ -426,11 +614,14 @@ return *this; } - const tvec4 operator-(const T& rhs) + // Subtract a scalar from a copy of this. Return the copy. + const tvec4 operator-(const T& rhs) const { return tvec4(*this) -= rhs; } + // Component-wise subtraction of another vector from this. + // Return a reference to this. tvec4& operator-=(const tvec4& rhs) { x_ -= rhs.x_; @@ -440,16 +631,20 @@ return *this; } - const tvec4 operator-(const tvec4& rhs) + // Component-wise subtraction of another vector from a copy of this. + // Return the copy. + const tvec4 operator-(const tvec4& rhs) const { return tvec4(*this) -= rhs; } + // Compute the length of this and return it. float length() const { return sqrt(dot(*this, *this)); } + // Make this a unit vector. void normalize() { float l = length(); @@ -459,6 +654,7 @@ w_ /= l; } + // Compute the dot product of two vectors. static T dot(const tvec4& v1, const tvec4& v2) { return (v1.x_ * v2.x_) + (v1.y_ * v2.y_) + (v1.z_ * v2.z_) + (v1.w_ * v2.w_); @@ -497,4 +693,24 @@ } // namespace LibMatrix +// Global operators to allow for things like defining a new vector in terms of +// a product of a scalar and a vector +template +const LibMatrix::tvec2 operator*(const T t, const LibMatrix::tvec2& v) +{ + return v * t; +} + +template +const LibMatrix::tvec3 operator*(const T t, const LibMatrix::tvec3& v) +{ + return v * t; +} + +template +const LibMatrix::tvec4 operator*(const T t, const LibMatrix::tvec4& v) +{ + return v * t; +} + #endif // VEC_H_ === removed file 'src/log.cc' --- src/log.cc 2011-01-17 18:15:21 +0000 +++ src/log.cc 1970-01-01 00:00:00 +0000 @@ -1,58 +0,0 @@ -/* - * 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 "options.h" -#include "log.h" - -void -Log::info(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stdout, fmt, ap); - va_end(ap); -} - -void -Log::debug(const char *fmt, ...) -{ - if (!Options::show_debug) - return; - va_list ap; - va_start(ap, fmt); - vfprintf(stdout, fmt, ap); - va_end(ap); -} - -void -Log::error(const char *fmt, ...) -{ - va_list ap; - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); -} - === removed file 'src/log.h' --- src/log.h 2011-01-17 18:15:21 +0000 +++ src/log.h 1970-01-01 00:00:00 +0000 @@ -1,35 +0,0 @@ -/* - * 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 LOG_H_ -#define LOG_H_ - -class Log -{ -public: - static void info(const char *fmt, ...); - static void debug(const char *fmt, ...); - static void error(const char *fmt, ...); -}; - -#endif /* LOG_H_ */ === removed file 'src/shader-source.cc' --- src/shader-source.cc 2011-12-12 12:43:08 +0000 +++ src/shader-source.cc 1970-01-01 00:00:00 +0000 @@ -1,625 +0,0 @@ -/* - * 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: - * Alexandros Frantzis (glmark2) - */ - -#include -#include - -#include "shader-source.h" -#include "log.h" -#include "vec.h" -#include "util.h" - -/** - * Holds default precision values for all shader types - * (even the unknown type, which is hardwired to default precision values) - */ -std::vector -ShaderSource::default_precision_(ShaderSource::ShaderTypeUnknown + 1); - -/** - * Loads the contents of a file into a string. - * - * @param filename the name of the file - * @param str the string to put the contents of the file into - */ -bool -ShaderSource::load_file(const std::string& filename, std::string& str) -{ - std::auto_ptr is_ptr(Util::get_resource(filename)); - std::istream& inputFile(*is_ptr); - - if (!inputFile) - { - Log::error("Failed to open \"%s\"\n", filename.c_str()); - return false; - } - - std::string curLine; - while (getline(inputFile, curLine)) - { - str += curLine; - str += '\n'; - } - - return true; -} - - -/** - * Appends a string to the shader source. - * - * @param str the string to append - */ -void -ShaderSource::append(const std::string &str) -{ - source_ << str; -} - -/** - * Appends the contents of a file to the shader source. - * - * @param filename the name of the file to append - */ -void -ShaderSource::append_file(const std::string &filename) -{ - std::string source; - if (load_file(filename, source)) - source_ << source; -} - -/** - * Replaces a string in the source with another string. - * - * @param remove the string to replace - * @param insert the string to replace with - */ -void -ShaderSource::replace(const std::string &remove, const std::string &insert) -{ - std::string::size_type pos = 0; - std::string str(source_.str()); - - while ((pos = str.find(remove, pos)) != std::string::npos) { - str.replace(pos, remove.size(), insert); - pos++; - } - - source_.clear(); - source_.str(str); -} - -/** - * Replaces a string in the source with the contents of a file. - * - * @param remove the string to replace - * @param filename the name of the file to read from - */ -void -ShaderSource::replace_with_file(const std::string &remove, const std::string &filename) -{ - std::string source; - if (load_file(filename, source)) - replace(remove, source); -} - -/** - * Adds a string (usually containing a constant definition) at - * global (per shader) scope. - * - * The string is placed after any default precision qualifiers. - * - * @param str the string to add - */ -void -ShaderSource::add_global(const std::string &str) -{ - std::string::size_type pos = 0; - std::string source(source_.str()); - - /* Find the last precision qualifier */ - pos = source.rfind("precision"); - - if (pos != std::string::npos) { - /* - * Find the next #endif line of a preprocessor block that contains - * the precision qualifier. - */ - std::string::size_type pos_if = source.find("#if", pos); - std::string::size_type pos_endif = source.find("#endif", pos); - - if (pos_endif != std::string::npos && pos_endif < pos_if) - pos = pos_endif; - - /* Go to the next line */ - pos = source.find("\n", pos); - if (pos != std::string::npos) - pos++; - } - else - pos = 0; - - source.insert(pos, str); - - source_.clear(); - source_.str(source); -} - -/** - * Adds a string (usually containing a constant definition) at - * global (per shader) scope. - * - * The string is placed after any default precision qualifiers. - * - * @param function the function to add the string into - * @param str the string to add - */ -void -ShaderSource::add_local(const std::string &str, const std::string &function) -{ - std::string::size_type pos = 0; - std::string source(source_.str()); - - /* Find the function */ - pos = source.find(function); - pos = source.find('{', pos); - - /* Go to the next line */ - pos = source.find("\n", pos); - if (pos != std::string::npos) - pos++; - - source.insert(pos, str); - - source_.clear(); - source_.str(source); -} - -/** - * Adds a string (usually containing a constant definition) to a shader source - * - * If the function parameter is empty, the string will be added to global - * scope, after any precision definitions. - * - * @param str the string to add - * @param function if not empty, the function to add the string into - */ -void -ShaderSource::add(const std::string &str, const std::string &function) -{ - if (!function.empty()) - add_local(str, function); - else - add_global(str); -} - -/** - * Adds a float constant definition. - * - * @param name the name of the constant - * @param f the value of the constant - * @param function if not empty, the function to put the definition in - */ -void -ShaderSource::add_const(const std::string &name, float f, - const std::string &function) -{ - std::stringstream ss; - - ss << "const float " << name << " = " << std::fixed << f << ";" << std::endl; - - add(ss.str(), function); -} - -/** - * Adds a float array constant definition. - * - * Note that various GLSL versions (including ES) don't support - * array constants. - * - * @param name the name of the constant - * @param v the value of the constant - * @param function if not empty, the function to put the definition in - */ -void -ShaderSource::add_const(const std::string &name, std::vector &array, - const std::string &function) -{ - std::stringstream ss; - - ss << "const float " << name << "[" << array.size() << "] = {" << std::fixed; - for(std::vector::const_iterator iter = array.begin(); - iter != array.end(); - iter++) - { - ss << *iter; - if (iter + 1 != array.end()) - ss << ", " << std::endl; - } - - ss << "};" << std::endl; - - add(ss.str(), function); -} - -/** - * Adds a vec2 constant definition. - * - * @param name the name of the constant - * @param v the value of the constant - * @param function if not empty, the function to put the definition in - */ -void -ShaderSource::add_const(const std::string &name, const LibMatrix::vec2 &v, - const std::string &function) -{ - std::stringstream ss; - - ss << "const vec2 " << name << " = vec2(" << std::fixed; - ss << v.x() << ", " << v.y() << ");" << std::endl; - - add(ss.str(), function); -} - -/** - * Adds a vec3 constant definition. - * - * @param name the name of the constant - * @param v the value of the constant - * @param function if not empty, the function to put the definition in - */ -void -ShaderSource::add_const(const std::string &name, const LibMatrix::vec3 &v, - const std::string &function) -{ - std::stringstream ss; - - ss << "const vec3 " << name << " = vec3(" << std::fixed; - ss << v.x() << ", " << v.y() << ", " << v.z() << ");" << std::endl; - - add(ss.str(), function); -} - -/** - * Adds a vec4 constant definition. - * - * @param name the name of the constant - * @param v the value of the constant - * @param function if not empty, the function to put the definition in - */ -void -ShaderSource::add_const(const std::string &name, const LibMatrix::vec4 &v, - const std::string &function) -{ - std::stringstream ss; - - ss << "const vec4 " << name << " = vec4(" << std::fixed; - ss << v.x() << ", " << v.y() << ", " << v.z() << ", " << v.w() << ");" << std::endl; - - add(ss.str(), function); -} - -/** - * Adds a mat3 constant definition. - * - * @param name the name of the constant - * @param v the value of the constant - * @param function if not empty, the function to put the definition in - */ -void -ShaderSource::add_const(const std::string &name, const LibMatrix::mat3 &m, - const std::string &function) -{ - std::stringstream ss; - - ss << "const mat3 " << name << " = mat3(" << std::fixed; - ss << m[0][0] << ", " << m[1][0] << ", " << m[2][0] << "," << std::endl; - ss << m[0][1] << ", " << m[1][1] << ", " << m[2][1] << "," << std::endl; - ss << m[0][2] << ", " << m[1][2] << ", " << m[2][2] << std::endl; - ss << ");" << std::endl; - - add(ss.str(), function); -} - -/** - * Adds a float array declaration and initialization. - * - * @param name the name of the array - * @param array the array values - * @param init_function the function to put the initialization in - * @param decl_function if not empty, the function to put the declaration in - */ -void -ShaderSource::add_array(const std::string &name, std::vector &array, - const std::string &init_function, - const std::string &decl_function) -{ - if (init_function.empty() || name.empty()) - return; - - std::stringstream ss; - ss << "float " << name << "[" << array.size() << "];" << std::endl; - - std::string decl(ss.str()); - - ss.clear(); - ss.str(""); - ss << std::fixed; - - for(std::vector::const_iterator iter = array.begin(); - iter != array.end(); - iter++) - { - ss << name << "[" << iter - array.begin() << "] = " << *iter << ";" << std::endl; - } - - add(ss.str(), init_function); - - add(decl, decl_function); -} - -/** - * Gets the ShaderType for this ShaderSource. - * - * If the ShaderType is unknown, an attempt is made to infer - * the type from the shader source contents. - * - * @return the ShaderType - */ -ShaderSource::ShaderType -ShaderSource::type() -{ - /* Try to infer the type from the source contents */ - if (type_ == ShaderSource::ShaderTypeUnknown) { - std::string source(source_.str()); - - if (source.find("gl_FragColor") != std::string::npos) - type_ = ShaderSource::ShaderTypeFragment; - else if (source.find("gl_Position") != std::string::npos) - type_ = ShaderSource::ShaderTypeVertex; - else - Log::debug("Cannot infer shader type from contents. Leaving it Unknown.\n"); - } - - return type_; -} - -/** - * Helper function that emits a precision statement. - * - * @param ss the stringstream to add the statement to - * @param val the precision value - * @param type_str the variable type to apply the precision value to - */ -void -ShaderSource::emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val, - const std::string& type_str) -{ - static const char *precision_map[] = { - "lowp", "mediump", "highp", NULL - }; - - if (val == ShaderSource::PrecisionValueHigh) { - if (type_ == ShaderSource::ShaderTypeFragment) - ss << "#ifdef GL_FRAGMENT_PRECISION_HIGH" << std::endl; - - ss << "precision highp " << type_str << ";" << std::endl; - - if (type_ == ShaderSource::ShaderTypeFragment) { - ss << "#else" << std::endl; - ss << "precision mediump " << type_str << ";" << std::endl; - ss << "#endif" << std::endl; - } - } - else if (val >= 0 && val < ShaderSource::PrecisionValueDefault) { - ss << "precision " << precision_map[val] << " "; - ss << type_str << ";" << std::endl; - } - - /* There is no default precision in the fragment shader, so set it to mediump */ - if (val == ShaderSource::PrecisionValueDefault - && type_str == "float" && type_ == ShaderSource::ShaderTypeFragment) - { - ss << "precision mediump float;" << std::endl; - } -} - -/** - * Gets a string containing the complete shader source. - * - * Precision statements are applied at this point. - * - * @return the shader source - */ -std::string -ShaderSource::str() -{ - /* Decide which precision values to use */ - ShaderSource::Precision precision; - - /* Ensure we have tried to infer the type from the contents */ - type(); - - if (precision_has_been_set_) - precision = precision_; - else - precision = default_precision(type_); - - /* Create the precision statements */ - std::stringstream ss; - - emit_precision(ss, precision.int_precision, "int"); - emit_precision(ss, precision.float_precision, "float"); - emit_precision(ss, precision.sampler2d_precision, "sampler2D"); - emit_precision(ss, precision.samplercube_precision, "samplerCube"); - - std::string precision_str(ss.str()); - if (!precision_str.empty()) { - precision_str.insert(0, "#ifdef GL_ES\n"); - precision_str.insert(precision_str.size(), "#endif\n"); - } - - return precision_str + source_.str(); -} - -/** - * Sets the precision that will be used for this shader. - * - * This overrides any default values set with ShaderSource::default_*_precision(). - * - * @param precision the precision to set - */ -void -ShaderSource::precision(const ShaderSource::Precision& precision) -{ - precision_ = precision; - precision_has_been_set_ = true; -} - -/** - * Gets the precision that will be used for this shader. - * - * @return the precision - */ -const ShaderSource::Precision& -ShaderSource::precision() -{ - return precision_; -} - -/** - * Sets the default precision that will be used for a shaders type. - * - * If type is ShaderTypeUnknown the supplied precision is used for all - * shader types. - * - * This can be overriden per ShaderSource object by using ::precision(). - * - * @param precision the default precision to set - * @param type the ShaderType to use the precision for - */ -void -ShaderSource::default_precision(const ShaderSource::Precision& precision, - ShaderSource::ShaderType type) -{ - if (type < 0 || type > ShaderSource::ShaderTypeUnknown) - type = ShaderSource::ShaderTypeUnknown; - - if (type == ShaderSource::ShaderTypeUnknown) { - for (size_t i = 0; i < ShaderSource::ShaderTypeUnknown; i++) - default_precision_[i] = precision; - } - else { - default_precision_[type] = precision; - } -} - -/** - * Gets the default precision that will be used for a shader type. - * - * It is valid to use a type of ShaderTypeUnknown. This will always - * return a Precision with default values. - * - * @param type the ShaderType to get the precision of - * - * @return the precision - */ -const ShaderSource::Precision& -ShaderSource::default_precision(ShaderSource::ShaderType type) -{ - if (type < 0 || type > ShaderSource::ShaderTypeUnknown) - type = ShaderSource::ShaderTypeUnknown; - - return default_precision_[type]; -} - -/**************************************** - * ShaderSource::Precision constructors * - ****************************************/ - -/** - * Creates a ShaderSource::Precision with default precision values. - */ -ShaderSource::Precision::Precision() : - int_precision(ShaderSource::PrecisionValueDefault), - float_precision(ShaderSource::PrecisionValueDefault), - sampler2d_precision(ShaderSource::PrecisionValueDefault), - samplercube_precision(ShaderSource::PrecisionValueDefault) -{ -} - -/** - * Creates a ShaderSource::Precision using the supplied precision values. - */ -ShaderSource::Precision::Precision(ShaderSource::PrecisionValue int_p, - ShaderSource::PrecisionValue float_p, - ShaderSource::PrecisionValue sampler2d_p, - ShaderSource::PrecisionValue samplercube_p) : - int_precision(int_p), float_precision(float_p), - sampler2d_precision(sampler2d_p), samplercube_precision(samplercube_p) -{ -} - -/** - * Creates a ShaderSource::Precision from a string representation of - * precision values. - * - * The string format is: - * ",,," - * - * Each precision value is one of "high", "medium", "low" or "default". - * - * @param precision_values the string representation of the precision values - */ -ShaderSource::Precision::Precision(const std::string& precision_values) : - int_precision(ShaderSource::PrecisionValueDefault), - float_precision(ShaderSource::PrecisionValueDefault), - sampler2d_precision(ShaderSource::PrecisionValueDefault), - samplercube_precision(ShaderSource::PrecisionValueDefault) -{ - std::vector elems; - - Util::split(precision_values, ',', elems); - - for (size_t i = 0; i < elems.size() && i < 4; i++) { - const std::string& pstr(elems[i]); - ShaderSource::PrecisionValue pval; - - if (pstr == "high") - pval = ShaderSource::PrecisionValueHigh; - else if (pstr == "medium") - pval = ShaderSource::PrecisionValueMedium; - else if (pstr == "low") - pval = ShaderSource::PrecisionValueLow; - else - pval = ShaderSource::PrecisionValueDefault; - - switch(i) { - case 0: int_precision = pval; break; - case 1: float_precision = pval; break; - case 2: sampler2d_precision = pval; break; - case 3: samplercube_precision = pval; break; - default: break; - } - } -} === removed file 'src/shader-source.h' --- src/shader-source.h 2011-12-02 21:54:50 +0000 +++ src/shader-source.h 1970-01-01 00:00:00 +0000 @@ -1,113 +0,0 @@ -/* - * 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: - * Alexandros Frantzis (glmark2) - */ - -#include -#include -#include -#include "vec.h" -#include "mat.h" - -/** - * Helper class for loading and manipulating shader sources. - */ -class ShaderSource -{ -public: - enum ShaderType { - ShaderTypeVertex, - ShaderTypeFragment, - ShaderTypeUnknown - }; - - ShaderSource(ShaderType type = ShaderTypeUnknown) : - precision_has_been_set_(false), type_(type) {} - ShaderSource(const std::string &filename, ShaderType type = ShaderTypeUnknown) : - precision_has_been_set_(false), type_(type) { append_file(filename); } - - void append(const std::string &str); - void append_file(const std::string &filename); - - void replace(const std::string &remove, const std::string &insert); - void replace_with_file(const std::string &remove, const std::string &filename); - - void add(const std::string &str, const std::string &function = ""); - - void add_const(const std::string &name, float f, - const std::string &function = ""); - void add_const(const std::string &name, std::vector &f, - const std::string &function = ""); - void add_const(const std::string &name, const LibMatrix::vec2 &v, - const std::string &function = ""); - void add_const(const std::string &name, const LibMatrix::vec3 &v, - const std::string &function = ""); - void add_const(const std::string &name, const LibMatrix::vec4 &v, - const std::string &function = ""); - void add_const(const std::string &name, const LibMatrix::mat3 &m, - const std::string &function = ""); - - void add_array(const std::string &name, std::vector &array, - const std::string &init_function, - const std::string &decl_function = ""); - - ShaderType type(); - std::string str(); - - enum PrecisionValue { - PrecisionValueLow, - PrecisionValueMedium, - PrecisionValueHigh, - PrecisionValueDefault, - }; - - struct Precision { - Precision(); - Precision(PrecisionValue int_p, PrecisionValue float_p, - PrecisionValue sampler2d_p, PrecisionValue samplercube_p); - Precision(const std::string& list); - - PrecisionValue int_precision; - PrecisionValue float_precision; - PrecisionValue sampler2d_precision; - PrecisionValue samplercube_precision; - }; - - void precision(const Precision& precision); - const Precision& precision(); - - static void default_precision(const Precision& precision, - ShaderType type = ShaderTypeUnknown); - static const Precision& default_precision(ShaderType type); - -private: - void add_global(const std::string &str); - void add_local(const std::string &str, const std::string &function); - bool load_file(const std::string& filename, std::string& str); - void emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val, - const std::string& type_str); - - std::stringstream source_; - Precision precision_; - bool precision_has_been_set_; - ShaderType type_; - - static std::vector default_precision_; -}; === removed file 'src/util.cc' --- src/util.cc 2011-12-02 21:54:50 +0000 +++ src/util.cc 1970-01-01 00:00:00 +0000 @@ -1,90 +0,0 @@ -/* - * 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 "log.h" -#include "util.h" - -/** - * Splits a string using a delimiter - * - * @param s the string to split - * @param delim the delimitir to use - * @param elems the string vector to populate - */ -void -Util::split(const std::string &s, char delim, std::vector &elems) -{ - std::stringstream ss(s); - - std::string item; - while(std::getline(ss, item, delim)) - elems.push_back(item); -} - -uint64_t -Util::get_timestamp_us() -{ - struct timeval tv; - gettimeofday(&tv, NULL); - uint64_t now = static_cast(tv.tv_sec) * 1000000 + - static_cast(tv.tv_usec); - return now; -} - -std::istream * -Util::get_resource(const std::string &path) -{ - std::ifstream *ifs = new std::ifstream(path.c_str()); - - return static_cast(ifs); -} - -void -Util::list_files(const std::string& dirName, std::vector& fileVec) -{ - DIR* dir = opendir(dirName.c_str()); - if (!dir) - { - Log::error("Failed to open models directory '%s'\n", dirName.c_str()); - return; - } - - struct dirent* entry = readdir(dir); - while (entry) - { - std::string pathname(dirName + "/"); - pathname += std::string(entry->d_name); - // Skip '.' and '..' - if (entry->d_name[0] != '.') - { - fileVec.push_back(pathname); - } - entry = readdir(dir); - } - closedir(dir); -} === removed file 'src/util.h' --- src/util.h 2011-12-02 21:54:50 +0000 +++ src/util.h 1970-01-01 00:00:00 +0000 @@ -1,69 +0,0 @@ -/* - * 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 UTIL_H_ -#define UTIL_H_ - -#include -#include -#include -#include -#include - -struct Util { - static void split(const std::string &s, char delim, std::vector &elems); - static uint64_t get_timestamp_us(); - static std::istream *get_resource(const std::string &path); - static void list_files(const std::string& dirName, std::vector& fileVec); - template static void dispose_pointer_vector(std::vector &vec) - { - for (typename std::vector::const_iterator iter = vec.begin(); - iter != vec.end(); - iter++) - { - delete *iter; - } - - vec.clear(); - } - template - static T - fromString(const std::string& asString) - { - std::stringstream ss(asString); - T retVal; - ss >> retVal; - return retVal; - } - - template - static std::string - toString(const T t) - { - std::stringstream ss; - ss << t; - return ss.str(); - } -}; - -#endif /* UTIL_H */