Merge lp:~glmark2-dev/glmark2/libmatrix-util into lp:glmark2/2011.11

Proposed by Jesse Barker
Status: Merged
Merged at revision: 193
Proposed branch: lp:~glmark2-dev/glmark2/libmatrix-util
Merge into: lp:glmark2/2011.11
Diff against target: 5238 lines (+2470/-1420)
40 files modified
android/jni/Android.mk (+1/-2)
android/jni/Android.ndk.mk (+1/-2)
src/android.cpp (+1/-0)
src/libmatrix/Makefile (+7/-2)
src/libmatrix/gl-if.h (+18/-0)
src/libmatrix/log.cc (+178/-0)
src/libmatrix/log.h (+46/-0)
src/libmatrix/mat.h (+138/-6)
src/libmatrix/matrix_inverse_test.cc (+0/-152)
src/libmatrix/program.cc (+5/-27)
src/libmatrix/program.h (+1/-4)
src/libmatrix/shader-source.cc (+615/-0)
src/libmatrix/shader-source.h (+103/-0)
src/libmatrix/test/basic-global-const.vert (+15/-0)
src/libmatrix/test/basic.frag (+7/-0)
src/libmatrix/test/basic.vert (+14/-0)
src/libmatrix/test/const_vec_test.cc (+60/-0)
src/libmatrix/test/const_vec_test.h (+39/-0)
src/libmatrix/test/inverse_test.cc (+172/-0)
src/libmatrix/test/inverse_test.h (+39/-0)
src/libmatrix/test/libmatrix_test.cc (+68/-0)
src/libmatrix/test/libmatrix_test.h (+51/-0)
src/libmatrix/test/options.cc (+76/-0)
src/libmatrix/test/shader_source_test.cc (+49/-0)
src/libmatrix/test/shader_source_test.h (+32/-0)
src/libmatrix/test/transpose_test.cc (+297/-0)
src/libmatrix/test/transpose_test.h (+38/-0)
src/libmatrix/util.cc (+165/-0)
src/libmatrix/util.h (+71/-0)
src/libmatrix/vec.h (+144/-6)
src/log.cpp (+0/-182)
src/log.h (+0/-43)
src/main.cpp (+9/-3)
src/options.cpp (+1/-2)
src/scene-effect-2d.cpp (+7/-4)
src/shader-source.cpp (+0/-625)
src/shader-source.h (+0/-113)
src/util.cpp (+0/-164)
src/util.h (+0/-81)
src/wscript_build (+2/-2)
To merge this branch: bzr merge lp:~glmark2-dev/glmark2/libmatrix-util
Reviewer Review Type Date Requested Status
Alexandros Frantzis Pending
Review via email: mp+90297@code.launchpad.net

Description of the change

libmatrix: Update version from current trunk. This brings some new operators on vectors and matrices, but also provides the Log, Util and ShaderSource objects previously defined in duplicate between glmark2 and glcompbench. This duplication is herein removed and references are updated to reflect the new versions.

To post a comment you must log in.
197. By Alexandros Frantzis

Android: Use all libmatrix source files when building it.

198. By Alexandros Frantzis

Main,Android,Options: Initialize the Log class explicitly after parsing the options.

This removes the coupling between the Log and Options classes, and keeps
Options::parse_args() free of side effects.

199. By Jesse Barker

Update local libmatrix to lp:libmatrix revno 34 to include some log fixes for Android

200. By Jesse Barker

Merge one more missing revision from lp:libmatrix found during glcompbench integration.
Remove obsolete matrix_inverse_test (all tests are now in test subdirectory).

201. By Jesse Barker

