--- /dev/null
+// XGL tests
+//
+// Copyright (C) 2014 LunarG, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#include "xgltestframework.h"
+#include "GL/freeglut_std.h"
+
+XglTestFramework::XglTestFramework() :
+ m_glut_initialized( false )
+{
+}
+
+// Define all the static elements
+bool XglTestFramework::m_show_images = false;
+bool XglTestFramework::m_save_images = false;
+int XglTestFramework::m_width = 0;
+int XglTestFramework::m_height = 0;
+int XglTestFramework::m_window = 0;
+std::list<XglTestImageRecord> XglTestFramework::m_images;
+std::list<XglTestImageRecord>::iterator XglTestFramework::m_display_image;
+int m_display_image_idx = 0;
+
+void XglTestFramework::InitArgs(int *argc, char *argv[])
+{
+ int i, n;
+
+ for (i=0, n=0; i< *argc; i++) {
+ if (strncmp("--show-images", argv[i], 13) == 0) {
+ m_show_images = true;
+ continue;
+ }
+ if (strncmp("--save-images", argv[i], 13) == 0) {
+ m_save_images = true;
+ continue;
+ }
+
+ /*
+ * Since the above "consume" inputs, update argv
+ * so that it contains the trimmed list of args for glutInit
+ */
+ argv[n] = argv[i];
+ n++;
+ }
+
+ if (m_show_images) {
+ glutInit(argc, argv);
+ }
+}
+
+void XglTestFramework::Reshape( int w, int h )
+{
+ if (!m_show_images) return; // Do nothing except save info if not enabled
+
+ // Resize window to be large enough to handle biggest image we've seen
+ // TODO: Probably need some sort of limits for the Window system.
+ if (w > m_width) {
+ m_width = w;
+ }
+ if (h > m_height) {
+ m_height = h;
+ }
+
+ glutReshapeWindow(m_width, m_height);
+
+ glViewport( 0, 0, m_width, m_height );
+ glMatrixMode( GL_PROJECTION );
+ glLoadIdentity();
+ glOrtho( 0.0, m_width, 0.0, m_height, 0.0, 2.0 );
+ glMatrixMode( GL_MODELVIEW );
+ glLoadIdentity();
+
+// glScissor(width/4, height/4, width/2, height/2);
+}
+
+void XglTestFramework::WritePPM( const char *basename, XglImage *image )
+{
+ string filename;
+ XGL_RESULT err;
+ int x, y;
+
+ filename.append(basename);
+ filename.append(".ppm");
+
+ const XGL_IMAGE_SUBRESOURCE sr = {
+ XGL_IMAGE_ASPECT_COLOR, 0, 0
+ };
+ XGL_SUBRESOURCE_LAYOUT sr_layout;
+ XGL_UINT data_size;
+
+ err = xglGetImageSubresourceInfo( image->image(), &sr,
+ XGL_INFO_TYPE_SUBRESOURCE_LAYOUT,
+ &data_size, &sr_layout);
+ ASSERT_XGL_SUCCESS( err );
+ ASSERT_EQ(data_size, sizeof(sr_layout));
+
+ const char *ptr;
+
+ err = xglMapMemory( image->memory(), 0, (XGL_VOID **) &ptr );
+ ASSERT_XGL_SUCCESS( err );
+
+ ptr += sr_layout.offset;
+
+ ofstream file (filename.c_str());
+ ASSERT_TRUE(file.is_open()) << "Unable to open file: " << filename;
+
+ file << "P6\n";
+ file << image->width() << "\n";
+ file << image->height() << "\n";
+ file << 255 << "\n";
+
+ for (y = 0; y < image->height(); y++) {
+ const char *row = ptr;
+
+ for (x = 0; x < image->width(); x++) {
+ file.write(row, 3);
+ row += 4;
+ }
+
+ ptr += sr_layout.rowPitch;
+ }
+
+ file.close();
+
+ err = xglUnmapMemory( image->memory() );
+ ASSERT_XGL_SUCCESS( err );
+}
+
+void XglTestFramework::InitGLUT(int w, int h)
+{
+
+ if (!m_show_images) return;
+
+ if (!m_glut_initialized) {
+ glutInitWindowSize(w, h);
+
+ glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
+ m_window = glutCreateWindow(NULL);
+ m_glut_initialized = true;
+ }
+
+ Reshape(w, h);
+}
+
+void XglTestFramework::Show(const char *comment, XglImage *image)
+{
+ XGL_RESULT err;
+
+ const XGL_IMAGE_SUBRESOURCE sr = {
+ XGL_IMAGE_ASPECT_COLOR, 0, 0
+ };
+ XGL_SUBRESOURCE_LAYOUT sr_layout;
+ XGL_UINT data_size;
+
+ if (!m_show_images) return;
+
+ InitGLUT(image->width(), image->height());
+
+ err = xglGetImageSubresourceInfo( image->image(), &sr, XGL_INFO_TYPE_SUBRESOURCE_LAYOUT,
+ &data_size, &sr_layout);
+ ASSERT_XGL_SUCCESS( err );
+ ASSERT_EQ(data_size, sizeof(sr_layout));
+
+ const char *ptr;
+
+ err = image->MapMemory( (XGL_VOID **) &ptr );
+ ASSERT_XGL_SUCCESS( err );
+
+ ptr += sr_layout.offset;
+
+ XglTestImageRecord record;
+ record.m_title.append(comment);
+ record.m_width = image->width();
+ record.m_height = image->height();
+ // TODO: Need to make this more robust to handle different image formats
+ record.m_data_size = image->width()*image->height()*4;
+ record.m_data = malloc(record.m_data_size);
+ memcpy(record.m_data, ptr, record.m_data_size);
+ m_images.push_back(record);
+ m_display_image = --m_images.end();
+
+ Display();
+
+ err = image->UnmapMemory();
+ ASSERT_XGL_SUCCESS( err );
+}
+
+void XglTestFramework::RecordImage(XglImage *image)
+{
+ const ::testing::TestInfo* const test_info =
+ ::testing::UnitTest::GetInstance()->current_test_info();
+
+ if (m_save_images) {
+ WritePPM(test_info->test_case_name(), image);
+ }
+
+ if (m_show_images) {
+ Show(test_info->test_case_name(), image);
+ }
+}
+
+void XglTestFramework::Display()
+{
+ glutSetWindowTitle(m_display_image->m_title.c_str());
+
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_COLOR_BUFFER_BIT);
+ glRasterPos3f(0, 0, 0);
+ glBitmap(0, 0, 0, 0, 0, 0, NULL);
+ glDrawPixels(m_display_image->m_width, m_display_image->m_height,
+ GL_RGBA, GL_UNSIGNED_BYTE, m_display_image->m_data);
+
+ glutSwapBuffers();
+}
+
+void XglTestFramework::Key( unsigned char key, int x, int y )
+{
+ (void) x;
+ (void) y;
+ switch (key) {
+ case 27:
+ glutDestroyWindow(m_window);
+ exit(0);
+ break;
+ }
+ glutPostRedisplay();
+}
+
+void XglTestFramework::SpecialKey( int key, int x, int y )
+{
+ (void) x;
+ (void) y;
+ switch (key) {
+ case GLUT_KEY_UP:
+ case GLUT_KEY_RIGHT:
+ ++m_display_image;
+ if (m_display_image == m_images.end()) {
+ m_display_image = m_images.begin();
+ }
+ break;
+ case GLUT_KEY_DOWN:
+ case GLUT_KEY_LEFT:
+ if (m_display_image == m_images.begin()) {
+ m_display_image = --m_images.end();
+ } else {
+ --m_display_image;
+ }
+
+ break;
+ }
+ glutPostRedisplay();
+}
+
+void XglTestFramework::Finish()
+{
+ if (m_images.size() == 0) return;
+
+ glutReshapeFunc( Reshape );
+ glutKeyboardFunc( Key );
+ glutSpecialFunc( SpecialKey );
+ glutDisplayFunc( Display );
+
+ glutMainLoop();
+}
+
+
+
+XglTestImageRecord::XglTestImageRecord() : // Constructor
+ m_width( 0 ),
+ m_height( 0 ),
+ m_data( NULL )
+{
+ m_data_size = 0;
+}
+
+XglTestImageRecord::~XglTestImageRecord()
+{
+
+}
+
+XglTestImageRecord::XglTestImageRecord(const XglTestImageRecord ©in) // Copy constructor to handle pass by value.
+{
+ m_title = copyin.m_title;
+ m_width = copyin.m_width;
+ m_height = copyin.m_height;
+ m_data_size = copyin.m_data_size;
+ m_data = copyin.m_data; // TODO: Do we need to copy the data or is pointer okay?
+}
+
+ostream &operator<<(ostream &output, const XglTestImageRecord &XglTestImageRecord)
+{
+ output << XglTestImageRecord.m_title << " (" << XglTestImageRecord.m_width <<
+ "," << XglTestImageRecord.m_height << ")" << endl;
+ return output;
+}
+
+XglTestImageRecord& XglTestImageRecord::operator=(const XglTestImageRecord &rhs)
+{
+ m_title = rhs.m_title;
+ m_width = rhs.m_width;
+ m_height = rhs.m_height;
+ m_data_size = rhs.m_data_size;
+ m_data = rhs.m_data;
+ return *this;
+}
+
+int XglTestImageRecord::operator==(const XglTestImageRecord &rhs) const
+{
+ if( this->m_data != rhs.m_data) return 0;
+ return 1;
+}
+
+// This function is required for built-in STL list functions like sort
+int XglTestImageRecord::operator<(const XglTestImageRecord &rhs) const
+{
+ if( this->m_data_size < rhs.m_data_size ) return 1;
+ return 0;
+}
+
--- /dev/null
+// XGL tests
+//
+// Copyright (C) 2014 LunarG, Inc.
+//
+// Permission is hereby granted, free of charge, to any person obtaining a
+// copy of this software and associated documentation files (the "Software"),
+// to deal in the Software without restriction, including without limitation
+// the rights to use, copy, modify, merge, publish, distribute, sublicense,
+// and/or sell copies of the Software, and to permit persons to whom the
+// Software is furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included
+// in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef XGLTESTFRAMEWORK_H
+#define XGLTESTFRAMEWORK_H
+
+#include "gtest-1.7.0/include/gtest/gtest.h"
+#include "xglimage.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <iostream>
+#include <fstream>
+#include <list>
+using namespace std;
+
+class XglTestImageRecord
+{
+public:
+ XglTestImageRecord();
+ XglTestImageRecord(const XglTestImageRecord &);
+ ~XglTestImageRecord();
+ XglTestImageRecord &operator=(const XglTestImageRecord &rhs);
+ int operator==(const XglTestImageRecord &rhs) const;
+ int operator<(const XglTestImageRecord &rhs) const;
+
+ string m_title;
+ void *m_data;
+ unsigned m_data_size;
+ int m_width;
+ int m_height;
+};
+
+class XglTestFramework : public ::testing::Test
+{
+public:
+ XglTestFramework();
+
+ static void InitArgs(int *argc, char *argv[]);
+ static void Finish();
+
+ void WritePPM( const char *basename, XglImage *image );
+ void Show(const char *comment, XglImage *image);
+ void RecordImage(XglImage *image);
+
+private:
+ static void Reshape( int w, int h );
+ static void Display();
+ static void Key(unsigned char key, int x, int y);
+ static void SpecialKey( int key, int x, int y );
+
+ void InitGLUT(int w, int h);
+
+ static bool m_show_images;
+ static bool m_save_images;
+ static std::list<XglTestImageRecord> m_images;
+ static std::list<XglTestImageRecord>::iterator m_display_image;
+ static int m_display_image_idx;
+
+ bool m_glut_initialized;
+ static int m_window;
+ static int m_width; // Window width
+ static int m_height; // Window height
+};
+
+#endif // XGLTESTFRAMEWORK_H