SurfaceTextureClient_test.cpp revision fa5b40ebb8923133df12dc70591bfe35b3f1c9b3
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_TAG "SurfaceTextureClient_test" 18//#define LOG_NDEBUG 0 19 20#include <EGL/egl.h> 21#include <gtest/gtest.h> 22#include <gui/SurfaceTextureClient.h> 23#include <utils/Log.h> 24#include <utils/Thread.h> 25 26namespace android { 27 28class SurfaceTextureClientTest : public ::testing::Test { 29protected: 30 SurfaceTextureClientTest(): 31 mEglDisplay(EGL_NO_DISPLAY), 32 mEglSurface(EGL_NO_SURFACE), 33 mEglContext(EGL_NO_CONTEXT) { 34 } 35 36 virtual void SetUp() { 37 const ::testing::TestInfo* const testInfo = 38 ::testing::UnitTest::GetInstance()->current_test_info(); 39 ALOGV("Begin test: %s.%s", testInfo->test_case_name(), 40 testInfo->name()); 41 42 mST = new SurfaceTexture(123); 43 mSTC = new SurfaceTextureClient(mST); 44 mANW = mSTC; 45 46 // We need a valid GL context so we can test updateTexImage() 47 // This initializes EGL and create a dummy GL context with a 48 // pbuffer render target. 49 mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 50 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 51 ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay); 52 53 EGLint majorVersion, minorVersion; 54 EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion)); 55 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 56 57 EGLConfig myConfig; 58 EGLint numConfigs = 0; 59 EXPECT_TRUE(eglChooseConfig(mEglDisplay, getConfigAttribs(), 60 &myConfig, 1, &numConfigs)); 61 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 62 63 EGLint pbufferAttribs[] = { 64 EGL_WIDTH, 16, 65 EGL_HEIGHT, 16, 66 EGL_NONE }; 67 mEglSurface = eglCreatePbufferSurface(mEglDisplay, myConfig, pbufferAttribs); 68 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 69 ASSERT_NE(EGL_NO_SURFACE, mEglSurface); 70 71 mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT, 0); 72 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 73 ASSERT_NE(EGL_NO_CONTEXT, mEglContext); 74 75 EXPECT_TRUE(eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)); 76 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 77 } 78 79 virtual void TearDown() { 80 mST.clear(); 81 mSTC.clear(); 82 mANW.clear(); 83 84 eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 85 eglDestroyContext(mEglDisplay, mEglContext); 86 eglDestroySurface(mEglDisplay, mEglSurface); 87 eglTerminate(mEglDisplay); 88 89 const ::testing::TestInfo* const testInfo = 90 ::testing::UnitTest::GetInstance()->current_test_info(); 91 ALOGV("End test: %s.%s", testInfo->test_case_name(), 92 testInfo->name()); 93 } 94 95 virtual EGLint const* getConfigAttribs() { 96 static EGLint sDefaultConfigAttribs[] = { 97 EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 98 EGL_NONE 99 }; 100 101 return sDefaultConfigAttribs; 102 } 103 104 sp<SurfaceTexture> mST; 105 sp<SurfaceTextureClient> mSTC; 106 sp<ANativeWindow> mANW; 107 108 EGLDisplay mEglDisplay; 109 EGLSurface mEglSurface; 110 EGLContext mEglContext; 111}; 112 113TEST_F(SurfaceTextureClientTest, GetISurfaceTextureIsNotNull) { 114 sp<ISurfaceTexture> ist(mSTC->getISurfaceTexture()); 115 ASSERT_TRUE(ist != NULL); 116} 117 118TEST_F(SurfaceTextureClientTest, QueuesToWindowCompositorIsFalse) { 119 int result = -123; 120 int err = mANW->query(mANW.get(), NATIVE_WINDOW_QUEUES_TO_WINDOW_COMPOSER, 121 &result); 122 EXPECT_EQ(NO_ERROR, err); 123 EXPECT_EQ(0, result); 124} 125 126TEST_F(SurfaceTextureClientTest, ConcreteTypeIsSurfaceTextureClient) { 127 int result = -123; 128 int err = mANW->query(mANW.get(), NATIVE_WINDOW_CONCRETE_TYPE, &result); 129 EXPECT_EQ(NO_ERROR, err); 130 EXPECT_EQ(NATIVE_WINDOW_SURFACE_TEXTURE_CLIENT, result); 131} 132 133TEST_F(SurfaceTextureClientTest, EglCreateWindowSurfaceSucceeds) { 134 EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); 135 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 136 ASSERT_NE(EGL_NO_DISPLAY, dpy); 137 138 EGLint majorVersion; 139 EGLint minorVersion; 140 EXPECT_TRUE(eglInitialize(dpy, &majorVersion, &minorVersion)); 141 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 142 143 EGLConfig myConfig = {0}; 144 EGLint numConfigs = 0; 145 EGLint configAttribs[] = { 146 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 147 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 148 EGL_RED_SIZE, 8, 149 EGL_GREEN_SIZE, 8, 150 EGL_BLUE_SIZE, 8, 151 EGL_ALPHA_SIZE, 8, 152 EGL_DEPTH_SIZE, 16, 153 EGL_STENCIL_SIZE, 8, 154 EGL_NONE }; 155 EXPECT_TRUE(eglChooseConfig(dpy, configAttribs, &myConfig, 1, 156 &numConfigs)); 157 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 158 159 EGLSurface eglSurface = eglCreateWindowSurface(dpy, myConfig, mANW.get(), 160 NULL); 161 EXPECT_NE(EGL_NO_SURFACE, eglSurface); 162 EXPECT_EQ(EGL_SUCCESS, eglGetError()); 163 164 if (eglSurface != EGL_NO_SURFACE) { 165 eglDestroySurface(dpy, eglSurface); 166 } 167 168 eglTerminate(dpy); 169} 170 171TEST_F(SurfaceTextureClientTest, BufferGeometryInvalidSizesFail) { 172 EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1, 0, 0)); 173 EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 0, -1, 0)); 174 EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, -1)); 175 EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), -1, -1, 0)); 176 EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 0, 8, 0)); 177 EXPECT_GT(OK, native_window_set_buffers_geometry(mANW.get(), 8, 0, 0)); 178} 179 180TEST_F(SurfaceTextureClientTest, DefaultGeometryValues) { 181 ANativeWindowBuffer* buf; 182 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf)); 183 EXPECT_EQ(1, buf->width); 184 EXPECT_EQ(1, buf->height); 185 EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format); 186 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf)); 187} 188 189TEST_F(SurfaceTextureClientTest, BufferGeometryCanBeSet) { 190 ANativeWindowBuffer* buf; 191 EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, PIXEL_FORMAT_RGB_565)); 192 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf)); 193 EXPECT_EQ(16, buf->width); 194 EXPECT_EQ(8, buf->height); 195 EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format); 196 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf)); 197} 198 199TEST_F(SurfaceTextureClientTest, BufferGeometryDefaultSizeSetFormat) { 200 ANativeWindowBuffer* buf; 201 EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565)); 202 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf)); 203 EXPECT_EQ(1, buf->width); 204 EXPECT_EQ(1, buf->height); 205 EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format); 206 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf)); 207} 208 209TEST_F(SurfaceTextureClientTest, BufferGeometrySetSizeDefaultFormat) { 210 ANativeWindowBuffer* buf; 211 EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0)); 212 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf)); 213 EXPECT_EQ(16, buf->width); 214 EXPECT_EQ(8, buf->height); 215 EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format); 216 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf)); 217} 218 219TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeUnset) { 220 ANativeWindowBuffer* buf; 221 EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0)); 222 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf)); 223 EXPECT_EQ(16, buf->width); 224 EXPECT_EQ(8, buf->height); 225 EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format); 226 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf)); 227 EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, 0)); 228 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf)); 229 EXPECT_EQ(1, buf->width); 230 EXPECT_EQ(1, buf->height); 231 EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format); 232 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf)); 233} 234 235TEST_F(SurfaceTextureClientTest, BufferGeometrySizeCanBeChangedWithoutFormat) { 236 ANativeWindowBuffer* buf; 237 EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, PIXEL_FORMAT_RGB_565)); 238 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf)); 239 EXPECT_EQ(1, buf->width); 240 EXPECT_EQ(1, buf->height); 241 EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format); 242 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf)); 243 EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0)); 244 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf)); 245 EXPECT_EQ(16, buf->width); 246 EXPECT_EQ(8, buf->height); 247 EXPECT_EQ(PIXEL_FORMAT_RGB_565, buf->format); 248 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf)); 249} 250 251TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSize) { 252 sp<SurfaceTexture> st(mST); 253 ANativeWindowBuffer* buf; 254 EXPECT_EQ(OK, st->setDefaultBufferSize(16, 8)); 255 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf)); 256 EXPECT_EQ(16, buf->width); 257 EXPECT_EQ(8, buf->height); 258 EXPECT_EQ(PIXEL_FORMAT_RGBA_8888, buf->format); 259 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf)); 260} 261 262TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeAfterDequeue) { 263 ANativeWindowBuffer* buf[2]; 264 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); 265 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 266 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 267 EXPECT_NE(buf[0], buf[1]); 268 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0])); 269 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1])); 270 EXPECT_EQ(OK, mST->setDefaultBufferSize(16, 8)); 271 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 272 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 273 EXPECT_NE(buf[0], buf[1]); 274 EXPECT_EQ(16, buf[0]->width); 275 EXPECT_EQ(16, buf[1]->width); 276 EXPECT_EQ(8, buf[0]->height); 277 EXPECT_EQ(8, buf[1]->height); 278 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0])); 279 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1])); 280} 281 282TEST_F(SurfaceTextureClientTest, SurfaceTextureSetDefaultSizeVsGeometry) { 283 ANativeWindowBuffer* buf[2]; 284 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); 285 EXPECT_EQ(OK, mST->setDefaultBufferSize(16, 8)); 286 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 287 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 288 EXPECT_NE(buf[0], buf[1]); 289 EXPECT_EQ(16, buf[0]->width); 290 EXPECT_EQ(16, buf[1]->width); 291 EXPECT_EQ(8, buf[0]->height); 292 EXPECT_EQ(8, buf[1]->height); 293 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0])); 294 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1])); 295 EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 12, 24, 0)); 296 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 297 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 298 EXPECT_NE(buf[0], buf[1]); 299 EXPECT_EQ(12, buf[0]->width); 300 EXPECT_EQ(12, buf[1]->width); 301 EXPECT_EQ(24, buf[0]->height); 302 EXPECT_EQ(24, buf[1]->height); 303 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0])); 304 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1])); 305} 306 307TEST_F(SurfaceTextureClientTest, SurfaceTextureTooManyUpdateTexImage) { 308 android_native_buffer_t* buf[3]; 309 ASSERT_EQ(OK, mST->setSynchronousMode(false)); 310 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); 311 312 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 313 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 314 EXPECT_EQ(OK, mST->updateTexImage()); 315 EXPECT_EQ(OK, mST->updateTexImage()); 316 317 ASSERT_EQ(OK, mST->setSynchronousMode(true)); 318 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3)); 319 320 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 321 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 322 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 323 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1])); 324 325 EXPECT_EQ(OK, mST->updateTexImage()); 326 EXPECT_EQ(OK, mST->updateTexImage()); 327 EXPECT_EQ(OK, mST->updateTexImage()); 328} 329 330TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeSlowRetire) { 331 android_native_buffer_t* buf[3]; 332 ASSERT_EQ(OK, mST->setSynchronousMode(true)); 333 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); 334 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 335 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 336 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2])); 337 EXPECT_NE(buf[0], buf[1]); 338 EXPECT_NE(buf[1], buf[2]); 339 EXPECT_NE(buf[2], buf[0]); 340 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 341 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1])); 342 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2])); 343 EXPECT_EQ(OK, mST->updateTexImage()); 344 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]); 345 EXPECT_EQ(OK, mST->updateTexImage()); 346 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]); 347 EXPECT_EQ(OK, mST->updateTexImage()); 348 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]); 349} 350 351TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeFastRetire) { 352 android_native_buffer_t* buf[3]; 353 ASSERT_EQ(OK, mST->setSynchronousMode(true)); 354 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); 355 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 356 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 357 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2])); 358 EXPECT_NE(buf[0], buf[1]); 359 EXPECT_NE(buf[1], buf[2]); 360 EXPECT_NE(buf[2], buf[0]); 361 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 362 EXPECT_EQ(OK, mST->updateTexImage()); 363 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]); 364 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1])); 365 EXPECT_EQ(OK, mST->updateTexImage()); 366 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]); 367 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2])); 368 EXPECT_EQ(OK, mST->updateTexImage()); 369 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]); 370} 371 372TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeDQQR) { 373 android_native_buffer_t* buf[3]; 374 ASSERT_EQ(OK, mST->setSynchronousMode(true)); 375 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3)); 376 377 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 378 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 379 EXPECT_EQ(OK, mST->updateTexImage()); 380 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]); 381 382 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 383 EXPECT_NE(buf[0], buf[1]); 384 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1])); 385 EXPECT_EQ(OK, mST->updateTexImage()); 386 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]); 387 388 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2])); 389 EXPECT_NE(buf[1], buf[2]); 390 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2])); 391 EXPECT_EQ(OK, mST->updateTexImage()); 392 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[2]); 393} 394 395// XXX: We currently have no hardware that properly handles dequeuing the 396// buffer that is currently bound to the texture. 397TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeDequeueCurrent) { 398 android_native_buffer_t* buf[3]; 399 android_native_buffer_t* firstBuf; 400 ASSERT_EQ(OK, mST->setSynchronousMode(true)); 401 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3)); 402 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &firstBuf)); 403 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), firstBuf)); 404 EXPECT_EQ(OK, mST->updateTexImage()); 405 EXPECT_EQ(mST->getCurrentBuffer().get(), firstBuf); 406 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 407 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 408 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 409 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1])); 410 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2])); 411 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2])); 412 EXPECT_NE(buf[0], buf[1]); 413 EXPECT_NE(buf[1], buf[2]); 414 EXPECT_NE(buf[2], buf[0]); 415 EXPECT_EQ(firstBuf, buf[2]); 416} 417 418TEST_F(SurfaceTextureClientTest, SurfaceTextureSyncModeMinUndequeued) { 419 android_native_buffer_t* buf[3]; 420 ASSERT_EQ(OK, mST->setSynchronousMode(true)); 421 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3)); 422 423 // We should be able to dequeue all the buffers before we've queued mANWy. 424 EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 425 EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 426 EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2])); 427 428 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2])); 429 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1])); 430 431 EXPECT_EQ(OK, mST->updateTexImage()); 432 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]); 433 434 EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2])); 435 436 // Once we've queued a buffer, however we should not be able to dequeue more 437 // than (buffer-count - MIN_UNDEQUEUED_BUFFERS), which is 2 in this case. 438 EXPECT_EQ(-EBUSY, mANW->dequeueBuffer(mANW.get(), &buf[1])); 439 440 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0])); 441 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2])); 442} 443 444// XXX: This is not expected to pass until the synchronization hacks are removed 445// from the SurfaceTexture class. 446TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeWaitRetire) { 447 class MyThread : public Thread { 448 sp<SurfaceTexture> mST; 449 EGLContext ctx; 450 EGLSurface sur; 451 EGLDisplay dpy; 452 bool mBufferRetired; 453 Mutex mLock; 454 virtual bool threadLoop() { 455 eglMakeCurrent(dpy, sur, sur, ctx); 456 usleep(20000); 457 Mutex::Autolock _l(mLock); 458 mST->updateTexImage(); 459 mBufferRetired = true; 460 eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 461 return false; 462 } 463 public: 464 MyThread(const sp<SurfaceTexture>& mST) 465 : mST(mST), mBufferRetired(false) { 466 ctx = eglGetCurrentContext(); 467 sur = eglGetCurrentSurface(EGL_DRAW); 468 dpy = eglGetCurrentDisplay(); 469 eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 470 } 471 ~MyThread() { 472 eglMakeCurrent(dpy, sur, sur, ctx); 473 } 474 void bufferDequeued() { 475 Mutex::Autolock _l(mLock); 476 EXPECT_EQ(true, mBufferRetired); 477 } 478 }; 479 480 android_native_buffer_t* buf[3]; 481 ASSERT_EQ(OK, mST->setSynchronousMode(true)); 482 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3)); 483 // dequeue/queue/update so we have a current buffer 484 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 485 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 486 mST->updateTexImage(); 487 488 MyThread* thread = new MyThread(mST); 489 sp<Thread> threadBase(thread); 490 491 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 492 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 493 thread->run(); 494 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 495 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1])); 496 //ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2])); 497 //ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2])); 498 thread->bufferDequeued(); 499 thread->requestExitAndWait(); 500} 501 502TEST_F(SurfaceTextureClientTest, GetTransformMatrixReturnsVerticalFlip) { 503 android_native_buffer_t* buf[3]; 504 float mtx[16] = {}; 505 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); 506 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 507 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 508 ASSERT_EQ(OK, mST->updateTexImage()); 509 mST->getTransformMatrix(mtx); 510 511 EXPECT_EQ(1.f, mtx[0]); 512 EXPECT_EQ(0.f, mtx[1]); 513 EXPECT_EQ(0.f, mtx[2]); 514 EXPECT_EQ(0.f, mtx[3]); 515 516 EXPECT_EQ(0.f, mtx[4]); 517 EXPECT_EQ(-1.f, mtx[5]); 518 EXPECT_EQ(0.f, mtx[6]); 519 EXPECT_EQ(0.f, mtx[7]); 520 521 EXPECT_EQ(0.f, mtx[8]); 522 EXPECT_EQ(0.f, mtx[9]); 523 EXPECT_EQ(1.f, mtx[10]); 524 EXPECT_EQ(0.f, mtx[11]); 525 526 EXPECT_EQ(0.f, mtx[12]); 527 EXPECT_EQ(1.f, mtx[13]); 528 EXPECT_EQ(0.f, mtx[14]); 529 EXPECT_EQ(1.f, mtx[15]); 530} 531 532TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffers) { 533 android_native_buffer_t* buf[3]; 534 float mtx[16] = {}; 535 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); 536 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 537 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 538 ASSERT_EQ(OK, mST->updateTexImage()); 539 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers 540 mST->getTransformMatrix(mtx); 541 542 EXPECT_EQ(1.f, mtx[0]); 543 EXPECT_EQ(0.f, mtx[1]); 544 EXPECT_EQ(0.f, mtx[2]); 545 EXPECT_EQ(0.f, mtx[3]); 546 547 EXPECT_EQ(0.f, mtx[4]); 548 EXPECT_EQ(-1.f, mtx[5]); 549 EXPECT_EQ(0.f, mtx[6]); 550 EXPECT_EQ(0.f, mtx[7]); 551 552 EXPECT_EQ(0.f, mtx[8]); 553 EXPECT_EQ(0.f, mtx[9]); 554 EXPECT_EQ(1.f, mtx[10]); 555 EXPECT_EQ(0.f, mtx[11]); 556 557 EXPECT_EQ(0.f, mtx[12]); 558 EXPECT_EQ(1.f, mtx[13]); 559 EXPECT_EQ(0.f, mtx[14]); 560 EXPECT_EQ(1.f, mtx[15]); 561} 562 563TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffersWithCrop) { 564 android_native_buffer_t* buf[3]; 565 float mtx[16] = {}; 566 android_native_rect_t crop; 567 crop.left = 0; 568 crop.top = 0; 569 crop.right = 5; 570 crop.bottom = 5; 571 572 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); 573 ASSERT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 8, 8, 0)); 574 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 575 ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &crop)); 576 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 577 ASSERT_EQ(OK, mST->updateTexImage()); 578 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers 579 mST->getTransformMatrix(mtx); 580 581 // This accounts for the 1 texel shrink for each edge that's included in the 582 // transform matrix to avoid texturing outside the crop region. 583 EXPECT_EQ(.5f, mtx[0]); 584 EXPECT_EQ(0.f, mtx[1]); 585 EXPECT_EQ(0.f, mtx[2]); 586 EXPECT_EQ(0.f, mtx[3]); 587 588 EXPECT_EQ(0.f, mtx[4]); 589 EXPECT_EQ(-.5f, mtx[5]); 590 EXPECT_EQ(0.f, mtx[6]); 591 EXPECT_EQ(0.f, mtx[7]); 592 593 EXPECT_EQ(0.f, mtx[8]); 594 EXPECT_EQ(0.f, mtx[9]); 595 EXPECT_EQ(1.f, mtx[10]); 596 EXPECT_EQ(0.f, mtx[11]); 597 598 EXPECT_EQ(0.f, mtx[12]); 599 EXPECT_EQ(.5f, mtx[13]); 600 EXPECT_EQ(0.f, mtx[14]); 601 EXPECT_EQ(1.f, mtx[15]); 602} 603 604// This test verifies that the buffer format can be queried immediately after 605// it is set. 606TEST_F(SurfaceTextureClientTest, QueryFormatAfterSettingWorks) { 607 sp<ANativeWindow> anw(mSTC); 608 int fmts[] = { 609 // RGBA_8888 should not come first, as it's the default 610 HAL_PIXEL_FORMAT_RGBX_8888, 611 HAL_PIXEL_FORMAT_RGBA_8888, 612 HAL_PIXEL_FORMAT_RGB_888, 613 HAL_PIXEL_FORMAT_RGB_565, 614 HAL_PIXEL_FORMAT_BGRA_8888, 615 HAL_PIXEL_FORMAT_RGBA_5551, 616 HAL_PIXEL_FORMAT_RGBA_4444, 617 HAL_PIXEL_FORMAT_YV12, 618 }; 619 620 const int numFmts = (sizeof(fmts) / sizeof(fmts[0])); 621 for (int i = 0; i < numFmts; i++) { 622 int fmt = -1; 623 ASSERT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, fmts[i])); 624 ASSERT_EQ(OK, anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt)); 625 EXPECT_EQ(fmts[i], fmt); 626 } 627} 628 629class MultiSurfaceTextureClientTest : public ::testing::Test { 630 631public: 632 MultiSurfaceTextureClientTest() : 633 mEglDisplay(EGL_NO_DISPLAY), 634 mEglContext(EGL_NO_CONTEXT) { 635 for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { 636 mEglSurfaces[i] = EGL_NO_CONTEXT; 637 } 638 } 639 640protected: 641 642 enum { NUM_SURFACE_TEXTURES = 32 }; 643 644 virtual void SetUp() { 645 mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 646 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 647 ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay); 648 649 EGLint majorVersion, minorVersion; 650 EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion)); 651 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 652 653 EGLConfig myConfig; 654 EGLint numConfigs = 0; 655 EGLint configAttribs[] = { 656 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 657 EGL_NONE 658 }; 659 EXPECT_TRUE(eglChooseConfig(mEglDisplay, configAttribs, &myConfig, 1, 660 &numConfigs)); 661 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 662 663 mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT, 664 0); 665 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 666 ASSERT_NE(EGL_NO_CONTEXT, mEglContext); 667 668 for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { 669 sp<SurfaceTexture> st(new SurfaceTexture(i)); 670 sp<SurfaceTextureClient> stc(new SurfaceTextureClient(st)); 671 mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig, 672 static_cast<ANativeWindow*>(stc.get()), NULL); 673 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 674 ASSERT_NE(EGL_NO_SURFACE, mEglSurfaces[i]); 675 } 676 } 677 678 virtual void TearDown() { 679 eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 680 EGL_NO_CONTEXT); 681 682 for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { 683 if (mEglSurfaces[i] != EGL_NO_SURFACE) { 684 eglDestroySurface(mEglDisplay, mEglSurfaces[i]); 685 } 686 } 687 688 if (mEglContext != EGL_NO_CONTEXT) { 689 eglDestroyContext(mEglDisplay, mEglContext); 690 } 691 692 if (mEglDisplay != EGL_NO_DISPLAY) { 693 eglTerminate(mEglDisplay); 694 } 695 } 696 697 EGLDisplay mEglDisplay; 698 EGLSurface mEglSurfaces[NUM_SURFACE_TEXTURES]; 699 EGLContext mEglContext; 700}; 701 702// XXX: This test is disabled because it causes a hang on some devices. See bug 703// 5015672. 704TEST_F(MultiSurfaceTextureClientTest, DISABLED_MakeCurrentBetweenSurfacesWorks) { 705 for (int iter = 0; iter < 8; iter++) { 706 for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { 707 eglMakeCurrent(mEglDisplay, mEglSurfaces[i], mEglSurfaces[i], 708 mEglContext); 709 glClear(GL_COLOR_BUFFER_BIT); 710 eglSwapBuffers(mEglDisplay, mEglSurfaces[i]); 711 } 712 } 713} 714 715} // namespace android 716