=== modified file 'src/glcompbench.cc'
@@ -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'
@@ -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'
@@ -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'
@@ -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 <alexandros.frantzis@linaro.org>
+// Jesse Barker <jesse.barker@linaro.org>
+//
+#include <cstdio>
+#include <cstdarg>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include "log.h"
+
+#ifdef ANDROID
+#include <android/log.h>
+#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'
@@ -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 <alexandros.frantzis@linaro.org>
+// Jesse Barker <jesse.barker@linaro.org>
+//
+#ifndef LOG_H_
+#define LOG_H_
+
+#include <string>
+
+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'
@@ -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<typename T>
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<float> 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<T, 2> operator[](int index)
{
return ArrayProxy<T, 2>(&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<typename T>
const tmat2<T> operator*(const T& lhs, const tmat2<T>& rhs)
{
return tmat2<T>(rhs) * lhs;
}
+// Multiply a copy of a vector and a matrix (matrix is right-hand operand).
+// Return the copy.
template<typename T>
const tvec2<T> operator*(const tvec2<T>& lhs, const tmat2<T>& rhs)
{
@@ -254,6 +291,8 @@
return tvec2<T>(x,y);
}
+// Multiply a copy of a vector and a matrix (matrix is left-hand operand).
+// Return the copy.
template<typename T>
const tvec2<T> operator*(const tmat2<T>& lhs, const tvec2<T>& rhs)
{
@@ -262,6 +301,7 @@
return tvec2<T>(x, y);
}
+// Compute the outer product of two vectors. Return the resultant matrix.
template<typename T>
const tmat2<T> outer(const tvec2<T>& a, const tvec2<T>& 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<typename T>
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<T> 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<float> 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<T, 3> operator[](int index)
{
return ArrayProxy<T, 3>(&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<typename T>
const tmat3<T> operator*(const T& lhs, const tmat3<T>& rhs)
{
return tmat3<T>(rhs) * lhs;
}
+// Multiply a copy of a vector and a matrix (matrix is right-hand operand).
+// Return the copy.
template<typename T>
const tvec3<T> operator*(const tvec3<T>& lhs, const tmat3<T>& rhs)
{
@@ -572,6 +648,8 @@
return tvec3<T>(x, y, z);
}
+// Multiply a copy of a vector and a matrix (matrix is left-hand operand).
+// Return the copy.
template<typename T>
const tvec3<T> operator*(const tmat3<T>& lhs, const tvec3<T>& rhs)
{
@@ -581,6 +659,7 @@
return tvec3<T>(x, y, z);
}
+// Compute the outer product of two vectors. Return the resultant matrix.
template<typename T>
const tmat3<T> outer(const tvec3<T>& a, const tvec3<T>& 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<typename T>
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<T> 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<float> 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<T, 4> operator[](int index)
{
return ArrayProxy<T, 4>(&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<typename T>
const tmat4<T> operator*(const T& lhs, const tmat4<T>& rhs)
{
return tmat4<T>(rhs) * lhs;
}
+// Multiply a copy of a vector and a matrix (matrix is right-hand operand).
+// Return the copy.
template<typename T>
const tvec4<T> operator*(const tvec4<T>& lhs, const tmat4<T>& rhs)
{
@@ -997,6 +1112,8 @@
return tvec4<T>(x, y, z, w);
}
+// Multiply a copy of a vector and a matrix (matrix is left-hand operand).
+// Return the copy.
template<typename T>
const tvec4<T> operator*(const tmat4<T>& lhs, const tvec4<T>& rhs)
{
@@ -1007,6 +1124,7 @@
return tvec4<T>(x, y, z, w);
}
+// Compute the outer product of two vectors. Return the resultant matrix.
template<typename T>
const tmat4<T> outer(const tvec4<T>& a, const tvec4<T>& b)
{
=== modified file 'src/libmatrix/program.cc'
@@ -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 <string>
#include <vector>
#include <sstream>
#include <fstream>
#include <iostream>
-#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'
@@ -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'
@@ -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 <alexandros.frantzis@linaro.org>
+// Jesse Barker <jesse.barker@linaro.org>
+//
+#include <istream>
+#include <memory>
+
+#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::Precision>
+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<std::istream> 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<float> &array,
+ const std::string &function)
+{
+ std::stringstream ss;
+
+ ss << "const float " << name << "[" << array.size() << "] = {" << std::fixed;
+ for(std::vector<float>::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<float> &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<float>::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:
+ * "<int>,<float>,<sampler2d>,<samplercube>"
+ *
+ * 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<std::string> 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'
@@ -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 <alexandros.frantzis@linaro.org>
+// Jesse Barker <jesse.barker@linaro.org>
+//
+#include <string>
+#include <sstream>
+#include <vector>
+#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<float> &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<float> &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<Precision> default_precision_;
+};
=== added file 'src/libmatrix/test/basic-global-const.vert'
@@ -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'
@@ -0,0 +1,7 @@
+varying vec4 color;
+
+void
+main(void)
+{
+ gl_FragColor = color;
+}
=== added file 'src/libmatrix/test/basic.vert'
@@ -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'
@@ -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 <iostream>
+#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'
@@ -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'
@@ -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 <iostream>
#include "libmatrix_test.h"
#include "inverse_test.h"
=== modified file 'src/libmatrix/test/inverse_test.h'
@@ -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'
@@ -14,6 +14,9 @@
#include <vector>
#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<MatrixTest*>::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'
@@ -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'
@@ -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 <iostream>
#include <iomanip>
#include <getopt.h>
@@ -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'
@@ -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 <string>
+#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'
@@ -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'
@@ -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 <iostream>
+#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'
@@ -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'
@@ -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 <alexandros.frantzis@linaro.org>
+// Jesse Barker <jesse.barker@linaro.org>
+//
+#include <sstream>
+#include <fstream>
+#include <sys/time.h>
+#ifdef ANDROID
+#include <android/asset_manager.h>
+#else
+#include <dirent.h>
+#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<std::string> &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<uint64_t>(tv.tv_sec) * 1000000 +
+ static_cast<double>(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<std::istream *>(ifs);
+}
+
+void
+Util::list_files(const std::string& dirName, std::vector<std::string>& 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<const char *>(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<std::istream *>(ss);
+}
+
+void
+Util::list_files(const std::string& dirName, std::vector<std::string>& 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'
@@ -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 <alexandros.frantzis@linaro.org>
+// Jesse Barker <jesse.barker@linaro.org>
+//
+#ifndef UTIL_H_
+#define UTIL_H_
+
+#include <string>
+#include <vector>
+#include <istream>
+#include <sstream>
+#include <stdint.h>
+
+#ifdef ANDROID
+#include <android/asset_manager_jni.h>
+#endif
+
+struct Util {
+ static void split(const std::string &s, char delim, std::vector<std::string> &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<std::string>& fileVec);
+ template <class T> static void dispose_pointer_vector(std::vector<T*> &vec)
+ {
+ for (typename std::vector<T*>::const_iterator iter = vec.begin();
+ iter != vec.end();
+ iter++)
+ {
+ delete *iter;
+ }
+
+ vec.clear();
+ }
+ template<typename T>
+ static T
+ fromString(const std::string& asString)
+ {
+ std::stringstream ss(asString);
+ T retVal;
+ ss >> retVal;
+ return retVal;
+ }
+
+ template<typename T>
+ 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'
@@ -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<typename T>
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<float> 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<typename T>
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<float> 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<typename T>
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<float> 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<typename T>
+const LibMatrix::tvec2<T> operator*(const T t, const LibMatrix::tvec2<T>& v)
+{
+ return v * t;
+}
+
+template<typename T>
+const LibMatrix::tvec3<T> operator*(const T t, const LibMatrix::tvec3<T>& v)
+{
+ return v * t;
+}
+
+template<typename T>
+const LibMatrix::tvec4<T> operator*(const T t, const LibMatrix::tvec4<T>& v)
+{
+ return v * t;
+}
+
#endif // VEC_H_
=== removed file 'src/log.cc'
@@ -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 <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Alexandros Frantzis <alexandros.frantzis@linaro.org>
- * Jesse Barker <jesse.barker@linaro.org>
- */
-
-#include <cstdio>
-#include <cstdarg>
-
-#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'
@@ -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 <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Alexandros Frantzis <alexandros.frantzis@linaro.org>
- * Jesse Barker <jesse.barker@linaro.org>
- */
-
-#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'
@@ -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 <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Alexandros Frantzis (glmark2)
- */
-
-#include <istream>
-#include <memory>
-
-#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::Precision>
-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<std::istream> 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<float> &array,
- const std::string &function)
-{
- std::stringstream ss;
-
- ss << "const float " << name << "[" << array.size() << "] = {" << std::fixed;
- for(std::vector<float>::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<float> &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<float>::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:
- * "<int>,<float>,<sampler2d>,<samplercube>"
- *
- * 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<std::string> 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'
@@ -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 <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Alexandros Frantzis (glmark2)
- */
-
-#include <string>
-#include <sstream>
-#include <vector>
-#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<float> &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<float> &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<Precision> default_precision_;
-};
=== removed file 'src/util.cc'
@@ -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 <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Alexandros Frantzis <alexandros.frantzis@linaro.org>
- * Jesse Barker <jesse.barker@linaro.org>
- */
-
-#include <sstream>
-#include <fstream>
-#include <sys/time.h>
-#include <dirent.h>
-
-#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<std::string> &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<uint64_t>(tv.tv_sec) * 1000000 +
- static_cast<double>(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<std::istream *>(ifs);
-}
-
-void
-Util::list_files(const std::string& dirName, std::vector<std::string>& 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'
@@ -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 <http://www.gnu.org/licenses/>.
- *
- * Authors:
- * Alexandros Frantzis <alexandros.frantzis@linaro.org>
- * Jesse Barker <jesse.barker@linaro.org>
- */
-
-#ifndef UTIL_H_
-#define UTIL_H_
-
-#include <string>
-#include <vector>
-#include <istream>
-#include <sstream>
-#include <stdint.h>
-
-struct Util {
- static void split(const std::string &s, char delim, std::vector<std::string> &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<std::string>& fileVec);
- template <class T> static void dispose_pointer_vector(std::vector<T*> &vec)
- {
- for (typename std::vector<T*>::const_iterator iter = vec.begin();
- iter != vec.end();
- iter++)
- {
- delete *iter;
- }
-
- vec.clear();
- }
- template<typename T>
- static T
- fromString(const std::string& asString)
- {
- std::stringstream ss(asString);
- T retVal;
- ss >> retVal;
- return retVal;
- }
-
- template<typename T>
- static std::string
- toString(const T t)
- {
- std::stringstream ss;
- ss << t;
- return ss.str();
- }
-};
-
-#endif /* UTIL_H */