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#include <gtest/gtest.h> 18 19#include <android/native_window.h> 20 21#include <binder/IMemory.h> 22 23#include <gui/ISurfaceComposer.h> 24#include <gui/Surface.h> 25#include <gui/SurfaceComposerClient.h> 26#include <private/gui/ComposerService.h> 27#include <private/gui/LayerState.h> 28 29#include <utils/String8.h> 30#include <ui/DisplayInfo.h> 31 32#include <math.h> 33 34namespace android { 35 36// Fill an RGBA_8888 formatted surface with a single color. 37static void fillSurfaceRGBA8(const sp<SurfaceControl>& sc, 38 uint8_t r, uint8_t g, uint8_t b) { 39 ANativeWindow_Buffer outBuffer; 40 sp<Surface> s = sc->getSurface(); 41 ASSERT_TRUE(s != NULL); 42 ASSERT_EQ(NO_ERROR, s->lock(&outBuffer, NULL)); 43 uint8_t* img = reinterpret_cast<uint8_t*>(outBuffer.bits); 44 for (int y = 0; y < outBuffer.height; y++) { 45 for (int x = 0; x < outBuffer.width; x++) { 46 uint8_t* pixel = img + (4 * (y*outBuffer.stride + x)); 47 pixel[0] = r; 48 pixel[1] = g; 49 pixel[2] = b; 50 pixel[3] = 255; 51 } 52 } 53 ASSERT_EQ(NO_ERROR, s->unlockAndPost()); 54} 55 56// A ScreenCapture is a screenshot from SurfaceFlinger that can be used to check 57// individual pixel values for testing purposes. 58class ScreenCapture : public RefBase { 59public: 60 static void captureScreen(sp<ScreenCapture>* sc) { 61 sp<IGraphicBufferProducer> producer; 62 sp<IGraphicBufferConsumer> consumer; 63 BufferQueue::createBufferQueue(&producer, &consumer); 64 IGraphicBufferProducer::QueueBufferOutput bufferOutput; 65 sp<CpuConsumer> cpuConsumer = new CpuConsumer(consumer, 1); 66 sp<ISurfaceComposer> sf(ComposerService::getComposerService()); 67 sp<IBinder> display(sf->getBuiltInDisplay( 68 ISurfaceComposer::eDisplayIdMain)); 69 SurfaceComposerClient::openGlobalTransaction(); 70 SurfaceComposerClient::closeGlobalTransaction(true); 71 ASSERT_EQ(NO_ERROR, sf->captureScreen(display, producer, Rect(), 0, 0, 72 0, INT_MAX, false)); 73 *sc = new ScreenCapture(cpuConsumer); 74 } 75 76 void checkPixel(uint32_t x, uint32_t y, uint8_t r, uint8_t g, uint8_t b) { 77 ASSERT_EQ(HAL_PIXEL_FORMAT_RGBA_8888, mBuf.format); 78 const uint8_t* img = static_cast<const uint8_t*>(mBuf.data); 79 const uint8_t* pixel = img + (4 * (y * mBuf.stride + x)); 80 if (r != pixel[0] || g != pixel[1] || b != pixel[2]) { 81 String8 err(String8::format("pixel @ (%3d, %3d): " 82 "expected [%3d, %3d, %3d], got [%3d, %3d, %3d]", 83 x, y, r, g, b, pixel[0], pixel[1], pixel[2])); 84 EXPECT_EQ(String8(), err) << err.string(); 85 } 86 } 87 88private: 89 ScreenCapture(const sp<CpuConsumer>& cc) : 90 mCC(cc) { 91 EXPECT_EQ(NO_ERROR, mCC->lockNextBuffer(&mBuf)); 92 } 93 94 ~ScreenCapture() { 95 mCC->unlockBuffer(mBuf); 96 } 97 98 sp<CpuConsumer> mCC; 99 CpuConsumer::LockedBuffer mBuf; 100}; 101 102class LayerUpdateTest : public ::testing::Test { 103protected: 104 virtual void SetUp() { 105 mComposerClient = new SurfaceComposerClient; 106 ASSERT_EQ(NO_ERROR, mComposerClient->initCheck()); 107 108 sp<IBinder> display(SurfaceComposerClient::getBuiltInDisplay( 109 ISurfaceComposer::eDisplayIdMain)); 110 DisplayInfo info; 111 SurfaceComposerClient::getDisplayInfo(display, &info); 112 113 ssize_t displayWidth = info.w; 114 ssize_t displayHeight = info.h; 115 116 // Background surface 117 mBGSurfaceControl = mComposerClient->createSurface( 118 String8("BG Test Surface"), displayWidth, displayHeight, 119 PIXEL_FORMAT_RGBA_8888, 0); 120 ASSERT_TRUE(mBGSurfaceControl != NULL); 121 ASSERT_TRUE(mBGSurfaceControl->isValid()); 122 fillSurfaceRGBA8(mBGSurfaceControl, 63, 63, 195); 123 124 // Foreground surface 125 mFGSurfaceControl = mComposerClient->createSurface( 126 String8("FG Test Surface"), 64, 64, PIXEL_FORMAT_RGBA_8888, 0); 127 ASSERT_TRUE(mFGSurfaceControl != NULL); 128 ASSERT_TRUE(mFGSurfaceControl->isValid()); 129 130 fillSurfaceRGBA8(mFGSurfaceControl, 195, 63, 63); 131 132 // Synchronization surface 133 mSyncSurfaceControl = mComposerClient->createSurface( 134 String8("Sync Test Surface"), 1, 1, PIXEL_FORMAT_RGBA_8888, 0); 135 ASSERT_TRUE(mSyncSurfaceControl != NULL); 136 ASSERT_TRUE(mSyncSurfaceControl->isValid()); 137 138 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); 139 140 SurfaceComposerClient::openGlobalTransaction(); 141 142 mComposerClient->setDisplayLayerStack(display, 0); 143 144 ASSERT_EQ(NO_ERROR, mBGSurfaceControl->setLayer(INT_MAX-2)); 145 ASSERT_EQ(NO_ERROR, mBGSurfaceControl->show()); 146 147 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayer(INT_MAX-1)); 148 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(64, 64)); 149 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->show()); 150 151 ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->setLayer(INT_MAX-1)); 152 ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->setPosition(displayWidth-2, 153 displayHeight-2)); 154 ASSERT_EQ(NO_ERROR, mSyncSurfaceControl->show()); 155 156 SurfaceComposerClient::closeGlobalTransaction(true); 157 } 158 159 virtual void TearDown() { 160 mComposerClient->dispose(); 161 mBGSurfaceControl = 0; 162 mFGSurfaceControl = 0; 163 mSyncSurfaceControl = 0; 164 mComposerClient = 0; 165 } 166 167 void waitForPostedBuffers() { 168 // Since the sync surface is in synchronous mode (i.e. double buffered) 169 // posting three buffers to it should ensure that at least two 170 // SurfaceFlinger::handlePageFlip calls have been made, which should 171 // guaranteed that a buffer posted to another Surface has been retired. 172 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); 173 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); 174 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); 175 } 176 177 sp<SurfaceComposerClient> mComposerClient; 178 sp<SurfaceControl> mBGSurfaceControl; 179 sp<SurfaceControl> mFGSurfaceControl; 180 181 // This surface is used to ensure that the buffers posted to 182 // mFGSurfaceControl have been picked up by SurfaceFlinger. 183 sp<SurfaceControl> mSyncSurfaceControl; 184}; 185 186TEST_F(LayerUpdateTest, LayerMoveWorks) { 187 sp<ScreenCapture> sc; 188 { 189 SCOPED_TRACE("before move"); 190 ScreenCapture::captureScreen(&sc); 191 sc->checkPixel( 0, 12, 63, 63, 195); 192 sc->checkPixel( 75, 75, 195, 63, 63); 193 sc->checkPixel(145, 145, 63, 63, 195); 194 } 195 196 SurfaceComposerClient::openGlobalTransaction(); 197 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(128, 128)); 198 SurfaceComposerClient::closeGlobalTransaction(true); 199 { 200 // This should reflect the new position, but not the new color. 201 SCOPED_TRACE("after move, before redraw"); 202 ScreenCapture::captureScreen(&sc); 203 sc->checkPixel( 24, 24, 63, 63, 195); 204 sc->checkPixel( 75, 75, 63, 63, 195); 205 sc->checkPixel(145, 145, 195, 63, 63); 206 } 207 208 fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63); 209 waitForPostedBuffers(); 210 { 211 // This should reflect the new position and the new color. 212 SCOPED_TRACE("after redraw"); 213 ScreenCapture::captureScreen(&sc); 214 sc->checkPixel( 24, 24, 63, 63, 195); 215 sc->checkPixel( 75, 75, 63, 63, 195); 216 sc->checkPixel(145, 145, 63, 195, 63); 217 } 218} 219 220TEST_F(LayerUpdateTest, LayerResizeWorks) { 221 sp<ScreenCapture> sc; 222 { 223 SCOPED_TRACE("before resize"); 224 ScreenCapture::captureScreen(&sc); 225 sc->checkPixel( 0, 12, 63, 63, 195); 226 sc->checkPixel( 75, 75, 195, 63, 63); 227 sc->checkPixel(145, 145, 63, 63, 195); 228 } 229 230 ALOGD("resizing"); 231 SurfaceComposerClient::openGlobalTransaction(); 232 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setSize(128, 128)); 233 SurfaceComposerClient::closeGlobalTransaction(true); 234 ALOGD("resized"); 235 { 236 // This should not reflect the new size or color because SurfaceFlinger 237 // has not yet received a buffer of the correct size. 238 SCOPED_TRACE("after resize, before redraw"); 239 ScreenCapture::captureScreen(&sc); 240 sc->checkPixel( 0, 12, 63, 63, 195); 241 sc->checkPixel( 75, 75, 195, 63, 63); 242 sc->checkPixel(145, 145, 63, 63, 195); 243 } 244 245 ALOGD("drawing"); 246 fillSurfaceRGBA8(mFGSurfaceControl, 63, 195, 63); 247 waitForPostedBuffers(); 248 ALOGD("drawn"); 249 { 250 // This should reflect the new size and the new color. 251 SCOPED_TRACE("after redraw"); 252 ScreenCapture::captureScreen(&sc); 253 sc->checkPixel( 24, 24, 63, 63, 195); 254 sc->checkPixel( 75, 75, 63, 195, 63); 255 sc->checkPixel(145, 145, 63, 195, 63); 256 } 257} 258 259TEST_F(LayerUpdateTest, LayerCropWorks) { 260 sp<ScreenCapture> sc; 261 { 262 SCOPED_TRACE("before crop"); 263 ScreenCapture::captureScreen(&sc); 264 sc->checkPixel( 24, 24, 63, 63, 195); 265 sc->checkPixel( 75, 75, 195, 63, 63); 266 sc->checkPixel(145, 145, 63, 63, 195); 267 } 268 269 SurfaceComposerClient::openGlobalTransaction(); 270 Rect cropRect(16, 16, 32, 32); 271 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setCrop(cropRect)); 272 SurfaceComposerClient::closeGlobalTransaction(true); 273 { 274 // This should crop the foreground surface. 275 SCOPED_TRACE("after crop"); 276 ScreenCapture::captureScreen(&sc); 277 sc->checkPixel( 24, 24, 63, 63, 195); 278 sc->checkPixel( 75, 75, 63, 63, 195); 279 sc->checkPixel( 95, 80, 195, 63, 63); 280 sc->checkPixel( 80, 95, 195, 63, 63); 281 sc->checkPixel( 96, 96, 63, 63, 195); 282 } 283} 284 285TEST_F(LayerUpdateTest, LayerFinalCropWorks) { 286 sp<ScreenCapture> sc; 287 { 288 SCOPED_TRACE("before crop"); 289 ScreenCapture::captureScreen(&sc); 290 sc->checkPixel( 24, 24, 63, 63, 195); 291 sc->checkPixel( 75, 75, 195, 63, 63); 292 sc->checkPixel(145, 145, 63, 63, 195); 293 } 294 SurfaceComposerClient::openGlobalTransaction(); 295 Rect cropRect(16, 16, 32, 32); 296 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setFinalCrop(cropRect)); 297 SurfaceComposerClient::closeGlobalTransaction(true); 298 { 299 // This should crop the foreground surface. 300 SCOPED_TRACE("after crop"); 301 ScreenCapture::captureScreen(&sc); 302 sc->checkPixel( 24, 24, 63, 63, 195); 303 sc->checkPixel( 75, 75, 63, 63, 195); 304 sc->checkPixel( 95, 80, 63, 63, 195); 305 sc->checkPixel( 80, 95, 63, 63, 195); 306 sc->checkPixel( 96, 96, 63, 63, 195); 307 } 308} 309 310TEST_F(LayerUpdateTest, LayerSetLayerWorks) { 311 sp<ScreenCapture> sc; 312 { 313 SCOPED_TRACE("before setLayer"); 314 ScreenCapture::captureScreen(&sc); 315 sc->checkPixel( 24, 24, 63, 63, 195); 316 sc->checkPixel( 75, 75, 195, 63, 63); 317 sc->checkPixel(145, 145, 63, 63, 195); 318 } 319 320 SurfaceComposerClient::openGlobalTransaction(); 321 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayer(INT_MAX - 3)); 322 SurfaceComposerClient::closeGlobalTransaction(true); 323 { 324 // This should hide the foreground surface beneath the background. 325 SCOPED_TRACE("after setLayer"); 326 ScreenCapture::captureScreen(&sc); 327 sc->checkPixel( 24, 24, 63, 63, 195); 328 sc->checkPixel( 75, 75, 63, 63, 195); 329 sc->checkPixel(145, 145, 63, 63, 195); 330 } 331} 332 333TEST_F(LayerUpdateTest, LayerShowHideWorks) { 334 sp<ScreenCapture> sc; 335 { 336 SCOPED_TRACE("before hide"); 337 ScreenCapture::captureScreen(&sc); 338 sc->checkPixel( 24, 24, 63, 63, 195); 339 sc->checkPixel( 75, 75, 195, 63, 63); 340 sc->checkPixel(145, 145, 63, 63, 195); 341 } 342 343 SurfaceComposerClient::openGlobalTransaction(); 344 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->hide()); 345 SurfaceComposerClient::closeGlobalTransaction(true); 346 { 347 // This should hide the foreground surface. 348 SCOPED_TRACE("after hide, before show"); 349 ScreenCapture::captureScreen(&sc); 350 sc->checkPixel( 24, 24, 63, 63, 195); 351 sc->checkPixel( 75, 75, 63, 63, 195); 352 sc->checkPixel(145, 145, 63, 63, 195); 353 } 354 355 SurfaceComposerClient::openGlobalTransaction(); 356 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->show()); 357 SurfaceComposerClient::closeGlobalTransaction(true); 358 { 359 // This should show the foreground surface. 360 SCOPED_TRACE("after show"); 361 ScreenCapture::captureScreen(&sc); 362 sc->checkPixel( 24, 24, 63, 63, 195); 363 sc->checkPixel( 75, 75, 195, 63, 63); 364 sc->checkPixel(145, 145, 63, 63, 195); 365 } 366} 367 368TEST_F(LayerUpdateTest, LayerSetAlphaWorks) { 369 sp<ScreenCapture> sc; 370 { 371 SCOPED_TRACE("before setAlpha"); 372 ScreenCapture::captureScreen(&sc); 373 sc->checkPixel( 24, 24, 63, 63, 195); 374 sc->checkPixel( 75, 75, 195, 63, 63); 375 sc->checkPixel(145, 145, 63, 63, 195); 376 } 377 378 SurfaceComposerClient::openGlobalTransaction(); 379 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(0.75f)); 380 SurfaceComposerClient::closeGlobalTransaction(true); 381 { 382 // This should set foreground to be 75% opaque. 383 SCOPED_TRACE("after setAlpha"); 384 ScreenCapture::captureScreen(&sc); 385 sc->checkPixel( 24, 24, 63, 63, 195); 386 sc->checkPixel( 75, 75, 162, 63, 96); 387 sc->checkPixel(145, 145, 63, 63, 195); 388 } 389} 390 391TEST_F(LayerUpdateTest, LayerSetLayerStackWorks) { 392 sp<ScreenCapture> sc; 393 { 394 SCOPED_TRACE("before setLayerStack"); 395 ScreenCapture::captureScreen(&sc); 396 sc->checkPixel( 24, 24, 63, 63, 195); 397 sc->checkPixel( 75, 75, 195, 63, 63); 398 sc->checkPixel(145, 145, 63, 63, 195); 399 } 400 401 SurfaceComposerClient::openGlobalTransaction(); 402 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setLayerStack(1)); 403 SurfaceComposerClient::closeGlobalTransaction(true); 404 { 405 // This should hide the foreground surface since it goes to a different 406 // layer stack. 407 SCOPED_TRACE("after setLayerStack"); 408 ScreenCapture::captureScreen(&sc); 409 sc->checkPixel( 24, 24, 63, 63, 195); 410 sc->checkPixel( 75, 75, 63, 63, 195); 411 sc->checkPixel(145, 145, 63, 63, 195); 412 } 413} 414 415TEST_F(LayerUpdateTest, LayerSetFlagsWorks) { 416 sp<ScreenCapture> sc; 417 { 418 SCOPED_TRACE("before setFlags"); 419 ScreenCapture::captureScreen(&sc); 420 sc->checkPixel( 24, 24, 63, 63, 195); 421 sc->checkPixel( 75, 75, 195, 63, 63); 422 sc->checkPixel(145, 145, 63, 63, 195); 423 } 424 425 SurfaceComposerClient::openGlobalTransaction(); 426 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setFlags( 427 layer_state_t::eLayerHidden, layer_state_t::eLayerHidden)); 428 SurfaceComposerClient::closeGlobalTransaction(true); 429 { 430 // This should hide the foreground surface 431 SCOPED_TRACE("after setFlags"); 432 ScreenCapture::captureScreen(&sc); 433 sc->checkPixel( 24, 24, 63, 63, 195); 434 sc->checkPixel( 75, 75, 63, 63, 195); 435 sc->checkPixel(145, 145, 63, 63, 195); 436 } 437} 438 439TEST_F(LayerUpdateTest, LayerSetMatrixWorks) { 440 sp<ScreenCapture> sc; 441 { 442 SCOPED_TRACE("before setMatrix"); 443 ScreenCapture::captureScreen(&sc); 444 sc->checkPixel( 24, 24, 63, 63, 195); 445 sc->checkPixel( 91, 96, 195, 63, 63); 446 sc->checkPixel( 96, 101, 195, 63, 63); 447 sc->checkPixel(145, 145, 63, 63, 195); 448 } 449 450 SurfaceComposerClient::openGlobalTransaction(); 451 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setMatrix(M_SQRT1_2, M_SQRT1_2, 452 -M_SQRT1_2, M_SQRT1_2)); 453 SurfaceComposerClient::closeGlobalTransaction(true); 454 { 455 SCOPED_TRACE("after setMatrix"); 456 ScreenCapture::captureScreen(&sc); 457 sc->checkPixel( 24, 24, 63, 63, 195); 458 sc->checkPixel( 91, 96, 195, 63, 63); 459 sc->checkPixel( 96, 91, 63, 63, 195); 460 sc->checkPixel(145, 145, 63, 63, 195); 461 } 462} 463 464TEST_F(LayerUpdateTest, DeferredTransactionTest) { 465 sp<ScreenCapture> sc; 466 { 467 SCOPED_TRACE("before anything"); 468 ScreenCapture::captureScreen(&sc); 469 sc->checkPixel( 32, 32, 63, 63, 195); 470 sc->checkPixel( 96, 96, 195, 63, 63); 471 sc->checkPixel(160, 160, 63, 63, 195); 472 } 473 474 // set up two deferred transactions on different frames 475 SurfaceComposerClient::openGlobalTransaction(); 476 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(0.75)); 477 mFGSurfaceControl->deferTransactionUntil(mSyncSurfaceControl->getHandle(), 478 mSyncSurfaceControl->getSurface()->getNextFrameNumber()); 479 SurfaceComposerClient::closeGlobalTransaction(true); 480 481 SurfaceComposerClient::openGlobalTransaction(); 482 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setPosition(128,128)); 483 mFGSurfaceControl->deferTransactionUntil(mSyncSurfaceControl->getHandle(), 484 mSyncSurfaceControl->getSurface()->getNextFrameNumber() + 1); 485 SurfaceComposerClient::closeGlobalTransaction(true); 486 487 { 488 SCOPED_TRACE("before any trigger"); 489 ScreenCapture::captureScreen(&sc); 490 sc->checkPixel( 32, 32, 63, 63, 195); 491 sc->checkPixel( 96, 96, 195, 63, 63); 492 sc->checkPixel(160, 160, 63, 63, 195); 493 } 494 495 // should trigger the first deferred transaction, but not the second one 496 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); 497 { 498 SCOPED_TRACE("after first trigger"); 499 ScreenCapture::captureScreen(&sc); 500 sc->checkPixel( 32, 32, 63, 63, 195); 501 sc->checkPixel( 96, 96, 162, 63, 96); 502 sc->checkPixel(160, 160, 63, 63, 195); 503 } 504 505 // should show up immediately since it's not deferred 506 SurfaceComposerClient::openGlobalTransaction(); 507 ASSERT_EQ(NO_ERROR, mFGSurfaceControl->setAlpha(1.0)); 508 SurfaceComposerClient::closeGlobalTransaction(true); 509 510 // trigger the second deferred transaction 511 fillSurfaceRGBA8(mSyncSurfaceControl, 31, 31, 31); 512 { 513 SCOPED_TRACE("after second trigger"); 514 ScreenCapture::captureScreen(&sc); 515 sc->checkPixel( 32, 32, 63, 63, 195); 516 sc->checkPixel( 96, 96, 63, 63, 195); 517 sc->checkPixel(160, 160, 195, 63, 63); 518 } 519} 520 521} 522