Update to reflect the addition of the appname string to the Log object in libmatrix.
Also, the Util object gets a member to generate the appname given the full path
of the program binary (argv[0]).

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'android/jni/Android.mk'
2--- android/jni/Android.mk 2012-01-19 18:13:38 +0000
3+++ android/jni/Android.mk 2012-01-27 22:08:04 +0000
4@@ -6,8 +6,7 @@
5 LOCAL_MODULE := libglmark2-matrix
6 LOCAL_CFLAGS := -DUSE_GLESv2
7 LOCAL_C_INCLUDES := $(LOCAL_PATH)/src
8-LOCAL_SRC_FILES := src/libmatrix/mat.cc \
9- src/libmatrix/program.cc
10+LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/libmatrix/*.cc))
11 LOCAL_SHARED_LIBRARIES := libdl libstlport
12
13 include external/stlport/libstlport.mk
14
15=== modified file 'android/jni/Android.ndk.mk'
16--- android/jni/Android.ndk.mk 2012-01-19 18:13:38 +0000
17+++ android/jni/Android.ndk.mk 2012-01-27 22:08:04 +0000
18@@ -6,8 +6,7 @@
19 LOCAL_MODULE := libglmark2-matrix
20 LOCAL_CFLAGS := -DUSE_GLESv2
21 LOCAL_C_INCLUDES := $(LOCAL_PATH)/src
22-LOCAL_SRC_FILES := src/libmatrix/mat.cc \
23- src/libmatrix/program.cc
24+LOCAL_SRC_FILES := $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/src/libmatrix/*.cc))
25
26 include $(BUILD_STATIC_LIBRARY)
27
28
29=== modified file 'src/android.cpp'
30--- src/android.cpp 2012-01-13 14:11:42 +0000
31+++ src/android.cpp 2012-01-27 22:08:04 +0000
32@@ -51,6 +51,7 @@
33 Java_org_linaro_glmark2_Glmark2Renderer_nativeInit(JNIEnv* env, jclass clazz,
34 jobject asset_manager)
35 {
36+ Log::init("glmark2", false);
37 Util::android_set_asset_manager(AAssetManager_fromJava(env, asset_manager));
38
39 g_canvas = new CanvasAndroid(100, 100);
40
41=== modified file 'src/libmatrix/Makefile'
42--- src/libmatrix/Makefile 2011-09-19 15:30:13 +0000
43+++ src/libmatrix/Makefile 2012-01-27 22:08:04 +0000
44@@ -1,6 +1,6 @@
45 CXXFLAGS = -Wall -Werror -pedantic -O3
46 LIBMATRIX = libmatrix.a
47-LIBSRCS = mat.cc program.cc
48+LIBSRCS = mat.cc program.cc log.cc util.cc shader-source.cc
49 LIBOBJS = $(LIBSRCS:.cc=.o)
50 TESTDIR = test
51 LIBMATRIX_TESTS = $(TESTDIR)/libmatrix_test
52@@ -8,6 +8,7 @@
53 $(TESTDIR)/const_vec_test.cc \
54 $(TESTDIR)/inverse_test.cc \
55 $(TESTDIR)/transpose_test.cc \
56+ $(TESTDIR)/shader_source_test.cc \
57 $(TESTDIR)/libmatrix_test.cc
58 TESTOBJS = $(TESTSRCS:.cc=.o)
59
60@@ -18,7 +19,10 @@
61 # Main library targets here.
62 mat.o : mat.cc mat.h vec.h
63 program.o: program.cc program.h mat.h vec.h
64-libmatrix.a : mat.o mat.h stack.h vec.h program.o program.h
65+log.o: log.cc log.h
66+util.o: util.cc util.h
67+shader-source.o: shader-source.cc shader-source.h mat.h vec.h
68+libmatrix.a : mat.o stack.h program.o log.o util.o shader-source.o
69 $(AR) -r $@ $(LIBOBJS)
70
71 # Tests and execution targets here.
72@@ -27,6 +31,7 @@
73 $(TESTDIR)/const_vec_test.o: $(TESTDIR)/const_vec_test.cc $(TESTDIR)/const_vec_test.h $(TESTDIR)/libmatrix_test.h vec.h
74 $(TESTDIR)/inverse_test.o: $(TESTDIR)/inverse_test.cc $(TESTDIR)/inverse_test.h $(TESTDIR)/libmatrix_test.h mat.h
75 $(TESTDIR)/transpose_test.o: $(TESTDIR)/transpose_test.cc $(TESTDIR)/transpose_test.h $(TESTDIR)/libmatrix_test.h mat.h
76+$(TESTDIR)/shader_source_test.o: $(TESTDIR)/shader_source_test.cc $(TESTDIR)/shader_source_test.h $(TESTDIR)/libmatrix_test.h shader-source.h
77 $(TESTDIR)/libmatrix_test: $(TESTOBJS) libmatrix.a
78 $(CXX) -o $@ $^
79 run_tests: $(LIBMATRIX_TESTS)
80
81=== added file 'src/libmatrix/gl-if.h'
82--- src/libmatrix/gl-if.h 1970-01-01 00:00:00 +0000
83+++ src/libmatrix/gl-if.h 2012-01-27 22:08:04 +0000
84@@ -0,0 +1,18 @@
85+//
86+// Copyright (c) 2012 Linaro Limited
87+//
88+// All rights reserved. This program and the accompanying materials
89+// are made available under the terms of the MIT License which accompanies
90+// this distribution, and is available at
91+// http://www.opensource.org/licenses/mit-license.php
92+//
93+// Contributors:
94+// Jesse Barker - original implementation.
95+//
96+#ifndef GL_IF_H_
97+#define GL_IF_H_
98+// Inclusion abstraction to provide project specific interface headers for
99+// whatever flavor of OpenGL(|ES) is appropriate. For core libmatrix, this
100+// is GLEW.
101+#include "gl-headers.h"
102+#endif // GL_IF_H_
103
104=== added file 'src/libmatrix/log.cc'
105--- src/libmatrix/log.cc 1970-01-01 00:00:00 +0000
106+++ src/libmatrix/log.cc 2012-01-27 22:08:04 +0000
107@@ -0,0 +1,178 @@
108+//
109+// Copyright (c) 2010-2012 Linaro Limited
110+//
111+// All rights reserved. This program and the accompanying materials
112+// are made available under the terms of the MIT License which accompanies
113+// this distribution, and is available at
114+// http://www.opensource.org/licenses/mit-license.php
115+//
116+// Contributors:
117+// Alexandros Frantzis <alexandros.frantzis@linaro.org>
118+// Jesse Barker <jesse.barker@linaro.org>
119+//
120+#include <cstdio>
121+#include <cstdarg>
122+#include <string>
123+#include <sstream>
124+#include <iostream>
125+#include "log.h"
126+
127+#ifdef ANDROID
128+#include <android/log.h>
129+#endif
130+
131+using std::string;
132+
133+const string Log::continuation_prefix("\x10");
134+string Log::appname_;
135+bool Log::do_debug_(false);
136+
137+#ifndef ANDROID
138+
139+static const string terminal_color_normal("\033[0m");
140+static const string terminal_color_red("\033[1;31m");
141+static const string terminal_color_cyan("\033[36m");
142+static const string terminal_color_yellow("\033[33m");
143+static const string empty;
144+
145+static void
146+print_prefixed_message(std::ostream& stream, const string& color, const string& prefix,
147+ const string& fmt, va_list ap)
148+{
149+ va_list aq;
150+
151+ /* Estimate message size */
152+ va_copy(aq, ap);
153+ int msg_size = vsnprintf(NULL, 0, fmt.c_str(), aq);
154+ va_end(aq);
155+
156+ /* Create the buffer to hold the message */
157+ char *buf = new char[msg_size + 1];
158+
159+ /* Store the message in the buffer */
160+ va_copy(aq, ap);
161+ vsnprintf(buf, msg_size + 1, fmt.c_str(), aq);
162+ va_end(aq);
163+
164+ /*
165+ * Print the message lines prefixed with the supplied prefix.
166+ * If the target stream is a terminal make the prefix colored.
167+ */
168+ string linePrefix;
169+ if (!prefix.empty())
170+ {
171+ static const string colon(": ");
172+ string start_color;
173+ string end_color;
174+ if (!color.empty())
175+ {
176+ start_color = color;
177+ end_color = terminal_color_normal;
178+ }
179+ linePrefix = start_color + prefix + end_color + colon;
180+ }
181+
182+ std::string line;
183+ std::stringstream ss(buf);
184+
185+ while(std::getline(ss, line)) {
186+ /*
187+ * If this line is a continuation of a previous log message
188+ * just print the line plainly.
189+ */
190+ if (line[0] == Log::continuation_prefix[0]) {
191+ stream << line.c_str() + 1;
192+ }
193+ else {
194+ /* Normal line, emit the prefix. */
195+ stream << linePrefix << line;
196+ }
197+
198+ /* Only emit a newline if the original message has it. */
199+ if (!(ss.rdstate() & std::stringstream::eofbit))
200+ stream << std::endl;
201+ }
202+
203+ delete[] buf;
204+}
205+
206+void
207+Log::info(const char *fmt, ...)
208+{
209+ static const string infoprefix("Info");
210+ static const string& infocolor(isatty(fileno(stdout)) ? terminal_color_cyan : empty);
211+ va_list ap;
212+ va_start(ap, fmt);
213+ if (do_debug_)
214+ print_prefixed_message(std::cout, infocolor, infoprefix, fmt, ap);
215+ else
216+ print_prefixed_message(std::cout, empty, empty, fmt, ap);
217+ va_end(ap);
218+}
219+
220+void
221+Log::debug(const char *fmt, ...)
222+{
223+ static const string dbgprefix("Debug");
224+ static const string& dbgcolor(isatty(fileno(stdout)) ? terminal_color_yellow : empty);
225+ if (!do_debug_)
226+ return;
227+ va_list ap;
228+ va_start(ap, fmt);
229+ print_prefixed_message(std::cout, dbgcolor, dbgprefix, fmt, ap);
230+ va_end(ap);
231+}
232+
233+void
234+Log::error(const char *fmt, ...)
235+{
236+ static const string errprefix("Error");
237+ static const string& errcolor(isatty(fileno(stderr)) ? terminal_color_red : empty);
238+ va_list ap;
239+ va_start(ap, fmt);
240+ print_prefixed_message(std::cerr, errcolor, errprefix, fmt, ap);
241+ va_end(ap);
242+}
243+
244+void
245+Log::flush()
246+{
247+ std::cout.flush();
248+ std::cerr.flush();
249+}
250+#else
251+void
252+Log::info(const char *fmt, ...)
253+{
254+ va_list ap;
255+ va_start(ap, fmt);
256+ __android_log_vprint(ANDROID_LOG_INFO, appname_.c_str(), fmt, ap);
257+ va_end(ap);
258+}
259+
260+void
261+Log::debug(const char *fmt, ...)
262+{
263+ if (!do_debug_)
264+ return;
265+ va_list ap;
266+ va_start(ap, fmt);
267+ __android_log_vprint(ANDROID_LOG_DEBUG, appname_.c_str(), fmt, ap);
268+ va_end(ap);
269+}
270+
271+void
272+Log::error(const char *fmt, ...)
273+{
274+ va_list ap;
275+ va_start(ap, fmt);
276+ __android_log_vprint(ANDROID_LOG_ERROR, appname_.c_str(), fmt, ap);
277+ va_end(ap);
278+}
279+
280+void
281+Log::flush()
282+{
283+}
284+
285+#endif
286
287=== added file 'src/libmatrix/log.h'
288--- src/libmatrix/log.h 1970-01-01 00:00:00 +0000
289+++ src/libmatrix/log.h 2012-01-27 22:08:04 +0000
290@@ -0,0 +1,46 @@
291+//
292+// Copyright (c) 2010-2012 Linaro Limited
293+//
294+// All rights reserved. This program and the accompanying materials
295+// are made available under the terms of the MIT License which accompanies
296+// this distribution, and is available at
297+// http://www.opensource.org/licenses/mit-license.php
298+//
299+// Contributors:
300+// Alexandros Frantzis <alexandros.frantzis@linaro.org>
301+// Jesse Barker <jesse.barker@linaro.org>
302+//
303+#ifndef LOG_H_
304+#define LOG_H_
305+
306+#include <string>
307+
308+class Log
309+{
310+public:
311+ static void init(const std::string& appname, bool do_debug = false)
312+ {
313+ appname_ = appname;
314+ do_debug_ = do_debug;
315+ }
316+ // Emit an informational message
317+ static void info(const char *fmt, ...);
318+ // Emit a debugging message
319+ static void debug(const char *fmt, ...);
320+ // Emit an error message
321+ static void error(const char *fmt, ...);
322+ // Explicit flush of the log buffer
323+ static void flush();
324+ // A prefix constant that informs the logging infrastructure that the log
325+ // message is a continuation of a previous log message to be put on the
326+ // same line.
327+ static const std::string continuation_prefix;
328+private:
329+ // A constant for identifying the log messages as originating from a
330+ // particular application.
331+ static std::string appname_;
332+ // Indicates whether debug level messages should generate any output
333+ static bool do_debug_;
334+};
335+
336+#endif /* LOG_H_ */
337
338=== modified file 'src/libmatrix/mat.h'
339--- src/libmatrix/mat.h 2011-09-19 15:30:13 +0000
340+++ src/libmatrix/mat.h 2012-01-27 22:08:04 +0000
341@@ -15,6 +15,11 @@
342 #include <iostream>
343 #include <iomanip>
344 #include "vec.h"
345+#ifndef USE_EXCEPTIONS
346+// If we're not throwing exceptions, we'll need the logger to make sure the
347+// caller is informed of errors.
348+#include "log.h"
349+#endif // USE_EXCEPTIONS
350
351 namespace LibMatrix
352 {
353@@ -46,6 +51,11 @@
354 // However, the internal data representation is column-major, so when using
355 // the raw data access member to treat the data as a singly-dimensioned array,
356 // it does not have to be transposed.
357+//
358+// A template class for creating, managing and operating on a 2x2 matrix
359+// of any type you like (intended for built-in types, but as long as it
360+// supports the basic arithmetic and assignment operators, any type should
361+// work).
362 template<typename T>
363 class tmat2
364 {
365@@ -70,6 +80,7 @@
366 }
367 ~tmat2() {}
368
369+ // Reset this to the identity matrix.
370 void setIdentity()
371 {
372 m_[0] = 1;
373@@ -78,6 +89,7 @@
374 m_[3] = 1;
375 }
376
377+ // Transpose this. Return a reference to this.
378 tmat2& transpose()
379 {
380 T tmp_val = m_[1];
381@@ -86,22 +98,30 @@
382 return *this;
383 }
384
385+ // Compute the determinant of this and return it.
386 T determinant()
387 {
388 return (m_[0] * m_[3]) - (m_[2] * m_[1]);
389 }
390
391+ // Invert this. Return a reference to this.
392+ //
393+ // NOTE: If this is non-invertible, we will
394+ // throw to avoid undefined behavior.
395 tmat2& inverse()
396 #ifdef USE_EXCEPTIONS
397 throw(std::runtime_error)
398-#endif
399+#endif // USE_EXCEPTIONS
400 {
401 T d(determinant());
402 if (d == static_cast<T>(0))
403 {
404 #ifdef USE_EXCEPTIONS
405 throw std::runtime_error("Matrix is noninvertible!!!!");
406-#endif
407+#else // !USE_EXCEPTIONS
408+ Log::error("Matrix is noninvertible!!!!\n");
409+ return *this;
410+#endif // USE_EXCEPTIONS
411 }
412 T c0r0(m_[3] / d);
413 T c0r1(-m_[1] / d);
414@@ -114,6 +134,8 @@
415 return *this;
416 }
417
418+ // Print the elements of the matrix to standard out.
419+ // Really only useful for debug and test.
420 void print() const
421 {
422 static const int precision(6);
423@@ -131,8 +153,12 @@
424 std::cout << " |" << std::endl;
425 }
426
427+ // Allow raw data access for API calls and the like.
428+ // For example, it is valid to pass a tmat2<float> into a call to
429+ // the OpenGL command "glUniformMatrix2fv()".
430 operator const T*() const { return &m_[0];}
431
432+ // Test if 'rhs' is equal to this.
433 bool operator==(const tmat2& rhs) const
434 {
435 return m_[0] == rhs.m_[0] &&
436@@ -141,11 +167,13 @@
437 m_[3] == rhs.m_[3];
438 }
439
440+ // Test if 'rhs' is not equal to this.
441 bool operator!=(const tmat2& rhs) const
442 {
443 return !(*this == rhs);
444 }
445
446+ // A direct assignment of 'rhs' to this. Return a reference to this.
447 tmat2& operator=(const tmat2& rhs)
448 {
449 if (this != &rhs)
450@@ -158,6 +186,7 @@
451 return *this;
452 }
453
454+ // Add another matrix to this. Return a reference to this.
455 tmat2& operator+=(const tmat2& rhs)
456 {
457 m_[0] += rhs.m_[0];
458@@ -167,11 +196,13 @@
459 return *this;
460 }
461
462+ // Add another matrix to a copy of this. Return the copy.
463 const tmat2 operator+(const tmat2& rhs)
464 {
465 return tmat2(*this) += rhs;
466 }
467
468+ // Subtract another matrix from this. Return a reference to this.
469 tmat2& operator-=(const tmat2& rhs)
470 {
471 m_[0] -= rhs.m_[0];
472@@ -181,11 +212,13 @@
473 return *this;
474 }
475
476+ // Subtract another matrix from a copy of this. Return the copy.
477 const tmat2 operator-(const tmat2& rhs)
478 {
479 return tmat2(*this) += rhs;
480 }
481
482+ // Multiply this by another matrix. Return a reference to this.
483 tmat2& operator*=(const tmat2& rhs)
484 {
485 T c0r0((m_[0] * rhs.m_[0]) + (m_[2] * rhs.m_[1]));
486@@ -199,11 +232,13 @@
487 return *this;
488 }
489
490+ // Multiply a copy of this by another matrix. Return the copy.
491 const tmat2 operator*(const tmat2& rhs)
492 {
493 return tmat2(*this) *= rhs;
494 }
495
496+ // Multiply this by a scalar. Return a reference to this.
497 tmat2& operator*=(const T& rhs)
498 {
499 m_[0] *= rhs;
500@@ -213,11 +248,13 @@
501 return *this;
502 }
503
504+ // Multiply a copy of this by a scalar. Return the copy.
505 const tmat2 operator*(const T& rhs)
506 {
507 return tmat2(*this) *= rhs;
508 }
509
510+ // Divide this by a scalar. Return a reference to this.
511 tmat2& operator/=(const T& rhs)
512 {
513 m_[0] /= rhs;
514@@ -227,11 +264,15 @@
515 return *this;
516 }
517
518+ // Divide a copy of this by a scalar. Return the copy.
519 const tmat2 operator/(const T& rhs)
520 {
521 return tmat2(*this) /= rhs;
522 }
523
524+ // Use an instance of the ArrayProxy class to support double-indexed
525+ // references to a matrix (i.e., m[1][1]). See comments above the
526+ // ArrayProxy definition for more details.
527 ArrayProxy<T, 2> operator[](int index)
528 {
529 return ArrayProxy<T, 2>(&m_[index]);
530@@ -245,12 +286,16 @@
531 T m_[4];
532 };
533
534+// Multiply a scalar and a matrix just like the member operator, but allow
535+// the scalar to be the left-hand operand.
536 template<typename T>
537 const tmat2<T> operator*(const T& lhs, const tmat2<T>& rhs)
538 {
539 return tmat2<T>(rhs) * lhs;
540 }
541
542+// Multiply a copy of a vector and a matrix (matrix is right-hand operand).
543+// Return the copy.
544 template<typename T>
545 const tvec2<T> operator*(const tvec2<T>& lhs, const tmat2<T>& rhs)
546 {
547@@ -259,6 +304,8 @@
548 return tvec2<T>(x,y);
549 }
550
551+// Multiply a copy of a vector and a matrix (matrix is left-hand operand).
552+// Return the copy.
553 template<typename T>
554 const tvec2<T> operator*(const tmat2<T>& lhs, const tvec2<T>& rhs)
555 {
556@@ -267,6 +314,7 @@
557 return tvec2<T>(x, y);
558 }
559
560+// Compute the outer product of two vectors. Return the resultant matrix.
561 template<typename T>
562 const tmat2<T> outer(const tvec2<T>& a, const tvec2<T>& b)
563 {
564@@ -278,6 +326,10 @@
565 return product;
566 }
567
568+// A template class for creating, managing and operating on a 3x3 matrix
569+// of any type you like (intended for built-in types, but as long as it
570+// supports the basic arithmetic and assignment operators, any type should
571+// work).
572 template<typename T>
573 class tmat3
574 {
575@@ -314,6 +366,7 @@
576 }
577 ~tmat3() {}
578
579+ // Reset this to the identity matrix.
580 void setIdentity()
581 {
582 m_[0] = 1;
583@@ -327,6 +380,7 @@
584 m_[8] = 1;
585 }
586
587+ // Transpose this. Return a reference to this.
588 tmat3& transpose()
589 {
590 T tmp_val = m_[1];
591@@ -341,6 +395,7 @@
592 return *this;
593 }
594
595+ // Compute the determinant of this and return it.
596 T determinant()
597 {
598 tmat2<T> minor0(m_[4], m_[5], m_[7], m_[8]);
599@@ -351,17 +406,24 @@
600 (m_[6] * minor6.determinant());
601 }
602
603+ // Invert this. Return a reference to this.
604+ //
605+ // NOTE: If this is non-invertible, we will
606+ // throw to avoid undefined behavior.
607 tmat3& inverse()
608 #ifdef USE_EXCEPTIONS
609 throw(std::runtime_error)
610-#endif
611+#endif // USE_EXCEPTIONS
612 {
613 T d(determinant());
614 if (d == static_cast<T>(0))
615 {
616 #ifdef USE_EXCEPTIONS
617 throw std::runtime_error("Matrix is noninvertible!!!!");
618-#endif
619+#else // !USE_EXCEPTIONS
620+ Log::error("Matrix is noninvertible!!!!\n");
621+ return *this;
622+#endif // USE_EXCEPTIONS
623 }
624 tmat2<T> minor0(m_[4], m_[5], m_[7], m_[8]);
625 tmat2<T> minor1(m_[7], m_[8], m_[1], m_[2]);
626@@ -384,6 +446,8 @@
627 return *this;
628 }
629
630+ // Print the elements of the matrix to standard out.
631+ // Really only useful for debug and test.
632 void print() const
633 {
634 static const int precision(6);
635@@ -413,8 +477,12 @@
636 std::cout << " |" << std::endl;
637 }
638
639+ // Allow raw data access for API calls and the like.
640+ // For example, it is valid to pass a tmat3<float> into a call to
641+ // the OpenGL command "glUniformMatrix3fv()".
642 operator const T*() const { return &m_[0];}
643
644+ // Test if 'rhs' is equal to this.
645 bool operator==(const tmat3& rhs) const
646 {
647 return m_[0] == rhs.m_[0] &&
648@@ -428,11 +496,13 @@
649 m_[8] == rhs.m_[8];
650 }
651
652+ // Test if 'rhs' is not equal to this.
653 bool operator!=(const tmat3& rhs) const
654 {
655 return !(*this == rhs);
656 }
657
658+ // A direct assignment of 'rhs' to this. Return a reference to this.
659 tmat3& operator=(const tmat3& rhs)
660 {
661 if (this != &rhs)
662@@ -450,6 +520,7 @@
663 return *this;
664 }
665
666+ // Add another matrix to this. Return a reference to this.
667 tmat3& operator+=(const tmat3& rhs)
668 {
669 m_[0] += rhs.m_[0];
670@@ -464,11 +535,13 @@
671 return *this;
672 }
673
674+ // Add another matrix to a copy of this. Return the copy.
675 const tmat3 operator+(const tmat3& rhs)
676 {
677 return tmat3(*this) += rhs;
678 }
679
680+ // Subtract another matrix from this. Return a reference to this.
681 tmat3& operator-=(const tmat3& rhs)
682 {
683 m_[0] -= rhs.m_[0];
684@@ -483,11 +556,13 @@
685 return *this;
686 }
687
688+ // Subtract another matrix from a copy of this. Return the copy.
689 const tmat3 operator-(const tmat3& rhs)
690 {
691 return tmat3(*this) -= rhs;
692 }
693
694+ // Multiply this by another matrix. Return a reference to this.
695 tmat3& operator*=(const tmat3& rhs)
696 {
697 T c0r0((m_[0] * rhs.m_[0]) + (m_[3] * rhs.m_[1]) + (m_[6] * rhs.m_[2]));
698@@ -511,11 +586,13 @@
699 return *this;
700 }
701
702+ // Multiply a copy of this by another matrix. Return the copy.
703 const tmat3 operator*(const tmat3& rhs)
704 {
705 return tmat3(*this) *= rhs;
706 }
707
708+ // Multiply this by a scalar. Return a reference to this.
709 tmat3& operator*=(const T& rhs)
710 {
711 m_[0] *= rhs;
712@@ -530,11 +607,13 @@
713 return *this;
714 }
715
716+ // Multiply a copy of this by a scalar. Return the copy.
717 const tmat3 operator*(const T& rhs)
718 {
719 return tmat3(*this) *= rhs;
720 }
721
722+ // Divide this by a scalar. Return a reference to this.
723 tmat3& operator/=(const T& rhs)
724 {
725 m_[0] /= rhs;
726@@ -549,11 +628,15 @@
727 return *this;
728 }
729
730+ // Divide a copy of this by a scalar. Return the copy.
731 const tmat3 operator/(const T& rhs)
732 {
733 return tmat3(*this) /= rhs;
734 }
735
736+ // Use an instance of the ArrayProxy class to support double-indexed
737+ // references to a matrix (i.e., m[1][1]). See comments above the
738+ // ArrayProxy definition for more details.
739 ArrayProxy<T, 3> operator[](int index)
740 {
741 return ArrayProxy<T, 3>(&m_[index]);
742@@ -567,12 +650,16 @@
743 T m_[9];
744 };
745
746+// Multiply a scalar and a matrix just like the member operator, but allow
747+// the scalar to be the left-hand operand.
748 template<typename T>
749 const tmat3<T> operator*(const T& lhs, const tmat3<T>& rhs)
750 {
751 return tmat3<T>(rhs) * lhs;
752 }
753
754+// Multiply a copy of a vector and a matrix (matrix is right-hand operand).
755+// Return the copy.
756 template<typename T>
757 const tvec3<T> operator*(const tvec3<T>& lhs, const tmat3<T>& rhs)
758 {
759@@ -582,6 +669,8 @@
760 return tvec3<T>(x, y, z);
761 }
762
763+// Multiply a copy of a vector and a matrix (matrix is left-hand operand).
764+// Return the copy.
765 template<typename T>
766 const tvec3<T> operator*(const tmat3<T>& lhs, const tvec3<T>& rhs)
767 {
768@@ -591,6 +680,7 @@
769 return tvec3<T>(x, y, z);
770 }
771
772+// Compute the outer product of two vectors. Return the resultant matrix.
773 template<typename T>
774 const tmat3<T> outer(const tvec3<T>& a, const tvec3<T>& b)
775 {
776@@ -607,6 +697,10 @@
777 return product;
778 }
779
780+// A template class for creating, managing and operating on a 4x4 matrix
781+// of any type you like (intended for built-in types, but as long as it
782+// supports the basic arithmetic and assignment operators, any type should
783+// work).
784 template<typename T>
785 class tmat4
786 {
787@@ -636,6 +730,7 @@
788 }
789 ~tmat4() {}
790
791+ // Reset this to the identity matrix.
792 void setIdentity()
793 {
794 m_[0] = 1;
795@@ -656,6 +751,7 @@
796 m_[15] = 1;
797 }
798
799+ // Transpose this. Return a reference to this.
800 tmat4& transpose()
801 {
802 T tmp_val = m_[1];
803@@ -679,6 +775,7 @@
804 return *this;
805 }
806
807+ // Compute the determinant of this and return it.
808 T determinant()
809 {
810 tmat3<T> minor0(m_[5], m_[6], m_[7], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]);
811@@ -691,17 +788,24 @@
812 (m_[12] * minor12.determinant());
813 }
814
815+ // Invert this. Return a reference to this.
816+ //
817+ // NOTE: If this is non-invertible, we will
818+ // throw to avoid undefined behavior.
819 tmat4& inverse()
820 #ifdef USE_EXCEPTIONS
821 throw(std::runtime_error)
822-#endif
823+#endif // USE_EXCEPTIONS
824 {
825 T d(determinant());
826 if (d == static_cast<T>(0))
827 {
828 #ifdef USE_EXCEPTIONS
829 throw std::runtime_error("Matrix is noninvertible!!!!");
830-#endif
831+#else // !USE_EXCEPTIONS
832+ Log::error("Matrix is noninvertible!!!!\n");
833+ return *this;
834+#endif // USE_EXCEPTIONS
835 }
836 tmat3<T> minor0(m_[5], m_[6], m_[7], m_[9], m_[10], m_[11], m_[13], m_[14], m_[15]);
837 tmat3<T> minor1(m_[1], m_[2], m_[3], m_[13], m_[14], m_[15], m_[9], m_[10], m_[11]);
838@@ -741,6 +845,8 @@
839 return *this;
840 }
841
842+ // Print the elements of the matrix to standard out.
843+ // Really only useful for debug and test.
844 void print() const
845 {
846 static const int precision(6);
847@@ -786,8 +892,12 @@
848 std::cout << " |" << std::endl;
849 }
850
851+ // Allow raw data access for API calls and the like.
852+ // For example, it is valid to pass a tmat4<float> into a call to
853+ // the OpenGL command "glUniformMatrix4fv()".
854 operator const T*() const { return &m_[0];}
855
856+ // Test if 'rhs' is equal to this.
857 bool operator==(const tmat4& rhs) const
858 {
859 return m_[0] == rhs.m_[0] &&
860@@ -808,11 +918,13 @@
861 m_[15] == rhs.m_[15];
862 }
863
864+ // Test if 'rhs' is not equal to this.
865 bool operator!=(const tmat4& rhs) const
866 {
867 return !(*this == rhs);
868 }
869
870+ // A direct assignment of 'rhs' to this. Return a reference to this.
871 tmat4& operator=(const tmat4& rhs)
872 {
873 if (this != &rhs)
874@@ -837,6 +949,7 @@
875 return *this;
876 }
877
878+ // Add another matrix to this. Return a reference to this.
879 tmat4& operator+=(const tmat4& rhs)
880 {
881 m_[0] += rhs.m_[0];
882@@ -858,11 +971,13 @@
883 return *this;
884 }
885
886+ // Add another matrix to a copy of this. Return the copy.
887 const tmat4 operator+(const tmat4& rhs)
888 {
889 return tmat4(*this) += rhs;
890 }
891
892+ // Subtract another matrix from this. Return a reference to this.
893 tmat4& operator-=(const tmat4& rhs)
894 {
895 m_[0] -= rhs.m_[0];
896@@ -884,11 +999,13 @@
897 return *this;
898 }
899
900+ // Subtract another matrix from a copy of this. Return the copy.
901 const tmat4 operator-(const tmat4& rhs)
902 {
903 return tmat4(*this) -= rhs;
904 }
905
906+ // Multiply this by another matrix. Return a reference to this.
907 tmat4& operator*=(const tmat4& rhs)
908 {
909 T c0r0((m_[0] * rhs.m_[0]) + (m_[4] * rhs.m_[1]) + (m_[8] * rhs.m_[2]) + (m_[12] * rhs.m_[3]));
910@@ -926,11 +1043,13 @@
911 return *this;
912 }
913
914+ // Multiply a copy of this by another matrix. Return the copy.
915 const tmat4 operator*(const tmat4& rhs)
916 {
917 return tmat4(*this) *= rhs;
918 }
919
920+ // Multiply this by a scalar. Return a reference to this.
921 tmat4& operator*=(const T& rhs)
922 {
923 m_[0] *= rhs;
924@@ -952,11 +1071,13 @@
925 return *this;
926 }
927
928+ // Multiply a copy of this by a scalar. Return the copy.
929 const tmat4 operator*(const T& rhs)
930 {
931 return tmat4(*this) *= rhs;
932 }
933
934+ // Divide this by a scalar. Return a reference to this.
935 tmat4& operator/=(const T& rhs)
936 {
937 m_[0] /= rhs;
938@@ -978,11 +1099,15 @@
939 return *this;
940 }
941
942+ // Divide a copy of this by a scalar. Return the copy.
943 const tmat4 operator/(const T& rhs)
944 {
945 return tmat4(*this) /= rhs;
946 }
947
948+ // Use an instance of the ArrayProxy class to support double-indexed
949+ // references to a matrix (i.e., m[1][1]). See comments above the
950+ // ArrayProxy definition for more details.
951 ArrayProxy<T, 4> operator[](int index)
952 {
953 return ArrayProxy<T, 4>(&m_[index]);
954@@ -996,12 +1121,16 @@
955 T m_[16];
956 };
957
958+// Multiply a scalar and a matrix just like the member operator, but allow
959+// the scalar to be the left-hand operand.
960 template<typename T>
961 const tmat4<T> operator*(const T& lhs, const tmat4<T>& rhs)
962 {
963 return tmat4<T>(rhs) * lhs;
964 }
965
966+// Multiply a copy of a vector and a matrix (matrix is right-hand operand).
967+// Return the copy.
968 template<typename T>
969 const tvec4<T> operator*(const tvec4<T>& lhs, const tmat4<T>& rhs)
970 {
971@@ -1012,6 +1141,8 @@
972 return tvec4<T>(x, y, z, w);
973 }
974
975+// Multiply a copy of a vector and a matrix (matrix is left-hand operand).
976+// Return the copy.
977 template<typename T>
978 const tvec4<T> operator*(const tmat4<T>& lhs, const tvec4<T>& rhs)
979 {
980@@ -1022,6 +1153,7 @@
981 return tvec4<T>(x, y, z, w);
982 }
983
984+// Compute the outer product of two vectors. Return the resultant matrix.
985 template<typename T>
986 const tmat4<T> outer(const tvec4<T>& a, const tvec4<T>& b)
987 {
988
989=== removed file 'src/libmatrix/matrix_inverse_test.cc'
990--- src/libmatrix/matrix_inverse_test.cc 2011-06-17 07:54:50 +0000
991+++ src/libmatrix/matrix_inverse_test.cc 1970-01-01 00:00:00 +0000
992@@ -1,152 +0,0 @@
993-//
994-// Copyright (c) 2010 Linaro Limited
995-//
996-// All rights reserved. This program and the accompanying materials
997-// are made available under the terms of the MIT License which accompanies
998-// this distribution, and is available at
999-// http://www.opensource.org/licenses/mit-license.php
1000-//
1001-// Contributors:
1002-// Jesse Barker - original implementation.
1003-//
1004-#include <iostream>
1005-#include "mat.h"
1006-
1007-using LibMatrix::mat4;
1008-using LibMatrix::mat3;
1009-using LibMatrix::mat2;
1010-using std::cerr;
1011-using std::cout;
1012-using std::endl;
1013-
1014-bool mat2OK()
1015-{
1016- mat2 m;
1017- cout << "Starting with mat2 (should be identity): " << endl << endl;
1018- m.print();
1019-
1020- m[0][1] = -2.5;
1021-
1022- cout << endl << "Matrix should now have (0, 1) == -2.500000" << endl << endl;
1023- m.print();
1024-
1025- mat2 mi(m);
1026-
1027- cout << endl << "Copy of previous matrix (should have (0, 1) == -2.500000)" << endl << endl;
1028- mi.print();
1029-
1030- mi.inverse();
1031-
1032- cout << endl << "Inverse of copy: " << endl << endl;
1033- mi.print();
1034-
1035- mat2 i = m * mi;
1036-
1037- cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
1038- i.print();
1039-
1040- mat2 ident;
1041- if (i != ident)
1042- {
1043- return false;
1044- }
1045-
1046- return true;
1047-}
1048-
1049-bool mat3OK()
1050-{
1051- mat3 m;
1052- cout << "Starting with mat3 (should be identity): " << endl << endl;
1053- m.print();
1054-
1055- m[1][2] = -2.5;
1056-
1057- cout << endl << "Matrix should now have (1, 2) == -2.500000" << endl << endl;
1058- m.print();
1059-
1060- mat3 mi(m);
1061-
1062- cout << endl << "Copy of previous matrix (should have (1, 2) == -2.500000)" << endl << endl;
1063- mi.print();
1064-
1065- mi.inverse();
1066-
1067- cout << endl << "Inverse of copy: " << endl << endl;
1068- mi.print();
1069-
1070- mat3 i = m * mi;
1071-
1072- cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
1073- i.print();
1074-
1075- mat3 ident;
1076- if (i != ident)
1077- {
1078- return false;
1079- }
1080-
1081- return true;
1082-}
1083-
1084-bool mat4OK()
1085-{
1086- mat4 m;
1087- cout << "Starting with mat4 (should be identity): " << endl << endl;
1088- m.print();
1089-
1090- m[2][3] = -2.5;
1091-
1092- cout << endl << "Matrix should now have (2, 3) == -2.500000" << endl << endl;
1093- m.print();
1094-
1095- mat4 mi(m);
1096-
1097- cout << endl << "Copy of previous matrix (should have (2, 3) == -2.500000)" << endl << endl;
1098- mi.print();
1099-
1100- mi.inverse();
1101-
1102- cout << endl << "Inverse of copy: " << endl << endl;
1103- mi.print();
1104-
1105- mat4 i = m * mi;
1106-
1107- cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
1108- i.print();
1109-
1110- mat4 ident;
1111- if (i != ident)
1112- {
1113- return false;
1114- }
1115-
1116- return true;
1117-}
1118-
1119-int
1120-main(int argc, char** argv)
1121-{
1122- if (!mat2OK())
1123- {
1124- cerr << "mat2::inverse() does not work!" << endl;
1125- return 1;
1126- }
1127- cout << "mat2::inverse() is okay!" << endl << endl;
1128-
1129- if (!mat3OK())
1130- {
1131- cerr << "mat3::inverse() does not work!" << endl;
1132- return 1;
1133- }
1134- cout << "mat3::inverse() is okay!" << endl << endl;
1135-
1136- if (!mat4OK())
1137- {
1138- cerr << "mat4::inverse() does not work!" << endl;
1139- return 1;
1140- }
1141- cout << "mat4::inverse() is okay!" << endl << endl;
1142-
1143- return 0;
1144-}
1145
1146=== modified file 'src/libmatrix/program.cc'
1147--- src/libmatrix/program.cc 2011-08-31 21:22:27 +0000
1148+++ src/libmatrix/program.cc 2012-01-27 22:08:04 +0000
1149@@ -1,5 +1,5 @@
1150 //
1151-// Copyright (c) 2011 Linaro Limited
1152+// Copyright (c) 2011-2012 Linaro Limited
1153 //
1154 // All rights reserved. This program and the accompanying materials
1155 // are made available under the terms of the MIT License which accompanies
1156@@ -14,8 +14,7 @@
1157 #include <sstream>
1158 #include <fstream>
1159 #include <iostream>
1160-
1161-#include "gl-headers.h"
1162+#include "gl-if.h"
1163 #include "program.h"
1164
1165 using std::string;
1166@@ -24,27 +23,6 @@
1167 using LibMatrix::vec3;
1168 using LibMatrix::vec4;
1169
1170-bool
1171-gotSource(const string& filename, string& source)
1172-{
1173- using std::ifstream;
1174- ifstream inputFile(filename.c_str());
1175- if (!inputFile)
1176- {
1177- std::cerr << "Failed to open \"" << filename << "\"" << std::endl;
1178- return false;
1179- }
1180-
1181- string curLine;
1182- while (getline(inputFile, curLine))
1183- {
1184- source += curLine;
1185- source += '\n';
1186- }
1187-
1188- return true;
1189-}
1190-
1191 Shader::Shader(unsigned int type, const string& source) :
1192 handle_(0),
1193 type_(type),
1194@@ -59,7 +37,7 @@
1195 message_ = string("Failed to create the new shader.");
1196 return;
1197 }
1198- const char* shaderSource = source_.c_str();
1199+ const GLchar* shaderSource = source_.c_str();
1200 glShaderSource(handle_, 1, &shaderSource, NULL);
1201 GLint param = 0;
1202 glGetShaderiv(handle_, GL_SHADER_SOURCE_LENGTH, &param);
1203@@ -95,7 +73,7 @@
1204 if (param == GL_FALSE)
1205 {
1206 glGetShaderiv(handle_, GL_INFO_LOG_LENGTH, &param);
1207- char* infoLog = new char[param + 1];
1208+ GLchar* infoLog = new GLchar[param + 1];
1209 glGetShaderInfoLog(handle_, param + 1, NULL, infoLog);
1210 message_ = infoLog;
1211 delete [] infoLog;
1212@@ -235,7 +213,7 @@
1213 if (param == GL_FALSE)
1214 {
1215 glGetProgramiv(handle_, GL_INFO_LOG_LENGTH, &param);
1216- char* infoLog = new char[param + 1];
1217+ GLchar* infoLog = new GLchar[param + 1];
1218 glGetProgramInfoLog(handle_, param + 1, NULL, infoLog);
1219 message_ = infoLog;
1220 delete [] infoLog;
1221
1222=== modified file 'src/libmatrix/program.h'
1223--- src/libmatrix/program.h 2011-08-31 21:22:27 +0000
1224+++ src/libmatrix/program.h 2012-01-27 22:08:04 +0000
1225@@ -1,5 +1,5 @@
1226 //
1227-// Copyright (c) 2011 Linaro Limited
1228+// Copyright (c) 2011-2012 Linaro Limited
1229 //
1230 // All rights reserved. This program and the accompanying materials
1231 // are made available under the terms of the MIT License which accompanies
1232@@ -161,7 +161,4 @@
1233 bool valid_;
1234 };
1235
1236-// Handy utility for extracting shader source from a named file
1237-bool gotSource(const std::string& filename, std::string& sourceOut);
1238-
1239 #endif // PROGRAM_H_
1240
1241=== added file 'src/libmatrix/shader-source.cc'
1242--- src/libmatrix/shader-source.cc 1970-01-01 00:00:00 +0000
1243+++ src/libmatrix/shader-source.cc 2012-01-27 22:08:04 +0000
1244@@ -0,0 +1,615 @@
1245+//
1246+// Copyright (c) 2010-2012 Linaro Limited
1247+//
1248+// All rights reserved. This program and the accompanying materials
1249+// are made available under the terms of the MIT License which accompanies
1250+// this distribution, and is available at
1251+// http://www.opensource.org/licenses/mit-license.php
1252+//
1253+// Contributors:
1254+// Alexandros Frantzis <alexandros.frantzis@linaro.org>
1255+// Jesse Barker <jesse.barker@linaro.org>
1256+//
1257+#include <istream>
1258+#include <memory>
1259+
1260+#include "shader-source.h"
1261+#include "log.h"
1262+#include "vec.h"
1263+#include "util.h"
1264+
1265+/**
1266+ * Holds default precision values for all shader types
1267+ * (even the unknown type, which is hardwired to default precision values)
1268+ */
1269+std::vector<ShaderSource::Precision>
1270+ShaderSource::default_precision_(ShaderSource::ShaderTypeUnknown + 1);
1271+
1272+/**
1273+ * Loads the contents of a file into a string.
1274+ *
1275+ * @param filename the name of the file
1276+ * @param str the string to put the contents of the file into
1277+ */
1278+bool
1279+ShaderSource::load_file(const std::string& filename, std::string& str)
1280+{
1281+ std::auto_ptr<std::istream> is_ptr(Util::get_resource(filename));
1282+ std::istream& inputFile(*is_ptr);
1283+
1284+ if (!inputFile)
1285+ {
1286+ Log::error("Failed to open \"%s\"\n", filename.c_str());
1287+ return false;
1288+ }
1289+
1290+ std::string curLine;
1291+ while (getline(inputFile, curLine))
1292+ {
1293+ str += curLine;
1294+ str += '\n';
1295+ }
1296+
1297+ return true;
1298+}
1299+
1300+
1301+/**
1302+ * Appends a string to the shader source.
1303+ *
1304+ * @param str the string to append
1305+ */
1306+void
1307+ShaderSource::append(const std::string &str)
1308+{
1309+ source_ << str;
1310+}
1311+
1312+/**
1313+ * Appends the contents of a file to the shader source.
1314+ *
1315+ * @param filename the name of the file to append
1316+ */
1317+void
1318+ShaderSource::append_file(const std::string &filename)
1319+{
1320+ std::string source;
1321+ if (load_file(filename, source))
1322+ source_ << source;
1323+}
1324+
1325+/**
1326+ * Replaces a string in the source with another string.
1327+ *
1328+ * @param remove the string to replace
1329+ * @param insert the string to replace with
1330+ */
1331+void
1332+ShaderSource::replace(const std::string &remove, const std::string &insert)
1333+{
1334+ std::string::size_type pos = 0;
1335+ std::string str(source_.str());
1336+
1337+ while ((pos = str.find(remove, pos)) != std::string::npos) {
1338+ str.replace(pos, remove.size(), insert);
1339+ pos++;
1340+ }
1341+
1342+ source_.clear();
1343+ source_.str(str);
1344+}
1345+
1346+/**
1347+ * Replaces a string in the source with the contents of a file.
1348+ *
1349+ * @param remove the string to replace
1350+ * @param filename the name of the file to read from
1351+ */
1352+void
1353+ShaderSource::replace_with_file(const std::string &remove, const std::string &filename)
1354+{
1355+ std::string source;
1356+ if (load_file(filename, source))
1357+ replace(remove, source);
1358+}
1359+
1360+/**
1361+ * Adds a string (usually containing a constant definition) at
1362+ * global (per shader) scope.
1363+ *
1364+ * The string is placed after any default precision qualifiers.
1365+ *
1366+ * @param str the string to add
1367+ */
1368+void
1369+ShaderSource::add_global(const std::string &str)
1370+{
1371+ std::string::size_type pos = 0;
1372+ std::string source(source_.str());
1373+
1374+ /* Find the last precision qualifier */
1375+ pos = source.rfind("precision");
1376+
1377+ if (pos != std::string::npos) {
1378+ /*
1379+ * Find the next #endif line of a preprocessor block that contains
1380+ * the precision qualifier.
1381+ */
1382+ std::string::size_type pos_if = source.find("#if", pos);
1383+ std::string::size_type pos_endif = source.find("#endif", pos);
1384+
1385+ if (pos_endif != std::string::npos && pos_endif < pos_if)
1386+ pos = pos_endif;
1387+
1388+ /* Go to the next line */
1389+ pos = source.find("\n", pos);
1390+ if (pos != std::string::npos)
1391+ pos++;
1392+ }
1393+ else
1394+ pos = 0;
1395+
1396+ source.insert(pos, str);
1397+
1398+ source_.clear();
1399+ source_.str(source);
1400+}
1401+
1402+/**
1403+ * Adds a string (usually containing a constant definition) at
1404+ * global (per shader) scope.
1405+ *
1406+ * The string is placed after any default precision qualifiers.
1407+ *
1408+ * @param function the function to add the string into
1409+ * @param str the string to add
1410+ */
1411+void
1412+ShaderSource::add_local(const std::string &str, const std::string &function)
1413+{
1414+ std::string::size_type pos = 0;
1415+ std::string source(source_.str());
1416+
1417+ /* Find the function */
1418+ pos = source.find(function);
1419+ pos = source.find('{', pos);
1420+
1421+ /* Go to the next line */
1422+ pos = source.find("\n", pos);
1423+ if (pos != std::string::npos)
1424+ pos++;
1425+
1426+ source.insert(pos, str);
1427+
1428+ source_.clear();
1429+ source_.str(source);
1430+}
1431+
1432+/**
1433+ * Adds a string (usually containing a constant definition) to a shader source
1434+ *
1435+ * If the function parameter is empty, the string will be added to global
1436+ * scope, after any precision definitions.
1437+ *
1438+ * @param str the string to add
1439+ * @param function if not empty, the function to add the string into
1440+ */
1441+void
1442+ShaderSource::add(const std::string &str, const std::string &function)
1443+{
1444+ if (!function.empty())
1445+ add_local(str, function);
1446+ else
1447+ add_global(str);
1448+}
1449+
1450+/**
1451+ * Adds a float constant definition.
1452+ *
1453+ * @param name the name of the constant
1454+ * @param f the value of the constant
1455+ * @param function if not empty, the function to put the definition in
1456+ */
1457+void
1458+ShaderSource::add_const(const std::string &name, float f,
1459+ const std::string &function)
1460+{
1461+ std::stringstream ss;
1462+
1463+ ss << "const float " << name << " = " << std::fixed << f << ";" << std::endl;
1464+
1465+ add(ss.str(), function);
1466+}
1467+
1468+/**
1469+ * Adds a float array constant definition.
1470+ *
1471+ * Note that various GLSL versions (including ES) don't support
1472+ * array constants.
1473+ *
1474+ * @param name the name of the constant
1475+ * @param v the value of the constant
1476+ * @param function if not empty, the function to put the definition in
1477+ */
1478+void
1479+ShaderSource::add_const(const std::string &name, std::vector<float> &array,
1480+ const std::string &function)
1481+{
1482+ std::stringstream ss;
1483+
1484+ ss << "const float " << name << "[" << array.size() << "] = {" << std::fixed;
1485+ for(std::vector<float>::const_iterator iter = array.begin();
1486+ iter != array.end();
1487+ iter++)
1488+ {
1489+ ss << *iter;
1490+ if (iter + 1 != array.end())
1491+ ss << ", " << std::endl;
1492+ }
1493+
1494+ ss << "};" << std::endl;
1495+
1496+ add(ss.str(), function);
1497+}
1498+
1499+/**
1500+ * Adds a vec2 constant definition.
1501+ *
1502+ * @param name the name of the constant
1503+ * @param v the value of the constant
1504+ * @param function if not empty, the function to put the definition in
1505+ */
1506+void
1507+ShaderSource::add_const(const std::string &name, const LibMatrix::vec2 &v,
1508+ const std::string &function)
1509+{
1510+ std::stringstream ss;
1511+
1512+ ss << "const vec2 " << name << " = vec2(" << std::fixed;
1513+ ss << v.x() << ", " << v.y() << ");" << std::endl;
1514+
1515+ add(ss.str(), function);
1516+}
1517+
1518+/**
1519+ * Adds a vec3 constant definition.
1520+ *
1521+ * @param name the name of the constant
1522+ * @param v the value of the constant
1523+ * @param function if not empty, the function to put the definition in
1524+ */
1525+void
1526+ShaderSource::add_const(const std::string &name, const LibMatrix::vec3 &v,
1527+ const std::string &function)
1528+{
1529+ std::stringstream ss;
1530+
1531+ ss << "const vec3 " << name << " = vec3(" << std::fixed;
1532+ ss << v.x() << ", " << v.y() << ", " << v.z() << ");" << std::endl;
1533+
1534+ add(ss.str(), function);
1535+}
1536+
1537+/**
1538+ * Adds a vec4 constant definition.
1539+ *
1540+ * @param name the name of the constant
1541+ * @param v the value of the constant
1542+ * @param function if not empty, the function to put the definition in
1543+ */
1544+void
1545+ShaderSource::add_const(const std::string &name, const LibMatrix::vec4 &v,
1546+ const std::string &function)
1547+{
1548+ std::stringstream ss;
1549+
1550+ ss << "const vec4 " << name << " = vec4(" << std::fixed;
1551+ ss << v.x() << ", " << v.y() << ", " << v.z() << ", " << v.w() << ");" << std::endl;
1552+
1553+ add(ss.str(), function);
1554+}
1555+
1556+/**
1557+ * Adds a mat3 constant definition.
1558+ *
1559+ * @param name the name of the constant
1560+ * @param v the value of the constant
1561+ * @param function if not empty, the function to put the definition in
1562+ */
1563+void
1564+ShaderSource::add_const(const std::string &name, const LibMatrix::mat3 &m,
1565+ const std::string &function)
1566+{
1567+ std::stringstream ss;
1568+
1569+ ss << "const mat3 " << name << " = mat3(" << std::fixed;
1570+ ss << m[0][0] << ", " << m[1][0] << ", " << m[2][0] << "," << std::endl;
1571+ ss << m[0][1] << ", " << m[1][1] << ", " << m[2][1] << "," << std::endl;
1572+ ss << m[0][2] << ", " << m[1][2] << ", " << m[2][2] << std::endl;
1573+ ss << ");" << std::endl;
1574+
1575+ add(ss.str(), function);
1576+}
1577+
1578+/**
1579+ * Adds a float array declaration and initialization.
1580+ *
1581+ * @param name the name of the array
1582+ * @param array the array values
1583+ * @param init_function the function to put the initialization in
1584+ * @param decl_function if not empty, the function to put the declaration in
1585+ */
1586+void
1587+ShaderSource::add_array(const std::string &name, std::vector<float> &array,
1588+ const std::string &init_function,
1589+ const std::string &decl_function)
1590+{
1591+ if (init_function.empty() || name.empty())
1592+ return;
1593+
1594+ std::stringstream ss;
1595+ ss << "float " << name << "[" << array.size() << "];" << std::endl;
1596+
1597+ std::string decl(ss.str());
1598+
1599+ ss.clear();
1600+ ss.str("");
1601+ ss << std::fixed;
1602+
1603+ for(std::vector<float>::const_iterator iter = array.begin();
1604+ iter != array.end();
1605+ iter++)
1606+ {
1607+ ss << name << "[" << iter - array.begin() << "] = " << *iter << ";" << std::endl;
1608+ }
1609+
1610+ add(ss.str(), init_function);
1611+
1612+ add(decl, decl_function);
1613+}
1614+
1615+/**
1616+ * Gets the ShaderType for this ShaderSource.
1617+ *
1618+ * If the ShaderType is unknown, an attempt is made to infer
1619+ * the type from the shader source contents.
1620+ *
1621+ * @return the ShaderType
1622+ */
1623+ShaderSource::ShaderType
1624+ShaderSource::type()
1625+{
1626+ /* Try to infer the type from the source contents */
1627+ if (type_ == ShaderSource::ShaderTypeUnknown) {
1628+ std::string source(source_.str());
1629+
1630+ if (source.find("gl_FragColor") != std::string::npos)
1631+ type_ = ShaderSource::ShaderTypeFragment;
1632+ else if (source.find("gl_Position") != std::string::npos)
1633+ type_ = ShaderSource::ShaderTypeVertex;
1634+ else
1635+ Log::debug("Cannot infer shader type from contents. Leaving it Unknown.\n");
1636+ }
1637+
1638+ return type_;
1639+}
1640+
1641+/**
1642+ * Helper function that emits a precision statement.
1643+ *
1644+ * @param ss the stringstream to add the statement to
1645+ * @param val the precision value
1646+ * @param type_str the variable type to apply the precision value to
1647+ */
1648+void
1649+ShaderSource::emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val,
1650+ const std::string& type_str)
1651+{
1652+ static const char *precision_map[] = {
1653+ "lowp", "mediump", "highp", NULL
1654+ };
1655+
1656+ if (val == ShaderSource::PrecisionValueHigh) {
1657+ if (type_ == ShaderSource::ShaderTypeFragment)
1658+ ss << "#ifdef GL_FRAGMENT_PRECISION_HIGH" << std::endl;
1659+
1660+ ss << "precision highp " << type_str << ";" << std::endl;
1661+
1662+ if (type_ == ShaderSource::ShaderTypeFragment) {
1663+ ss << "#else" << std::endl;
1664+ ss << "precision mediump " << type_str << ";" << std::endl;
1665+ ss << "#endif" << std::endl;
1666+ }
1667+ }
1668+ else if (val >= 0 && val < ShaderSource::PrecisionValueDefault) {
1669+ ss << "precision " << precision_map[val] << " ";
1670+ ss << type_str << ";" << std::endl;
1671+ }
1672+
1673+ /* There is no default precision in the fragment shader, so set it to mediump */
1674+ if (val == ShaderSource::PrecisionValueDefault
1675+ && type_str == "float" && type_ == ShaderSource::ShaderTypeFragment)
1676+ {
1677+ ss << "precision mediump float;" << std::endl;
1678+ }
1679+}
1680+
1681+/**
1682+ * Gets a string containing the complete shader source.
1683+ *
1684+ * Precision statements are applied at this point.
1685+ *
1686+ * @return the shader source
1687+ */
1688+std::string
1689+ShaderSource::str()
1690+{
1691+ /* Decide which precision values to use */
1692+ ShaderSource::Precision precision;
1693+
1694+ /* Ensure we have tried to infer the type from the contents */
1695+ type();
1696+
1697+ if (precision_has_been_set_)
1698+ precision = precision_;
1699+ else
1700+ precision = default_precision(type_);
1701+
1702+ /* Create the precision statements */
1703+ std::stringstream ss;
1704+
1705+ emit_precision(ss, precision.int_precision, "int");
1706+ emit_precision(ss, precision.float_precision, "float");
1707+ emit_precision(ss, precision.sampler2d_precision, "sampler2D");
1708+ emit_precision(ss, precision.samplercube_precision, "samplerCube");
1709+
1710+ std::string precision_str(ss.str());
1711+ if (!precision_str.empty()) {
1712+ precision_str.insert(0, "#ifdef GL_ES\n");
1713+ precision_str.insert(precision_str.size(), "#endif\n");
1714+ }
1715+
1716+ return precision_str + source_.str();
1717+}
1718+
1719+/**
1720+ * Sets the precision that will be used for this shader.
1721+ *
1722+ * This overrides any default values set with ShaderSource::default_*_precision().
1723+ *
1724+ * @param precision the precision to set
1725+ */
1726+void
1727+ShaderSource::precision(const ShaderSource::Precision& precision)
1728+{
1729+ precision_ = precision;
1730+ precision_has_been_set_ = true;
1731+}
1732+
1733+/**
1734+ * Gets the precision that will be used for this shader.
1735+ *
1736+ * @return the precision
1737+ */
1738+const ShaderSource::Precision&
1739+ShaderSource::precision()
1740+{
1741+ return precision_;
1742+}
1743+
1744+/**
1745+ * Sets the default precision that will be used for a shaders type.
1746+ *
1747+ * If type is ShaderTypeUnknown the supplied precision is used for all
1748+ * shader types.
1749+ *
1750+ * This can be overriden per ShaderSource object by using ::precision().
1751+ *
1752+ * @param precision the default precision to set
1753+ * @param type the ShaderType to use the precision for
1754+ */
1755+void
1756+ShaderSource::default_precision(const ShaderSource::Precision& precision,
1757+ ShaderSource::ShaderType type)
1758+{
1759+ if (type < 0 || type > ShaderSource::ShaderTypeUnknown)
1760+ type = ShaderSource::ShaderTypeUnknown;
1761+
1762+ if (type == ShaderSource::ShaderTypeUnknown) {
1763+ for (size_t i = 0; i < ShaderSource::ShaderTypeUnknown; i++)
1764+ default_precision_[i] = precision;
1765+ }
1766+ else {
1767+ default_precision_[type] = precision;
1768+ }
1769+}
1770+
1771+/**
1772+ * Gets the default precision that will be used for a shader type.
1773+ *
1774+ * It is valid to use a type of ShaderTypeUnknown. This will always
1775+ * return a Precision with default values.
1776+ *
1777+ * @param type the ShaderType to get the precision of
1778+ *
1779+ * @return the precision
1780+ */
1781+const ShaderSource::Precision&
1782+ShaderSource::default_precision(ShaderSource::ShaderType type)
1783+{
1784+ if (type < 0 || type > ShaderSource::ShaderTypeUnknown)
1785+ type = ShaderSource::ShaderTypeUnknown;
1786+
1787+ return default_precision_[type];
1788+}
1789+
1790+/****************************************
1791+ * ShaderSource::Precision constructors *
1792+ ****************************************/
1793+
1794+/**
1795+ * Creates a ShaderSource::Precision with default precision values.
1796+ */
1797+ShaderSource::Precision::Precision() :
1798+ int_precision(ShaderSource::PrecisionValueDefault),
1799+ float_precision(ShaderSource::PrecisionValueDefault),
1800+ sampler2d_precision(ShaderSource::PrecisionValueDefault),
1801+ samplercube_precision(ShaderSource::PrecisionValueDefault)
1802+{
1803+}
1804+
1805+/**
1806+ * Creates a ShaderSource::Precision using the supplied precision values.
1807+ */
1808+ShaderSource::Precision::Precision(ShaderSource::PrecisionValue int_p,
1809+ ShaderSource::PrecisionValue float_p,
1810+ ShaderSource::PrecisionValue sampler2d_p,
1811+ ShaderSource::PrecisionValue samplercube_p) :
1812+ int_precision(int_p), float_precision(float_p),
1813+ sampler2d_precision(sampler2d_p), samplercube_precision(samplercube_p)
1814+{
1815+}
1816+
1817+/**
1818+ * Creates a ShaderSource::Precision from a string representation of
1819+ * precision values.
1820+ *
1821+ * The string format is:
1822+ * "<int>,<float>,<sampler2d>,<samplercube>"
1823+ *
1824+ * Each precision value is one of "high", "medium", "low" or "default".
1825+ *
1826+ * @param precision_values the string representation of the precision values
1827+ */
1828+ShaderSource::Precision::Precision(const std::string& precision_values) :
1829+ int_precision(ShaderSource::PrecisionValueDefault),
1830+ float_precision(ShaderSource::PrecisionValueDefault),
1831+ sampler2d_precision(ShaderSource::PrecisionValueDefault),
1832+ samplercube_precision(ShaderSource::PrecisionValueDefault)
1833+{
1834+ std::vector<std::string> elems;
1835+
1836+ Util::split(precision_values, ',', elems);
1837+
1838+ for (size_t i = 0; i < elems.size() && i < 4; i++) {
1839+ const std::string& pstr(elems[i]);
1840+ ShaderSource::PrecisionValue pval;
1841+
1842+ if (pstr == "high")
1843+ pval = ShaderSource::PrecisionValueHigh;
1844+ else if (pstr == "medium")
1845+ pval = ShaderSource::PrecisionValueMedium;
1846+ else if (pstr == "low")
1847+ pval = ShaderSource::PrecisionValueLow;
1848+ else
1849+ pval = ShaderSource::PrecisionValueDefault;
1850+
1851+ switch(i) {
1852+ case 0: int_precision = pval; break;
1853+ case 1: float_precision = pval; break;
1854+ case 2: sampler2d_precision = pval; break;
1855+ case 3: samplercube_precision = pval; break;
1856+ default: break;
1857+ }
1858+ }
1859+}
1860
1861=== added file 'src/libmatrix/shader-source.h'
1862--- src/libmatrix/shader-source.h 1970-01-01 00:00:00 +0000
1863+++ src/libmatrix/shader-source.h 2012-01-27 22:08:04 +0000
1864@@ -0,0 +1,103 @@
1865+//
1866+// Copyright (c) 2010-2012 Linaro Limited
1867+//
1868+// All rights reserved. This program and the accompanying materials
1869+// are made available under the terms of the MIT License which accompanies
1870+// this distribution, and is available at
1871+// http://www.opensource.org/licenses/mit-license.php
1872+//
1873+// Contributors:
1874+// Alexandros Frantzis <alexandros.frantzis@linaro.org>
1875+// Jesse Barker <jesse.barker@linaro.org>
1876+//
1877+#include <string>
1878+#include <sstream>
1879+#include <vector>
1880+#include "vec.h"
1881+#include "mat.h"
1882+
1883+/**
1884+ * Helper class for loading and manipulating shader sources.
1885+ */
1886+class ShaderSource
1887+{
1888+public:
1889+ enum ShaderType {
1890+ ShaderTypeVertex,
1891+ ShaderTypeFragment,
1892+ ShaderTypeUnknown
1893+ };
1894+
1895+ ShaderSource(ShaderType type = ShaderTypeUnknown) :
1896+ precision_has_been_set_(false), type_(type) {}
1897+ ShaderSource(const std::string &filename, ShaderType type = ShaderTypeUnknown) :
1898+ precision_has_been_set_(false), type_(type) { append_file(filename); }
1899+
1900+ void append(const std::string &str);
1901+ void append_file(const std::string &filename);
1902+
1903+ void replace(const std::string &remove, const std::string &insert);
1904+ void replace_with_file(const std::string &remove, const std::string &filename);
1905+
1906+ void add(const std::string &str, const std::string &function = "");
1907+
1908+ void add_const(const std::string &name, float f,
1909+ const std::string &function = "");
1910+ void add_const(const std::string &name, std::vector<float> &f,
1911+ const std::string &function = "");
1912+ void add_const(const std::string &name, const LibMatrix::vec2 &v,
1913+ const std::string &function = "");
1914+ void add_const(const std::string &name, const LibMatrix::vec3 &v,
1915+ const std::string &function = "");
1916+ void add_const(const std::string &name, const LibMatrix::vec4 &v,
1917+ const std::string &function = "");
1918+ void add_const(const std::string &name, const LibMatrix::mat3 &m,
1919+ const std::string &function = "");
1920+
1921+ void add_array(const std::string &name, std::vector<float> &array,
1922+ const std::string &init_function,
1923+ const std::string &decl_function = "");
1924+
1925+ ShaderType type();
1926+ std::string str();
1927+
1928+ enum PrecisionValue {
1929+ PrecisionValueLow,
1930+ PrecisionValueMedium,
1931+ PrecisionValueHigh,
1932+ PrecisionValueDefault
1933+ };
1934+
1935+ struct Precision {
1936+ Precision();
1937+ Precision(PrecisionValue int_p, PrecisionValue float_p,
1938+ PrecisionValue sampler2d_p, PrecisionValue samplercube_p);
1939+ Precision(const std::string& list);
1940+
1941+ PrecisionValue int_precision;
1942+ PrecisionValue float_precision;
1943+ PrecisionValue sampler2d_precision;
1944+ PrecisionValue samplercube_precision;
1945+ };
1946+
1947+ void precision(const Precision& precision);
1948+ const Precision& precision();
1949+
1950+ static void default_precision(const Precision& precision,
1951+ ShaderType type = ShaderTypeUnknown);
1952+ static const Precision& default_precision(ShaderType type);
1953+
1954+private:
1955+ void add_global(const std::string &str);
1956+ void add_local(const std::string &str, const std::string &function);
1957+ bool load_file(const std::string& filename, std::string& str);
1958+ void emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val,
1959+ const std::string& type_str);
1960+
1961+ std::stringstream source_;
1962+ Precision precision_;
1963+ bool precision_has_been_set_;
1964+ ShaderType type_;
1965+
1966+ static std::vector<Precision> default_precision_;
1967+};
1968
1969=== added directory 'src/libmatrix/test'
1970=== added file 'src/libmatrix/test/basic-global-const.vert'
1971--- src/libmatrix/test/basic-global-const.vert 1970-01-01 00:00:00 +0000
1972+++ src/libmatrix/test/basic-global-const.vert 2012-01-27 22:08:04 +0000
1973@@ -0,0 +1,15 @@
1974+const vec4 ConstantColor = vec4(1.000000, 1.000000, 1.000000, 1.000000);
1975+attribute vec3 position;
1976+
1977+uniform mat4 modelview;
1978+uniform mat4 projection;
1979+
1980+varying vec4 color;
1981+
1982+void
1983+main(void)
1984+{
1985+ vec4 curVertex = vec4(position, 1.0);
1986+ gl_Position = projection * modelview * curVertex;
1987+ color = ConstantColor;
1988+}
1989
1990=== added file 'src/libmatrix/test/basic.frag'
1991--- src/libmatrix/test/basic.frag 1970-01-01 00:00:00 +0000
1992+++ src/libmatrix/test/basic.frag 2012-01-27 22:08:04 +0000
1993@@ -0,0 +1,7 @@
1994+varying vec4 color;
1995+
1996+void
1997+main(void)
1998+{
1999+ gl_FragColor = color;
2000+}
2001
2002=== added file 'src/libmatrix/test/basic.vert'
2003--- src/libmatrix/test/basic.vert 1970-01-01 00:00:00 +0000
2004+++ src/libmatrix/test/basic.vert 2012-01-27 22:08:04 +0000
2005@@ -0,0 +1,14 @@
2006+attribute vec3 position;
2007+
2008+uniform mat4 modelview;
2009+uniform mat4 projection;
2010+
2011+varying vec4 color;
2012+
2013+void
2014+main(void)
2015+{
2016+ vec4 curVertex = vec4(position, 1.0);
2017+ gl_Position = projection * modelview * curVertex;
2018+ color = ConstantColor;
2019+}
2020
2021=== added file 'src/libmatrix/test/const_vec_test.cc'
2022--- src/libmatrix/test/const_vec_test.cc 1970-01-01 00:00:00 +0000
2023+++ src/libmatrix/test/const_vec_test.cc 2012-01-27 22:08:04 +0000
2024@@ -0,0 +1,60 @@
2025+//
2026+// Copyright (c) 2011 Linaro Limited
2027+//
2028+// All rights reserved. This program and the accompanying materials
2029+// are made available under the terms of the MIT License which accompanies
2030+// this distribution, and is available at
2031+// http://www.opensource.org/licenses/mit-license.php
2032+//
2033+// Contributors:
2034+// Jesse Barker - original implementation.
2035+//
2036+#include <iostream>
2037+#include "libmatrix_test.h"
2038+#include "const_vec_test.h"
2039+#include "../vec.h"
2040+
2041+using LibMatrix::vec2;
2042+using LibMatrix::vec3;
2043+using LibMatrix::vec4;
2044+using std::cout;
2045+using std::endl;
2046+
2047+void
2048+Vec2TestConstOperator::run(const Options& options)
2049+{
2050+ const vec2 a(1.0, 1.0);
2051+ const vec2 b(2.0, 2.0);
2052+ vec2 aplusb(a + b);
2053+ vec2 aminusb(a - b);
2054+ vec2 atimesb(a * b);
2055+ vec2 adivb(a / b);
2056+ const float s(2.5);
2057+ vec2 stimesb(s * b);
2058+}
2059+
2060+void
2061+Vec3TestConstOperator::run(const Options& options)
2062+{
2063+ const vec3 a(1.0, 1.0, 1.0);
2064+ const vec3 b(2.0, 2.0, 2.0);
2065+ vec3 aplusb(a + b);
2066+ vec3 aminusb(a - b);
2067+ vec3 atimesb(a * b);
2068+ vec3 adivb(a / b);
2069+ const float s(2.5);
2070+ vec3 stimesb(s * b);
2071+}
2072+
2073+void
2074+Vec4TestConstOperator::run(const Options& options)
2075+{
2076+ const vec4 a(1.0, 1.0, 1.0, 1.0);
2077+ const vec4 b(2.0, 2.0, 2.0, 2.0);
2078+ vec4 aplusb(a + b);
2079+ vec4 aminusb(a - b);
2080+ vec4 atimesb(a * b);
2081+ vec4 adivb(a / b);
2082+ const float s(2.5);
2083+ vec4 stimesb(s * b);
2084+}
2085
2086=== added file 'src/libmatrix/test/const_vec_test.h'
2087--- src/libmatrix/test/const_vec_test.h 1970-01-01 00:00:00 +0000
2088+++ src/libmatrix/test/const_vec_test.h 2012-01-27 22:08:04 +0000
2089@@ -0,0 +1,39 @@
2090+//
2091+// Copyright (c) 2011 Linaro Limited
2092+//
2093+// All rights reserved. This program and the accompanying materials
2094+// are made available under the terms of the MIT License which accompanies
2095+// this distribution, and is available at
2096+// http://www.opensource.org/licenses/mit-license.php
2097+//
2098+// Contributors:
2099+// Jesse Barker - original implementation.
2100+//
2101+#ifndef CONST_VEC_TEST_H_
2102+#define CONST_VEC_TEST_H_
2103+
2104+class MatrixTest;
2105+class Options;
2106+
2107+class Vec2TestConstOperator : public MatrixTest
2108+{
2109+public:
2110+ Vec2TestConstOperator() : MatrixTest("vec2::const") {}
2111+ virtual void run(const Options& options);
2112+};
2113+
2114+class Vec3TestConstOperator : public MatrixTest
2115+{
2116+public:
2117+ Vec3TestConstOperator() : MatrixTest("vec3::const") {}
2118+ virtual void run(const Options& options);
2119+};
2120+
2121+class Vec4TestConstOperator : public MatrixTest
2122+{
2123+public:
2124+ Vec4TestConstOperator() : MatrixTest("vec4::const") {}
2125+ virtual void run(const Options& options);
2126+};
2127+
2128+#endif // CONST_VEC_TEST_H_
2129
2130=== added file 'src/libmatrix/test/inverse_test.cc'
2131--- src/libmatrix/test/inverse_test.cc 1970-01-01 00:00:00 +0000
2132+++ src/libmatrix/test/inverse_test.cc 2012-01-27 22:08:04 +0000
2133@@ -0,0 +1,172 @@
2134+//
2135+// Copyright (c) 2010 Linaro Limited
2136+//
2137+// All rights reserved. This program and the accompanying materials
2138+// are made available under the terms of the MIT License which accompanies
2139+// this distribution, and is available at
2140+// http://www.opensource.org/licenses/mit-license.php
2141+//
2142+// Contributors:
2143+// Jesse Barker - original implementation.
2144+//
2145+#include <iostream>
2146+#include "libmatrix_test.h"
2147+#include "inverse_test.h"
2148+#include "../mat.h"
2149+
2150+using LibMatrix::mat2;
2151+using LibMatrix::mat3;
2152+using LibMatrix::mat4;
2153+using std::cout;
2154+using std::endl;
2155+
2156+void
2157+MatrixTest2x2Inverse::run(const Options& options)
2158+{
2159+ mat2 m;
2160+
2161+ if (options.beVerbose())
2162+ {
2163+ cout << "Starting with mat2 (should be identity): " << endl << endl;
2164+ m.print();
2165+ }
2166+
2167+ m[0][1] = -2.5;
2168+
2169+ if (options.beVerbose())
2170+ {
2171+ cout << endl << "Matrix should now have (0, 1) == -2.500000" << endl << endl;
2172+ m.print();
2173+ }
2174+
2175+ mat2 mi(m);
2176+
2177+ if (options.beVerbose())
2178+ {
2179+ cout << endl << "Copy of previous matrix (should have (0, 1) == -2.500000)" << endl << endl;
2180+ mi.print();
2181+ }
2182+
2183+ mi.inverse();
2184+
2185+ if (options.beVerbose())
2186+ {
2187+ cout << endl << "Inverse of copy: " << endl << endl;
2188+ mi.print();
2189+ }
2190+
2191+ mat2 i = m * mi;
2192+
2193+ if (options.beVerbose())
2194+ {
2195+ cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
2196+ i.print();
2197+ }
2198+
2199+ mat2 ident;
2200+ if (i == ident)
2201+ {
2202+ pass_ = true;
2203+ }
2204+}
2205+
2206+void
2207+MatrixTest3x3Inverse::run(const Options& options)
2208+{
2209+ mat3 m;
2210+
2211+ if (options.beVerbose())
2212+ {
2213+ cout << "Starting with mat3 (should be identity): " << endl << endl;
2214+ m.print();
2215+ }
2216+
2217+ m[1][2] = -2.5;
2218+
2219+ if (options.beVerbose())
2220+ {
2221+ cout << endl << "Matrix should now have (1, 2) == -2.500000" << endl << endl;
2222+ m.print();
2223+ }
2224+
2225+ mat3 mi(m);
2226+
2227+ if (options.beVerbose())
2228+ {
2229+ cout << endl << "Copy of previous matrix (should have (1, 2) == -2.500000)" << endl << endl;
2230+ mi.print();
2231+ }
2232+
2233+ mi.inverse();
2234+
2235+ if (options.beVerbose())
2236+ {
2237+ cout << endl << "Inverse of copy: " << endl << endl;
2238+ mi.print();
2239+ }
2240+
2241+ mat3 i = m * mi;
2242+
2243+ if (options.beVerbose())
2244+ {
2245+ cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
2246+ i.print();
2247+ }
2248+
2249+ mat3 ident;
2250+ if (i == ident)
2251+ {
2252+ pass_ = true;
2253+ }
2254+}
2255+
2256+void
2257+MatrixTest4x4Inverse::run(const Options& options)
2258+{
2259+ mat4 m;
2260+
2261+ if (options.beVerbose())
2262+ {
2263+ cout << "Starting with mat4 (should be identity): " << endl << endl;
2264+ m.print();
2265+ }
2266+
2267+ m[2][3] = -2.5;
2268+
2269+ if (options.beVerbose())
2270+ {
2271+ cout << endl << "Matrix should now have (2, 3) == -2.500000" << endl << endl;
2272+ m.print();
2273+ }
2274+
2275+ mat4 mi(m);
2276+
2277+ if (options.beVerbose())
2278+ {
2279+ cout << endl << "Copy of previous matrix (should have (2, 3) == -2.500000)" << endl << endl;
2280+ mi.print();
2281+ }
2282+
2283+ mi.inverse();
2284+
2285+ if (options.beVerbose())
2286+ {
2287+ cout << endl << "Inverse of copy: " << endl << endl;
2288+ mi.print();
2289+ }
2290+
2291+ mat4 i = m * mi;
2292+
2293+ if (options.beVerbose())
2294+ {
2295+ cout << endl << "Product of original and inverse (should be identity): " << endl << endl;
2296+ i.print();
2297+ }
2298+
2299+ mat4 ident;
2300+ if (i == ident)
2301+ {
2302+ pass_ = true;
2303+ }
2304+}
2305+
2306
2307=== added file 'src/libmatrix/test/inverse_test.h'
2308--- src/libmatrix/test/inverse_test.h 1970-01-01 00:00:00 +0000
2309+++ src/libmatrix/test/inverse_test.h 2012-01-27 22:08:04 +0000
2310@@ -0,0 +1,39 @@
2311+//
2312+// Copyright (c) 2010 Linaro Limited
2313+//
2314+// All rights reserved. This program and the accompanying materials
2315+// are made available under the terms of the MIT License which accompanies
2316+// this distribution, and is available at
2317+// http://www.opensource.org/licenses/mit-license.php
2318+//
2319+// Contributors:
2320+// Jesse Barker - original implementation.
2321+//
2322+#ifndef INVERSE_TEST_H_
2323+#define INVERSE_TEST_H_
2324+
2325+class MatrixTest;
2326+class Options;
2327+
2328+class MatrixTest2x2Inverse : public MatrixTest
2329+{
2330+public:
2331+ MatrixTest2x2Inverse() : MatrixTest("mat2::inverse") {}
2332+ virtual void run(const Options& options);
2333+};
2334+
2335+class MatrixTest3x3Inverse : public MatrixTest
2336+{
2337+public:
2338+ MatrixTest3x3Inverse() : MatrixTest("mat3::inverse") {}
2339+ virtual void run(const Options& options);
2340+};
2341+
2342+class MatrixTest4x4Inverse : public MatrixTest
2343+{
2344+public:
2345+ MatrixTest4x4Inverse() : MatrixTest("mat4::inverse") {}
2346+ virtual void run(const Options& options);
2347+};
2348+
2349+#endif // INVERSE_TEST_H_
2350
2351=== added file 'src/libmatrix/test/libmatrix_test.cc'
2352--- src/libmatrix/test/libmatrix_test.cc 1970-01-01 00:00:00 +0000
2353+++ src/libmatrix/test/libmatrix_test.cc 2012-01-27 22:08:04 +0000
2354@@ -0,0 +1,68 @@
2355+//
2356+// Copyright (c) 2010 Linaro Limited
2357+//
2358+// All rights reserved. This program and the accompanying materials
2359+// are made available under the terms of the MIT License which accompanies
2360+// this distribution, and is available at
2361+// http://www.opensource.org/licenses/mit-license.php
2362+//
2363+// Contributors:
2364+// Jesse Barker - original implementation.
2365+//
2366+#include <iostream>
2367+#include <string>
2368+#include <vector>
2369+#include "libmatrix_test.h"
2370+#include "inverse_test.h"
2371+#include "transpose_test.h"
2372+#include "const_vec_test.h"
2373+#include "shader_source_test.h"
2374+
2375+using std::cerr;
2376+using std::cout;
2377+using std::endl;
2378+
2379+int
2380+main(int argc, char** argv)
2381+{
2382+ Options testOptions("matrix_test");
2383+ testOptions.parseArgs(argc, argv);
2384+ if (testOptions.showHelp())
2385+ {
2386+ testOptions.printUsage();
2387+ return 0;
2388+ }
2389+
2390+ using std::vector;
2391+ vector<MatrixTest*> testVec;
2392+ testVec.push_back(new MatrixTest2x2Inverse());
2393+ testVec.push_back(new MatrixTest3x3Inverse());
2394+ testVec.push_back(new MatrixTest4x4Inverse());
2395+ testVec.push_back(new MatrixTest2x2Transpose());
2396+ testVec.push_back(new MatrixTest3x3Transpose());
2397+ testVec.push_back(new MatrixTest4x4Transpose());
2398+ testVec.push_back(new ShaderSourceBasic());
2399+
2400+ for (vector<MatrixTest*>::iterator testIt = testVec.begin();
2401+ testIt != testVec.end();
2402+ testIt++)
2403+ {
2404+ MatrixTest* curTest = *testIt;
2405+ if (testOptions.beVerbose())
2406+ {
2407+ cout << "Running test " << curTest->name() << endl;
2408+ }
2409+ curTest->run(testOptions);
2410+ if (!curTest->passed())
2411+ {
2412+ cerr << curTest->name() << " does not work!" << endl;
2413+ return 1;
2414+ }
2415+ if (testOptions.beVerbose())
2416+ {
2417+ cout << curTest->name() << " is okay!" << endl;
2418+ }
2419+ }
2420+
2421+ return 0;
2422+}
2423
2424=== added file 'src/libmatrix/test/libmatrix_test.h'
2425--- src/libmatrix/test/libmatrix_test.h 1970-01-01 00:00:00 +0000
2426+++ src/libmatrix/test/libmatrix_test.h 2012-01-27 22:08:04 +0000
2427@@ -0,0 +1,51 @@
2428+//
2429+// Copyright (c) 2010 Linaro Limited
2430+//
2431+// All rights reserved. This program and the accompanying materials
2432+// are made available under the terms of the MIT License which accompanies
2433+// this distribution, and is available at
2434+// http://www.opensource.org/licenses/mit-license.php
2435+//
2436+// Contributors:
2437+// Jesse Barker - original implementation.
2438+//
2439+#ifndef LIBMATRIX_TEST_H_
2440+#define LIBMATRIX_TEST_H_
2441+
2442+class Options
2443+{
2444+ Options();
2445+ static const std::string verbose_name_;
2446+ static const std::string help_name_;
2447+ std::string app_name_;
2448+ bool show_help_;
2449+ bool verbose_;
2450+public:
2451+ Options(const std::string& app_name) :
2452+ app_name_(app_name),
2453+ show_help_(false),
2454+ verbose_(false) {}
2455+ ~Options() {}
2456+ bool beVerbose() const { return verbose_; }
2457+ bool showHelp() const { return show_help_; }
2458+ void parseArgs(int argc, char** argv);
2459+ void printUsage();
2460+};
2461+
2462+class MatrixTest
2463+{
2464+ std::string name_;
2465+protected:
2466+ bool pass_;
2467+ MatrixTest();
2468+public:
2469+ MatrixTest(const std::string& name) :
2470+ name_(name),
2471+ pass_(false) {}
2472+ ~MatrixTest();
2473+ const std::string& name() const { return name_; }
2474+ virtual void run(const Options& options) = 0;
2475+ const bool passed() const { return pass_; }
2476+};
2477+
2478+#endif // LIBMATRIX_TEST_H_
2479
2480=== added file 'src/libmatrix/test/options.cc'
2481--- src/libmatrix/test/options.cc 1970-01-01 00:00:00 +0000
2482+++ src/libmatrix/test/options.cc 2012-01-27 22:08:04 +0000
2483@@ -0,0 +1,76 @@
2484+//
2485+// Copyright (c) 2010 Linaro Limited
2486+//
2487+// All rights reserved. This program and the accompanying materials
2488+// are made available under the terms of the MIT License which accompanies
2489+// this distribution, and is available at
2490+// http://www.opensource.org/licenses/mit-license.php
2491+//
2492+// Contributors:
2493+// Jesse Barker - original implementation.
2494+//
2495+#include <iostream>
2496+#include <iomanip>
2497+#include <getopt.h>
2498+#include "libmatrix_test.h"
2499+
2500+using std::cout;
2501+using std::endl;
2502+
2503+const std::string Options::verbose_name_("verbose");
2504+const std::string Options::help_name_("help");
2505+
2506+void
2507+Options::parseArgs(int argc, char** argv)
2508+{
2509+ static struct option long_options[] = {
2510+ {"verbose", 0, 0, 0},
2511+ {"help", 0, 0, 0},
2512+ {0, 0, 0, 0}
2513+ };
2514+ int option_index(0);
2515+ int c = getopt_long(argc, argv, "", long_options, &option_index);
2516+ while (c != -1)
2517+ {
2518+ // getopt_long() returns '?' and prints an "unrecognized option" error
2519+ // to stderr if it does not recognize an option. Just trigger
2520+ // the help/usage message, stop processing and get out.
2521+ if (c == '?')
2522+ {
2523+ show_help_ = true;
2524+ break;
2525+ }
2526+
2527+ std::string optname(long_options[option_index].name);
2528+
2529+ if (optname == verbose_name_)
2530+ {
2531+ verbose_ = true;
2532+ }
2533+ else if (optname == help_name_)
2534+ {
2535+ show_help_ = true;
2536+ }
2537+ c = getopt_long(argc, argv, "",
2538+ long_options, &option_index);
2539+ }
2540+}
2541+
2542+
2543+static void
2544+emitColumnOne(const std::string& text)
2545+{
2546+ cout << std::setw(16) << text;
2547+}
2548+
2549+void
2550+Options::printUsage()
2551+{
2552+ cout << app_name_ << ": directed functional test utility for libmatrix." << endl;
2553+ cout << "Options:" << endl;
2554+ emitColumnOne("--verbose");
2555+ cout << std::setw(0) << " Enable verbose output during test runs." << endl;
2556+ emitColumnOne("--help");
2557+ cout << std::setw(0) << " Print this usage text." << endl;
2558+}
2559+
2560
2561=== added file 'src/libmatrix/test/shader_source_test.cc'
2562--- src/libmatrix/test/shader_source_test.cc 1970-01-01 00:00:00 +0000
2563+++ src/libmatrix/test/shader_source_test.cc 2012-01-27 22:08:04 +0000
2564@@ -0,0 +1,49 @@
2565+//
2566+// Copyright (c) 2012 Linaro Limited
2567+//
2568+// All rights reserved. This program and the accompanying materials
2569+// are made available under the terms of the MIT License which accompanies
2570+// this distribution, and is available at
2571+// http://www.opensource.org/licenses/mit-license.php
2572+//
2573+// Contributors:
2574+// Jesse Barker - original implementation.
2575+//
2576+#include <string>
2577+#include "libmatrix_test.h"
2578+#include "shader_source_test.h"
2579+#include "../shader-source.h"
2580+#include "../vec.h"
2581+
2582+using std::string;
2583+using LibMatrix::vec4;
2584+
2585+void
2586+ShaderSourceBasic::run(const Options& options)
2587+{
2588+ static const string vtx_shader_filename("test/basic.vert");
2589+
2590+ ShaderSource vtx_source(vtx_shader_filename);
2591+ ShaderSource vtx_source2(vtx_shader_filename);
2592+
2593+ pass_ = (vtx_source.str() == vtx_source2.str());
2594+}
2595+
2596+void
2597+ShaderSourceAddConstGlobal::run(const Options& options)
2598+{
2599+ // Load the original shader source.
2600+ static const string src_shader_filename("test/basic.vert");
2601+ ShaderSource src_shader(src_shader_filename);
2602+
2603+ // Add constant at global scope
2604+ static const vec4 constantColor(1.0, 1.0, 1.0, 1.0);
2605+ src_shader.add_const("ConstantColor", constantColor);
2606+
2607+ // Load the pre-modified shader
2608+ static const string result_shader_filename("test/basic-global-const.vert");
2609+ ShaderSource result_shader(result_shader_filename);
2610+
2611+ // Compare the output strings to confirm the results.
2612+ pass_ = (src_shader.str() == result_shader.str());
2613+}
2614
2615=== added file 'src/libmatrix/test/shader_source_test.h'
2616--- src/libmatrix/test/shader_source_test.h 1970-01-01 00:00:00 +0000
2617+++ src/libmatrix/test/shader_source_test.h 2012-01-27 22:08:04 +0000
2618@@ -0,0 +1,32 @@
2619+//
2620+// Copyright (c) 2012 Linaro Limited
2621+//
2622+// All rights reserved. This program and the accompanying materials
2623+// are made available under the terms of the MIT License which accompanies
2624+// this distribution, and is available at
2625+// http://www.opensource.org/licenses/mit-license.php
2626+//
2627+// Contributors:
2628+// Jesse Barker - original implementation.
2629+//
2630+#ifndef SHADER_SOURCE_TEST_H_
2631+#define SHADER_SOURCE_TEST_H_
2632+
2633+class MatrixTest;
2634+class Options;
2635+
2636+class ShaderSourceBasic : public MatrixTest
2637+{
2638+public:
2639+ ShaderSourceBasic() : MatrixTest("ShaderSource::basic") {}
2640+ virtual void run(const Options& options);
2641+};
2642+
2643+class ShaderSourceAddConstGlobal : public MatrixTest
2644+{
2645+public:
2646+ ShaderSourceAddConstGlobal() : MatrixTest("ShaderSource::AddConstGlobal") {}
2647+ virtual void run(const Options& options);
2648+};
2649+
2650+#endif // SHADER_SOURCE_TEST_H
2651
2652=== added file 'src/libmatrix/test/transpose_test.cc'
2653--- src/libmatrix/test/transpose_test.cc 1970-01-01 00:00:00 +0000
2654+++ src/libmatrix/test/transpose_test.cc 2012-01-27 22:08:04 +0000
2655@@ -0,0 +1,297 @@
2656+//
2657+// Copyright (c) 2010 Linaro Limited
2658+//
2659+// All rights reserved. This program and the accompanying materials
2660+// are made available under the terms of the MIT License which accompanies
2661+// this distribution, and is available at
2662+// http://www.opensource.org/licenses/mit-license.php
2663+//
2664+// Contributors:
2665+// Jesse Barker - original implementation.
2666+//
2667+#include <iostream>
2668+#include "libmatrix_test.h"
2669+#include "transpose_test.h"
2670+#include "../mat.h"
2671+
2672+using LibMatrix::mat2;
2673+using LibMatrix::mat3;
2674+using LibMatrix::mat4;
2675+using std::cout;
2676+using std::endl;
2677+
2678+void
2679+MatrixTest2x2Transpose::run(const Options& options)
2680+{
2681+ // First, a simple test to ensure that the transpose of the identity is
2682+ // the identity.
2683+ if (options.beVerbose())
2684+ {
2685+ cout << endl << "Assertion 1: Transpose of the identity is the identity." << endl << endl;
2686+ }
2687+
2688+ mat2 m;
2689+
2690+ if (options.beVerbose())
2691+ {
2692+ cout << "Starting with mat2 (should be identity): " << endl << endl;
2693+ m.print();
2694+ }
2695+
2696+ m.transpose();
2697+
2698+ if (options.beVerbose())
2699+ {
2700+ cout << endl << "Transpose of identity (should be identity): " << endl << endl;
2701+ m.print();
2702+ }
2703+
2704+ mat2 mi;
2705+ if (m != mi)
2706+ {
2707+ // FAIL! Transpose of the identity is the identity.
2708+ return;
2709+ }
2710+
2711+ // At this point, we have 2 identity matrices.
2712+ // Next, set an element in the matrix and transpose twice. We should see
2713+ // the original matrix (with i,j set).
2714+ if (options.beVerbose())
2715+ {
2716+ cout << endl << "Assertion 2: Transposing a matrix twice yields the original matrix." << endl << endl;
2717+ }
2718+
2719+ m[0][1] = 6.3;
2720+
2721+ if (options.beVerbose())
2722+ {
2723+ cout << "Matrix should now have (0, 1) == 6.300000" << endl << endl;
2724+ m.print();
2725+ }
2726+
2727+ mi = m;
2728+
2729+ m.transpose().transpose();
2730+
2731+ if (options.beVerbose())
2732+ {
2733+ cout << endl << "Matrix should now have (0, 1) == 6.300000" << endl << endl;
2734+ m.print();
2735+ }
2736+
2737+ if (m != mi)
2738+ {
2739+ // FAIL! Transposing the same matrix twice should yield the original.
2740+ return;
2741+ }
2742+
2743+ // Next, reset mi back to the identity. Set element element j,i in this
2744+ // matrix and transpose m. They should now be equal.
2745+ if (options.beVerbose())
2746+ {
2747+ cout << endl << "Assertion 3: Transpose of matrix (i,j) == x is equal to matrix (j,i) == x." << endl << endl;
2748+ }
2749+
2750+ mi.setIdentity();
2751+ mi[1][0] = 6.3;
2752+
2753+ m.transpose();
2754+
2755+ if (options.beVerbose())
2756+ {
2757+ cout << "Matrix should now have (1, 0) == 6.300000" << endl << endl;
2758+ m.print();
2759+ cout << endl;
2760+ }
2761+
2762+ if (m == mi)
2763+ {
2764+ pass_ = true;
2765+ }
2766+
2767+ // FAIL! Transposing the same matrix twice should yield the original.
2768+}
2769+
2770+void
2771+MatrixTest3x3Transpose::run(const Options& options)
2772+{
2773+ // First, a simple test to ensure that the transpose of the identity is
2774+ // the identity.
2775+ if (options.beVerbose())
2776+ {
2777+ cout << endl << "Assertion 1: Transpose of the identity is the identity." << endl << endl;
2778+ }
2779+
2780+ mat3 m;
2781+
2782+ if (options.beVerbose())
2783+ {
2784+ cout << "Starting with mat2 (should be identity): " << endl << endl;
2785+ m.print();
2786+ }
2787+
2788+ m.transpose();
2789+
2790+ if (options.beVerbose())
2791+ {
2792+ cout << endl << "Transpose of identity (should be identity): " << endl << endl;
2793+ m.print();
2794+ }
2795+
2796+ mat3 mi;
2797+ if (m != mi)
2798+ {
2799+ // FAIL! Transpose of the identity is the identity.
2800+ return;
2801+ }
2802+
2803+ // At this point, we have 2 identity matrices.
2804+ // Next, set an element in the matrix and transpose twice. We should see
2805+ // the original matrix (with i,j set).
2806+ if (options.beVerbose())
2807+ {
2808+ cout << endl << "Assertion 2: Transposing a matrix twice yields the original matrix." << endl << endl;
2809+ }
2810+
2811+ m[0][1] = 6.3;
2812+
2813+ if (options.beVerbose())
2814+ {
2815+ cout << "Matrix should now have (0, 1) == 6.300000" << endl << endl;
2816+ m.print();
2817+ }
2818+
2819+ mi = m;
2820+
2821+ m.transpose().transpose();
2822+
2823+ if (options.beVerbose())
2824+ {
2825+ cout << endl << "Matrix should now have (0, 1) == 6.300000" << endl << endl;
2826+ m.print();
2827+ }
2828+
2829+ if (m != mi)
2830+ {
2831+ // FAIL! Transposing the same matrix twice should yield the original.
2832+ return;
2833+ }
2834+
2835+ // Next, reset mi back to the identity. Set element element j,i in this
2836+ // matrix and transpose m. They should now be equal.
2837+ if (options.beVerbose())
2838+ {
2839+ cout << endl << "Assertion 3: Transpose of matrix (i,j) == x is equal to matrix (j,i) == x." << endl << endl;
2840+ }
2841+
2842+ mi.setIdentity();
2843+ mi[1][0] = 6.3;
2844+
2845+ m.transpose();
2846+
2847+ if (options.beVerbose())
2848+ {
2849+ cout << "Matrix should now have (1, 0) == 6.300000" << endl << endl;
2850+ m.print();
2851+ cout << endl;
2852+ }
2853+
2854+ if (m == mi)
2855+ {
2856+ pass_ = true;
2857+ }
2858+
2859+ // FAIL! Transposing the same matrix twice should yield the original.
2860+}
2861+
2862+void
2863+MatrixTest4x4Transpose::run(const Options& options)
2864+{
2865+ // First, a simple test to ensure that the transpose of the identity is
2866+ // the identity.
2867+ if (options.beVerbose())
2868+ {
2869+ cout << endl << "Assertion 1: Transpose of the identity is the identity." << endl << endl;
2870+ }
2871+
2872+ mat4 m;
2873+
2874+ if (options.beVerbose())
2875+ {
2876+ cout << "Starting with mat2 (should be identity): " << endl << endl;
2877+ m.print();
2878+ }
2879+
2880+ m.transpose();
2881+
2882+ if (options.beVerbose())
2883+ {
2884+ cout << endl << "Transpose of identity (should be identity): " << endl << endl;
2885+ m.print();
2886+ }
2887+
2888+ mat4 mi;
2889+ if (m != mi)
2890+ {
2891+ // FAIL! Transpose of the identity is the identity.
2892+ return;
2893+ }
2894+
2895+ // At this point, we have 2 identity matrices.
2896+ // Next, set an element in the matrix and transpose twice. We should see
2897+ // the original matrix (with i,j set).
2898+ if (options.beVerbose())
2899+ {
2900+ cout << endl << "Assertion 2: Transposing a matrix twice yields the original matrix." << endl << endl;
2901+ }
2902+
2903+ m[0][1] = 6.3;
2904+
2905+ if (options.beVerbose())
2906+ {
2907+ cout << "Matrix should now have (0, 1) == 6.300000" << endl << endl;
2908+ m.print();
2909+ }
2910+
2911+ mi = m;
2912+
2913+ m.transpose().transpose();
2914+
2915+ if (options.beVerbose())
2916+ {
2917+ cout << endl << "Matrix should now have (0, 1) == 6.300000" << endl << endl;
2918+ m.print();
2919+ }
2920+
2921+ if (m != mi)
2922+ {
2923+ // FAIL! Transposing the same matrix twice should yield the original.
2924+ return;
2925+ }
2926+
2927+ // Next, reset mi back to the identity. Set element element j,i in this
2928+ // matrix and transpose m. They should now be equal.
2929+ if (options.beVerbose())
2930+ {
2931+ cout << endl << "Assertion 3: Transpose of matrix (i,j) == x is equal to matrix (j,i) == x." << endl << endl;
2932+ }
2933+
2934+ mi.setIdentity();
2935+ mi[1][0] = 6.3;
2936+
2937+ m.transpose();
2938+
2939+ if (options.beVerbose())
2940+ {
2941+ cout << "Matrix should now have (1, 0) == 6.300000" << endl << endl;
2942+ m.print();
2943+ cout << endl;
2944+ }
2945+
2946+ if (m == mi)
2947+ {
2948+ pass_ = true;
2949+ }
2950+
2951+ // FAIL! Transposing the same matrix twice should yield the original.
2952+}
2953
2954=== added file 'src/libmatrix/test/transpose_test.h'
2955--- src/libmatrix/test/transpose_test.h 1970-01-01 00:00:00 +0000
2956+++ src/libmatrix/test/transpose_test.h 2012-01-27 22:08:04 +0000
2957@@ -0,0 +1,38 @@
2958+//
2959+// Copyright (c) 2010 Linaro Limited
2960+//
2961+// All rights reserved. This program and the accompanying materials
2962+// are made available under the terms of the MIT License which accompanies
2963+// this distribution, and is available at
2964+// http://www.opensource.org/licenses/mit-license.php
2965+//
2966+// Contributors:
2967+// Jesse Barker - original implementation.
2968+//
2969+#ifndef TRANSPOSE_TEST_H_
2970+#define TRANSPOSE_TEST_H_
2971+
2972+class MatrixTest;
2973+class Options;
2974+
2975+class MatrixTest2x2Transpose : public MatrixTest
2976+{
2977+public:
2978+ MatrixTest2x2Transpose() : MatrixTest("mat2::transpose") {}
2979+ virtual void run(const Options& options);
2980+};
2981+
2982+class MatrixTest3x3Transpose : public MatrixTest
2983+{
2984+public:
2985+ MatrixTest3x3Transpose() : MatrixTest("mat3::transpose") {}
2986+ virtual void run(const Options& options);
2987+};
2988+
2989+class MatrixTest4x4Transpose : public MatrixTest
2990+{
2991+public:
2992+ MatrixTest4x4Transpose() : MatrixTest("mat4::transpose") {}
2993+ virtual void run(const Options& options);
2994+};
2995+#endif // TRANSPOSE_TEST_H_
2996
2997=== added file 'src/libmatrix/util.cc'
2998--- src/libmatrix/util.cc 1970-01-01 00:00:00 +0000
2999+++ src/libmatrix/util.cc 2012-01-27 22:08:04 +0000
3000@@ -0,0 +1,165 @@
3001+//
3002+// Copyright (c) 2010-2011 Linaro Limited
3003+//
3004+// All rights reserved. This program and the accompanying materials
3005+// are made available under the terms of the MIT License which accompanies
3006+// this distribution, and is available at
3007+// http://www.opensource.org/licenses/mit-license.php
3008+//
3009+// Contributors:
3010+// Alexandros Frantzis <alexandros.frantzis@linaro.org>
3011+// Jesse Barker <jesse.barker@linaro.org>
3012+//
3013+#include <sstream>
3014+#include <fstream>
3015+#include <sys/time.h>
3016+#ifdef ANDROID
3017+#include <android/asset_manager.h>
3018+#else
3019+#include <dirent.h>
3020+#endif
3021+
3022+#include "log.h"
3023+#include "util.h"
3024+
3025+/**
3026+ * Splits a string using a delimiter
3027+ *
3028+ * @param s the string to split
3029+ * @param delim the delimitir to use
3030+ * @param elems the string vector to populate
3031+ */
3032+void
3033+Util::split(const std::string &s, char delim, std::vector<std::string> &elems)
3034+{
3035+ std::stringstream ss(s);
3036+
3037+ std::string item;
3038+ while(std::getline(ss, item, delim))
3039+ elems.push_back(item);
3040+}
3041+
3042+uint64_t
3043+Util::get_timestamp_us()
3044+{
3045+ struct timeval tv;
3046+ gettimeofday(&tv, NULL);
3047+ uint64_t now = static_cast<uint64_t>(tv.tv_sec) * 1000000 +
3048+ static_cast<double>(tv.tv_usec);
3049+ return now;
3050+}
3051+
3052+std::string
3053+Util::appname_from_path(const std::string& path)
3054+{
3055+ std::string::size_type slashPos = path.rfind("/");
3056+ std::string::size_type startPos(0);
3057+ if (slashPos != std::string::npos)
3058+ {
3059+ startPos = slashPos + 1;
3060+ }
3061+ return std::string(path, startPos, std::string::npos);
3062+}
3063+
3064+#ifndef ANDROID
3065+
3066+std::istream *
3067+Util::get_resource(const std::string &path)
3068+{
3069+ std::ifstream *ifs = new std::ifstream(path.c_str());
3070+
3071+ return static_cast<std::istream *>(ifs);
3072+}
3073+
3074+void
3075+Util::list_files(const std::string& dirName, std::vector<std::string>& fileVec)
3076+{
3077+ DIR* dir = opendir(dirName.c_str());
3078+ if (!dir)
3079+ {
3080+ Log::error("Failed to open models directory '%s'\n", dirName.c_str());
3081+ return;
3082+ }
3083+
3084+ struct dirent* entry = readdir(dir);
3085+ while (entry)
3086+ {
3087+ std::string pathname(dirName + "/");
3088+ pathname += std::string(entry->d_name);
3089+ // Skip '.' and '..'
3090+ if (entry->d_name[0] != '.')
3091+ {
3092+ fileVec.push_back(pathname);
3093+ }
3094+ entry = readdir(dir);
3095+ }
3096+ closedir(dir);
3097+}
3098+
3099+#else
3100+
3101+AAssetManager *Util::android_asset_manager = 0;
3102+
3103+void
3104+Util::android_set_asset_manager(AAssetManager *asset_manager)
3105+{
3106+ Util::android_asset_manager = asset_manager;
3107+}
3108+
3109+AAssetManager *
3110+Util::android_get_asset_manager()
3111+{
3112+ return Util::android_asset_manager;
3113+}
3114+
3115+std::istream *
3116+Util::get_resource(const std::string &path)
3117+{
3118+ std::string path2(path);
3119+ /* Remove leading '/' from path name, it confuses the AssetManager */
3120+ if (path2.size() > 0 && path2[0] == '/')
3121+ path2.erase(0, 1);
3122+
3123+ std::stringstream *ss = new std::stringstream;
3124+ AAsset *asset = AAssetManager_open(Util::android_asset_manager,
3125+ path2.c_str(), AASSET_MODE_RANDOM);
3126+ if (asset) {
3127+ ss->write(reinterpret_cast<const char *>(AAsset_getBuffer(asset)),
3128+ AAsset_getLength(asset));
3129+ Log::debug("Load asset %s\n", path2.c_str());
3130+ AAsset_close(asset);
3131+ }
3132+ else {
3133+ Log::error("Couldn't load asset %s\n", path2.c_str());
3134+ }
3135+
3136+ return static_cast<std::istream *>(ss);
3137+}
3138+
3139+void
3140+Util::list_files(const std::string& dirName, std::vector<std::string>& fileVec)
3141+{
3142+ AAssetManager *mgr(Util::android_get_asset_manager());
3143+ std::string dir_name(dirName);
3144+
3145+ /* Remove leading '/' from path, it confuses the AssetManager */
3146+ if (dir_name.size() > 0 && dir_name[0] == '/')
3147+ dir_name.erase(0, 1);
3148+
3149+ AAssetDir* dir = AAssetManager_openDir(mgr, dir_name.c_str());
3150+ if (!dir)
3151+ {
3152+ Log::error("Failed to open models directory '%s'\n", dir_name.c_str());
3153+ return;
3154+ }
3155+
3156+ const char *filename(0);
3157+ while ((filename = AAssetDir_getNextFileName(dir)) != 0)
3158+ {
3159+ std::string pathname(dir_name + "/");
3160+ pathname += std::string(filename);
3161+ fileVec.push_back(pathname);
3162+ }
3163+ AAssetDir_close(dir);
3164+}
3165+#endif
3166
3167=== added file 'src/libmatrix/util.h'
3168--- src/libmatrix/util.h 1970-01-01 00:00:00 +0000
3169+++ src/libmatrix/util.h 2012-01-27 22:08:04 +0000
3170@@ -0,0 +1,71 @@
3171+//
3172+// Copyright (c) 2010-2011 Linaro Limited
3173+//
3174+// All rights reserved. This program and the accompanying materials
3175+// are made available under the terms of the MIT License which accompanies
3176+// this distribution, and is available at
3177+// http://www.opensource.org/licenses/mit-license.php
3178+//
3179+// Contributors:
3180+// Alexandros Frantzis <alexandros.frantzis@linaro.org>
3181+// Jesse Barker <jesse.barker@linaro.org>
3182+//
3183+#ifndef UTIL_H_
3184+#define UTIL_H_
3185+
3186+#include <string>
3187+#include <vector>
3188+#include <istream>
3189+#include <sstream>
3190+#include <stdint.h>
3191+
3192+#ifdef ANDROID
3193+#include <android/asset_manager_jni.h>
3194+#endif
3195+
3196+struct Util {
3197+ static void split(const std::string &s, char delim, std::vector<std::string> &elems);
3198+ static uint64_t get_timestamp_us();
3199+ static std::istream *get_resource(const std::string &path);
3200+ static void list_files(const std::string& dirName, std::vector<std::string>& fileVec);
3201+ template <class T> static void dispose_pointer_vector(std::vector<T*> &vec)
3202+ {
3203+ for (typename std::vector<T*>::const_iterator iter = vec.begin();
3204+ iter != vec.end();
3205+ iter++)
3206+ {
3207+ delete *iter;
3208+ }
3209+
3210+ vec.clear();
3211+ }
3212+ template<typename T>
3213+ static T
3214+ fromString(const std::string& asString)
3215+ {
3216+ std::stringstream ss(asString);
3217+ T retVal;
3218+ ss >> retVal;
3219+ return retVal;
3220+ }
3221+
3222+ template<typename T>
3223+ static std::string
3224+ toString(const T t)
3225+ {
3226+ std::stringstream ss;
3227+ ss << t;
3228+ return ss.str();
3229+ }
3230+ static std::string
3231+ appname_from_path(const std::string& path);
3232+
3233+#ifdef ANDROID
3234+ static void android_set_asset_manager(AAssetManager *asset_manager);
3235+ static AAssetManager *android_get_asset_manager(void);
3236+private:
3237+ static AAssetManager *android_asset_manager;
3238+#endif
3239+};
3240+
3241+#endif /* UTIL_H */
3242
3243=== modified file 'src/libmatrix/vec.h'
3244--- src/libmatrix/vec.h 2011-09-19 15:30:13 +0000
3245+++ src/libmatrix/vec.h 2012-01-27 22:08:04 +0000
3246@@ -17,6 +17,10 @@
3247
3248 namespace LibMatrix
3249 {
3250+// A template class for creating, managing and operating on a 2-element vector
3251+// of any type you like (intended for built-in types, but as long as it
3252+// supports the basic arithmetic and assignment operators, any type should
3253+// work).
3254 template<typename T>
3255 class tvec2
3256 {
3257@@ -24,10 +28,10 @@
3258 tvec2() :
3259 x_(0),
3260 y_(0) {}
3261- tvec2(T t) :
3262+ tvec2(const T t) :
3263 x_(t),
3264 y_(t) {}
3265- tvec2(T x, T y) :
3266+ tvec2(const T x, const T y) :
3267 x_(x),
3268 y_(y) {}
3269 tvec2(const tvec2& v) :
3270@@ -35,18 +39,26 @@
3271 y_(v.y_) {}
3272 ~tvec2() {}
3273
3274+ // Print the elements of the vector to standard out.
3275+ // Really only useful for debug and test.
3276 void print() const
3277 {
3278 std::cout << "| " << x_ << " " << y_ << " |" << std::endl;
3279 }
3280+
3281+ // Allow raw data access for API calls and the like.
3282+ // For example, it is valid to pass a tvec2<float> into a call to
3283+ // the OpenGL command "glUniform2fv()".
3284 operator const T*() const { return &x_;}
3285
3286+ // Get and set access members for the individual elements.
3287 const T x() const { return x_; }
3288 const T y() const { return y_; }
3289
3290 void x(const T& val) { x_ = val; }
3291 void y(const T& val) { y_ = val; }
3292
3293+ // A direct assignment of 'rhs' to this. Return a reference to this.
3294 tvec2& operator=(const tvec2& rhs)
3295 {
3296 if (this != &rhs)
3297@@ -57,6 +69,7 @@
3298 return *this;
3299 }
3300
3301+ // Divide this by a scalar. Return a reference to this.
3302 tvec2& operator/=(const T& rhs)
3303 {
3304 x_ /= rhs;
3305@@ -64,11 +77,14 @@
3306 return *this;
3307 }
3308
3309+ // Divide a copy of this by a scalar. Return the copy.
3310 const tvec2 operator/(const T& rhs) const
3311 {
3312 return tvec2(*this) /= rhs;
3313 }
3314
3315+ // Component-wise divide of this by another vector.
3316+ // Return a reference to this.
3317 tvec2& operator/=(const tvec2& rhs)
3318 {
3319 x_ /= rhs.x_;
3320@@ -76,11 +92,14 @@
3321 return *this;
3322 }
3323
3324+ // Component-wise divide of a copy of this by another vector.
3325+ // Return the copy.
3326 const tvec2 operator/(const tvec2& rhs) const
3327 {
3328 return tvec2(*this) /= rhs;
3329 }
3330
3331+ // Multiply this by a scalar. Return a reference to this.
3332 tvec2& operator*=(const T& rhs)
3333 {
3334 x_ *= rhs;
3335@@ -88,11 +107,14 @@
3336 return *this;
3337 }
3338
3339+ // Multiply a copy of this by a scalar. Return the copy.
3340 const tvec2 operator*(const T& rhs) const
3341 {
3342 return tvec2(*this) *= rhs;
3343 }
3344
3345+ // Component-wise multiply of this by another vector.
3346+ // Return a reference to this.
3347 tvec2& operator*=(const tvec2& rhs)
3348 {
3349 x_ *= rhs.x_;
3350@@ -100,11 +122,14 @@
3351 return *this;
3352 }
3353
3354+ // Component-wise multiply of a copy of this by another vector.
3355+ // Return the copy.
3356 const tvec2 operator*(const tvec2& rhs) const
3357 {
3358 return tvec2(*this) *= rhs;
3359 }
3360
3361+ // Add a scalar to this. Return a reference to this.
3362 tvec2& operator+=(const T& rhs)
3363 {
3364 x_ += rhs;
3365@@ -112,11 +137,14 @@
3366 return *this;
3367 }
3368
3369+ // Add a scalar to a copy of this. Return the copy.
3370 const tvec2 operator+(const T& rhs) const
3371 {
3372 return tvec2(*this) += rhs;
3373 }
3374
3375+ // Component-wise addition of another vector to this.
3376+ // Return a reference to this.
3377 tvec2& operator+=(const tvec2& rhs)
3378 {
3379 x_ += rhs.x_;
3380@@ -124,11 +152,14 @@
3381 return *this;
3382 }
3383
3384+ // Component-wise addition of another vector to a copy of this.
3385+ // Return the copy.
3386 const tvec2 operator+(const tvec2& rhs) const
3387 {
3388 return tvec2(*this) += rhs;
3389 }
3390
3391+ // Subtract a scalar from this. Return a reference to this.
3392 tvec2& operator-=(const T& rhs)
3393 {
3394 x_ -= rhs;
3395@@ -136,11 +167,14 @@
3396 return *this;
3397 }
3398
3399+ // Subtract a scalar from a copy of this. Return the copy.
3400 const tvec2 operator-(const T& rhs) const
3401 {
3402 return tvec2(*this) -= rhs;
3403 }
3404
3405+ // Component-wise subtraction of another vector from this.
3406+ // Return a reference to this.
3407 tvec2& operator-=(const tvec2& rhs)
3408 {
3409 x_ -= rhs.x_;
3410@@ -148,16 +182,20 @@
3411 return *this;
3412 }
3413
3414+ // Component-wise subtraction of another vector from a copy of this.
3415+ // Return the copy.
3416 const tvec2 operator-(const tvec2& rhs) const
3417 {
3418 return tvec2(*this) -= rhs;
3419 }
3420
3421+ // Compute the length of this and return it.
3422 float length() const
3423 {
3424 return sqrt(dot(*this, *this));
3425 }
3426
3427+ // Make this a unit vector.
3428 void normalize()
3429 {
3430 float l = length();
3431@@ -165,6 +203,7 @@
3432 y_ /= l;
3433 }
3434
3435+ // Compute the dot product of two vectors.
3436 static T dot(const tvec2& v1, const tvec2& v2)
3437 {
3438 return (v1.x_ * v2.x_) + (v1.y_ * v2.y_);
3439@@ -175,6 +214,10 @@
3440 T y_;
3441 };
3442
3443+// A template class for creating, managing and operating on a 3-element vector
3444+// of any type you like (intended for built-in types, but as long as it
3445+// supports the basic arithmetic and assignment operators, any type should
3446+// work).
3447 template<typename T>
3448 class tvec3
3449 {
3450@@ -183,11 +226,11 @@
3451 x_(0),
3452 y_(0),
3453 z_(0) {}
3454- tvec3(T t) :
3455+ tvec3(const T t) :
3456 x_(t),
3457 y_(t),
3458 z_(t) {}
3459- tvec3(T x, T y, T z) :
3460+ tvec3(const T x, const T y, const T z) :
3461 x_(x),
3462 y_(y),
3463 z_(z) {}
3464@@ -197,12 +240,19 @@
3465 z_(v.z_) {}
3466 ~tvec3() {}
3467
3468+ // Print the elements of the vector to standard out.
3469+ // Really only useful for debug and test.
3470 void print() const
3471 {
3472 std::cout << "| " << x_ << " " << y_ << " " << z_ << " |" << std::endl;
3473 }
3474+
3475+ // Allow raw data access for API calls and the like.
3476+ // For example, it is valid to pass a tvec3<float> into a call to
3477+ // the OpenGL command "glUniform3fv()".
3478 operator const T*() const { return &x_;}
3479
3480+ // Get and set access members for the individual elements.
3481 const T x() const { return x_; }
3482 const T y() const { return y_; }
3483 const T z() const { return z_; }
3484@@ -211,6 +261,7 @@
3485 void y(const T& val) { y_ = val; }
3486 void z(const T& val) { z_ = val; }
3487
3488+ // A direct assignment of 'rhs' to this. Return a reference to this.
3489 tvec3& operator=(const tvec3& rhs)
3490 {
3491 if (this != &rhs)
3492@@ -222,6 +273,7 @@
3493 return *this;
3494 }
3495
3496+ // Divide this by a scalar. Return a reference to this.
3497 tvec3& operator/=(const T& rhs)
3498 {
3499 x_ /= rhs;
3500@@ -230,11 +282,14 @@
3501 return *this;
3502 }
3503
3504+ // Divide a copy of this by a scalar. Return the copy.
3505 const tvec3 operator/(const T& rhs) const
3506 {
3507 return tvec3(*this) /= rhs;
3508 }
3509
3510+ // Component-wise divide of this by another vector.
3511+ // Return a reference to this.
3512 tvec3& operator/=(const tvec3& rhs)
3513 {
3514 x_ /= rhs.x_;
3515@@ -243,11 +298,14 @@
3516 return *this;
3517 }
3518
3519+ // Component-wise divide of a copy of this by another vector.
3520+ // Return the copy.
3521 const tvec3 operator/(const tvec3& rhs) const
3522 {
3523 return tvec3(*this) /= rhs;
3524 }
3525
3526+ // Multiply this by a scalar. Return a reference to this.
3527 tvec3& operator*=(const T& rhs)
3528 {
3529 x_ *= rhs;
3530@@ -256,11 +314,14 @@
3531 return *this;
3532 }
3533
3534+ // Multiply a copy of this by a scalar. Return the copy.
3535 const tvec3 operator*(const T& rhs) const
3536 {
3537 return tvec3(*this) *= rhs;
3538 }
3539
3540+ // Component-wise multiply of this by another vector.
3541+ // Return a reference to this.
3542 tvec3& operator*=(const tvec3& rhs)
3543 {
3544 x_ *= rhs.x_;
3545@@ -269,11 +330,14 @@
3546 return *this;
3547 }
3548
3549+ // Component-wise multiply of a copy of this by another vector.
3550+ // Return the copy.
3551 const tvec3 operator*(const tvec3& rhs) const
3552 {
3553 return tvec3(*this) *= rhs;
3554 }
3555
3556+ // Add a scalar to this. Return a reference to this.
3557 tvec3& operator+=(const T& rhs)
3558 {
3559 x_ += rhs;
3560@@ -282,11 +346,14 @@
3561 return *this;
3562 }
3563
3564+ // Add a scalar to a copy of this. Return the copy.
3565 const tvec3 operator+(const T& rhs) const
3566 {
3567 return tvec3(*this) += rhs;
3568 }
3569
3570+ // Component-wise addition of another vector to this.
3571+ // Return a reference to this.
3572 tvec3& operator+=(const tvec3& rhs)
3573 {
3574 x_ += rhs.x_;
3575@@ -295,11 +362,14 @@
3576 return *this;
3577 }
3578
3579+ // Component-wise addition of another vector to a copy of this.
3580+ // Return the copy.
3581 const tvec3 operator+(const tvec3& rhs) const
3582 {
3583 return tvec3(*this) += rhs;
3584 }
3585
3586+ // Subtract a scalar from this. Return a reference to this.
3587 tvec3& operator-=(const T& rhs)
3588 {
3589 x_ -= rhs;
3590@@ -308,11 +378,14 @@
3591 return *this;
3592 }
3593
3594+ // Subtract a scalar from a copy of this. Return the copy.
3595 const tvec3 operator-(const T& rhs) const
3596 {
3597 return tvec3(*this) -= rhs;
3598 }
3599
3600+ // Component-wise subtraction of another vector from this.
3601+ // Return a reference to this.
3602 tvec3& operator-=(const tvec3& rhs)
3603 {
3604 x_ -= rhs.x_;
3605@@ -321,16 +394,20 @@
3606 return *this;
3607 }
3608
3609+ // Component-wise subtraction of another vector from a copy of this.
3610+ // Return the copy.
3611 const tvec3 operator-(const tvec3& rhs) const
3612 {
3613 return tvec3(*this) -= rhs;
3614 }
3615
3616+ // Compute the length of this and return it.
3617 float length() const
3618 {
3619 return sqrt(dot(*this, *this));
3620 }
3621
3622+ // Make this a unit vector.
3623 void normalize()
3624 {
3625 float l = length();
3626@@ -339,11 +416,13 @@
3627 z_ /= l;
3628 }
3629
3630+ // Compute the dot product of two vectors.
3631 static T dot(const tvec3& v1, const tvec3& v2)
3632 {
3633 return (v1.x_ * v2.x_) + (v1.y_ * v2.y_) + (v1.z_ * v2.z_);
3634 }
3635
3636+ // Compute the cross product of two vectors.
3637 static tvec3 cross(const tvec3& u, const tvec3& v)
3638 {
3639 return tvec3((u.y_ * v.z_) - (u.z_ * v.y_),
3640@@ -357,6 +436,10 @@
3641 T z_;
3642 };
3643
3644+// A template class for creating, managing and operating on a 4-element vector
3645+// of any type you like (intended for built-in types, but as long as it
3646+// supports the basic arithmetic and assignment operators, any type should
3647+// work).
3648 template<typename T>
3649 class tvec4
3650 {
3651@@ -366,12 +449,12 @@
3652 y_(0),
3653 z_(0),
3654 w_(0) {}
3655- tvec4(T t) :
3656+ tvec4(const T t) :
3657 x_(t),
3658 y_(t),
3659 z_(t),
3660 w_(t) {}
3661- tvec4(T x, T y, T z, T w) :
3662+ tvec4(const T x, const T y, const T z, const T w) :
3663 x_(x),
3664 y_(y),
3665 z_(z),
3666@@ -383,12 +466,19 @@
3667 w_(v.w_) {}
3668 ~tvec4() {}
3669
3670+ // Print the elements of the vector to standard out.
3671+ // Really only useful for debug and test.
3672 void print() const
3673 {
3674 std::cout << "| " << x_ << " " << y_ << " " << z_ << " " << w_ << " |" << std::endl;
3675 }
3676+
3677+ // Allow raw data access for API calls and the like.
3678+ // For example, it is valid to pass a tvec4<float> into a call to
3679+ // the OpenGL command "glUniform4fv()".
3680 operator const T*() const { return &x_;}
3681
3682+ // Get and set access members for the individual elements.
3683 const T x() const { return x_; }
3684 const T y() const { return y_; }
3685 const T z() const { return z_; }
3686@@ -399,6 +489,7 @@
3687 void z(const T& val) { z_ = val; }
3688 void w(const T& val) { w_ = val; }
3689
3690+ // A direct assignment of 'rhs' to this. Return a reference to this.
3691 tvec4& operator=(const tvec4& rhs)
3692 {
3693 if (this != &rhs)
3694@@ -411,6 +502,7 @@
3695 return *this;
3696 }
3697
3698+ // Divide this by a scalar. Return a reference to this.
3699 tvec4& operator/=(const T& rhs)
3700 {
3701 x_ /= rhs;
3702@@ -420,11 +512,14 @@
3703 return *this;
3704 }
3705
3706+ // Divide a copy of this by a scalar. Return the copy.
3707 const tvec4 operator/(const T& rhs) const
3708 {
3709 return tvec4(*this) /= rhs;
3710 }
3711
3712+ // Component-wise divide of this by another vector.
3713+ // Return a reference to this.
3714 tvec4& operator/=(const tvec4& rhs)
3715 {
3716 x_ /= rhs.x_;
3717@@ -434,11 +529,14 @@
3718 return *this;
3719 }
3720
3721+ // Component-wise divide of a copy of this by another vector.
3722+ // Return the copy.
3723 const tvec4 operator/(const tvec4& rhs) const
3724 {
3725 return tvec4(*this) /= rhs;
3726 }
3727
3728+ // Multiply this by a scalar. Return a reference to this.
3729 tvec4& operator*=(const T& rhs)
3730 {
3731 x_ *= rhs;
3732@@ -448,11 +546,14 @@
3733 return *this;
3734 }
3735
3736+ // Multiply a copy of this by a scalar. Return the copy.
3737 const tvec4 operator*(const T& rhs) const
3738 {
3739 return tvec4(*this) *= rhs;
3740 }
3741
3742+ // Component-wise multiply of this by another vector.
3743+ // Return a reference to this.
3744 tvec4& operator*=(const tvec4& rhs)
3745 {
3746 x_ *= rhs.x_;
3747@@ -462,11 +563,14 @@
3748 return *this;
3749 }
3750
3751+ // Component-wise multiply of a copy of this by another vector.
3752+ // Return the copy.
3753 const tvec4 operator*(const tvec4& rhs) const
3754 {
3755 return tvec4(*this) *= rhs;
3756 }
3757
3758+ // Add a scalar to this. Return a reference to this.
3759 tvec4& operator+=(const T& rhs)
3760 {
3761 x_ += rhs;
3762@@ -476,11 +580,14 @@
3763 return *this;
3764 }
3765
3766+ // Add a scalar to a copy of this. Return the copy.
3767 const tvec4 operator+(const T& rhs) const
3768 {
3769 return tvec4(*this) += rhs;
3770 }
3771
3772+ // Component-wise addition of another vector to this.
3773+ // Return a reference to this.
3774 tvec4& operator+=(const tvec4& rhs)
3775 {
3776 x_ += rhs.x_;
3777@@ -490,11 +597,14 @@
3778 return *this;
3779 }
3780
3781+ // Component-wise addition of another vector to a copy of this.
3782+ // Return the copy.
3783 const tvec4 operator+(const tvec4& rhs) const
3784 {
3785 return tvec4(*this) += rhs;
3786 }
3787
3788+ // Subtract a scalar from this. Return a reference to this.
3789 tvec4& operator-=(const T& rhs)
3790 {
3791 x_ -= rhs;
3792@@ -504,11 +614,14 @@
3793 return *this;
3794 }
3795
3796+ // Subtract a scalar from a copy of this. Return the copy.
3797 const tvec4 operator-(const T& rhs) const
3798 {
3799 return tvec4(*this) -= rhs;
3800 }
3801
3802+ // Component-wise subtraction of another vector from this.
3803+ // Return a reference to this.
3804 tvec4& operator-=(const tvec4& rhs)
3805 {
3806 x_ -= rhs.x_;
3807@@ -518,16 +631,20 @@
3808 return *this;
3809 }
3810
3811+ // Component-wise subtraction of another vector from a copy of this.
3812+ // Return the copy.
3813 const tvec4 operator-(const tvec4& rhs) const
3814 {
3815 return tvec4(*this) -= rhs;
3816 }
3817
3818+ // Compute the length of this and return it.
3819 float length() const
3820 {
3821 return sqrt(dot(*this, *this));
3822 }
3823
3824+ // Make this a unit vector.
3825 void normalize()
3826 {
3827 float l = length();
3828@@ -537,6 +654,7 @@
3829 w_ /= l;
3830 }
3831
3832+ // Compute the dot product of two vectors.
3833 static T dot(const tvec4& v1, const tvec4& v2)
3834 {
3835 return (v1.x_ * v2.x_) + (v1.y_ * v2.y_) + (v1.z_ * v2.z_) + (v1.w_ * v2.w_);
3836@@ -575,4 +693,24 @@
3837
3838 } // namespace LibMatrix
3839
3840+// Global operators to allow for things like defining a new vector in terms of
3841+// a product of a scalar and a vector
3842+template<typename T>
3843+const LibMatrix::tvec2<T> operator*(const T t, const LibMatrix::tvec2<T>& v)
3844+{
3845+ return v * t;
3846+}
3847+
3848+template<typename T>
3849+const LibMatrix::tvec3<T> operator*(const T t, const LibMatrix::tvec3<T>& v)
3850+{
3851+ return v * t;
3852+}
3853+
3854+template<typename T>
3855+const LibMatrix::tvec4<T> operator*(const T t, const LibMatrix::tvec4<T>& v)
3856+{
3857+ return v * t;
3858+}
3859+
3860 #endif // VEC_H_
3861
3862=== removed file 'src/log.cpp'
3863--- src/log.cpp 2011-11-11 10:36:48 +0000
3864+++ src/log.cpp 1970-01-01 00:00:00 +0000
3865@@ -1,182 +0,0 @@
3866-/*
3867- * Copyright © 2011 Linaro Limited
3868- *
3869- * This file is part of glcompbench.
3870- *
3871- * glcompbench is free software: you can redistribute it and/or modify
3872- * it under the terms of the GNU General Public License as published by
3873- * the Free Software Foundation, either version 3 of the License, or
3874- * (at your option) any later version.
3875- *
3876- * glcompbench is distributed in the hope that it will be useful,
3877- * but WITHOUT ANY WARRANTY; without even the implied warranty of
3878- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3879- * GNU General Public License for more details.
3880- *
3881- * You should have received a copy of the GNU General Public License
3882- * along with glcompbench. If not, see <http://www.gnu.org/licenses/>.
3883- *
3884- * Authors:
3885- * Alexandros Frantzis <alexandros.frantzis@linaro.org>
3886- * Jesse Barker <jesse.barker@linaro.org>
3887- */
3888-
3889-#include <cstdio>
3890-#include <cstdarg>
3891-#include <string>
3892-#include <sstream>
3893-
3894-#include "options.h"
3895-#include "log.h"
3896-
3897-#ifdef ANDROID
3898-#include <android/log.h>
3899-#endif
3900-
3901-#ifndef ANDROID
3902-
3903-static const char *terminal_color_normal("\033[0m");
3904-static const char *terminal_color_red("\033[1;31m");
3905-static const char *terminal_color_cyan("\033[36m");
3906-static const char *terminal_color_yellow("\033[33m");
3907-
3908-static void
3909-print_prefixed_message(FILE *stream, const char *color, const char *prefix,
3910- const char *fmt, va_list ap)
3911-{
3912- va_list aq;
3913-
3914- /* Estimate message size */
3915- va_copy(aq, ap);
3916- int msg_size = vsnprintf(NULL, 0, fmt, aq);
3917- va_end(aq);
3918-
3919- /* Create the buffer to hold the message */
3920- char *buf = new char[msg_size + 1];
3921-
3922- /* Store the message in the buffer */
3923- va_copy(aq, ap);
3924- vsnprintf(buf, msg_size + 1, fmt, aq);
3925- va_end(aq);
3926-
3927- /*
3928- * Print the message lines prefixed with the supplied prefix.
3929- * If the target stream is a terminal make the prefix colored.
3930- */
3931- bool use_color = isatty(fileno(stream));
3932- const char *start_color(use_color ? color : "");
3933- const char *end_color(use_color && *color ? terminal_color_normal : "");
3934-
3935- std::string line;
3936- std::stringstream ss(buf);
3937-
3938- while(std::getline(ss, line)) {
3939- /*
3940- * If this line is a continuation of a previous log message
3941- * just print the line plainly.
3942- */
3943- if (line[0] == LOG_CONTINUE[0]) {
3944- fprintf(stream, "%s", line.c_str() + 1);
3945- }
3946- else {
3947- /* Normal line, emit the prefix. */
3948- fprintf(stream, "%s%s%s: %s", start_color, prefix, end_color,
3949- line.c_str());
3950- }
3951-
3952- /* Only emit a newline if the original message has it. */
3953- if (!(ss.rdstate() & std::stringstream::eofbit))
3954- fputs("\n", stream);
3955- }
3956-
3957- delete[] buf;
3958-}
3959-
3960-static void
3961-print_plain_message(FILE *stream, const char *fmt, va_list ap)
3962-{
3963- va_list aq;
3964- const char *msg = fmt;
3965-
3966- if (msg[0] == LOG_CONTINUE[0])
3967- msg++;
3968-
3969- va_copy(aq, ap);
3970- vfprintf(stream, msg, ap);
3971- va_end(aq);
3972-}
3973-
3974-void
3975-Log::info(const char *fmt, ...)
3976-{
3977- va_list ap;
3978- va_start(ap, fmt);
3979- if (Options::show_debug)
3980- print_prefixed_message(stdout, terminal_color_cyan, "Info", fmt, ap);
3981- else
3982- print_plain_message(stdout, fmt, ap);
3983- va_end(ap);
3984-}
3985-
3986-void
3987-Log::debug(const char *fmt, ...)
3988-{
3989- if (!Options::show_debug)
3990- return;
3991- va_list ap;
3992- va_start(ap, fmt);
3993- print_prefixed_message(stdout, terminal_color_yellow, "Debug", fmt, ap);
3994- va_end(ap);
3995-}
3996-
3997-void
3998-Log::error(const char *fmt, ...)
3999-{
4000- va_list ap;
4001- va_start(ap, fmt);
4002- print_prefixed_message(stderr, terminal_color_red, "Error", fmt, ap);
4003- va_end(ap);
4004-}
4005-
4006-void
4007-Log::flush()
4008-{
4009- fflush(stdout);
4010- fflush(stderr);
4011-}
4012-#else
4013-void
4014-Log::info(const char *fmt, ...)
4015-{
4016- va_list ap;
4017- va_start(ap, fmt);
4018- __android_log_vprint(ANDROID_LOG_INFO, "glmark2", fmt, ap);
4019- va_end(ap);
4020-}
4021-
4022-void
4023-Log::debug(const char *fmt, ...)
4024-{
4025- if (!Options::show_debug)
4026- return;
4027- va_list ap;
4028- va_start(ap, fmt);
4029- __android_log_vprint(ANDROID_LOG_DEBUG, "glmark2", fmt, ap);
4030- va_end(ap);
4031-}
4032-
4033-void
4034-Log::error(const char *fmt, ...)
4035-{
4036- va_list ap;
4037- va_start(ap, fmt);
4038- __android_log_vprint(ANDROID_LOG_ERROR, "glmark2", fmt, ap);
4039- va_end(ap);
4040-}
4041-
4042-void
4043-Log::flush()
4044-{
4045-}
4046-
4047-#endif
4048
4049=== removed file 'src/log.h'
4050--- src/log.h 2011-11-10 10:33:26 +0000
4051+++ src/log.h 1970-01-01 00:00:00 +0000
4052@@ -1,43 +0,0 @@
4053-/*
4054- * Copyright © 2011 Linaro Limited
4055- *
4056- * This file is part of glcompbench.
4057- *
4058- * glcompbench is free software: you can redistribute it and/or modify
4059- * it under the terms of the GNU General Public License as published by
4060- * the Free Software Foundation, either version 3 of the License, or
4061- * (at your option) any later version.
4062- *
4063- * glcompbench is distributed in the hope that it will be useful,
4064- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4065- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4066- * GNU General Public License for more details.
4067- *
4068- * You should have received a copy of the GNU General Public License
4069- * along with glcompbench. If not, see <http://www.gnu.org/licenses/>.
4070- *
4071- * Authors:
4072- * Alexandros Frantzis <alexandros.frantzis@linaro.org>
4073- * Jesse Barker <jesse.barker@linaro.org>
4074- */
4075-
4076-#ifndef LOG_H_
4077-#define LOG_H_
4078-
4079-/**
4080- * A prefix that informs the logging infrastructure that the log
4081- * message is a continuation of a previous log message to be put
4082- * on the same line.
4083- */
4084-#define LOG_CONTINUE "\x10"
4085-
4086-class Log
4087-{
4088-public:
4089- static void info(const char *fmt, ...);
4090- static void debug(const char *fmt, ...);
4091- static void error(const char *fmt, ...);
4092- static void flush();
4093-};
4094-
4095-#endif /* LOG_H_ */
4096
4097=== modified file 'src/main.cpp'
4098--- src/main.cpp 2012-01-19 10:58:18 +0000
4099+++ src/main.cpp 2012-01-27 22:08:04 +0000
4100@@ -1,6 +1,6 @@
4101 /*
4102 * Copyright © 2008 Ben Smith
4103- * Copyright © 2010-2011 Linaro Limited
4104+ * Copyright © 2010-2012 Linaro Limited
4105 *
4106 * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
4107 *
4108@@ -20,6 +20,7 @@
4109 * Authors:
4110 * Ben Smith (original glmark benchmark)
4111 * Alexandros Frantzis (glmark2)
4112+ * Jesse Barker (glmark2)
4113 */
4114 #include "gl-headers.h"
4115 #include "scene.h"
4116@@ -177,6 +178,7 @@
4117 unsigned score = 0;
4118 unsigned int last_fps = 0;
4119 unsigned int benchmarks_run = 0;
4120+ static const string format(Log::continuation_prefix + " FPS: %u\n");
4121
4122 for (vector<Benchmark *>::iterator bench_iter = benchmarks.begin();
4123 bench_iter != benchmarks.end();
4124@@ -219,7 +221,7 @@
4125 canvas.update();
4126 }
4127
4128- Log::info(LOG_CONTINUE" FPS: %u\n", scene.average_fps());
4129+ Log::info(format.c_str(), scene.average_fps());
4130 score += scene.average_fps();
4131 benchmarks_run++;
4132 }
4133@@ -242,6 +244,7 @@
4134 void
4135 do_validation(Canvas &canvas, vector<Benchmark *> &benchmarks)
4136 {
4137+ static const string format(Log::continuation_prefix + " Validation: %s\n");
4138 for (vector<Benchmark *>::iterator bench_iter = benchmarks.begin();
4139 bench_iter != benchmarks.end();
4140 bench_iter++)
4141@@ -275,7 +278,7 @@
4142 break;
4143 }
4144
4145- Log::info(LOG_CONTINUE" Validation: %s\n", result.c_str());
4146+ Log::info(format.c_str(), result.c_str());
4147 }
4148
4149 bench->teardown_scene();
4150@@ -289,6 +292,9 @@
4151 if (!Options::parse_args(argc, argv))
4152 return 1;
4153
4154+ /* Initialize Log class */
4155+ Log::init(Util::appname_from_path(argv[0]), Options::show_debug);
4156+
4157 if (Options::show_help) {
4158 Options::print_help();
4159 return 0;
4160
4161=== modified file 'src/options.cpp'
4162--- src/options.cpp 2012-01-18 17:13:28 +0000
4163+++ src/options.cpp 2012-01-27 22:08:04 +0000
4164@@ -1,5 +1,5 @@
4165 /*
4166- * Copyright © 2011 Linaro Limited
4167+ * Copyright © 2011-2012 Linaro Limited
4168 *
4169 * This file is part of glcompbench.
4170 *
4171@@ -29,7 +29,6 @@
4172
4173 #include "options.h"
4174 #include "util.h"
4175-#include "log.h"
4176
4177 std::vector<std::string> Options::benchmarks;
4178 std::vector<std::string> Options::benchmark_files;
4179
4180=== modified file 'src/scene-effect-2d.cpp'
4181--- src/scene-effect-2d.cpp 2011-12-08 11:09:09 +0000
4182+++ src/scene-effect-2d.cpp 2012-01-27 22:08:04 +0000
4183@@ -1,5 +1,5 @@
4184 /*
4185- * Copyright © 2010-2011 Linaro Limited
4186+ * Copyright © 2010-2012 Linaro Limited
4187 *
4188 * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
4189 *
4190@@ -196,6 +196,9 @@
4191 Util::split(str, ';', rows);
4192
4193 Log::debug("Parsing kernel matrix:\n");
4194+ static const std::string format("%f ");
4195+ static const std::string format_cont(Log::continuation_prefix + format);
4196+ static const std::string newline(Log::continuation_prefix + "\n");
4197
4198 for (std::vector<std::string>::const_iterator iter = rows.begin();
4199 iter != rows.end();
4200@@ -220,12 +223,12 @@
4201 float f(Util::fromString<float>(*iter_el));
4202 matrix.push_back(f);
4203 if (iter_el == elems.begin())
4204- Log::debug("%f ", f);
4205+ Log::debug(format.c_str(), f);
4206 else
4207- Log::debug(LOG_CONTINUE"%f ", f);
4208+ Log::debug(format_cont.c_str(), f);
4209 }
4210
4211- Log::debug(LOG_CONTINUE"\n");
4212+ Log::debug(newline.c_str());
4213 }
4214
4215 width = w;
4216
4217=== removed file 'src/shader-source.cpp'
4218--- src/shader-source.cpp 2011-12-12 12:39:00 +0000
4219+++ src/shader-source.cpp 1970-01-01 00:00:00 +0000
4220@@ -1,625 +0,0 @@
4221-/*
4222- * Copyright © 2010-2011 Linaro Limited
4223- *
4224- * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
4225- *
4226- * glmark2 is free software: you can redistribute it and/or modify it under the
4227- * terms of the GNU General Public License as published by the Free Software
4228- * Foundation, either version 3 of the License, or (at your option) any later
4229- * version.
4230- *
4231- * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
4232- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4233- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
4234- * details.
4235- *
4236- * You should have received a copy of the GNU General Public License along with
4237- * glmark2. If not, see <http://www.gnu.org/licenses/>.
4238- *
4239- * Authors:
4240- * Alexandros Frantzis (glmark2)
4241- */
4242-
4243-#include <istream>
4244-#include <memory>
4245-
4246-#include "shader-source.h"
4247-#include "log.h"
4248-#include "vec.h"
4249-#include "util.h"
4250-
4251-/**
4252- * Holds default precision values for all shader types
4253- * (even the unknown type, which is hardwired to default precision values)
4254- */
4255-std::vector<ShaderSource::Precision>
4256-ShaderSource::default_precision_(ShaderSource::ShaderTypeUnknown + 1);
4257-
4258-/**
4259- * Loads the contents of a file into a string.
4260- *
4261- * @param filename the name of the file
4262- * @param str the string to put the contents of the file into
4263- */
4264-bool
4265-ShaderSource::load_file(const std::string& filename, std::string& str)
4266-{
4267- std::auto_ptr<std::istream> is_ptr(Util::get_resource(filename));
4268- std::istream& inputFile(*is_ptr);
4269-
4270- if (!inputFile)
4271- {
4272- Log::error("Failed to open \"%s\"\n", filename.c_str());
4273- return false;
4274- }
4275-
4276- std::string curLine;
4277- while (getline(inputFile, curLine))
4278- {
4279- str += curLine;
4280- str += '\n';
4281- }
4282-
4283- return true;
4284-}
4285-
4286-
4287-/**
4288- * Appends a string to the shader source.
4289- *
4290- * @param str the string to append
4291- */
4292-void
4293-ShaderSource::append(const std::string &str)
4294-{
4295- source_ << str;
4296-}
4297-
4298-/**
4299- * Appends the contents of a file to the shader source.
4300- *
4301- * @param filename the name of the file to append
4302- */
4303-void
4304-ShaderSource::append_file(const std::string &filename)
4305-{
4306- std::string source;
4307- if (load_file(filename, source))
4308- source_ << source;
4309-}
4310-
4311-/**
4312- * Replaces a string in the source with another string.
4313- *
4314- * @param remove the string to replace
4315- * @param insert the string to replace with
4316- */
4317-void
4318-ShaderSource::replace(const std::string &remove, const std::string &insert)
4319-{
4320- std::string::size_type pos = 0;
4321- std::string str(source_.str());
4322-
4323- while ((pos = str.find(remove, pos)) != std::string::npos) {
4324- str.replace(pos, remove.size(), insert);
4325- pos++;
4326- }
4327-
4328- source_.clear();
4329- source_.str(str);
4330-}
4331-
4332-/**
4333- * Replaces a string in the source with the contents of a file.
4334- *
4335- * @param remove the string to replace
4336- * @param filename the name of the file to read from
4337- */
4338-void
4339-ShaderSource::replace_with_file(const std::string &remove, const std::string &filename)
4340-{
4341- std::string source;
4342- if (load_file(filename, source))
4343- replace(remove, source);
4344-}
4345-
4346-/**
4347- * Adds a string (usually containing a constant definition) at
4348- * global (per shader) scope.
4349- *
4350- * The string is placed after any default precision qualifiers.
4351- *
4352- * @param str the string to add
4353- */
4354-void
4355-ShaderSource::add_global(const std::string &str)
4356-{
4357- std::string::size_type pos = 0;
4358- std::string source(source_.str());
4359-
4360- /* Find the last precision qualifier */
4361- pos = source.rfind("precision");
4362-
4363- if (pos != std::string::npos) {
4364- /*
4365- * Find the next #endif line of a preprocessor block that contains
4366- * the precision qualifier.
4367- */
4368- std::string::size_type pos_if = source.find("#if", pos);
4369- std::string::size_type pos_endif = source.find("#endif", pos);
4370-
4371- if (pos_endif != std::string::npos && pos_endif < pos_if)
4372- pos = pos_endif;
4373-
4374- /* Go to the next line */
4375- pos = source.find("\n", pos);
4376- if (pos != std::string::npos)
4377- pos++;
4378- }
4379- else
4380- pos = 0;
4381-
4382- source.insert(pos, str);
4383-
4384- source_.clear();
4385- source_.str(source);
4386-}
4387-
4388-/**
4389- * Adds a string (usually containing a constant definition) at
4390- * global (per shader) scope.
4391- *
4392- * The string is placed after any default precision qualifiers.
4393- *
4394- * @param function the function to add the string into
4395- * @param str the string to add
4396- */
4397-void
4398-ShaderSource::add_local(const std::string &str, const std::string &function)
4399-{
4400- std::string::size_type pos = 0;
4401- std::string source(source_.str());
4402-
4403- /* Find the function */
4404- pos = source.find(function);
4405- pos = source.find('{', pos);
4406-
4407- /* Go to the next line */
4408- pos = source.find("\n", pos);
4409- if (pos != std::string::npos)
4410- pos++;
4411-
4412- source.insert(pos, str);
4413-
4414- source_.clear();
4415- source_.str(source);
4416-}
4417-
4418-/**
4419- * Adds a string (usually containing a constant definition) to a shader source
4420- *
4421- * If the function parameter is empty, the string will be added to global
4422- * scope, after any precision definitions.
4423- *
4424- * @param str the string to add
4425- * @param function if not empty, the function to add the string into
4426- */
4427-void
4428-ShaderSource::add(const std::string &str, const std::string &function)
4429-{
4430- if (!function.empty())
4431- add_local(str, function);
4432- else
4433- add_global(str);
4434-}
4435-
4436-/**
4437- * Adds a float constant definition.
4438- *
4439- * @param name the name of the constant
4440- * @param f the value of the constant
4441- * @param function if not empty, the function to put the definition in
4442- */
4443-void
4444-ShaderSource::add_const(const std::string &name, float f,
4445- const std::string &function)
4446-{
4447- std::stringstream ss;
4448-
4449- ss << "const float " << name << " = " << std::fixed << f << ";" << std::endl;
4450-
4451- add(ss.str(), function);
4452-}
4453-
4454-/**
4455- * Adds a float array constant definition.
4456- *
4457- * Note that various GLSL versions (including ES) don't support
4458- * array constants.
4459- *
4460- * @param name the name of the constant
4461- * @param v the value of the constant
4462- * @param function if not empty, the function to put the definition in
4463- */
4464-void
4465-ShaderSource::add_const(const std::string &name, std::vector<float> &array,
4466- const std::string &function)
4467-{
4468- std::stringstream ss;
4469-
4470- ss << "const float " << name << "[" << array.size() << "] = {" << std::fixed;
4471- for(std::vector<float>::const_iterator iter = array.begin();
4472- iter != array.end();
4473- iter++)
4474- {
4475- ss << *iter;
4476- if (iter + 1 != array.end())
4477- ss << ", " << std::endl;
4478- }
4479-
4480- ss << "};" << std::endl;
4481-
4482- add(ss.str(), function);
4483-}
4484-
4485-/**
4486- * Adds a vec2 constant definition.
4487- *
4488- * @param name the name of the constant
4489- * @param v the value of the constant
4490- * @param function if not empty, the function to put the definition in
4491- */
4492-void
4493-ShaderSource::add_const(const std::string &name, const LibMatrix::vec2 &v,
4494- const std::string &function)
4495-{
4496- std::stringstream ss;
4497-
4498- ss << "const vec2 " << name << " = vec2(" << std::fixed;
4499- ss << v.x() << ", " << v.y() << ");" << std::endl;
4500-
4501- add(ss.str(), function);
4502-}
4503-
4504-/**
4505- * Adds a vec3 constant definition.
4506- *
4507- * @param name the name of the constant
4508- * @param v the value of the constant
4509- * @param function if not empty, the function to put the definition in
4510- */
4511-void
4512-ShaderSource::add_const(const std::string &name, const LibMatrix::vec3 &v,
4513- const std::string &function)
4514-{
4515- std::stringstream ss;
4516-
4517- ss << "const vec3 " << name << " = vec3(" << std::fixed;
4518- ss << v.x() << ", " << v.y() << ", " << v.z() << ");" << std::endl;
4519-
4520- add(ss.str(), function);
4521-}
4522-
4523-/**
4524- * Adds a vec4 constant definition.
4525- *
4526- * @param name the name of the constant
4527- * @param v the value of the constant
4528- * @param function if not empty, the function to put the definition in
4529- */
4530-void
4531-ShaderSource::add_const(const std::string &name, const LibMatrix::vec4 &v,
4532- const std::string &function)
4533-{
4534- std::stringstream ss;
4535-
4536- ss << "const vec4 " << name << " = vec4(" << std::fixed;
4537- ss << v.x() << ", " << v.y() << ", " << v.z() << ", " << v.w() << ");" << std::endl;
4538-
4539- add(ss.str(), function);
4540-}
4541-
4542-/**
4543- * Adds a mat3 constant definition.
4544- *
4545- * @param name the name of the constant
4546- * @param v the value of the constant
4547- * @param function if not empty, the function to put the definition in
4548- */
4549-void
4550-ShaderSource::add_const(const std::string &name, const LibMatrix::mat3 &m,
4551- const std::string &function)
4552-{
4553- std::stringstream ss;
4554-
4555- ss << "const mat3 " << name << " = mat3(" << std::fixed;
4556- ss << m[0][0] << ", " << m[1][0] << ", " << m[2][0] << "," << std::endl;
4557- ss << m[0][1] << ", " << m[1][1] << ", " << m[2][1] << "," << std::endl;
4558- ss << m[0][2] << ", " << m[1][2] << ", " << m[2][2] << std::endl;
4559- ss << ");" << std::endl;
4560-
4561- add(ss.str(), function);
4562-}
4563-
4564-/**
4565- * Adds a float array declaration and initialization.
4566- *
4567- * @param name the name of the array
4568- * @param array the array values
4569- * @param init_function the function to put the initialization in
4570- * @param decl_function if not empty, the function to put the declaration in
4571- */
4572-void
4573-ShaderSource::add_array(const std::string &name, std::vector<float> &array,
4574- const std::string &init_function,
4575- const std::string &decl_function)
4576-{
4577- if (init_function.empty() || name.empty())
4578- return;
4579-
4580- std::stringstream ss;
4581- ss << "float " << name << "[" << array.size() << "];" << std::endl;
4582-
4583- std::string decl(ss.str());
4584-
4585- ss.clear();
4586- ss.str("");
4587- ss << std::fixed;
4588-
4589- for(std::vector<float>::const_iterator iter = array.begin();
4590- iter != array.end();
4591- iter++)
4592- {
4593- ss << name << "[" << iter - array.begin() << "] = " << *iter << ";" << std::endl;
4594- }
4595-
4596- add(ss.str(), init_function);
4597-
4598- add(decl, decl_function);
4599-}
4600-
4601-/**
4602- * Gets the ShaderType for this ShaderSource.
4603- *
4604- * If the ShaderType is unknown, an attempt is made to infer
4605- * the type from the shader source contents.
4606- *
4607- * @return the ShaderType
4608- */
4609-ShaderSource::ShaderType
4610-ShaderSource::type()
4611-{
4612- /* Try to infer the type from the source contents */
4613- if (type_ == ShaderSource::ShaderTypeUnknown) {
4614- std::string source(source_.str());
4615-
4616- if (source.find("gl_FragColor") != std::string::npos)
4617- type_ = ShaderSource::ShaderTypeFragment;
4618- else if (source.find("gl_Position") != std::string::npos)
4619- type_ = ShaderSource::ShaderTypeVertex;
4620- else
4621- Log::debug("Cannot infer shader type from contents. Leaving it Unknown.\n");
4622- }
4623-
4624- return type_;
4625-}
4626-
4627-/**
4628- * Helper function that emits a precision statement.
4629- *
4630- * @param ss the stringstream to add the statement to
4631- * @param val the precision value
4632- * @param type_str the variable type to apply the precision value to
4633- */
4634-void
4635-ShaderSource::emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val,
4636- const std::string& type_str)
4637-{
4638- static const char *precision_map[] = {
4639- "lowp", "mediump", "highp", NULL
4640- };
4641-
4642- if (val == ShaderSource::PrecisionValueHigh) {
4643- if (type_ == ShaderSource::ShaderTypeFragment)
4644- ss << "#ifdef GL_FRAGMENT_PRECISION_HIGH" << std::endl;
4645-
4646- ss << "precision highp " << type_str << ";" << std::endl;
4647-
4648- if (type_ == ShaderSource::ShaderTypeFragment) {
4649- ss << "#else" << std::endl;
4650- ss << "precision mediump " << type_str << ";" << std::endl;
4651- ss << "#endif" << std::endl;
4652- }
4653- }
4654- else if (val >= 0 && val < ShaderSource::PrecisionValueDefault) {
4655- ss << "precision " << precision_map[val] << " ";
4656- ss << type_str << ";" << std::endl;
4657- }
4658-
4659- /* There is no default precision in the fragment shader, so set it to mediump */
4660- if (val == ShaderSource::PrecisionValueDefault
4661- && type_str == "float" && type_ == ShaderSource::ShaderTypeFragment)
4662- {
4663- ss << "precision mediump float;" << std::endl;
4664- }
4665-}
4666-
4667-/**
4668- * Gets a string containing the complete shader source.
4669- *
4670- * Precision statements are applied at this point.
4671- *
4672- * @return the shader source
4673- */
4674-std::string
4675-ShaderSource::str()
4676-{
4677- /* Decide which precision values to use */
4678- ShaderSource::Precision precision;
4679-
4680- /* Ensure we have tried to infer the type from the contents */
4681- type();
4682-
4683- if (precision_has_been_set_)
4684- precision = precision_;
4685- else
4686- precision = default_precision(type_);
4687-
4688- /* Create the precision statements */
4689- std::stringstream ss;
4690-
4691- emit_precision(ss, precision.int_precision, "int");
4692- emit_precision(ss, precision.float_precision, "float");
4693- emit_precision(ss, precision.sampler2d_precision, "sampler2D");
4694- emit_precision(ss, precision.samplercube_precision, "samplerCube");
4695-
4696- std::string precision_str(ss.str());
4697- if (!precision_str.empty()) {
4698- precision_str.insert(0, "#ifdef GL_ES\n");
4699- precision_str.insert(precision_str.size(), "#endif\n");
4700- }
4701-
4702- return precision_str + source_.str();
4703-}
4704-
4705-/**
4706- * Sets the precision that will be used for this shader.
4707- *
4708- * This overrides any default values set with ShaderSource::default_*_precision().
4709- *
4710- * @param precision the precision to set
4711- */
4712-void
4713-ShaderSource::precision(const ShaderSource::Precision& precision)
4714-{
4715- precision_ = precision;
4716- precision_has_been_set_ = true;
4717-}
4718-
4719-/**
4720- * Gets the precision that will be used for this shader.
4721- *
4722- * @return the precision
4723- */
4724-const ShaderSource::Precision&
4725-ShaderSource::precision()
4726-{
4727- return precision_;
4728-}
4729-
4730-/**
4731- * Sets the default precision that will be used for a shaders type.
4732- *
4733- * If type is ShaderTypeUnknown the supplied precision is used for all
4734- * shader types.
4735- *
4736- * This can be overriden per ShaderSource object by using ::precision().
4737- *
4738- * @param precision the default precision to set
4739- * @param type the ShaderType to use the precision for
4740- */
4741-void
4742-ShaderSource::default_precision(const ShaderSource::Precision& precision,
4743- ShaderSource::ShaderType type)
4744-{
4745- if (type < 0 || type > ShaderSource::ShaderTypeUnknown)
4746- type = ShaderSource::ShaderTypeUnknown;
4747-
4748- if (type == ShaderSource::ShaderTypeUnknown) {
4749- for (size_t i = 0; i < ShaderSource::ShaderTypeUnknown; i++)
4750- default_precision_[i] = precision;
4751- }
4752- else {
4753- default_precision_[type] = precision;
4754- }
4755-}
4756-
4757-/**
4758- * Gets the default precision that will be used for a shader type.
4759- *
4760- * It is valid to use a type of ShaderTypeUnknown. This will always
4761- * return a Precision with default values.
4762- *
4763- * @param type the ShaderType to get the precision of
4764- *
4765- * @return the precision
4766- */
4767-const ShaderSource::Precision&
4768-ShaderSource::default_precision(ShaderSource::ShaderType type)
4769-{
4770- if (type < 0 || type > ShaderSource::ShaderTypeUnknown)
4771- type = ShaderSource::ShaderTypeUnknown;
4772-
4773- return default_precision_[type];
4774-}
4775-
4776-/****************************************
4777- * ShaderSource::Precision constructors *
4778- ****************************************/
4779-
4780-/**
4781- * Creates a ShaderSource::Precision with default precision values.
4782- */
4783-ShaderSource::Precision::Precision() :
4784- int_precision(ShaderSource::PrecisionValueDefault),
4785- float_precision(ShaderSource::PrecisionValueDefault),
4786- sampler2d_precision(ShaderSource::PrecisionValueDefault),
4787- samplercube_precision(ShaderSource::PrecisionValueDefault)
4788-{
4789-}
4790-
4791-/**
4792- * Creates a ShaderSource::Precision using the supplied precision values.
4793- */
4794-ShaderSource::Precision::Precision(ShaderSource::PrecisionValue int_p,
4795- ShaderSource::PrecisionValue float_p,
4796- ShaderSource::PrecisionValue sampler2d_p,
4797- ShaderSource::PrecisionValue samplercube_p) :
4798- int_precision(int_p), float_precision(float_p),
4799- sampler2d_precision(sampler2d_p), samplercube_precision(samplercube_p)
4800-{
4801-}
4802-
4803-/**
4804- * Creates a ShaderSource::Precision from a string representation of
4805- * precision values.
4806- *
4807- * The string format is:
4808- * "<int>,<float>,<sampler2d>,<samplercube>"
4809- *
4810- * Each precision value is one of "high", "medium", "low" or "default".
4811- *
4812- * @param precision_values the string representation of the precision values
4813- */
4814-ShaderSource::Precision::Precision(const std::string& precision_values) :
4815- int_precision(ShaderSource::PrecisionValueDefault),
4816- float_precision(ShaderSource::PrecisionValueDefault),
4817- sampler2d_precision(ShaderSource::PrecisionValueDefault),
4818- samplercube_precision(ShaderSource::PrecisionValueDefault)
4819-{
4820- std::vector<std::string> elems;
4821-
4822- Util::split(precision_values, ',', elems);
4823-
4824- for (size_t i = 0; i < elems.size() && i < 4; i++) {
4825- const std::string& pstr(elems[i]);
4826- ShaderSource::PrecisionValue pval;
4827-
4828- if (pstr == "high")
4829- pval = ShaderSource::PrecisionValueHigh;
4830- else if (pstr == "medium")
4831- pval = ShaderSource::PrecisionValueMedium;
4832- else if (pstr == "low")
4833- pval = ShaderSource::PrecisionValueLow;
4834- else
4835- pval = ShaderSource::PrecisionValueDefault;
4836-
4837- switch(i) {
4838- case 0: int_precision = pval; break;
4839- case 1: float_precision = pval; break;
4840- case 2: sampler2d_precision = pval; break;
4841- case 3: samplercube_precision = pval; break;
4842- default: break;
4843- }
4844- }
4845-}
4846
4847=== removed file 'src/shader-source.h'
4848--- src/shader-source.h 2011-11-29 10:36:37 +0000
4849+++ src/shader-source.h 1970-01-01 00:00:00 +0000
4850@@ -1,113 +0,0 @@
4851-/*
4852- * Copyright © 2010-2011 Linaro Limited
4853- *
4854- * This file is part of the glmark2 OpenGL (ES) 2.0 benchmark.
4855- *
4856- * glmark2 is free software: you can redistribute it and/or modify it under the
4857- * terms of the GNU General Public License as published by the Free Software
4858- * Foundation, either version 3 of the License, or (at your option) any later
4859- * version.
4860- *
4861- * glmark2 is distributed in the hope that it will be useful, but WITHOUT ANY
4862- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
4863- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
4864- * details.
4865- *
4866- * You should have received a copy of the GNU General Public License along with
4867- * glmark2. If not, see <http://www.gnu.org/licenses/>.
4868- *
4869- * Authors:
4870- * Alexandros Frantzis (glmark2)
4871- */
4872-
4873-#include <string>
4874-#include <sstream>
4875-#include <vector>
4876-#include "vec.h"
4877-#include "mat.h"
4878-
4879-/**
4880- * Helper class for loading and manipulating shader sources.
4881- */
4882-class ShaderSource
4883-{
4884-public:
4885- enum ShaderType {
4886- ShaderTypeVertex,
4887- ShaderTypeFragment,
4888- ShaderTypeUnknown
4889- };
4890-
4891- ShaderSource(ShaderType type = ShaderTypeUnknown) :
4892- precision_has_been_set_(false), type_(type) {}
4893- ShaderSource(const std::string &filename, ShaderType type = ShaderTypeUnknown) :
4894- precision_has_been_set_(false), type_(type) { append_file(filename); }
4895-
4896- void append(const std::string &str);
4897- void append_file(const std::string &filename);
4898-
4899- void replace(const std::string &remove, const std::string &insert);
4900- void replace_with_file(const std::string &remove, const std::string &filename);
4901-
4902- void add(const std::string &str, const std::string &function = "");
4903-
4904- void add_const(const std::string &name, float f,
4905- const std::string &function = "");
4906- void add_const(const std::string &name, std::vector<float> &f,
4907- const std::string &function = "");
4908- void add_const(const std::string &name, const LibMatrix::vec2 &v,
4909- const std::string &function = "");
4910- void add_const(const std::string &name, const LibMatrix::vec3 &v,
4911- const std::string &function = "");
4912- void add_const(const std::string &name, const LibMatrix::vec4 &v,
4913- const std::string &function = "");
4914- void add_const(const std::string &name, const LibMatrix::mat3 &m,
4915- const std::string &function = "");
4916-
4917- void add_array(const std::string &name, std::vector<float> &array,
4918- const std::string &init_function,
4919- const std::string &decl_function = "");
4920-
4921- ShaderType type();
4922- std::string str();
4923-
4924- enum PrecisionValue {
4925- PrecisionValueLow,
4926- PrecisionValueMedium,
4927- PrecisionValueHigh,
4928- PrecisionValueDefault,
4929- };
4930-
4931- struct Precision {
4932- Precision();
4933- Precision(PrecisionValue int_p, PrecisionValue float_p,
4934- PrecisionValue sampler2d_p, PrecisionValue samplercube_p);
4935- Precision(const std::string& list);
4936-
4937- PrecisionValue int_precision;
4938- PrecisionValue float_precision;
4939- PrecisionValue sampler2d_precision;
4940- PrecisionValue samplercube_precision;
4941- };
4942-
4943- void precision(const Precision& precision);
4944- const Precision& precision();
4945-
4946- static void default_precision(const Precision& precision,
4947- ShaderType type = ShaderTypeUnknown);
4948- static const Precision& default_precision(ShaderType type);
4949-
4950-private:
4951- void add_global(const std::string &str);
4952- void add_local(const std::string &str, const std::string &function);
4953- bool load_file(const std::string& filename, std::string& str);
4954- void emit_precision(std::stringstream& ss, ShaderSource::PrecisionValue val,
4955- const std::string& type_str);
4956-
4957- std::stringstream source_;
4958- Precision precision_;
4959- bool precision_has_been_set_;
4960- ShaderType type_;
4961-
4962- static std::vector<Precision> default_precision_;
4963-};
4964
4965=== removed file 'src/util.cpp'
4966--- src/util.cpp 2011-11-08 20:41:46 +0000
4967+++ src/util.cpp 1970-01-01 00:00:00 +0000
4968@@ -1,164 +0,0 @@
4969-/*
4970- * Copyright © 2011 Linaro Limited
4971- *
4972- * This file is part of glcompbench.
4973- *
4974- * glcompbench is free software: you can redistribute it and/or modify
4975- * it under the terms of the GNU General Public License as published by
4976- * the Free Software Foundation, either version 3 of the License, or
4977- * (at your option) any later version.
4978- *
4979- * glcompbench is distributed in the hope that it will be useful,
4980- * but WITHOUT ANY WARRANTY; without even the implied warranty of
4981- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4982- * GNU General Public License for more details.
4983- *
4984- * You should have received a copy of the GNU General Public License
4985- * along with glcompbench. If not, see <http://www.gnu.org/licenses/>.
4986- *
4987- * Authors:
4988- * Alexandros Frantzis <alexandros.frantzis@linaro.org>
4989- * Jesse Barker <jesse.barker@linaro.org>
4990- */
4991-
4992-#include <sstream>
4993-#include <fstream>
4994-#include <sys/time.h>
4995-#ifdef ANDROID
4996-#include <android/asset_manager.h>
4997-#else
4998-#include <dirent.h>
4999-#endif
5000-
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches

to all changes: