1 /* Copyright 2016 The Android Open Source Project 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 //#define LOG_NDEBUG 0 17 #define LOG_TAG "SurfaceReplayer" 18 19 #include "Replayer.h" 20 21 #include <android/native_window.h> 22 23 #include <android-base/file.h> 24 25 #include <gui/BufferQueue.h> 26 #include <gui/ISurfaceComposer.h> 27 #include <gui/LayerState.h> 28 #include <gui/Surface.h> 29 #include <private/gui/ComposerService.h> 30 31 #include <ui/DisplayInfo.h> 32 #include <utils/Log.h> 33 #include <utils/String8.h> 34 #include <utils/Trace.h> 35 36 #include <chrono> 37 #include <cmath> 38 #include <condition_variable> 39 #include <cstdlib> 40 #include <fstream> 41 #include <functional> 42 #include <iostream> 43 #include <mutex> 44 #include <sstream> 45 #include <string> 46 #include <thread> 47 #include <vector> 48 49 using namespace android; 50 51 std::atomic_bool Replayer::sReplayingManually(false); 52 53 Replayer::Replayer(const std::string& filename, bool replayManually, int numThreads, bool wait, 54 nsecs_t stopHere) 55 : mTrace(), 56 mLoaded(false), 57 mIncrementIndex(0), 58 mCurrentTime(0), 59 mNumThreads(numThreads), 60 mWaitForTimeStamps(wait), 61 mStopTimeStamp(stopHere) { 62 srand(RAND_COLOR_SEED); 63 64 std::string input; 65 if (!android::base::ReadFileToString(filename, &input, true)) { 66 std::cerr << "Trace did not load. Does " << filename << " exist?" << std::endl; 67 abort(); 68 } 69 70 mLoaded = mTrace.ParseFromString(input); 71 if (!mLoaded) { 72 std::cerr << "Trace did not load." << std::endl; 73 abort(); 74 } 75 76 mCurrentTime = mTrace.increment(0).time_stamp(); 77 78 sReplayingManually.store(replayManually); 79 80 if (stopHere < 0) { 81 mHasStopped = true; 82 } 83 } 84 85 Replayer::Replayer(const Trace& t, bool replayManually, int numThreads, bool wait, nsecs_t stopHere) 86 : mTrace(t), 87 mLoaded(true), 88 mIncrementIndex(0), 89 mCurrentTime(0), 90 mNumThreads(numThreads), 91 mWaitForTimeStamps(wait), 92 mStopTimeStamp(stopHere) { 93 srand(RAND_COLOR_SEED); 94 mCurrentTime = mTrace.increment(0).time_stamp(); 95 96 sReplayingManually.store(replayManually); 97 98 if (stopHere < 0) { 99 mHasStopped = true; 100 } 101 } 102 103 status_t Replayer::replay() { 104 signal(SIGINT, Replayer::stopAutoReplayHandler); //for manual control 105 106 ALOGV("There are %d increments.", mTrace.increment_size()); 107 108 status_t status = loadSurfaceComposerClient(); 109 110 if (status != NO_ERROR) { 111 ALOGE("Couldn't create SurfaceComposerClient (%d)", status); 112 return status; 113 } 114 115 SurfaceComposerClient::enableVSyncInjections(true); 116 117 initReplay(); 118 119 ALOGV("Starting actual Replay!"); 120 while (!mPendingIncrements.empty()) { 121 mCurrentIncrement = mTrace.increment(mIncrementIndex); 122 123 if (mHasStopped == false && mCurrentIncrement.time_stamp() >= mStopTimeStamp) { 124 mHasStopped = true; 125 sReplayingManually.store(true); 126 } 127 128 waitForConsoleCommmand(); 129 130 if (mWaitForTimeStamps) { 131 waitUntilTimestamp(mCurrentIncrement.time_stamp()); 132 } 133 134 auto event = mPendingIncrements.front(); 135 mPendingIncrements.pop(); 136 137 event->complete(); 138 139 if (event->getIncrementType() == Increment::kVsyncEvent) { 140 mWaitingForNextVSync = false; 141 } 142 143 if (mIncrementIndex + mNumThreads < mTrace.increment_size()) { 144 status = dispatchEvent(mIncrementIndex + mNumThreads); 145 146 if (status != NO_ERROR) { 147 SurfaceComposerClient::enableVSyncInjections(false); 148 return status; 149 } 150 } 151 152 mIncrementIndex++; 153 mCurrentTime = mCurrentIncrement.time_stamp(); 154 } 155 156 SurfaceComposerClient::enableVSyncInjections(false); 157 158 return status; 159 } 160 161 status_t Replayer::initReplay() { 162 for (int i = 0; i < mNumThreads && i < mTrace.increment_size(); i++) { 163 status_t status = dispatchEvent(i); 164 165 if (status != NO_ERROR) { 166 ALOGE("Unable to dispatch event (%d)", status); 167 return status; 168 } 169 } 170 171 return NO_ERROR; 172 } 173 174 void Replayer::stopAutoReplayHandler(int /*signal*/) { 175 if (sReplayingManually) { 176 SurfaceComposerClient::enableVSyncInjections(false); 177 exit(0); 178 } 179 180 sReplayingManually.store(true); 181 } 182 183 std::vector<std::string> split(const std::string& s, const char delim) { 184 std::vector<std::string> elems; 185 std::stringstream ss(s); 186 std::string item; 187 while (getline(ss, item, delim)) { 188 elems.push_back(item); 189 } 190 return elems; 191 } 192 193 bool isNumber(const std::string& s) { 194 return !s.empty() && 195 std::find_if(s.begin(), s.end(), [](char c) { return !std::isdigit(c); }) == s.end(); 196 } 197 198 void Replayer::waitForConsoleCommmand() { 199 if (!sReplayingManually || mWaitingForNextVSync) { 200 return; 201 } 202 203 while (true) { 204 std::string input = ""; 205 std::cout << "> "; 206 getline(std::cin, input); 207 208 if (input.empty()) { 209 input = mLastInput; 210 } else { 211 mLastInput = input; 212 } 213 214 if (mLastInput.empty()) { 215 continue; 216 } 217 218 std::vector<std::string> inputs = split(input, ' '); 219 220 if (inputs[0] == "n") { // next vsync 221 mWaitingForNextVSync = true; 222 break; 223 224 } else if (inputs[0] == "ni") { // next increment 225 break; 226 227 } else if (inputs[0] == "c") { // continue 228 if (inputs.size() > 1 && isNumber(inputs[1])) { 229 long milliseconds = stoi(inputs[1]); 230 std::thread([&] { 231 std::cout << "Started!" << std::endl; 232 std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds)); 233 sReplayingManually.store(true); 234 std::cout << "Should have stopped!" << std::endl; 235 }).detach(); 236 } 237 sReplayingManually.store(false); 238 mWaitingForNextVSync = false; 239 break; 240 241 } else if (inputs[0] == "s") { // stop at this timestamp 242 if (inputs.size() < 1) { 243 std::cout << "No time stamp given" << std::endl; 244 continue; 245 } 246 sReplayingManually.store(false); 247 mStopTimeStamp = stol(inputs[1]); 248 mHasStopped = false; 249 break; 250 } else if (inputs[0] == "l") { // list 251 std::cout << "Time stamp: " << mCurrentIncrement.time_stamp() << "\n"; 252 continue; 253 } else if (inputs[0] == "q") { // quit 254 SurfaceComposerClient::enableVSyncInjections(false); 255 exit(0); 256 257 } else if (inputs[0] == "h") { // help 258 // add help menu 259 std::cout << "Manual Replay options:\n"; 260 std::cout << " n - Go to next VSync\n"; 261 std::cout << " ni - Go to next increment\n"; 262 std::cout << " c - Continue\n"; 263 std::cout << " c [milliseconds] - Continue until specified number of milliseconds\n"; 264 std::cout << " s [timestamp] - Continue and stop at specified timestamp\n"; 265 std::cout << " l - List out timestamp of current increment\n"; 266 std::cout << " h - Display help menu\n"; 267 std::cout << std::endl; 268 continue; 269 } 270 271 std::cout << "Invalid Command" << std::endl; 272 } 273 } 274 275 status_t Replayer::dispatchEvent(int index) { 276 auto increment = mTrace.increment(index); 277 std::shared_ptr<Event> event = std::make_shared<Event>(increment.increment_case()); 278 mPendingIncrements.push(event); 279 280 status_t status = NO_ERROR; 281 switch (increment.increment_case()) { 282 case increment.kTransaction: { 283 std::thread(&Replayer::doTransaction, this, increment.transaction(), event).detach(); 284 } break; 285 case increment.kSurfaceCreation: { 286 std::thread(&Replayer::createSurfaceControl, this, increment.surface_creation(), event) 287 .detach(); 288 } break; 289 case increment.kBufferUpdate: { 290 std::lock_guard<std::mutex> lock1(mLayerLock); 291 std::lock_guard<std::mutex> lock2(mBufferQueueSchedulerLock); 292 293 Dimensions dimensions(increment.buffer_update().w(), increment.buffer_update().h()); 294 BufferEvent bufferEvent(event, dimensions); 295 296 auto layerId = increment.buffer_update().id(); 297 if (mBufferQueueSchedulers.count(layerId) == 0) { 298 mBufferQueueSchedulers[layerId] = std::make_shared<BufferQueueScheduler>( 299 mLayers[layerId], mColors[layerId], layerId); 300 mBufferQueueSchedulers[layerId]->addEvent(bufferEvent); 301 302 std::thread(&BufferQueueScheduler::startScheduling, 303 mBufferQueueSchedulers[increment.buffer_update().id()].get()) 304 .detach(); 305 } else { 306 auto bqs = mBufferQueueSchedulers[increment.buffer_update().id()]; 307 bqs->addEvent(bufferEvent); 308 } 309 } break; 310 case increment.kVsyncEvent: { 311 std::thread(&Replayer::injectVSyncEvent, this, increment.vsync_event(), event).detach(); 312 } break; 313 case increment.kDisplayCreation: { 314 std::thread(&Replayer::createDisplay, this, increment.display_creation(), event) 315 .detach(); 316 } break; 317 case increment.kDisplayDeletion: { 318 std::thread(&Replayer::deleteDisplay, this, increment.display_deletion(), event) 319 .detach(); 320 } break; 321 case increment.kPowerModeUpdate: { 322 std::thread(&Replayer::updatePowerMode, this, increment.power_mode_update(), event) 323 .detach(); 324 } break; 325 default: 326 ALOGE("Unknown Increment Type: %d", increment.increment_case()); 327 status = BAD_VALUE; 328 break; 329 } 330 331 return status; 332 } 333 334 status_t Replayer::doTransaction(const Transaction& t, const std::shared_ptr<Event>& event) { 335 ALOGV("Started Transaction"); 336 337 SurfaceComposerClient::Transaction liveTransaction; 338 339 status_t status = NO_ERROR; 340 341 status = doSurfaceTransaction(liveTransaction, t.surface_change()); 342 doDisplayTransaction(liveTransaction, t.display_change()); 343 344 if (t.animation()) { 345 liveTransaction.setAnimationTransaction(); 346 } 347 348 event->readyToExecute(); 349 350 liveTransaction.apply(t.synchronous()); 351 352 ALOGV("Ended Transaction"); 353 354 return status; 355 } 356 357 status_t Replayer::doSurfaceTransaction( 358 SurfaceComposerClient::Transaction& transaction, 359 const SurfaceChanges& surfaceChanges) { 360 status_t status = NO_ERROR; 361 362 for (const SurfaceChange& change : surfaceChanges) { 363 std::unique_lock<std::mutex> lock(mLayerLock); 364 if (mLayers[change.id()] == nullptr) { 365 mLayerCond.wait(lock, [&] { return (mLayers[change.id()] != nullptr); }); 366 } 367 368 switch (change.SurfaceChange_case()) { 369 case SurfaceChange::SurfaceChangeCase::kPosition: 370 setPosition(transaction, change.id(), change.position()); 371 break; 372 case SurfaceChange::SurfaceChangeCase::kSize: 373 setSize(transaction, change.id(), change.size()); 374 break; 375 case SurfaceChange::SurfaceChangeCase::kAlpha: 376 setAlpha(transaction, change.id(), change.alpha()); 377 break; 378 case SurfaceChange::SurfaceChangeCase::kLayer: 379 setLayer(transaction, change.id(), change.layer()); 380 break; 381 case SurfaceChange::SurfaceChangeCase::kCrop: 382 setCrop(transaction, change.id(), change.crop()); 383 break; 384 case SurfaceChange::SurfaceChangeCase::kCornerRadius: 385 setCornerRadius(transaction, change.id(), change.corner_radius()); 386 break; 387 case SurfaceChange::SurfaceChangeCase::kMatrix: 388 setMatrix(transaction, change.id(), change.matrix()); 389 break; 390 case SurfaceChange::SurfaceChangeCase::kOverrideScalingMode: 391 setOverrideScalingMode(transaction, change.id(), 392 change.override_scaling_mode()); 393 break; 394 case SurfaceChange::SurfaceChangeCase::kTransparentRegionHint: 395 setTransparentRegionHint(transaction, change.id(), 396 change.transparent_region_hint()); 397 break; 398 case SurfaceChange::SurfaceChangeCase::kLayerStack: 399 setLayerStack(transaction, change.id(), change.layer_stack()); 400 break; 401 case SurfaceChange::SurfaceChangeCase::kHiddenFlag: 402 setHiddenFlag(transaction, change.id(), change.hidden_flag()); 403 break; 404 case SurfaceChange::SurfaceChangeCase::kOpaqueFlag: 405 setOpaqueFlag(transaction, change.id(), change.opaque_flag()); 406 break; 407 case SurfaceChange::SurfaceChangeCase::kSecureFlag: 408 setSecureFlag(transaction, change.id(), change.secure_flag()); 409 break; 410 case SurfaceChange::SurfaceChangeCase::kDeferredTransaction: 411 waitUntilDeferredTransactionLayerExists(change.deferred_transaction(), lock); 412 setDeferredTransaction(transaction, change.id(), 413 change.deferred_transaction()); 414 break; 415 default: 416 status = 1; 417 break; 418 } 419 420 if (status != NO_ERROR) { 421 ALOGE("Unknown Transaction Code"); 422 return status; 423 } 424 } 425 return status; 426 } 427 428 void Replayer::doDisplayTransaction(SurfaceComposerClient::Transaction& t, 429 const DisplayChanges& displayChanges) { 430 for (const DisplayChange& change : displayChanges) { 431 ALOGV("Doing display transaction"); 432 std::unique_lock<std::mutex> lock(mDisplayLock); 433 if (mDisplays[change.id()] == nullptr) { 434 mDisplayCond.wait(lock, [&] { return (mDisplays[change.id()] != nullptr); }); 435 } 436 437 switch (change.DisplayChange_case()) { 438 case DisplayChange::DisplayChangeCase::kSurface: 439 setDisplaySurface(t, change.id(), change.surface()); 440 break; 441 case DisplayChange::DisplayChangeCase::kLayerStack: 442 setDisplayLayerStack(t, change.id(), change.layer_stack()); 443 break; 444 case DisplayChange::DisplayChangeCase::kSize: 445 setDisplaySize(t, change.id(), change.size()); 446 break; 447 case DisplayChange::DisplayChangeCase::kProjection: 448 setDisplayProjection(t, change.id(), change.projection()); 449 break; 450 default: 451 break; 452 } 453 } 454 } 455 456 void Replayer::setPosition(SurfaceComposerClient::Transaction& t, 457 layer_id id, const PositionChange& pc) { 458 ALOGV("Layer %d: Setting Position -- x=%f, y=%f", id, pc.x(), pc.y()); 459 t.setPosition(mLayers[id], pc.x(), pc.y()); 460 } 461 462 void Replayer::setSize(SurfaceComposerClient::Transaction& t, 463 layer_id id, const SizeChange& sc) { 464 ALOGV("Layer %d: Setting Size -- w=%u, h=%u", id, sc.w(), sc.h()); 465 t.setSize(mLayers[id], sc.w(), sc.h()); 466 } 467 468 void Replayer::setLayer(SurfaceComposerClient::Transaction& t, 469 layer_id id, const LayerChange& lc) { 470 ALOGV("Layer %d: Setting Layer -- layer=%d", id, lc.layer()); 471 t.setLayer(mLayers[id], lc.layer()); 472 } 473 474 void Replayer::setAlpha(SurfaceComposerClient::Transaction& t, 475 layer_id id, const AlphaChange& ac) { 476 ALOGV("Layer %d: Setting Alpha -- alpha=%f", id, ac.alpha()); 477 t.setAlpha(mLayers[id], ac.alpha()); 478 } 479 480 void Replayer::setCrop(SurfaceComposerClient::Transaction& t, 481 layer_id id, const CropChange& cc) { 482 ALOGV("Layer %d: Setting Crop -- left=%d, top=%d, right=%d, bottom=%d", id, 483 cc.rectangle().left(), cc.rectangle().top(), cc.rectangle().right(), 484 cc.rectangle().bottom()); 485 486 Rect r = Rect(cc.rectangle().left(), cc.rectangle().top(), cc.rectangle().right(), 487 cc.rectangle().bottom()); 488 t.setCrop_legacy(mLayers[id], r); 489 } 490 491 void Replayer::setCornerRadius(SurfaceComposerClient::Transaction& t, 492 layer_id id, const CornerRadiusChange& cc) { 493 ALOGV("Layer %d: Setting Corner Radius -- cornerRadius=%d", id, cc.corner_radius()); 494 495 t.setCornerRadius(mLayers[id], cc.corner_radius()); 496 } 497 498 void Replayer::setMatrix(SurfaceComposerClient::Transaction& t, 499 layer_id id, const MatrixChange& mc) { 500 ALOGV("Layer %d: Setting Matrix -- dsdx=%f, dtdx=%f, dsdy=%f, dtdy=%f", id, mc.dsdx(), 501 mc.dtdx(), mc.dsdy(), mc.dtdy()); 502 t.setMatrix(mLayers[id], mc.dsdx(), mc.dtdx(), mc.dsdy(), mc.dtdy()); 503 } 504 505 void Replayer::setOverrideScalingMode(SurfaceComposerClient::Transaction& t, 506 layer_id id, const OverrideScalingModeChange& osmc) { 507 ALOGV("Layer %d: Setting Override Scaling Mode -- mode=%d", id, osmc.override_scaling_mode()); 508 t.setOverrideScalingMode(mLayers[id], osmc.override_scaling_mode()); 509 } 510 511 void Replayer::setTransparentRegionHint(SurfaceComposerClient::Transaction& t, 512 layer_id id, const TransparentRegionHintChange& trhc) { 513 ALOGV("Setting Transparent Region Hint"); 514 Region re = Region(); 515 516 for (const auto& r : trhc.region()) { 517 Rect rect = Rect(r.left(), r.top(), r.right(), r.bottom()); 518 re.merge(rect); 519 } 520 521 t.setTransparentRegionHint(mLayers[id], re); 522 } 523 524 void Replayer::setLayerStack(SurfaceComposerClient::Transaction& t, 525 layer_id id, const LayerStackChange& lsc) { 526 ALOGV("Layer %d: Setting LayerStack -- layer_stack=%d", id, lsc.layer_stack()); 527 t.setLayerStack(mLayers[id], lsc.layer_stack()); 528 } 529 530 void Replayer::setHiddenFlag(SurfaceComposerClient::Transaction& t, 531 layer_id id, const HiddenFlagChange& hfc) { 532 ALOGV("Layer %d: Setting Hidden Flag -- hidden_flag=%d", id, hfc.hidden_flag()); 533 layer_id flag = hfc.hidden_flag() ? layer_state_t::eLayerHidden : 0; 534 535 t.setFlags(mLayers[id], flag, layer_state_t::eLayerHidden); 536 } 537 538 void Replayer::setOpaqueFlag(SurfaceComposerClient::Transaction& t, 539 layer_id id, const OpaqueFlagChange& ofc) { 540 ALOGV("Layer %d: Setting Opaque Flag -- opaque_flag=%d", id, ofc.opaque_flag()); 541 layer_id flag = ofc.opaque_flag() ? layer_state_t::eLayerOpaque : 0; 542 543 t.setFlags(mLayers[id], flag, layer_state_t::eLayerOpaque); 544 } 545 546 void Replayer::setSecureFlag(SurfaceComposerClient::Transaction& t, 547 layer_id id, const SecureFlagChange& sfc) { 548 ALOGV("Layer %d: Setting Secure Flag -- secure_flag=%d", id, sfc.secure_flag()); 549 layer_id flag = sfc.secure_flag() ? layer_state_t::eLayerSecure : 0; 550 551 t.setFlags(mLayers[id], flag, layer_state_t::eLayerSecure); 552 } 553 554 void Replayer::setDeferredTransaction(SurfaceComposerClient::Transaction& t, 555 layer_id id, const DeferredTransactionChange& dtc) { 556 ALOGV("Layer %d: Setting Deferred Transaction -- layer_id=%d, " 557 "frame_number=%llu", 558 id, dtc.layer_id(), dtc.frame_number()); 559 if (mLayers.count(dtc.layer_id()) == 0 || mLayers[dtc.layer_id()] == nullptr) { 560 ALOGE("Layer %d not found in Deferred Transaction", dtc.layer_id()); 561 return; 562 } 563 564 auto handle = mLayers[dtc.layer_id()]->getHandle(); 565 566 t.deferTransactionUntil_legacy(mLayers[id], handle, dtc.frame_number()); 567 } 568 569 void Replayer::setDisplaySurface(SurfaceComposerClient::Transaction& t, 570 display_id id, const DispSurfaceChange& /*dsc*/) { 571 sp<IGraphicBufferProducer> outProducer; 572 sp<IGraphicBufferConsumer> outConsumer; 573 BufferQueue::createBufferQueue(&outProducer, &outConsumer); 574 575 t.setDisplaySurface(mDisplays[id], outProducer); 576 } 577 578 void Replayer::setDisplayLayerStack(SurfaceComposerClient::Transaction& t, 579 display_id id, const LayerStackChange& lsc) { 580 t.setDisplayLayerStack(mDisplays[id], lsc.layer_stack()); 581 } 582 583 void Replayer::setDisplaySize(SurfaceComposerClient::Transaction& t, 584 display_id id, const SizeChange& sc) { 585 t.setDisplaySize(mDisplays[id], sc.w(), sc.h()); 586 } 587 588 void Replayer::setDisplayProjection(SurfaceComposerClient::Transaction& t, 589 display_id id, const ProjectionChange& pc) { 590 Rect viewport = Rect(pc.viewport().left(), pc.viewport().top(), pc.viewport().right(), 591 pc.viewport().bottom()); 592 Rect frame = Rect(pc.frame().left(), pc.frame().top(), pc.frame().right(), pc.frame().bottom()); 593 594 t.setDisplayProjection(mDisplays[id], pc.orientation(), viewport, frame); 595 } 596 597 status_t Replayer::createSurfaceControl( 598 const SurfaceCreation& create, const std::shared_ptr<Event>& event) { 599 event->readyToExecute(); 600 601 ALOGV("Creating Surface Control: ID: %d", create.id()); 602 sp<SurfaceControl> surfaceControl = mComposerClient->createSurface( 603 String8(create.name().c_str()), create.w(), create.h(), PIXEL_FORMAT_RGBA_8888, 0); 604 605 if (surfaceControl == nullptr) { 606 ALOGE("CreateSurfaceControl: unable to create surface control"); 607 return BAD_VALUE; 608 } 609 610 std::lock_guard<std::mutex> lock1(mLayerLock); 611 auto& layer = mLayers[create.id()]; 612 layer = surfaceControl; 613 614 mColors[create.id()] = HSV(rand() % 360, 1, 1); 615 616 mLayerCond.notify_all(); 617 618 std::lock_guard<std::mutex> lock2(mBufferQueueSchedulerLock); 619 if (mBufferQueueSchedulers.count(create.id()) != 0) { 620 mBufferQueueSchedulers[create.id()]->setSurfaceControl( 621 mLayers[create.id()], mColors[create.id()]); 622 } 623 624 return NO_ERROR; 625 } 626 627 status_t Replayer::injectVSyncEvent( 628 const VSyncEvent& vSyncEvent, const std::shared_ptr<Event>& event) { 629 ALOGV("Injecting VSync Event"); 630 631 event->readyToExecute(); 632 633 SurfaceComposerClient::injectVSync(vSyncEvent.when()); 634 635 return NO_ERROR; 636 } 637 638 void Replayer::createDisplay(const DisplayCreation& create, const std::shared_ptr<Event>& event) { 639 ALOGV("Creating display"); 640 event->readyToExecute(); 641 642 std::lock_guard<std::mutex> lock(mDisplayLock); 643 sp<IBinder> display = SurfaceComposerClient::createDisplay( 644 String8(create.name().c_str()), create.is_secure()); 645 mDisplays[create.id()] = display; 646 647 mDisplayCond.notify_all(); 648 649 ALOGV("Done creating display"); 650 } 651 652 void Replayer::deleteDisplay(const DisplayDeletion& delete_, const std::shared_ptr<Event>& event) { 653 ALOGV("Delete display"); 654 event->readyToExecute(); 655 656 std::lock_guard<std::mutex> lock(mDisplayLock); 657 SurfaceComposerClient::destroyDisplay(mDisplays[delete_.id()]); 658 mDisplays.erase(delete_.id()); 659 } 660 661 void Replayer::updatePowerMode(const PowerModeUpdate& pmu, const std::shared_ptr<Event>& event) { 662 ALOGV("Updating power mode"); 663 event->readyToExecute(); 664 SurfaceComposerClient::setDisplayPowerMode(mDisplays[pmu.id()], pmu.mode()); 665 } 666 667 void Replayer::waitUntilTimestamp(int64_t timestamp) { 668 ALOGV("Waiting for %lld nanoseconds...", static_cast<int64_t>(timestamp - mCurrentTime)); 669 std::this_thread::sleep_for(std::chrono::nanoseconds(timestamp - mCurrentTime)); 670 } 671 672 void Replayer::waitUntilDeferredTransactionLayerExists( 673 const DeferredTransactionChange& dtc, std::unique_lock<std::mutex>& lock) { 674 if (mLayers.count(dtc.layer_id()) == 0 || mLayers[dtc.layer_id()] == nullptr) { 675 mLayerCond.wait(lock, [&] { return (mLayers[dtc.layer_id()] != nullptr); }); 676 } 677 } 678 679 status_t Replayer::loadSurfaceComposerClient() { 680 mComposerClient = new SurfaceComposerClient; 681 return mComposerClient->initCheck(); 682 } 683