Commit 8a079e5e by Geoff Lang

Added an angle_tests project and base class for tests.

TRAC #23776 Signed-off-by: Jamie Madill Signed-off-by: Shannon Woods
parent 1ec57f80
#include "ANGLETest.h"
ANGLETest::ANGLETest()
: mClientVersion(2)
, mWidth(1280)
, mHeight(720)
, mRedBits(-1)
, mGreenBits(-1)
, mBlueBits(-1)
, mAlphaBits(-1)
, mDepthBits(-1)
, mStencilBits(-1)
, mMultisample(false)
{
}
EGLDisplay ANGLETest::mDisplay = 0;
EGLNativeWindowType ANGLETest::mNativeWindow = 0;
EGLNativeDisplayType ANGLETest::mNativeDisplay = 0;
void ANGLETest::SetUp()
{
ReizeWindow(mWidth, mHeight);
if (!createEGLContext())
{
FAIL() << "egl context creation failed.";
}
}
void ANGLETest::TearDown()
{
swapBuffers();
if (!destroyEGLContext())
{
FAIL() << "egl context destruction failed.";
}
}
void ANGLETest::swapBuffers()
{
eglSwapBuffers(mDisplay, mSurface);
}
void ANGLETest::drawQuad(GLuint program, const std::string& positionAttribName, GLfloat quadDepth)
{
GLint positionLocation = glGetAttribLocation(program, positionAttribName.c_str());
glUseProgram(program);
const GLfloat vertices[] =
{
-1.0f, 1.0f, quadDepth,
-1.0f, -1.0f, quadDepth,
1.0f, -1.0f, quadDepth,
-1.0f, 1.0f, quadDepth,
1.0f, -1.0f, quadDepth,
1.0f, 1.0f, quadDepth,
};
glVertexAttribPointer(positionLocation, 3, GL_FLOAT, GL_FALSE, 0, vertices);
glEnableVertexAttribArray(positionLocation);
glDrawArrays(GL_TRIANGLES, 0, 6);
glDisableVertexAttribArray(positionLocation);
glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, NULL);
glUseProgram(0);
}
GLuint ANGLETest::compileProgram(const std::string &vsSource, const std::string &fsSource)
{
GLuint program = glCreateProgram();
GLuint vs = glCreateShader(GL_VERTEX_SHADER);
const char *vsSourceArray[1] = { vsSource.c_str() };
glShaderSource(vs, 1, vsSourceArray, NULL);
glCompileShader(vs);
glAttachShader(program, vs);
glDeleteShader(vs);
GLuint fs = glCreateShader(GL_FRAGMENT_SHADER);
const char *fsSourceArray[1] = { fsSource.c_str() };
glShaderSource(fs, 1, fsSourceArray, NULL);
glCompileShader(fs);
glAttachShader(program, fs);
glDeleteShader(fs);
glLinkProgram(program);
GLint linkStatus;
glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
if (!linkStatus)
{
glDeleteProgram(program);
program = 0;
}
return program;
}
bool ANGLETest::extensionEnabled(const std::string &extName)
{
const char* extString = reinterpret_cast<const char*>(glGetString(GL_EXTENSIONS));
return strstr(extString, extName.c_str()) != NULL;
}
void ANGLETest::setClientVersion(int clientVersion)
{
mClientVersion = clientVersion;
}
void ANGLETest::setWindowWidth(int width)
{
mWidth = width;
}
void ANGLETest::setWindowHeight(int height)
{
mHeight = height;
}
void ANGLETest::setRedBits(int bits)
{
mRedBits = bits;
}
void ANGLETest::setGreenBits(int bits)
{
mGreenBits = bits;
}
void ANGLETest::setBlueBits(int bits)
{
mBlueBits = bits;
}
void ANGLETest::setAlphaBits(int bits)
{
mAlphaBits = bits;
}
void ANGLETest::setDepthBits(int bits)
{
mDepthBits = bits;
}
void ANGLETest::setStencilBits(int bits)
{
mStencilBits = bits;
}
void ANGLETest::setMultisampleEnabled(bool enabled)
{
mMultisample = enabled;
}
int ANGLETest::getClientVersion() const
{
return mClientVersion;
}
int ANGLETest::getWindowWidth() const
{
return mWidth;
}
int ANGLETest::getWindowHeight() const
{
return mHeight;
}
int ANGLETest::getRedBits() const
{
return mRedBits;
}
int ANGLETest::getGreenBits() const
{
return mGreenBits;
}
int ANGLETest::getBlueBits() const
{
return mBlueBits;
}
int ANGLETest::getAlphaBits() const
{
return mAlphaBits;
}
int ANGLETest::getDepthBits() const
{
return mDepthBits;
}
int ANGLETest::getStencilBits() const
{
return mStencilBits;
}
bool ANGLETest::multisampleEnabled() const
{
return mMultisample;
}
bool ANGLETest::createEGLContext()
{
const EGLint configAttributes[] =
{
EGL_RED_SIZE, (mRedBits >= 0) ? mRedBits : EGL_DONT_CARE,
EGL_GREEN_SIZE, (mGreenBits >= 0) ? mGreenBits : EGL_DONT_CARE,
EGL_BLUE_SIZE, (mBlueBits >= 0) ? mBlueBits : EGL_DONT_CARE,
EGL_ALPHA_SIZE, (mAlphaBits >= 0) ? mAlphaBits : EGL_DONT_CARE,
EGL_DEPTH_SIZE, (mDepthBits >= 0) ? mDepthBits : EGL_DONT_CARE,
EGL_STENCIL_SIZE, (mStencilBits >= 0) ? mStencilBits : EGL_DONT_CARE,
EGL_SAMPLE_BUFFERS, mMultisample ? 1 : 0,
EGL_NONE
};
EGLint configCount;
if (!eglChooseConfig(mDisplay, configAttributes, &mConfig, 1, &configCount) || (configCount != 1))
{
destroyEGLContext();
return false;
}
eglGetConfigAttrib(mDisplay, mConfig, EGL_RED_SIZE, &mRedBits);
eglGetConfigAttrib(mDisplay, mConfig, EGL_GREEN_SIZE, &mGreenBits);
eglGetConfigAttrib(mDisplay, mConfig, EGL_BLUE_SIZE, &mBlueBits);
eglGetConfigAttrib(mDisplay, mConfig, EGL_ALPHA_SIZE, &mBlueBits);
eglGetConfigAttrib(mDisplay, mConfig, EGL_DEPTH_SIZE, &mDepthBits);
eglGetConfigAttrib(mDisplay, mConfig, EGL_STENCIL_SIZE, &mStencilBits);
EGLint samples;
eglGetConfigAttrib(mDisplay, mConfig, EGL_SAMPLE_BUFFERS, &samples);
mMultisample = (samples != 0);
mSurface = eglCreateWindowSurface(mDisplay, mConfig, mNativeWindow, NULL);
if(mSurface == EGL_NO_SURFACE)
{
eglGetError(); // Clear error
mSurface = eglCreateWindowSurface(mDisplay, mConfig, NULL, NULL);
}
if (eglGetError() != EGL_SUCCESS)
{
destroyEGLContext();
return false;
}
EGLint contextAttibutes[] =
{
EGL_CONTEXT_CLIENT_VERSION, mClientVersion,
EGL_NONE
};
mContext = eglCreateContext(mDisplay, mConfig, NULL, contextAttibutes);
if (eglGetError() != EGL_SUCCESS)
{
destroyEGLContext();
return false;
}
eglMakeCurrent(mDisplay, mSurface, mSurface, mContext);
if (eglGetError() != EGL_SUCCESS)
{
destroyEGLContext();
return false;
}
return true;
}
bool ANGLETest::destroyEGLContext()
{
eglDestroySurface(mDisplay, mSurface);
eglDestroyContext(mDisplay, mContext);
return true;
}
//
// Copyright (c) 2012 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#ifndef ANGLE_TESTS_ANGLE_TEST_H_
#define ANGLE_TESTS_ANGLE_TEST_H_
#include "gtest/gtest.h"
#define GL_GLEXT_PROTOTYPES
#include <GLES3/gl3.h>
#include <GLES3/gl3ext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>
#include <EGL/egl.h>
#include <EGL/eglext.h>
#define EXPECT_GL_ERROR(err) EXPECT_EQ(glGetError(), (err))
#define EXPECT_GL_NO_ERROR() EXPECT_GL_ERROR(GL_NO_ERROR)
#define ASSERT_GL_ERROR(err) EXPECT_EQ(glGetError(), (err))
#define ASSERT_GL_NO_ERROR() ASSERT_GL_ERROR(GL_NO_ERROR)
#define EXPECT_PIXEL_EQ(x, y, r, g, b, a) \
{ \
GLubyte pixel[4]; \
glReadPixels((x), (y), 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); \
EXPECT_GL_NO_ERROR(); \
EXPECT_EQ(pixel[0], (r)); \
EXPECT_EQ(pixel[1], (g)); \
EXPECT_EQ(pixel[2], (b)); \
EXPECT_EQ(pixel[3], (a)); \
}
#define SHADER_SOURCE(...) #__VA_ARGS__
class ANGLETest : public testing::Test
{
protected:
ANGLETest();
public:
static bool InitTestWindow();
static bool DestroyTestWindow();
static bool ReizeWindow(int width, int height);
protected:
virtual void SetUp();
virtual void TearDown();
virtual void swapBuffers();
static void drawQuad(GLuint program, const std::string& positionAttribName, GLfloat quadDepth);
static GLuint compileProgram(const std::string &vsSource, const std::string &fsSource);
static bool extensionEnabled(const std::string &extName);
void setClientVersion(int clientVersion);
void setWindowWidth(int width);
void setWindowHeight(int height);
void setRedBits(int bits);
void setGreenBits(int bits);
void setBlueBits(int bits);
void setAlphaBits(int bits);
void setDepthBits(int bits);
void setStencilBits(int bits);
void setMultisampleEnabled(bool enabled);
int getClientVersion() const;
int getWindowWidth() const;
int getWindowHeight() const;
int getRedBits() const;
int getGreenBits() const;
int getBlueBits() const;
int getAlphaBits() const;
int getDepthBits() const;
int getStencilBits() const;
bool multisampleEnabled() const;
private:
bool createEGLContext();
bool destroyEGLContext();
int mClientVersion;
int mWidth;
int mHeight;
int mRedBits;
int mGreenBits;
int mBlueBits;
int mAlphaBits;
int mDepthBits;
int mStencilBits;
bool mMultisample;
EGLConfig mConfig;
EGLSurface mSurface;
EGLContext mContext;
static EGLDisplay mDisplay;
static EGLNativeWindowType mNativeWindow;
static EGLNativeDisplayType mNativeDisplay;
};
#endif // ANGLE_TESTS_ANGLE_TEST_H_
//
// Copyright (c) 2013 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "ANGLETest.h"
int main(int argc, char** argv)
{
if (!ANGLETest::InitTestWindow())
{
return -1;
}
testing::InitGoogleMock(&argc, argv);
int rt = RUN_ALL_TESTS();
ANGLETest::DestroyTestWindow();
return rt;
}
#include "ANGLETest.h"
#include <windows.h>
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_CLOSE:
PostQuitMessage(0);
return 1;
default:
break;
}
return DefWindowProc(hWnd, message, wParam, lParam);
}
static const PTCHAR GetTestWindowName()
{
return TEXT("ANGLE_TEST");
}
bool ANGLETest::InitTestWindow()
{
WNDCLASS sWC;
sWC.style = CS_OWNDC;
sWC.lpfnWndProc = WndProc;
sWC.cbClsExtra = 0;
sWC.cbWndExtra = 0;
sWC.hInstance = NULL;
sWC.hIcon = NULL;
sWC.hCursor = LoadCursor(NULL, IDC_ARROW);
sWC.lpszMenuName = NULL;
sWC.hbrBackground = NULL;
sWC.lpszClassName = GetTestWindowName();
if (!RegisterClass(&sWC))
{
return false;
}
mNativeWindow = CreateWindow(GetTestWindowName(), NULL, WS_BORDER, 128, 128, 128, 128, NULL, NULL, NULL, NULL);
SetWindowLong(mNativeWindow, GWL_STYLE, 0);
ShowWindow(mNativeWindow, SW_SHOW);
mNativeDisplay = GetDC(mNativeWindow);
if (!mNativeDisplay)
{
DestroyTestWindow();
return false;
}
mDisplay = eglGetDisplay(mNativeDisplay);
if(mDisplay == EGL_NO_DISPLAY)
{
mDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
}
EGLint majorVersion, minorVersion;
if (!eglInitialize(mDisplay, &majorVersion, &minorVersion))
{
DestroyTestWindow();
return false;
}
eglBindAPI(EGL_OPENGL_ES_API);
if (eglGetError() != EGL_SUCCESS)
{
DestroyTestWindow();
return false;
}
return true;
}
bool ANGLETest::DestroyTestWindow()
{
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglTerminate(mDisplay);
if (mNativeDisplay)
{
ReleaseDC(mNativeWindow, mNativeDisplay);
mNativeDisplay = 0;
}
if (mNativeWindow)
{
DestroyWindow(mNativeWindow);
mNativeWindow = 0;
}
UnregisterClass(GetTestWindowName(), NULL);
return true;
}
bool ANGLETest::ReizeWindow(int width, int height)
{
RECT windowRect;
if (!GetWindowRect(mNativeWindow, &windowRect))
{
return false;
}
if (!MoveWindow(mNativeWindow, windowRect.left, windowRect.top, width, height, FALSE))
{
return false;
}
return true;
}
......@@ -99,6 +99,38 @@
],
},
],
'conditions':
[
['OS=="win"',
{
'targets':
[
{
'target_name': 'angle_tests',
'type': 'executable',
'dependencies':
[
'../src/angle.gyp:libGLESv2',
'../src/angle.gyp:libEGL',
'gtest',
'gmock',
],
'include_dirs':
[
'../include',
'angle_tests',
'third_party/googletest/include',
'third_party/googlemock/include',
],
'sources':
[
'<!@(python enumerate_files.py angle_tests -types *.cpp *.h)'
],
},
],
}],
],
}
# Local Variables:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment