SurfaceTextureClient_test.cpp revision d72f233ffa125856a44976a50a66ceb669f49ab2
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, mANW->dequeueBuffer(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)); 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, mANW->dequeueBuffer(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)); 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, mANW->dequeueBuffer(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)); 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, mANW->dequeueBuffer(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)); 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, mANW->dequeueBuffer(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)); 228 EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 0, 0, 0)); 229 ASSERT_EQ(OK, mANW->dequeueBuffer(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)); 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, mANW->dequeueBuffer(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)); 244 EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 16, 8, 0)); 245 ASSERT_EQ(OK, mANW->dequeueBuffer(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)); 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, mANW->dequeueBuffer(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)); 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, mANW->dequeueBuffer(mANW.get(), &buf[0])); 267 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 268 EXPECT_NE(buf[0], buf[1]); 269 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0])); 270 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1])); 271 EXPECT_EQ(OK, mST->setDefaultBufferSize(16, 8)); 272 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 273 ASSERT_EQ(OK, mANW->dequeueBuffer(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])); 280 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[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, mANW->dequeueBuffer(mANW.get(), &buf[0])); 288 ASSERT_EQ(OK, mANW->dequeueBuffer(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])); 295 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[1])); 296 EXPECT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 12, 24, 0)); 297 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 298 ASSERT_EQ(OK, mANW->dequeueBuffer(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])); 305 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[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, mANW->dequeueBuffer(mANW.get(), &buf[0])); 314 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 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, mANW->dequeueBuffer(mANW.get(), &buf[0])); 322 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 323 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 324 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[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, mANW->dequeueBuffer(mANW.get(), &buf[0])); 336 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 337 ASSERT_EQ(OK, mANW->dequeueBuffer(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])); 342 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1])); 343 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2])); 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, mANW->dequeueBuffer(mANW.get(), &buf[0])); 357 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 358 ASSERT_EQ(OK, mANW->dequeueBuffer(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])); 363 EXPECT_EQ(OK, mST->updateTexImage()); 364 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]); 365 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[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])); 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, mANW->dequeueBuffer(mANW.get(), &buf[0])); 379 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 380 EXPECT_EQ(OK, mST->updateTexImage()); 381 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[0]); 382 383 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 384 EXPECT_NE(buf[0], buf[1]); 385 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1])); 386 EXPECT_EQ(OK, mST->updateTexImage()); 387 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]); 388 389 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2])); 390 EXPECT_NE(buf[1], buf[2]); 391 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2])); 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, mANW->dequeueBuffer(mANW.get(), &firstBuf)); 404 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), firstBuf)); 405 EXPECT_EQ(OK, mST->updateTexImage()); 406 EXPECT_EQ(mST->getCurrentBuffer().get(), firstBuf); 407 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 408 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 409 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 410 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1])); 411 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2])); 412 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2])); 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, mANW->dequeueBuffer(mANW.get(), &buf[0])); 426 EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 427 EXPECT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2])); 428 429 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2])); 430 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1])); 431 432 EXPECT_EQ(OK, mST->updateTexImage()); 433 EXPECT_EQ(mST->getCurrentBuffer().get(), buf[1]); 434 435 EXPECT_EQ(OK, mANW->dequeueBuffer(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, mANW->dequeueBuffer(mANW.get(), &buf[1])); 440 441 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[0])); 442 ASSERT_EQ(OK, mANW->cancelBuffer(mANW.get(), buf[2])); 443} 444 445TEST_F(SurfaceTextureClientTest, SetPostTransformCropUntransforms) { 446 android_native_rect_t rect = {1, 5, 4, 14}; 447 native_window_set_post_transform_crop(mANW.get(), &rect); 448 449 uint32_t xforms[] = { 450 HAL_TRANSFORM_FLIP_H, 451 HAL_TRANSFORM_FLIP_V, 452 HAL_TRANSFORM_ROT_90, 453 HAL_TRANSFORM_ROT_180, 454 HAL_TRANSFORM_ROT_270, 455 }; 456 457 Rect expectedRects[] = { 458 Rect(4, 5, 7, 14), // HAL_TRANSFORM_FLIP_H 459 Rect(1, 2, 4, 11), // HAL_TRANSFORM_FLIP_V 460 Rect(5, 4, 14, 7), // HAL_TRANSFORM_ROT_90 461 Rect(4, 2, 7, 11), // HAL_TRANSFORM_ROT_180 462 Rect(2, 1, 11, 4), // HAL_TRANSFORM_ROT_270 463 }; 464 465 for (size_t i = 0; i < sizeof(xforms)/sizeof(xforms[0]); i++) { 466 SCOPED_TRACE(String8::format("xform=%#x", xforms[i]).string()); 467 468 int w = 8, h = 16; 469 if (xforms[i] & HAL_TRANSFORM_ROT_90) { 470 w = 16; 471 h = 8; 472 } 473 ASSERT_EQ(OK, native_window_set_buffers_transform(mANW.get(), xforms[i])); 474 ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), w, h)); 475 476 android_native_buffer_t* buf; 477 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf)); 478 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf)); 479 ASSERT_EQ(OK, mST->updateTexImage()); 480 481 Rect crop = mST->getCurrentCrop(); 482 EXPECT_EQ(expectedRects[i].left, crop.left); 483 EXPECT_EQ(expectedRects[i].top, crop.top); 484 EXPECT_EQ(expectedRects[i].right, crop.right); 485 EXPECT_EQ(expectedRects[i].bottom, crop.bottom); 486 } 487} 488 489TEST_F(SurfaceTextureClientTest, SetCropCropsCrop) { 490 android_native_rect_t rect = {-2, -13, 40, 18}; 491 native_window_set_crop(mANW.get(), &rect); 492 493 ASSERT_EQ(OK, native_window_set_buffers_dimensions(mANW.get(), 4, 4)); 494 495 android_native_buffer_t* buf; 496 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf)); 497 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf)); 498 ASSERT_EQ(OK, mST->updateTexImage()); 499 500 Rect crop = mST->getCurrentCrop(); 501 EXPECT_EQ(0, crop.left); 502 EXPECT_EQ(0, crop.top); 503 EXPECT_EQ(4, crop.right); 504 EXPECT_EQ(4, crop.bottom); 505} 506 507// XXX: This is not expected to pass until the synchronization hacks are removed 508// from the SurfaceTexture class. 509TEST_F(SurfaceTextureClientTest, DISABLED_SurfaceTextureSyncModeWaitRetire) { 510 class MyThread : public Thread { 511 sp<SurfaceTexture> mST; 512 EGLContext ctx; 513 EGLSurface sur; 514 EGLDisplay dpy; 515 bool mBufferRetired; 516 Mutex mLock; 517 virtual bool threadLoop() { 518 eglMakeCurrent(dpy, sur, sur, ctx); 519 usleep(20000); 520 Mutex::Autolock _l(mLock); 521 mST->updateTexImage(); 522 mBufferRetired = true; 523 eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 524 return false; 525 } 526 public: 527 MyThread(const sp<SurfaceTexture>& mST) 528 : mST(mST), mBufferRetired(false) { 529 ctx = eglGetCurrentContext(); 530 sur = eglGetCurrentSurface(EGL_DRAW); 531 dpy = eglGetCurrentDisplay(); 532 eglMakeCurrent(dpy, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT); 533 } 534 ~MyThread() { 535 eglMakeCurrent(dpy, sur, sur, ctx); 536 } 537 void bufferDequeued() { 538 Mutex::Autolock _l(mLock); 539 EXPECT_EQ(true, mBufferRetired); 540 } 541 }; 542 543 android_native_buffer_t* buf[3]; 544 ASSERT_EQ(OK, mST->setSynchronousMode(true)); 545 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 3)); 546 // dequeue/queue/update so we have a current buffer 547 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 548 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 549 mST->updateTexImage(); 550 551 MyThread* thread = new MyThread(mST); 552 sp<Thread> threadBase(thread); 553 554 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 555 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 556 thread->run(); 557 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[1])); 558 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[1])); 559 //ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[2])); 560 //ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[2])); 561 thread->bufferDequeued(); 562 thread->requestExitAndWait(); 563} 564 565TEST_F(SurfaceTextureClientTest, GetTransformMatrixReturnsVerticalFlip) { 566 android_native_buffer_t* buf[3]; 567 float mtx[16] = {}; 568 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); 569 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 570 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 571 ASSERT_EQ(OK, mST->updateTexImage()); 572 mST->getTransformMatrix(mtx); 573 574 EXPECT_EQ(1.f, mtx[0]); 575 EXPECT_EQ(0.f, mtx[1]); 576 EXPECT_EQ(0.f, mtx[2]); 577 EXPECT_EQ(0.f, mtx[3]); 578 579 EXPECT_EQ(0.f, mtx[4]); 580 EXPECT_EQ(-1.f, mtx[5]); 581 EXPECT_EQ(0.f, mtx[6]); 582 EXPECT_EQ(0.f, mtx[7]); 583 584 EXPECT_EQ(0.f, mtx[8]); 585 EXPECT_EQ(0.f, mtx[9]); 586 EXPECT_EQ(1.f, mtx[10]); 587 EXPECT_EQ(0.f, mtx[11]); 588 589 EXPECT_EQ(0.f, mtx[12]); 590 EXPECT_EQ(1.f, mtx[13]); 591 EXPECT_EQ(0.f, mtx[14]); 592 EXPECT_EQ(1.f, mtx[15]); 593} 594 595TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffers) { 596 android_native_buffer_t* buf[3]; 597 float mtx[16] = {}; 598 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); 599 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 600 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 601 ASSERT_EQ(OK, mST->updateTexImage()); 602 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers 603 mST->getTransformMatrix(mtx); 604 605 EXPECT_EQ(1.f, mtx[0]); 606 EXPECT_EQ(0.f, mtx[1]); 607 EXPECT_EQ(0.f, mtx[2]); 608 EXPECT_EQ(0.f, mtx[3]); 609 610 EXPECT_EQ(0.f, mtx[4]); 611 EXPECT_EQ(-1.f, mtx[5]); 612 EXPECT_EQ(0.f, mtx[6]); 613 EXPECT_EQ(0.f, mtx[7]); 614 615 EXPECT_EQ(0.f, mtx[8]); 616 EXPECT_EQ(0.f, mtx[9]); 617 EXPECT_EQ(1.f, mtx[10]); 618 EXPECT_EQ(0.f, mtx[11]); 619 620 EXPECT_EQ(0.f, mtx[12]); 621 EXPECT_EQ(1.f, mtx[13]); 622 EXPECT_EQ(0.f, mtx[14]); 623 EXPECT_EQ(1.f, mtx[15]); 624} 625 626TEST_F(SurfaceTextureClientTest, GetTransformMatrixSucceedsAfterFreeingBuffersWithCrop) { 627 android_native_buffer_t* buf[3]; 628 float mtx[16] = {}; 629 android_native_rect_t crop; 630 crop.left = 0; 631 crop.top = 0; 632 crop.right = 5; 633 crop.bottom = 5; 634 635 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 4)); 636 ASSERT_EQ(OK, native_window_set_buffers_geometry(mANW.get(), 8, 8, 0)); 637 ASSERT_EQ(OK, mANW->dequeueBuffer(mANW.get(), &buf[0])); 638 ASSERT_EQ(OK, native_window_set_crop(mANW.get(), &crop)); 639 ASSERT_EQ(OK, mANW->queueBuffer(mANW.get(), buf[0])); 640 ASSERT_EQ(OK, mST->updateTexImage()); 641 ASSERT_EQ(OK, native_window_set_buffer_count(mANW.get(), 6)); // frees buffers 642 mST->getTransformMatrix(mtx); 643 644 // This accounts for the 1 texel shrink for each edge that's included in the 645 // transform matrix to avoid texturing outside the crop region. 646 EXPECT_EQ(.375f, mtx[0]); 647 EXPECT_EQ(0.f, mtx[1]); 648 EXPECT_EQ(0.f, mtx[2]); 649 EXPECT_EQ(0.f, mtx[3]); 650 651 EXPECT_EQ(0.f, mtx[4]); 652 EXPECT_EQ(-.375f, mtx[5]); 653 EXPECT_EQ(0.f, mtx[6]); 654 EXPECT_EQ(0.f, mtx[7]); 655 656 EXPECT_EQ(0.f, mtx[8]); 657 EXPECT_EQ(0.f, mtx[9]); 658 EXPECT_EQ(1.f, mtx[10]); 659 EXPECT_EQ(0.f, mtx[11]); 660 661 EXPECT_EQ(.125f, mtx[12]); 662 EXPECT_EQ(.5f, mtx[13]); 663 EXPECT_EQ(0.f, mtx[14]); 664 EXPECT_EQ(1.f, mtx[15]); 665} 666 667// This test verifies that the buffer format can be queried immediately after 668// it is set. 669TEST_F(SurfaceTextureClientTest, QueryFormatAfterSettingWorks) { 670 sp<ANativeWindow> anw(mSTC); 671 int fmts[] = { 672 // RGBA_8888 should not come first, as it's the default 673 HAL_PIXEL_FORMAT_RGBX_8888, 674 HAL_PIXEL_FORMAT_RGBA_8888, 675 HAL_PIXEL_FORMAT_RGB_888, 676 HAL_PIXEL_FORMAT_RGB_565, 677 HAL_PIXEL_FORMAT_BGRA_8888, 678 HAL_PIXEL_FORMAT_RGBA_5551, 679 HAL_PIXEL_FORMAT_RGBA_4444, 680 HAL_PIXEL_FORMAT_YV12, 681 }; 682 683 const int numFmts = (sizeof(fmts) / sizeof(fmts[0])); 684 for (int i = 0; i < numFmts; i++) { 685 int fmt = -1; 686 ASSERT_EQ(OK, native_window_set_buffers_geometry(anw.get(), 0, 0, fmts[i])); 687 ASSERT_EQ(OK, anw->query(anw.get(), NATIVE_WINDOW_FORMAT, &fmt)); 688 EXPECT_EQ(fmts[i], fmt); 689 } 690} 691 692class MultiSurfaceTextureClientTest : public ::testing::Test { 693 694public: 695 MultiSurfaceTextureClientTest() : 696 mEglDisplay(EGL_NO_DISPLAY), 697 mEglContext(EGL_NO_CONTEXT) { 698 for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { 699 mEglSurfaces[i] = EGL_NO_CONTEXT; 700 } 701 } 702 703protected: 704 705 enum { NUM_SURFACE_TEXTURES = 32 }; 706 707 virtual void SetUp() { 708 mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 709 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 710 ASSERT_NE(EGL_NO_DISPLAY, mEglDisplay); 711 712 EGLint majorVersion, minorVersion; 713 EXPECT_TRUE(eglInitialize(mEglDisplay, &majorVersion, &minorVersion)); 714 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 715 716 EGLConfig myConfig; 717 EGLint numConfigs = 0; 718 EGLint configAttribs[] = { 719 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 720 EGL_NONE 721 }; 722 EXPECT_TRUE(eglChooseConfig(mEglDisplay, configAttribs, &myConfig, 1, 723 &numConfigs)); 724 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 725 726 mEglContext = eglCreateContext(mEglDisplay, myConfig, EGL_NO_CONTEXT, 727 0); 728 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 729 ASSERT_NE(EGL_NO_CONTEXT, mEglContext); 730 731 for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { 732 sp<SurfaceTexture> st(new SurfaceTexture(i)); 733 sp<SurfaceTextureClient> stc(new SurfaceTextureClient(st)); 734 mEglSurfaces[i] = eglCreateWindowSurface(mEglDisplay, myConfig, 735 static_cast<ANativeWindow*>(stc.get()), NULL); 736 ASSERT_EQ(EGL_SUCCESS, eglGetError()); 737 ASSERT_NE(EGL_NO_SURFACE, mEglSurfaces[i]); 738 } 739 } 740 741 virtual void TearDown() { 742 eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 743 EGL_NO_CONTEXT); 744 745 for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { 746 if (mEglSurfaces[i] != EGL_NO_SURFACE) { 747 eglDestroySurface(mEglDisplay, mEglSurfaces[i]); 748 } 749 } 750 751 if (mEglContext != EGL_NO_CONTEXT) { 752 eglDestroyContext(mEglDisplay, mEglContext); 753 } 754 755 if (mEglDisplay != EGL_NO_DISPLAY) { 756 eglTerminate(mEglDisplay); 757 } 758 } 759 760 EGLDisplay mEglDisplay; 761 EGLSurface mEglSurfaces[NUM_SURFACE_TEXTURES]; 762 EGLContext mEglContext; 763}; 764 765// XXX: This test is disabled because it causes a hang on some devices. See bug 766// 5015672. 767TEST_F(MultiSurfaceTextureClientTest, DISABLED_MakeCurrentBetweenSurfacesWorks) { 768 for (int iter = 0; iter < 8; iter++) { 769 for (int i = 0; i < NUM_SURFACE_TEXTURES; i++) { 770 eglMakeCurrent(mEglDisplay, mEglSurfaces[i], mEglSurfaces[i], 771 mEglContext); 772 glClear(GL_COLOR_BUFFER_BIT); 773 eglSwapBuffers(mEglDisplay, mEglSurfaces[i]); 774 } 775 } 776} 777 778} // namespace android 779