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