SurfaceTexture_test.cpp revision 5dd0c4fd7efcb99bdd346ed01f1a8f1d2baa8ef1
1/* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17//#define LOG_NDEBUG 0 18 19#include <gtest/gtest.h> 20#include <gui/SurfaceTexture.h> 21#include <gui/SurfaceTextureClient.h> 22#include <ui/GraphicBuffer.h> 23#include <utils/String8.h> 24#include <utils/threads.h> 25 26#include <surfaceflinger/ISurfaceComposer.h> 27#include <surfaceflinger/Surface.h> 28#include <surfaceflinger/SurfaceComposerClient.h> 29 30#include <EGL/egl.h> 31#include <EGL/eglext.h> 32#include <GLES2/gl2.h> 33#include <GLES2/gl2ext.h> 34 35#include <ui/FramebufferNativeWindow.h> 36 37namespace android { 38 39class GLTest : public ::testing::Test { 40protected: 41 42 GLTest(): 43 mEglDisplay(EGL_NO_DISPLAY), 44 mEglSurface(EGL_NO_SURFACE), 45 mEglContext(EGL_NO_CONTEXT) { 46 } 47 48 virtual void SetUp() { 49 mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 50 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 51 ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay); 52 53 EGLint majorVersion; 54 EGLint minorVersion; 55 EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion)); 56 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 57 RecordProperty("EglVersionMajor", majorVersion); 58 RecordProperty("EglVersionMajor", minorVersion); 59 60 EGLint numConfigs = 0; 61 EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &mGlConfig, 62 1, &numConfigs)); 63 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 64 65 char* displaySecsEnv = getenv("GLTEST_DISPLAY_SECS"); 66 if (displaySecsEnv != NULL) { 67 mDisplaySecs = atoi(displaySecsEnv); 68 if (mDisplaySecs < 0) { 69 mDisplaySecs = 0; 70 } 71 } else { 72 mDisplaySecs = 0; 73 } 74 75 if (mDisplaySecs > 0) { 76 mComposerClient = new SurfaceComposerClient; 77 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); 78 79 mSurfaceControl = mComposerClient->createSurface( 80 String8("Test Surface"), 0, 81 getSurfaceWidth(), getSurfaceHeight(), 82 PIXEL_FORMAT_RGB_888, 0); 83 84 ASSERT_TRUE(mSurfaceControl != NULL); 85 ASSERT_TRUE(mSurfaceControl->isValid()); 86 87 ASSERT_EQ(NO_ERROR, mComposerClient->openTransaction()); 88 ASSERT_EQ(NO_ERROR, mSurfaceControl->setLayer(0x7FFFFFFF)); 89 ASSERT_EQ(NO_ERROR, mSurfaceControl->show()); 90 ASSERT_EQ(NO_ERROR, mComposerClient->closeTransaction()); 91 92 sp<ANativeWindow> window = mSurfaceControl->getSurface(); 93 mEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig, 94 window.get(), NULL); 95 } else { 96 EGLint pbufferAttribs[] = { 97 EGL_WIDTH, getSurfaceWidth(), 98 EGL_HEIGHT, getSurfaceHeight(), 99 EGL_NONE }; 100 101 mEglSurface = eglCreatePbufferSurface(mEglDisplay, mGlConfig, 102 pbufferAttribs); 103 } 104 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 105 ASSERT_NE(EGL_NO_SURFACE, mEglSurface); 106 107 mEglContext = eglCreateContext(mEglDisplay, mGlConfig, EGL_NO_CONTEXT, 108 getContextAttribs()); 109 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 110 ASSERT_NE(EGL_NO_CONTEXT, mEglContext); 111 112 EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 113 mEglContext)); 114 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 115 116 EGLint w, h; 117 EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_WIDTH, &w)); 118 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 119 EXPECT_TRUE(eglQuerySurface(mEglDisplay, mEglSurface, EGL_HEIGHT, &h)); 120 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 121 RecordProperty("EglSurfaceWidth", w); 122 RecordProperty("EglSurfaceHeight", h); 123 124 glViewport(0, 0, w, h); 125 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 126 } 127 128 virtual void TearDown() { 129 // Display the result 130 if (mDisplaySecs > 0 && mEglSurface != EGL_NO_SURFACE) { 131 eglSwapBuffers(mEglDisplay, mEglSurface); 132 sleep(mDisplaySecs); 133 } 134 135 if (mComposerClient != NULL) { 136 mComposerClient->dispose(); 137 } 138 if (mEglContext != EGL_NO_CONTEXT) { 139 eglDestroyContext(mEglDisplay, mEglContext); 140 } 141 if (mEglSurface != EGL_NO_SURFACE) { 142 eglDestroySurface(mEglDisplay, mEglSurface); 143 } 144 if (mEglDisplay != EGL_NO_DISPLAY) { 145 eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 146 EGL_NO_CONTEXT); 147 eglTerminate(mEglDisplay); 148 } 149 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 150 } 151 152 virtual EGLint const* getConfigAttribs() { 153 static EGLint sDefaultConfigAttribs[] = { 154 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 155 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 156 EGL_RED_SIZE, 8, 157 EGL_GREEN_SIZE, 8, 158 EGL_BLUE_SIZE, 8, 159 EGL_ALPHA_SIZE, 8, 160 EGL_DEPTH_SIZE, 16, 161 EGL_STENCIL_SIZE, 8, 162 EGL_NONE }; 163 164 return sDefaultConfigAttribs; 165 } 166 167 virtual EGLint const* getContextAttribs() { 168 static EGLint sDefaultContextAttribs[] = { 169 EGL_CONTEXT_CLIENT_VERSION, 2, 170 EGL_NONE }; 171 172 return sDefaultContextAttribs; 173 } 174 175 virtual EGLint getSurfaceWidth() { 176 return 64; 177 } 178 179 virtual EGLint getSurfaceHeight() { 180 return 64; 181 } 182 183 void loadShader(GLenum shaderType, const char* pSource, GLuint* outShader) { 184 GLuint shader = glCreateShader(shaderType); 185 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 186 if (shader) { 187 glShaderSource(shader, 1, &pSource, NULL); 188 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 189 glCompileShader(shader); 190 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 191 GLint compiled = 0; 192 glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled); 193 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 194 if (!compiled) { 195 GLint infoLen = 0; 196 glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen); 197 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 198 if (infoLen) { 199 char* buf = (char*) malloc(infoLen); 200 if (buf) { 201 glGetShaderInfoLog(shader, infoLen, NULL, buf); 202 printf("Shader compile log:\n%s\n", buf); 203 free(buf); 204 FAIL(); 205 } 206 } else { 207 char* buf = (char*) malloc(0x1000); 208 if (buf) { 209 glGetShaderInfoLog(shader, 0x1000, NULL, buf); 210 printf("Shader compile log:\n%s\n", buf); 211 free(buf); 212 FAIL(); 213 } 214 } 215 glDeleteShader(shader); 216 shader = 0; 217 } 218 } 219 ASSERT_TRUE(shader != 0); 220 *outShader = shader; 221 } 222 223 void createProgram(const char* pVertexSource, const char* pFragmentSource, 224 GLuint* outPgm) { 225 GLuint vertexShader, fragmentShader; 226 { 227 SCOPED_TRACE("compiling vertex shader"); 228 loadShader(GL_VERTEX_SHADER, pVertexSource, &vertexShader); 229 if (HasFatalFailure()) { 230 return; 231 } 232 } 233 { 234 SCOPED_TRACE("compiling fragment shader"); 235 loadShader(GL_FRAGMENT_SHADER, pFragmentSource, &fragmentShader); 236 if (HasFatalFailure()) { 237 return; 238 } 239 } 240 241 GLuint program = glCreateProgram(); 242 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 243 if (program) { 244 glAttachShader(program, vertexShader); 245 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 246 glAttachShader(program, fragmentShader); 247 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 248 glLinkProgram(program); 249 GLint linkStatus = GL_FALSE; 250 glGetProgramiv(program, GL_LINK_STATUS, &linkStatus); 251 if (linkStatus != GL_TRUE) { 252 GLint bufLength = 0; 253 glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength); 254 if (bufLength) { 255 char* buf = (char*) malloc(bufLength); 256 if (buf) { 257 glGetProgramInfoLog(program, bufLength, NULL, buf); 258 printf("Program link log:\n%s\n", buf); 259 free(buf); 260 FAIL(); 261 } 262 } 263 glDeleteProgram(program); 264 program = 0; 265 } 266 } 267 glDeleteShader(vertexShader); 268 glDeleteShader(fragmentShader); 269 ASSERT_TRUE(program != 0); 270 *outPgm = program; 271 } 272 273 static int abs(int value) { 274 return value > 0 ? value : -value; 275 } 276 277 ::testing::AssertionResult checkPixel(int x, int y, int r, 278 int g, int b, int a, int tolerance=2) { 279 GLubyte pixel[4]; 280 String8 msg; 281 glReadPixels(x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, pixel); 282 GLenum err = glGetError(); 283 if (err != GL_NO_ERROR) { 284 msg += String8::format("error reading pixel: %#x", err); 285 while ((err = glGetError()) != GL_NO_ERROR) { 286 msg += String8::format(", %#x", err); 287 } 288 fprintf(stderr, "pixel check failure: %s\n", msg.string()); 289 return ::testing::AssertionFailure( 290 ::testing::Message(msg.string())); 291 } 292 if (r >= 0 && abs(r - int(pixel[0])) > tolerance) { 293 msg += String8::format("r(%d isn't %d)", pixel[0], r); 294 } 295 if (g >= 0 && abs(g - int(pixel[1])) > tolerance) { 296 if (!msg.isEmpty()) { 297 msg += " "; 298 } 299 msg += String8::format("g(%d isn't %d)", pixel[1], g); 300 } 301 if (b >= 0 && abs(b - int(pixel[2])) > tolerance) { 302 if (!msg.isEmpty()) { 303 msg += " "; 304 } 305 msg += String8::format("b(%d isn't %d)", pixel[2], b); 306 } 307 if (a >= 0 && abs(a - int(pixel[3])) > tolerance) { 308 if (!msg.isEmpty()) { 309 msg += " "; 310 } 311 msg += String8::format("a(%d isn't %d)", pixel[3], a); 312 } 313 if (!msg.isEmpty()) { 314 fprintf(stderr, "pixel check failure: %s\n", msg.string()); 315 return ::testing::AssertionFailure( 316 ::testing::Message(msg.string())); 317 } else { 318 return ::testing::AssertionSuccess(); 319 } 320 } 321 322 int mDisplaySecs; 323 sp<SurfaceComposerClient> mComposerClient; 324 sp<SurfaceControl> mSurfaceControl; 325 326 EGLDisplay mEglDisplay; 327 EGLSurface mEglSurface; 328 EGLContext mEglContext; 329 EGLConfig mGlConfig; 330}; 331 332// XXX: Code above this point should live elsewhere 333 334class SurfaceTextureGLTest : public GLTest { 335protected: 336 static const GLint TEX_ID = 123; 337 338 virtual void SetUp() { 339 GLTest::SetUp(); 340 mST = new SurfaceTexture(TEX_ID); 341 mSTC = new SurfaceTextureClient(mST); 342 mANW = mSTC; 343 344 const char vsrc[] = 345 "attribute vec4 vPosition;\n" 346 "varying vec2 texCoords;\n" 347 "uniform mat4 texMatrix;\n" 348 "void main() {\n" 349 " vec2 vTexCoords = 0.5 * (vPosition.xy + vec2(1.0, 1.0));\n" 350 " texCoords = (texMatrix * vec4(vTexCoords, 0.0, 1.0)).xy;\n" 351 " gl_Position = vPosition;\n" 352 "}\n"; 353 354 const char fsrc[] = 355 "#extension GL_OES_EGL_image_external : require\n" 356 "precision mediump float;\n" 357 "uniform samplerExternalOES texSampler;\n" 358 "varying vec2 texCoords;\n" 359 "void main() {\n" 360 " gl_FragColor = texture2D(texSampler, texCoords);\n" 361 "}\n"; 362 363 { 364 SCOPED_TRACE("creating shader program"); 365 createProgram(vsrc, fsrc, &mPgm); 366 if (HasFatalFailure()) { 367 return; 368 } 369 } 370 371 mPositionHandle = glGetAttribLocation(mPgm, "vPosition"); 372 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 373 ASSERT_NE(-1, mPositionHandle); 374 mTexSamplerHandle = glGetUniformLocation(mPgm, "texSampler"); 375 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 376 ASSERT_NE(-1, mTexSamplerHandle); 377 mTexMatrixHandle = glGetUniformLocation(mPgm, "texMatrix"); 378 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 379 ASSERT_NE(-1, mTexMatrixHandle); 380 } 381 382 // drawTexture draws the SurfaceTexture over the entire GL viewport. 383 void drawTexture() { 384 const GLfloat triangleVertices[] = { 385 -1.0f, 1.0f, 386 -1.0f, -1.0f, 387 1.0f, -1.0f, 388 1.0f, 1.0f, 389 }; 390 391 glVertexAttribPointer(mPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, triangleVertices); 392 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 393 glEnableVertexAttribArray(mPositionHandle); 394 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 395 396 glUseProgram(mPgm); 397 glUniform1i(mTexSamplerHandle, 0); 398 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 399 glBindTexture(GL_TEXTURE_EXTERNAL_OES, TEX_ID); 400 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 401 402 // XXX: These calls are not needed for GL_TEXTURE_EXTERNAL_OES as 403 // they're setting the defautls for that target, but when hacking things 404 // to use GL_TEXTURE_2D they are needed to achieve the same behavior. 405 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 406 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 407 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 408 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 409 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 410 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 411 glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 412 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 413 414 GLfloat texMatrix[16]; 415 mST->getTransformMatrix(texMatrix); 416 glUniformMatrix4fv(mTexMatrixHandle, 1, GL_FALSE, texMatrix); 417 418 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 419 ASSERT_EQ(GLenum(GL_NO_ERROR), glGetError()); 420 } 421 422 sp<SurfaceTexture> mST; 423 sp<SurfaceTextureClient> mSTC; 424 sp<ANativeWindow> mANW; 425 426 GLuint mPgm; 427 GLint mPositionHandle; 428 GLint mTexSamplerHandle; 429 GLint mTexMatrixHandle; 430}; 431 432// Fill a YV12 buffer with a multi-colored checkerboard pattern 433void fillYV12Buffer(uint8_t* buf, int w, int h, int stride) { 434 const int blockWidth = w > 16 ? w / 16 : 1; 435 const int blockHeight = h > 16 ? h / 16 : 1; 436 const int yuvTexOffsetY = 0; 437 int yuvTexStrideY = stride; 438 int yuvTexOffsetV = yuvTexStrideY * h; 439 int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf; 440 int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2; 441 int yuvTexStrideU = yuvTexStrideV; 442 for (int x = 0; x < w; x++) { 443 for (int y = 0; y < h; y++) { 444 int parityX = (x / blockWidth) & 1; 445 int parityY = (y / blockHeight) & 1; 446 unsigned char intensity = (parityX ^ parityY) ? 63 : 191; 447 buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = intensity; 448 if (x < w / 2 && y < h / 2) { 449 buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = intensity; 450 if (x * 2 < w / 2 && y * 2 < h / 2) { 451 buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 0] = 452 buf[yuvTexOffsetV + (y*2 * yuvTexStrideV) + x*2 + 1] = 453 buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 0] = 454 buf[yuvTexOffsetV + ((y*2+1) * yuvTexStrideV) + x*2 + 1] = 455 intensity; 456 } 457 } 458 } 459 } 460} 461 462// Fill a YV12 buffer with red outside a given rectangle and green inside it. 463void fillYV12BufferRect(uint8_t* buf, int w, int h, int stride, 464 const android_native_rect_t& rect) { 465 const int yuvTexOffsetY = 0; 466 int yuvTexStrideY = stride; 467 int yuvTexOffsetV = yuvTexStrideY * h; 468 int yuvTexStrideV = (yuvTexStrideY/2 + 0xf) & ~0xf; 469 int yuvTexOffsetU = yuvTexOffsetV + yuvTexStrideV * h/2; 470 int yuvTexStrideU = yuvTexStrideV; 471 for (int x = 0; x < w; x++) { 472 for (int y = 0; y < h; y++) { 473 bool inside = rect.left <= x && x < rect.right && 474 rect.top <= y && y < rect.bottom; 475 buf[yuvTexOffsetY + (y * yuvTexStrideY) + x] = inside ? 240 : 64; 476 if (x < w / 2 && y < h / 2) { 477 bool inside = rect.left <= 2*x && 2*x < rect.right && 478 rect.top <= 2*y && 2*y < rect.bottom; 479 buf[yuvTexOffsetU + (y * yuvTexStrideU) + x] = 16; 480 buf[yuvTexOffsetV + (y * yuvTexStrideV) + x] = 481 inside ? 16 : 255; 482 } 483 } 484 } 485} 486 487void fillRGBA8Buffer(uint8_t* buf, int w, int h, int stride) { 488 const size_t PIXEL_SIZE = 4; 489 for (int x = 0; x < w; x++) { 490 for (int y = 0; y < h; y++) { 491 off_t offset = (y * stride + x) * PIXEL_SIZE; 492 for (int c = 0; c < 4; c++) { 493 int parityX = (x / (1 << (c+2))) & 1; 494 int parityY = (y / (1 << (c+2))) & 1; 495 buf[offset + c] = (parityX ^ parityY) ? 231 : 35; 496 } 497 } 498 } 499} 500 501TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferNpot) { 502 const int texWidth = 64; 503 const int texHeight = 66; 504 505 ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 506 texWidth, texHeight, HAL_PIXEL_FORMAT_YV12)); 507 ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 508 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 509 510 ANativeWindowBuffer* anb; 511 ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb)); 512 ASSERT_TRUE(anb != NULL); 513 514 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 515 ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer())); 516 517 // Fill the buffer with the a checkerboard pattern 518 uint8_t* img = NULL; 519 buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 520 fillYV12Buffer(img, texWidth, texHeight, buf->getStride()); 521 buf->unlock(); 522 ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer())); 523 524 mST->updateTexImage(); 525 526 glClearColor(0.2, 0.2, 0.2, 0.2); 527 glClear(GL_COLOR_BUFFER_BIT); 528 529 drawTexture(); 530 531 EXPECT_TRUE(checkPixel( 0, 0, 255, 127, 255, 255)); 532 EXPECT_TRUE(checkPixel(63, 0, 0, 133, 0, 255)); 533 EXPECT_TRUE(checkPixel(63, 63, 0, 133, 0, 255)); 534 EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255)); 535 536 EXPECT_TRUE(checkPixel(22, 44, 247, 70, 255, 255)); 537 EXPECT_TRUE(checkPixel(45, 52, 209, 32, 235, 255)); 538 EXPECT_TRUE(checkPixel(52, 51, 100, 255, 73, 255)); 539 EXPECT_TRUE(checkPixel( 7, 31, 155, 0, 118, 255)); 540 EXPECT_TRUE(checkPixel(31, 9, 148, 71, 110, 255)); 541 EXPECT_TRUE(checkPixel(29, 35, 255, 127, 255, 255)); 542 EXPECT_TRUE(checkPixel(36, 22, 155, 29, 0, 255)); 543} 544 545// XXX: This test is disabled because it it currently broken on all devices to 546// which I have access. Some of the checkPixel calls are not correct because 547// I just copied them from the npot test above and haven't bothered to figure 548// out the correct values. 549TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledYV12BufferPow2) { 550 const int texWidth = 64; 551 const int texHeight = 64; 552 553 ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 554 texWidth, texHeight, HAL_PIXEL_FORMAT_YV12)); 555 ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 556 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 557 558 ANativeWindowBuffer* anb; 559 ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb)); 560 ASSERT_TRUE(anb != NULL); 561 562 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 563 ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer())); 564 565 // Fill the buffer with the a checkerboard pattern 566 uint8_t* img = NULL; 567 buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 568 fillYV12Buffer(img, texWidth, texHeight, buf->getStride()); 569 buf->unlock(); 570 ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer())); 571 572 mST->updateTexImage(); 573 574 glClearColor(0.2, 0.2, 0.2, 0.2); 575 glClear(GL_COLOR_BUFFER_BIT); 576 577 drawTexture(); 578 579 EXPECT_TRUE(checkPixel( 0, 0, 255, 127, 255, 255)); 580 EXPECT_TRUE(checkPixel(63, 0, 0, 133, 0, 255)); 581 EXPECT_TRUE(checkPixel(63, 63, 0, 133, 0, 255)); 582 EXPECT_TRUE(checkPixel( 0, 63, 255, 127, 255, 255)); 583 584 EXPECT_TRUE(checkPixel(22, 19, 247, 70, 255, 255)); 585 EXPECT_TRUE(checkPixel(45, 11, 209, 32, 235, 255)); 586 EXPECT_TRUE(checkPixel(52, 12, 100, 255, 73, 255)); 587 EXPECT_TRUE(checkPixel( 7, 32, 155, 0, 118, 255)); 588 EXPECT_TRUE(checkPixel(31, 54, 148, 71, 110, 255)); 589 EXPECT_TRUE(checkPixel(29, 28, 255, 127, 255, 255)); 590 EXPECT_TRUE(checkPixel(36, 41, 155, 29, 0, 255)); 591} 592 593TEST_F(SurfaceTextureGLTest, TexturingFromCpuFilledYV12BufferWithCrop) { 594 const int texWidth = 64; 595 const int texHeight = 66; 596 597 ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 598 texWidth, texHeight, HAL_PIXEL_FORMAT_YV12)); 599 ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 600 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 601 602 android_native_rect_t crops[] = { 603 {4, 6, 22, 36}, 604 {0, 6, 22, 36}, 605 {4, 0, 22, 36}, 606 {4, 6, texWidth, 36}, 607 {4, 6, 22, texHeight}, 608 }; 609 610 for (int i = 0; i < 5; i++) { 611 const android_native_rect_t& crop(crops[i]); 612 SCOPED_TRACE(String8::format("rect{ l: %d t: %d r: %d b: %d }", crop.left, 613 crop.top, crop.right, crop.bottom).string()); 614 615 ASSERT_EQ(NO_ERROR, native_window_set_crop(mANW.get(), &crop)); 616 617 ANativeWindowBuffer* anb; 618 ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb)); 619 ASSERT_TRUE(anb != NULL); 620 621 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 622 ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer())); 623 624 uint8_t* img = NULL; 625 buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 626 fillYV12BufferRect(img, texWidth, texHeight, buf->getStride(), crop); 627 buf->unlock(); 628 ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer())); 629 630 mST->updateTexImage(); 631 632 glClearColor(0.2, 0.2, 0.2, 0.2); 633 glClear(GL_COLOR_BUFFER_BIT); 634 635 drawTexture(); 636 637 EXPECT_TRUE(checkPixel( 0, 0, 82, 255, 35, 255)); 638 EXPECT_TRUE(checkPixel(63, 0, 82, 255, 35, 255)); 639 EXPECT_TRUE(checkPixel(63, 63, 82, 255, 35, 255)); 640 EXPECT_TRUE(checkPixel( 0, 63, 82, 255, 35, 255)); 641 642 EXPECT_TRUE(checkPixel(25, 14, 82, 255, 35, 255)); 643 EXPECT_TRUE(checkPixel(35, 31, 82, 255, 35, 255)); 644 EXPECT_TRUE(checkPixel(57, 6, 82, 255, 35, 255)); 645 EXPECT_TRUE(checkPixel( 5, 42, 82, 255, 35, 255)); 646 EXPECT_TRUE(checkPixel(32, 33, 82, 255, 35, 255)); 647 EXPECT_TRUE(checkPixel(16, 26, 82, 255, 35, 255)); 648 EXPECT_TRUE(checkPixel(46, 51, 82, 255, 35, 255)); 649 } 650} 651 652// XXX: This test is disabled because there are currently no drivers that can 653// handle RGBA textures with the GL_TEXTURE_EXTERNAL_OES target. 654TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledRGBABufferNpot) { 655 const int texWidth = 64; 656 const int texHeight = 66; 657 658 ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 659 texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888)); 660 ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 661 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 662 663 android_native_buffer_t* anb; 664 ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb)); 665 ASSERT_TRUE(anb != NULL); 666 667 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 668 ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer())); 669 670 // Fill the buffer with the a checkerboard pattern 671 uint8_t* img = NULL; 672 buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 673 fillRGBA8Buffer(img, texWidth, texHeight, buf->getStride()); 674 buf->unlock(); 675 ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer())); 676 677 mST->updateTexImage(); 678 679 glClearColor(0.2, 0.2, 0.2, 0.2); 680 glClear(GL_COLOR_BUFFER_BIT); 681 682 drawTexture(); 683 684 EXPECT_TRUE(checkPixel( 0, 0, 35, 35, 35, 35)); 685 EXPECT_TRUE(checkPixel(63, 0, 231, 231, 231, 231)); 686 EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231)); 687 EXPECT_TRUE(checkPixel( 0, 63, 35, 35, 35, 35)); 688 689 EXPECT_TRUE(checkPixel(15, 10, 35, 231, 231, 231)); 690 EXPECT_TRUE(checkPixel(24, 63, 35, 231, 231, 35)); 691 EXPECT_TRUE(checkPixel(19, 40, 87, 179, 35, 35)); 692 EXPECT_TRUE(checkPixel(38, 30, 231, 35, 35, 35)); 693 EXPECT_TRUE(checkPixel(42, 54, 35, 35, 35, 231)); 694 EXPECT_TRUE(checkPixel(37, 33, 35, 231, 231, 231)); 695 EXPECT_TRUE(checkPixel(31, 8, 231, 35, 35, 231)); 696 EXPECT_TRUE(checkPixel(36, 47, 231, 35, 231, 231)); 697 EXPECT_TRUE(checkPixel(24, 63, 35, 231, 231, 35)); 698 EXPECT_TRUE(checkPixel(48, 3, 231, 231, 35, 35)); 699 EXPECT_TRUE(checkPixel(54, 50, 35, 231, 231, 231)); 700 EXPECT_TRUE(checkPixel(24, 25, 191, 191, 231, 231)); 701 EXPECT_TRUE(checkPixel(10, 9, 93, 93, 231, 231)); 702 EXPECT_TRUE(checkPixel(29, 4, 35, 35, 35, 231)); 703 EXPECT_TRUE(checkPixel(56, 31, 35, 231, 231, 35)); 704 EXPECT_TRUE(checkPixel(58, 55, 35, 35, 231, 231)); 705} 706 707// XXX: This test is disabled because there are currently no drivers that can 708// handle RGBA textures with the GL_TEXTURE_EXTERNAL_OES target. 709TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromCpuFilledRGBABufferPow2) { 710 const int texWidth = 64; 711 const int texHeight = 64; 712 713 ASSERT_EQ(NO_ERROR, native_window_set_buffers_geometry(mANW.get(), 714 texWidth, texHeight, HAL_PIXEL_FORMAT_RGBA_8888)); 715 ASSERT_EQ(NO_ERROR, native_window_set_usage(mANW.get(), 716 GRALLOC_USAGE_SW_READ_OFTEN | GRALLOC_USAGE_SW_WRITE_OFTEN)); 717 718 android_native_buffer_t* anb; 719 ASSERT_EQ(NO_ERROR, mANW->dequeueBuffer(mANW.get(), &anb)); 720 ASSERT_TRUE(anb != NULL); 721 722 sp<GraphicBuffer> buf(new GraphicBuffer(anb, false)); 723 ASSERT_EQ(NO_ERROR, mANW->lockBuffer(mANW.get(), buf->getNativeBuffer())); 724 725 // Fill the buffer with the a checkerboard pattern 726 uint8_t* img = NULL; 727 buf->lock(GRALLOC_USAGE_SW_WRITE_OFTEN, (void**)(&img)); 728 fillRGBA8Buffer(img, texWidth, texHeight, buf->getStride()); 729 buf->unlock(); 730 ASSERT_EQ(NO_ERROR, mANW->queueBuffer(mANW.get(), buf->getNativeBuffer())); 731 732 mST->updateTexImage(); 733 734 glClearColor(0.2, 0.2, 0.2, 0.2); 735 glClear(GL_COLOR_BUFFER_BIT); 736 737 drawTexture(); 738 739 EXPECT_TRUE(checkPixel( 0, 0, 231, 231, 231, 231)); 740 EXPECT_TRUE(checkPixel(63, 0, 35, 35, 35, 35)); 741 EXPECT_TRUE(checkPixel(63, 63, 231, 231, 231, 231)); 742 EXPECT_TRUE(checkPixel( 0, 63, 35, 35, 35, 35)); 743 744 EXPECT_TRUE(checkPixel(12, 46, 231, 231, 231, 35)); 745 EXPECT_TRUE(checkPixel(16, 1, 231, 231, 35, 231)); 746 EXPECT_TRUE(checkPixel(21, 12, 231, 35, 35, 231)); 747 EXPECT_TRUE(checkPixel(26, 51, 231, 35, 231, 35)); 748 EXPECT_TRUE(checkPixel( 5, 32, 35, 231, 231, 35)); 749 EXPECT_TRUE(checkPixel(13, 8, 35, 231, 231, 231)); 750 EXPECT_TRUE(checkPixel(46, 3, 35, 35, 231, 35)); 751 EXPECT_TRUE(checkPixel(30, 33, 35, 35, 35, 35)); 752 EXPECT_TRUE(checkPixel( 6, 52, 231, 231, 35, 35)); 753 EXPECT_TRUE(checkPixel(55, 33, 35, 231, 35, 231)); 754 EXPECT_TRUE(checkPixel(16, 29, 35, 35, 231, 231)); 755 EXPECT_TRUE(checkPixel( 1, 30, 35, 35, 35, 231)); 756 EXPECT_TRUE(checkPixel(41, 37, 35, 35, 231, 231)); 757 EXPECT_TRUE(checkPixel(46, 29, 231, 231, 35, 35)); 758 EXPECT_TRUE(checkPixel(15, 25, 35, 231, 35, 231)); 759 EXPECT_TRUE(checkPixel( 3, 52, 35, 231, 35, 35)); 760} 761 762// XXX: This test is disabled because there are currently no drivers that can 763// handle RGBA textures with the GL_TEXTURE_EXTERNAL_OES target. 764TEST_F(SurfaceTextureGLTest, DISABLED_TexturingFromGLFilledRGBABufferPow2) { 765 const int texWidth = 64; 766 const int texHeight = 64; 767 768 mST->setDefaultBufferSize(texWidth, texHeight); 769 770 // Do the producer side of things 771 EGLSurface stcEglSurface = eglCreateWindowSurface(mEglDisplay, mGlConfig, 772 mANW.get(), NULL); 773 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 774 ASSERT_NE(EGL_NO_SURFACE, mEglSurface); 775 776 EXPECT_TRUE(eglMakeCurrent(mEglDisplay, stcEglSurface, stcEglSurface, 777 mEglContext)); 778 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 779 780 glClearColor(0.6, 0.6, 0.6, 0.6); 781 glClear(GL_COLOR_BUFFER_BIT); 782 783 glEnable(GL_SCISSOR_TEST); 784 glScissor(4, 4, 4, 4); 785 glClearColor(1.0, 0.0, 0.0, 1.0); 786 glClear(GL_COLOR_BUFFER_BIT); 787 788 glScissor(24, 48, 4, 4); 789 glClearColor(0.0, 1.0, 0.0, 1.0); 790 glClear(GL_COLOR_BUFFER_BIT); 791 792 glScissor(37, 17, 4, 4); 793 glClearColor(0.0, 0.0, 1.0, 1.0); 794 glClear(GL_COLOR_BUFFER_BIT); 795 796 eglSwapBuffers(mEglDisplay, stcEglSurface); 797 798 // Do the consumer side of things 799 EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, 800 mEglContext)); 801 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 802 803 glDisable(GL_SCISSOR_TEST); 804 805 mST->updateTexImage(); 806 807 glClearColor(0.2, 0.2, 0.2, 0.2); 808 glClear(GL_COLOR_BUFFER_BIT); 809 810 drawTexture(); 811 812 EXPECT_TRUE(checkPixel( 0, 0, 153, 153, 153, 153)); 813 EXPECT_TRUE(checkPixel(63, 0, 153, 153, 153, 153)); 814 EXPECT_TRUE(checkPixel(63, 63, 153, 153, 153, 153)); 815 EXPECT_TRUE(checkPixel( 0, 63, 153, 153, 153, 153)); 816 817 EXPECT_TRUE(checkPixel( 4, 7, 255, 0, 0, 255)); 818 EXPECT_TRUE(checkPixel(25, 51, 0, 255, 0, 255)); 819 EXPECT_TRUE(checkPixel(40, 19, 0, 0, 255, 255)); 820 EXPECT_TRUE(checkPixel(29, 51, 153, 153, 153, 153)); 821 EXPECT_TRUE(checkPixel( 5, 32, 153, 153, 153, 153)); 822 EXPECT_TRUE(checkPixel(13, 8, 153, 153, 153, 153)); 823 EXPECT_TRUE(checkPixel(46, 3, 153, 153, 153, 153)); 824 EXPECT_TRUE(checkPixel(30, 33, 153, 153, 153, 153)); 825 EXPECT_TRUE(checkPixel( 6, 52, 153, 153, 153, 153)); 826 EXPECT_TRUE(checkPixel(55, 33, 153, 153, 153, 153)); 827 EXPECT_TRUE(checkPixel(16, 29, 153, 153, 153, 153)); 828 EXPECT_TRUE(checkPixel( 1, 30, 153, 153, 153, 153)); 829 EXPECT_TRUE(checkPixel(41, 37, 153, 153, 153, 153)); 830 EXPECT_TRUE(checkPixel(46, 29, 153, 153, 153, 153)); 831 EXPECT_TRUE(checkPixel(15, 25, 153, 153, 153, 153)); 832 EXPECT_TRUE(checkPixel( 3, 52, 153, 153, 153, 153)); 833} 834 835/* 836 * This test is for testing GL -> GL texture streaming via SurfaceTexture. It 837 * contains functionality to create a producer thread that will perform GL 838 * rendering to an ANativeWindow that feeds frames to a SurfaceTexture. 839 * Additionally it supports interlocking the producer and consumer threads so 840 * that a specific sequence of calls can be deterministically created by the 841 * test. 842 * 843 * The intended usage is as follows: 844 * 845 * TEST_F(...) { 846 * class PT : public ProducerThread { 847 * virtual void render() { 848 * ... 849 * swapBuffers(); 850 * } 851 * }; 852 * 853 * runProducerThread(new PT()); 854 * 855 * // The order of these calls will vary from test to test and may include 856 * // multiple frames and additional operations (e.g. GL rendering from the 857 * // texture). 858 * fc->waitForFrame(); 859 * mST->updateTexImage(); 860 * fc->finishFrame(); 861 * } 862 * 863 */ 864class SurfaceTextureGLToGLTest : public SurfaceTextureGLTest { 865protected: 866 867 // ProducerThread is an abstract base class to simplify the creation of 868 // OpenGL ES frame producer threads. 869 class ProducerThread : public Thread { 870 public: 871 virtual ~ProducerThread() { 872 } 873 874 void setEglObjects(EGLDisplay producerEglDisplay, 875 EGLSurface producerEglSurface, 876 EGLContext producerEglContext) { 877 mProducerEglDisplay = producerEglDisplay; 878 mProducerEglSurface = producerEglSurface; 879 mProducerEglContext = producerEglContext; 880 } 881 882 virtual bool threadLoop() { 883 eglMakeCurrent(mProducerEglDisplay, mProducerEglSurface, 884 mProducerEglSurface, mProducerEglContext); 885 render(); 886 eglMakeCurrent(mProducerEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 887 EGL_NO_CONTEXT); 888 return false; 889 } 890 891 protected: 892 virtual void render() = 0; 893 894 void swapBuffers() { 895 eglSwapBuffers(mProducerEglDisplay, mProducerEglSurface); 896 } 897 898 EGLDisplay mProducerEglDisplay; 899 EGLSurface mProducerEglSurface; 900 EGLContext mProducerEglContext; 901 }; 902 903 // FrameCondition is a utility class for interlocking between the producer 904 // and consumer threads. The FrameCondition object should be created and 905 // destroyed in the consumer thread only. The consumer thread should set 906 // the FrameCondition as the FrameAvailableListener of the SurfaceTexture, 907 // and should call both waitForFrame and finishFrame once for each expected 908 // frame. 909 // 910 // This interlocking relies on the fact that onFrameAvailable gets called 911 // synchronously from SurfaceTexture::queueBuffer. 912 class FrameCondition : public SurfaceTexture::FrameAvailableListener { 913 public: 914 // waitForFrame waits for the next frame to arrive. This should be 915 // called from the consumer thread once for every frame expected by the 916 // test. 917 void waitForFrame() { 918 LOGV("+waitForFrame"); 919 Mutex::Autolock lock(mMutex); 920 status_t result = mFrameAvailableCondition.wait(mMutex); 921 LOGV("-waitForFrame"); 922 } 923 924 // Allow the producer to return from its swapBuffers call and continue 925 // on to produce the next frame. This should be called by the consumer 926 // thread once for every frame expected by the test. 927 void finishFrame() { 928 LOGV("+finishFrame"); 929 Mutex::Autolock lock(mMutex); 930 mFrameFinishCondition.signal(); 931 LOGV("-finishFrame"); 932 } 933 934 // This should be called by SurfaceTexture on the producer thread. 935 virtual void onFrameAvailable() { 936 LOGV("+onFrameAvailable"); 937 Mutex::Autolock lock(mMutex); 938 mFrameAvailableCondition.signal(); 939 mFrameFinishCondition.wait(mMutex); 940 LOGV("-onFrameAvailable"); 941 } 942 943 protected: 944 Mutex mMutex; 945 Condition mFrameAvailableCondition; 946 Condition mFrameFinishCondition; 947 }; 948 949 SurfaceTextureGLToGLTest(): 950 mProducerEglSurface(EGL_NO_SURFACE), 951 mProducerEglContext(EGL_NO_CONTEXT) { 952 } 953 954 virtual void SetUp() { 955 SurfaceTextureGLTest::SetUp(); 956 957 EGLConfig myConfig = {0}; 958 EGLint numConfigs = 0; 959 EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), &myConfig, 960 1, &numConfigs)); 961 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 962 963 mProducerEglSurface = eglCreateWindowSurface(mEglDisplay, myConfig, 964 mANW.get(), NULL); 965 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 966 ASSERT_NE(EGL_NO_SURFACE, mProducerEglSurface); 967 968 mProducerEglContext = eglCreateContext(mEglDisplay, myConfig, 969 EGL_NO_CONTEXT, getContextAttribs()); 970 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 971 ASSERT_NE(EGL_NO_CONTEXT, mProducerEglContext); 972 973 mFC = new FrameCondition(); 974 mST->setFrameAvailableListener(mFC); 975 } 976 977 virtual void TearDown() { 978 if (mProducerThread != NULL) { 979 mProducerThread->requestExitAndWait(); 980 } 981 if (mProducerEglContext != EGL_NO_CONTEXT) { 982 eglDestroyContext(mEglDisplay, mProducerEglContext); 983 } 984 if (mProducerEglSurface != EGL_NO_SURFACE) { 985 eglDestroySurface(mEglDisplay, mProducerEglSurface); 986 } 987 mProducerThread.clear(); 988 mFC.clear(); 989 } 990 991 void runProducerThread(const sp<ProducerThread> producerThread) { 992 ASSERT_TRUE(mProducerThread == NULL); 993 mProducerThread = producerThread; 994 producerThread->setEglObjects(mEglDisplay, mProducerEglSurface, 995 mProducerEglContext); 996 producerThread->run(); 997 } 998 999 EGLSurface mProducerEglSurface; 1000 EGLContext mProducerEglContext; 1001 sp<ProducerThread> mProducerThread; 1002 sp<FrameCondition> mFC; 1003}; 1004 1005// XXX: This test is disabled because it causes hangs on some devices. 1006TEST_F(SurfaceTextureGLToGLTest, DISABLED_UpdateTexImageBeforeFrameFinishedWorks) { 1007 class PT : public ProducerThread { 1008 virtual void render() { 1009 glClearColor(0.0f, 1.0f, 0.0f, 1.0f); 1010 glClear(GL_COLOR_BUFFER_BIT); 1011 swapBuffers(); 1012 } 1013 }; 1014 1015 runProducerThread(new PT()); 1016 1017 mFC->waitForFrame(); 1018 mST->updateTexImage(); 1019 mFC->finishFrame(); 1020 1021 // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported! 1022} 1023 1024// XXX: This test is disabled because it causes hangs on some devices. 1025TEST_F(SurfaceTextureGLToGLTest, DISABLED_UpdateTexImageAfterFrameFinishedWorks) { 1026 class PT : public ProducerThread { 1027 virtual void render() { 1028 glClearColor(0.0f, 1.0f, 0.0f, 1.0f); 1029 glClear(GL_COLOR_BUFFER_BIT); 1030 swapBuffers(); 1031 } 1032 }; 1033 1034 runProducerThread(new PT()); 1035 1036 mFC->waitForFrame(); 1037 mFC->finishFrame(); 1038 mST->updateTexImage(); 1039 1040 // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported! 1041} 1042 1043// XXX: This test is disabled because it causes hangs on some devices. 1044TEST_F(SurfaceTextureGLToGLTest, DISABLED_RepeatedUpdateTexImageBeforeFrameFinishedWorks) { 1045 enum { NUM_ITERATIONS = 1024 }; 1046 1047 class PT : public ProducerThread { 1048 virtual void render() { 1049 for (int i = 0; i < NUM_ITERATIONS; i++) { 1050 glClearColor(0.0f, 1.0f, 0.0f, 1.0f); 1051 glClear(GL_COLOR_BUFFER_BIT); 1052 LOGV("+swapBuffers"); 1053 swapBuffers(); 1054 LOGV("-swapBuffers"); 1055 } 1056 } 1057 }; 1058 1059 runProducerThread(new PT()); 1060 1061 for (int i = 0; i < NUM_ITERATIONS; i++) { 1062 mFC->waitForFrame(); 1063 LOGV("+updateTexImage"); 1064 mST->updateTexImage(); 1065 LOGV("-updateTexImage"); 1066 mFC->finishFrame(); 1067 1068 // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported! 1069 } 1070} 1071 1072// XXX: This test is disabled because it causes hangs on some devices. 1073TEST_F(SurfaceTextureGLToGLTest, DISABLED_RepeatedUpdateTexImageAfterFrameFinishedWorks) { 1074 enum { NUM_ITERATIONS = 1024 }; 1075 1076 class PT : public ProducerThread { 1077 virtual void render() { 1078 for (int i = 0; i < NUM_ITERATIONS; i++) { 1079 glClearColor(0.0f, 1.0f, 0.0f, 1.0f); 1080 glClear(GL_COLOR_BUFFER_BIT); 1081 LOGV("+swapBuffers"); 1082 swapBuffers(); 1083 LOGV("-swapBuffers"); 1084 } 1085 } 1086 }; 1087 1088 runProducerThread(new PT()); 1089 1090 for (int i = 0; i < NUM_ITERATIONS; i++) { 1091 mFC->waitForFrame(); 1092 mFC->finishFrame(); 1093 LOGV("+updateTexImage"); 1094 mST->updateTexImage(); 1095 LOGV("-updateTexImage"); 1096 1097 // TODO: Add frame verification once RGB TEX_EXTERNAL_OES is supported! 1098 } 1099} 1100 1101} // namespace android 1102