GLTest.cpp revision f3730fb8f7da368740f9e5ed2603b405aeb4be72
1#include "GLTest.h" 2 3#include <gui/Surface.h> 4 5#include <GLES2/gl2.h> 6 7namespace android { 8 9static int abs(int value) { 10 return value > 0 ? value : -value; 11} 12 13void GLTest::SetUp() { 14 const ::testing::TestInfo* const testInfo = 15 ::testing::UnitTest::GetInstance()->current_test_info(); 16 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), testInfo->name()); 17 18 mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 19 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 20 ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay); 21 22 EGLint majorVersion; 23 EGLint minorVersion; 24 EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion)); 25 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 26 RecordProperty("EglVersionMajor", majorVersion); 27 RecordProperty("EglVersionMinor", minorVersion); 28 29 EGLint numConfigs = 0; 30 EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig, 1, 31 &numConfigs)); 32 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 33 34 char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS"); 35 if (displaySecsEnv != NULL) { 36 mDisplaySecs = atoi(displaySecsEnv); 37 if (mDisplaySecs < 0) { 38 mDisplaySecs = 0; 39 } 40 } else { 41 mDisplaySecs = 0; 42 } 43 44 if (mDisplaySecs > 0) { 45 mComposerClient = new SurfaceComposerClient; 46 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); 47 48 mSurfaceControl = mComposerClient->createSurface( 49 String8("Test Surface"), getSurfaceWidth(), getSurfaceHeight(), 50 PIXEL_FORMAT_RGB_888, 0); 51 52 ASSERT_TRUE(mSurfaceControl != NULL); 53 ASSERT_TRUE(mSurfaceControl->isValid()); 54 55 SurfaceComposerClient::openGlobalTransaction(); 56 ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF)); 57 ASSERT_EQ(NO_ERROR, mSurfaceControl->show()); 58 SurfaceComposerClient::closeGlobalTransaction(); 59 60 sp<ANativeWindow> window = mSurfaceControl->getSurface(); 61 mEglSurface = createWindowSurface(mEglDisplay, mGlConfig, window); 62 } else { 63 EGLint pbufferAttribs[] = { 64 EGL_WIDTH, getSurfaceWidth(), 65 EGL_HEIGHT, getSurfaceHeight(), 66 EGL_NONE }; 67 68 mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig, 69 pbufferAttribs); 70 } 71 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 72 ASSERT_NE(EGL_NO_SURFACE, mEglSurface); 73 74 mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT, 75 getContextAttribs()); 76 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 77 ASSERT_NE(EGL_NO_CONTEXT, mEglContext); 78 79 EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 80 mEglContext)); 81 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 82 83 EGLint w, h; 84 EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w)); 85 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 86 EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h)); 87 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 88 RecordProperty("EglSurfaceWidth", w); 89 RecordProperty("EglSurfaceHeight", h); 90 91 glViewport(0, 0, w, h); 92 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 93} 94 95void GLTest::TearDown() { 96 // Display the result 97 if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) { 98 eglSwapBuffers(mEglDisplay, mEglSurface); 99 sleep(mDisplaySecs); 100 } 101 102 if (mComposerClient != NULL) { 103 mComposerClient->dispose(); 104 } 105 if (mEglContext != EGL_NO_CONTEXT) { 106 eglDestroyContext(mEglDisplay, mEglContext); 107 } 108 if (mEglSurface != EGL_NO_SURFACE) { 109 eglDestroySurface(mEglDisplay, mEglSurface); 110 } 111 if (mEglDisplay != EGL_NO_DISPLAY) { 112 eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 113 EGL_NO_CONTEXT); 114 eglTerminate(mEglDisplay); 115 } 116 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 117 118 const ::testing::TestInfo* const testInfo = 119 ::testing::UnitTest::GetInstance()->current_test_info(); 120 ALOGV("End test: %s.%s", testInfo->test_case_name(), testInfo->name()); 121} 122 123EGLint const* GLTest::getConfigAttribs() { 124 static const EGLint sDefaultConfigAttribs[] = { 125 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 126 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 127 EGL_RED_SIZE, 8, 128 EGL_GREEN_SIZE, 8, 129 EGL_BLUE_SIZE, 8, 130 EGL_ALPHA_SIZE, 8, 131 EGL_DEPTH_SIZE, 16, 132 EGL_STENCIL_SIZE, 8, 133 EGL_NONE }; 134 135 return sDefaultConfigAttribs; 136} 137 138EGLint const* GLTest::getContextAttribs() { 139 static const EGLint sDefaultContextAttribs[] = { 140 EGL_CONTEXT_CLIENT_VERSION, 2, 141 EGL_NONE }; 142 143 return sDefaultContextAttribs; 144} 145 146EGLint GLTest::getSurfaceWidth() { 147 return 512; 148} 149 150EGLint GLTest::getSurfaceHeight() { 151 return 512; 152} 153 154EGLSurface GLTest::createWindowSurface(EGLDisplay display, EGLConfig config, 155 sp<ANativeWindow>& window) const { 156 ALOGI("Creating window surface (non-SRGB)"); 157 return eglCreateWindowSurface(display, config, window.get(), NULL); 158} 159 160::testing::AssertionResult GLTest::checkPixel(int x, int y, 161 int r, int g, int b, int a, int tolerance) { 162 GLubyte pixel[4]; 163 String8 msg; 164 glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); 165 GLenum err = glGetError(); 166 if (err != GL_NO_ERROR) { 167 msg += String8::format("error reading pixel: %#x", err); 168 while ((err = glGetError()) != GL_NO_ERROR) { 169 msg += String8::format(", %#x", err); 170 } 171 return ::testing::AssertionFailure(::testing::Message(msg.string())); 172 } 173 if (r >= 0 && abs(r - int(pixel[0])) > tolerance) { 174 msg += String8::format("r(%d isn't %d)", pixel[0], r); 175 } 176 if (g >= 0 && abs(g - int(pixel[1])) > tolerance) { 177 if (!msg.isEmpty()) { 178 msg += " "; 179 } 180 msg += String8::format("g(%d isn't %d)", pixel[1], g); 181 } 182 if (b >= 0 && abs(b - int(pixel[2])) > tolerance) { 183 if (!msg.isEmpty()) { 184 msg += " "; 185 } 186 msg += String8::format("b(%d isn't %d)", pixel[2], b); 187 } 188 if (a >= 0 && abs(a - int(pixel[3])) > tolerance) { 189 if (!msg.isEmpty()) { 190 msg += " "; 191 } 192 msg += String8::format("a(%d isn't %d)", pixel[3], a); 193 } 194 if (!msg.isEmpty()) { 195 return ::testing::AssertionFailure(::testing::Message(msg.string())); 196 } else { 197 return ::testing::AssertionSuccess(); 198 } 199} 200 201::testing::AssertionResult GLTest::assertRectEq(const Rect &r1, const Rect &r2, 202 int tolerance) { 203 String8 msg; 204 205 if (abs(r1.left - r2.left) > tolerance) { 206 msg += String8::format("left(%d isn't %d)", r1.left, r2.left); 207 } 208 if (abs(r1.top - r2.top) > tolerance) { 209 if (!msg.isEmpty()) { 210 msg += " "; 211 } 212 msg += String8::format("top(%d isn't %d)", r1.top, r2.top); 213 } 214 if (abs(r1.right - r2.right) > tolerance) { 215 if (!msg.isEmpty()) { 216 msg += " "; 217 } 218 msg += String8::format("right(%d isn't %d)", r1.right, r2.right); 219 } 220 if (abs(r1.bottom - r2.bottom) > tolerance) { 221 if (!msg.isEmpty()) { 222 msg += " "; 223 } 224 msg += String8::format("bottom(%d isn't %d)", r1.bottom, r2.bottom); 225 } 226 if (!msg.isEmpty()) { 227 msg += String8::format(" R1: [%d %d %d %d] R2: [%d %d %d %d]", 228 r1.left, r1.top, r1.right, r1.bottom, 229 r2.left, r2.top, r2.right, r2.bottom); 230 fprintf(stderr, "assertRectEq: %s\n", msg.string()); 231 return ::testing::AssertionFailure(::testing::Message(msg.string())); 232 } else { 233 return ::testing::AssertionSuccess(); 234 } 235} 236 237void GLTest::loadShader(GLenum shaderType, const char* pSource, 238 GLuint* outShader) { 239 GLuint shader = glCreateShader(shaderType); 240 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 241 if (shader) { 242 glShaderSource(shader, 1, &pSource, NULL); 243 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 244 glCompileShader(shader); 245 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 246 GLint compiled = 0; 247 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 248 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 249 if (!compiled) { 250 GLint infoLen = 0; 251 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 252 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 253 if (infoLen) { 254 char* buf = (char*) malloc(infoLen); 255 if (buf) { 256 glGetShaderInfoLog(shader, infoLen, NULL, buf); 257 printf("Shader compile log:\n%s\n", buf); 258 free(buf); 259 FAIL(); 260 } 261 } else { 262 char* buf = (char*) malloc(0x1000); 263 if (buf) { 264 glGetShaderInfoLog(shader, 0x1000, NULL, buf); 265 printf("Shader compile log:\n%s\n", buf); 266 free(buf); 267 FAIL(); 268 } 269 } 270 glDeleteShader(shader); 271 shader = 0; 272 } 273 } 274 ASSERT_TRUE(shader != 0); 275 *outShader = shader; 276} 277 278void GLTest::createProgram(const char* pVertexSource, 279 const char* pFragmentSource, GLuint* outPgm) { 280 GLuint vertexShader, fragmentShader; 281 { 282 SCOPED_TRACE("compiling vertex shader"); 283 ASSERT_NO_FATAL_FAILURE(loadShader(GL_VERTEX_SHADER, pVertexSource, 284 &vertexShader)); 285 } 286 { 287 SCOPED_TRACE("compiling fragment shader"); 288 ASSERT_NO_FATAL_FAILURE(loadShader(GL_FRAGMENT_SHADER, pFragmentSource, 289 &fragmentShader)); 290 } 291 292 GLuint program = glCreateProgram(); 293 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 294 if (program) { 295 glAttachShader(program, vertexShader); 296 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 297 glAttachShader(program, fragmentShader); 298 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 299 glLinkProgram(program); 300 GLint linkStatus = GL_FALSE; 301 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 302 if (linkStatus != GL_TRUE) { 303 GLint bufLength = 0; 304 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 305 if (bufLength) { 306 char* buf = (char*) malloc(bufLength); 307 if (buf) { 308 glGetProgramInfoLog(program, bufLength, NULL, buf); 309 printf("Program link log:\n%s\n", buf); 310 free(buf); 311 FAIL(); 312 } 313 } 314 glDeleteProgram(program); 315 program = 0; 316 } 317 } 318 glDeleteShader(vertexShader); 319 glDeleteShader(fragmentShader); 320 ASSERT_TRUE(program != 0); 321 *outPgm = program; 322} 323 324} // namespace android 325