Replayer.cpp revision 01041fe22aead67520962b534134b3e3291b1622
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 <binder/IMemory.h> 24 25#include <gui/BufferQueue.h> 26#include <gui/ISurfaceComposer.h> 27#include <gui/Surface.h> 28#include <private/gui/ComposerService.h> 29#include <private/gui/LayerState.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 49using namespace android; 50 51std::atomic_bool Replayer::sReplayingManually(false); 52 53Replayer::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::fstream input(filename, std::ios::in | std::ios::binary); 65 66 mLoaded = mTrace.ParseFromIstream(&input); 67 if (!mLoaded) { 68 std::cerr << "Trace did not load. Does " << filename << " exist?" << std::endl; 69 abort(); 70 } 71 72 mCurrentTime = mTrace.increment(0).time_stamp(); 73 74 sReplayingManually.store(replayManually); 75 76 if (stopHere < 0) { 77 mHasStopped = true; 78 } 79} 80 81Replayer::Replayer(const Trace& t, bool replayManually, int numThreads, bool wait, nsecs_t stopHere) 82 : mTrace(t), 83 mLoaded(true), 84 mIncrementIndex(0), 85 mCurrentTime(0), 86 mNumThreads(numThreads), 87 mWaitForTimeStamps(wait), 88 mStopTimeStamp(stopHere) { 89 srand(RAND_COLOR_SEED); 90 mCurrentTime = mTrace.increment(0).time_stamp(); 91 92 sReplayingManually.store(replayManually); 93 94 if (stopHere < 0) { 95 mHasStopped = true; 96 } 97} 98 99status_t Replayer::replay() { 100 signal(SIGINT, Replayer::stopAutoReplayHandler); //for manual control 101 102 ALOGV("There are %d increments.", mTrace.increment_size()); 103 104 status_t status = loadSurfaceComposerClient(); 105 106 if (status != NO_ERROR) { 107 ALOGE("Couldn't create SurfaceComposerClient (%d)", status); 108 return status; 109 } 110 111 SurfaceComposerClient::enableVSyncInjections(true); 112 113 initReplay(); 114 115 ALOGV("Starting actual Replay!"); 116 while (!mPendingIncrements.empty()) { 117 mCurrentIncrement = mTrace.increment(mIncrementIndex); 118 119 if (mHasStopped == false && mCurrentIncrement.time_stamp() >= mStopTimeStamp) { 120 mHasStopped = true; 121 sReplayingManually.store(true); 122 } 123 124 waitForConsoleCommmand(); 125 126 if (mWaitForTimeStamps) { 127 waitUntilTimestamp(mCurrentIncrement.time_stamp()); 128 } 129 130 auto event = mPendingIncrements.front(); 131 mPendingIncrements.pop(); 132 133 event->complete(); 134 135 if (event->getIncrementType() == Increment::kVsyncEvent) { 136 mWaitingForNextVSync = false; 137 } 138 139 if (mIncrementIndex + mNumThreads < mTrace.increment_size()) { 140 status = dispatchEvent(mIncrementIndex + mNumThreads); 141 142 if (status != NO_ERROR) { 143 SurfaceComposerClient::enableVSyncInjections(false); 144 return status; 145 } 146 } 147 148 mIncrementIndex++; 149 mCurrentTime = mCurrentIncrement.time_stamp(); 150 } 151 152 SurfaceComposerClient::enableVSyncInjections(false); 153 154 return status; 155} 156 157status_t Replayer::initReplay() { 158 for (int i = 0; i < mNumThreads && i < mTrace.increment_size(); i++) { 159 status_t status = dispatchEvent(i); 160 161 if (status != NO_ERROR) { 162 ALOGE("Unable to dispatch event (%d)", status); 163 return status; 164 } 165 } 166 167 return NO_ERROR; 168} 169 170void Replayer::stopAutoReplayHandler(int /*signal*/) { 171 if (sReplayingManually) { 172 SurfaceComposerClient::enableVSyncInjections(false); 173 exit(0); 174 } 175 176 sReplayingManually.store(true); 177} 178 179std::vector<std::string> split(const std::string& s, const char delim) { 180 std::vector<std::string> elems; 181 std::stringstream ss(s); 182 std::string item; 183 while (getline(ss, item, delim)) { 184 elems.push_back(item); 185 } 186 return elems; 187} 188 189bool isNumber(const std::string& s) { 190 return !s.empty() && 191 std::find_if(s.begin(), s.end(), [](char c) { return !std::isdigit(c); }) == s.end(); 192} 193 194void Replayer::waitForConsoleCommmand() { 195 if (!sReplayingManually || mWaitingForNextVSync) { 196 return; 197 } 198 199 while (true) { 200 std::string input = ""; 201 std::cout << "> "; 202 getline(std::cin, input); 203 204 if (input.empty()) { 205 input = mLastInput; 206 } else { 207 mLastInput = input; 208 } 209 210 if (mLastInput.empty()) { 211 continue; 212 } 213 214 std::vector<std::string> inputs = split(input, ' '); 215 216 if (inputs[0] == "n") { // next vsync 217 mWaitingForNextVSync = true; 218 break; 219 220 } else if (inputs[0] == "ni") { // next increment 221 break; 222 223 } else if (inputs[0] == "c") { // continue 224 if (inputs.size() > 1 && isNumber(inputs[1])) { 225 long milliseconds = stoi(inputs[1]); 226 std::thread([&] { 227 std::cout << "Started!" << std::endl; 228 std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds)); 229 sReplayingManually.store(true); 230 std::cout << "Should have stopped!" << std::endl; 231 }).detach(); 232 } 233 sReplayingManually.store(false); 234 mWaitingForNextVSync = false; 235 break; 236 237 } else if (inputs[0] == "s") { // stop at this timestamp 238 if (inputs.size() < 1) { 239 std::cout << "No time stamp given" << std::endl; 240 continue; 241 } 242 sReplayingManually.store(false); 243 mStopTimeStamp = stol(inputs[1]); 244 mHasStopped = false; 245 break; 246 } else if (inputs[0] == "l") { // list 247 std::cout << "Time stamp: " << mCurrentIncrement.time_stamp() << "\n"; 248 continue; 249 } else if (inputs[0] == "q") { // quit 250 SurfaceComposerClient::enableVSyncInjections(false); 251 exit(0); 252 253 } else if (inputs[0] == "h") { // help 254 // add help menu 255 std::cout << "Manual Replay options:\n"; 256 std::cout << " n - Go to next VSync\n"; 257 std::cout << " ni - Go to next increment\n"; 258 std::cout << " c - Continue\n"; 259 std::cout << " c [milliseconds] - Continue until specified number of milliseconds\n"; 260 std::cout << " s [timestamp] - Continue and stop at specified timestamp\n"; 261 std::cout << " l - List out timestamp of current increment\n"; 262 std::cout << " h - Display help menu\n"; 263 std::cout << std::endl; 264 continue; 265 } 266 267 std::cout << "Invalid Command" << std::endl; 268 } 269} 270 271status_t Replayer::dispatchEvent(int index) { 272 auto increment = mTrace.increment(index); 273 std::shared_ptr<Event> event = std::make_shared<Event>(increment.increment_case()); 274 mPendingIncrements.push(event); 275 276 status_t status = NO_ERROR; 277 switch (increment.increment_case()) { 278 case increment.kTransaction: { 279 std::thread(&Replayer::doTransaction, this, increment.transaction(), event).detach(); 280 } break; 281 case increment.kSurfaceCreation: { 282 std::thread(&Replayer::createSurfaceControl, this, increment.surface_creation(), event) 283 .detach(); 284 } break; 285 case increment.kSurfaceDeletion: { 286 std::thread(&Replayer::deleteSurfaceControl, this, increment.surface_deletion(), 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 334status_t Replayer::doTransaction(const Transaction& t, const std::shared_ptr<Event>& event) { 335 ALOGV("Started Transaction"); 336 337 SurfaceComposerClient::openGlobalTransaction(); 338 339 status_t status = NO_ERROR; 340 341 status = doSurfaceTransaction(t.surface_change()); 342 doDisplayTransaction(t.display_change()); 343 344 if (t.animation()) { 345 SurfaceComposerClient::setAnimationTransaction(); 346 } 347 348 event->readyToExecute(); 349 350 SurfaceComposerClient::closeGlobalTransaction(t.synchronous()); 351 352 ALOGV("Ended Transaction"); 353 354 return status; 355} 356 357status_t Replayer::doSurfaceTransaction(const SurfaceChanges& surfaceChanges) { 358 status_t status = NO_ERROR; 359 360 for (const SurfaceChange& change : surfaceChanges) { 361 std::unique_lock<std::mutex> lock(mLayerLock); 362 if (mLayers[change.id()] == nullptr) { 363 mLayerCond.wait(lock, [&] { return (mLayers[change.id()] != nullptr); }); 364 } 365 366 switch (change.SurfaceChange_case()) { 367 case SurfaceChange::SurfaceChangeCase::kPosition: 368 status = setPosition(change.id(), change.position()); 369 break; 370 case SurfaceChange::SurfaceChangeCase::kSize: 371 status = setSize(change.id(), change.size()); 372 break; 373 case SurfaceChange::SurfaceChangeCase::kAlpha: 374 status = setAlpha(change.id(), change.alpha()); 375 break; 376 case SurfaceChange::SurfaceChangeCase::kLayer: 377 status = setLayer(change.id(), change.layer()); 378 break; 379 case SurfaceChange::SurfaceChangeCase::kCrop: 380 status = setCrop(change.id(), change.crop()); 381 break; 382 case SurfaceChange::SurfaceChangeCase::kMatrix: 383 status = setMatrix(change.id(), change.matrix()); 384 break; 385 case SurfaceChange::SurfaceChangeCase::kFinalCrop: 386 status = setFinalCrop(change.id(), change.final_crop()); 387 break; 388 case SurfaceChange::SurfaceChangeCase::kOverrideScalingMode: 389 status = setOverrideScalingMode(change.id(), change.override_scaling_mode()); 390 break; 391 case SurfaceChange::SurfaceChangeCase::kTransparentRegionHint: 392 status = setTransparentRegionHint(change.id(), change.transparent_region_hint()); 393 break; 394 case SurfaceChange::SurfaceChangeCase::kLayerStack: 395 status = setLayerStack(change.id(), change.layer_stack()); 396 break; 397 case SurfaceChange::SurfaceChangeCase::kHiddenFlag: 398 status = setHiddenFlag(change.id(), change.hidden_flag()); 399 break; 400 case SurfaceChange::SurfaceChangeCase::kOpaqueFlag: 401 status = setOpaqueFlag(change.id(), change.opaque_flag()); 402 break; 403 case SurfaceChange::SurfaceChangeCase::kSecureFlag: 404 status = setSecureFlag(change.id(), change.secure_flag()); 405 break; 406 case SurfaceChange::SurfaceChangeCase::kDeferredTransaction: 407 waitUntilDeferredTransactionLayerExists(change.deferred_transaction(), lock); 408 status = setDeferredTransaction(change.id(), change.deferred_transaction()); 409 break; 410 default: 411 status = NO_ERROR; 412 break; 413 } 414 415 if (status != NO_ERROR) { 416 ALOGE("SET TRANSACTION FAILED"); 417 return status; 418 } 419 } 420 return status; 421} 422 423void Replayer::doDisplayTransaction(const DisplayChanges& displayChanges) { 424 for (const DisplayChange& change : displayChanges) { 425 ALOGV("Doing display transaction"); 426 std::unique_lock<std::mutex> lock(mDisplayLock); 427 if (mDisplays[change.id()] == nullptr) { 428 mDisplayCond.wait(lock, [&] { return (mDisplays[change.id()] != nullptr); }); 429 } 430 431 switch (change.DisplayChange_case()) { 432 case DisplayChange::DisplayChangeCase::kSurface: 433 setDisplaySurface(change.id(), change.surface()); 434 break; 435 case DisplayChange::DisplayChangeCase::kLayerStack: 436 setDisplayLayerStack(change.id(), change.layer_stack()); 437 break; 438 case DisplayChange::DisplayChangeCase::kSize: 439 setDisplaySize(change.id(), change.size()); 440 break; 441 case DisplayChange::DisplayChangeCase::kProjection: 442 setDisplayProjection(change.id(), change.projection()); 443 break; 444 default: 445 break; 446 } 447 } 448} 449 450status_t Replayer::setPosition(layer_id id, const PositionChange& pc) { 451 ALOGV("Layer %d: Setting Position -- x=%f, y=%f", id, pc.x(), pc.y()); 452 return mLayers[id]->setPosition(pc.x(), pc.y()); 453} 454 455status_t Replayer::setSize(layer_id id, const SizeChange& sc) { 456 ALOGV("Layer %d: Setting Size -- w=%u, h=%u", id, sc.w(), sc.h()); 457 return mLayers[id]->setSize(sc.w(), sc.h()); 458} 459 460status_t Replayer::setLayer(layer_id id, const LayerChange& lc) { 461 ALOGV("Layer %d: Setting Layer -- layer=%d", id, lc.layer()); 462 return mLayers[id]->setLayer(lc.layer()); 463} 464 465status_t Replayer::setAlpha(layer_id id, const AlphaChange& ac) { 466 ALOGV("Layer %d: Setting Alpha -- alpha=%f", id, ac.alpha()); 467 return mLayers[id]->setAlpha(ac.alpha()); 468} 469 470status_t Replayer::setCrop(layer_id id, const CropChange& cc) { 471 ALOGV("Layer %d: Setting Crop -- left=%d, top=%d, right=%d, bottom=%d", id, 472 cc.rectangle().left(), cc.rectangle().top(), cc.rectangle().right(), 473 cc.rectangle().bottom()); 474 475 Rect r = Rect(cc.rectangle().left(), cc.rectangle().top(), cc.rectangle().right(), 476 cc.rectangle().bottom()); 477 return mLayers[id]->setCrop(r); 478} 479 480status_t Replayer::setFinalCrop(layer_id id, const FinalCropChange& fcc) { 481 ALOGV("Layer %d: Setting Final Crop -- left=%d, top=%d, right=%d, bottom=%d", id, 482 fcc.rectangle().left(), fcc.rectangle().top(), fcc.rectangle().right(), 483 fcc.rectangle().bottom()); 484 Rect r = Rect(fcc.rectangle().left(), fcc.rectangle().top(), fcc.rectangle().right(), 485 fcc.rectangle().bottom()); 486 return mLayers[id]->setFinalCrop(r); 487} 488 489status_t Replayer::setMatrix(layer_id id, const MatrixChange& mc) { 490 ALOGV("Layer %d: Setting Matrix -- dsdx=%f, dtdx=%f, dsdy=%f, dtdy=%f", id, mc.dsdx(), 491 mc.dtdx(), mc.dsdy(), mc.dtdy()); 492 return mLayers[id]->setMatrix(mc.dsdx(), mc.dtdx(), mc.dsdy(), mc.dtdy()); 493} 494 495status_t Replayer::setOverrideScalingMode(layer_id id, const OverrideScalingModeChange& osmc) { 496 ALOGV("Layer %d: Setting Override Scaling Mode -- mode=%d", id, osmc.override_scaling_mode()); 497 return mLayers[id]->setOverrideScalingMode(osmc.override_scaling_mode()); 498} 499 500status_t Replayer::setTransparentRegionHint(layer_id id, const TransparentRegionHintChange& trhc) { 501 ALOGV("Setting Transparent Region Hint"); 502 Region re = Region(); 503 504 for (auto r : trhc.region()) { 505 Rect rect = Rect(r.left(), r.top(), r.right(), r.bottom()); 506 re.merge(rect); 507 } 508 509 return mLayers[id]->setTransparentRegionHint(re); 510} 511 512status_t Replayer::setLayerStack(layer_id id, const LayerStackChange& lsc) { 513 ALOGV("Layer %d: Setting LayerStack -- layer_stack=%d", id, lsc.layer_stack()); 514 return mLayers[id]->setLayerStack(lsc.layer_stack()); 515} 516 517status_t Replayer::setHiddenFlag(layer_id id, const HiddenFlagChange& hfc) { 518 ALOGV("Layer %d: Setting Hidden Flag -- hidden_flag=%d", id, hfc.hidden_flag()); 519 layer_id flag = hfc.hidden_flag() ? layer_state_t::eLayerHidden : 0; 520 521 return mLayers[id]->setFlags(flag, layer_state_t::eLayerHidden); 522} 523 524status_t Replayer::setOpaqueFlag(layer_id id, const OpaqueFlagChange& ofc) { 525 ALOGV("Layer %d: Setting Opaque Flag -- opaque_flag=%d", id, ofc.opaque_flag()); 526 layer_id flag = ofc.opaque_flag() ? layer_state_t::eLayerOpaque : 0; 527 528 return mLayers[id]->setFlags(flag, layer_state_t::eLayerOpaque); 529} 530 531status_t Replayer::setSecureFlag(layer_id id, const SecureFlagChange& sfc) { 532 ALOGV("Layer %d: Setting Secure Flag -- secure_flag=%d", id, sfc.secure_flag()); 533 layer_id flag = sfc.secure_flag() ? layer_state_t::eLayerSecure : 0; 534 535 return mLayers[id]->setFlags(flag, layer_state_t::eLayerSecure); 536} 537 538status_t Replayer::setDeferredTransaction(layer_id id, const DeferredTransactionChange& dtc) { 539 ALOGV("Layer %d: Setting Deferred Transaction -- layer_id=%d, " 540 "frame_number=%llu", 541 id, dtc.layer_id(), dtc.frame_number()); 542 if (mLayers.count(dtc.layer_id()) == 0 || mLayers[dtc.layer_id()] == nullptr) { 543 ALOGE("Layer %d not found in Deferred Transaction", dtc.layer_id()); 544 return BAD_VALUE; 545 } 546 547 auto handle = mLayers[dtc.layer_id()]->getHandle(); 548 549 return mLayers[id]->deferTransactionUntil(handle, dtc.frame_number()); 550} 551 552void Replayer::setDisplaySurface(display_id id, const DispSurfaceChange& /*dsc*/) { 553 sp<IGraphicBufferProducer> outProducer; 554 sp<IGraphicBufferConsumer> outConsumer; 555 BufferQueue::createBufferQueue(&outProducer, &outConsumer); 556 557 SurfaceComposerClient::setDisplaySurface(mDisplays[id], outProducer); 558} 559 560void Replayer::setDisplayLayerStack(display_id id, const LayerStackChange& lsc) { 561 SurfaceComposerClient::setDisplayLayerStack(mDisplays[id], lsc.layer_stack()); 562} 563 564void Replayer::setDisplaySize(display_id id, const SizeChange& sc) { 565 SurfaceComposerClient::setDisplaySize(mDisplays[id], sc.w(), sc.h()); 566} 567 568void Replayer::setDisplayProjection(display_id id, const ProjectionChange& pc) { 569 Rect viewport = Rect(pc.viewport().left(), pc.viewport().top(), pc.viewport().right(), 570 pc.viewport().bottom()); 571 Rect frame = Rect(pc.frame().left(), pc.frame().top(), pc.frame().right(), pc.frame().bottom()); 572 573 SurfaceComposerClient::setDisplayProjection(mDisplays[id], pc.orientation(), viewport, frame); 574} 575 576status_t Replayer::createSurfaceControl( 577 const SurfaceCreation& create, const std::shared_ptr<Event>& event) { 578 event->readyToExecute(); 579 580 ALOGV("Creating Surface Control: ID: %d", create.id()); 581 sp<SurfaceControl> surfaceControl = mComposerClient->createSurface( 582 String8(create.name().c_str()), create.w(), create.h(), PIXEL_FORMAT_RGBA_8888, 0); 583 584 if (surfaceControl == nullptr) { 585 ALOGE("CreateSurfaceControl: unable to create surface control"); 586 return BAD_VALUE; 587 } 588 589 std::lock_guard<std::mutex> lock1(mLayerLock); 590 auto& layer = mLayers[create.id()]; 591 layer = surfaceControl; 592 593 mColors[create.id()] = HSV(rand() % 360, 1, 1); 594 595 mLayerCond.notify_all(); 596 597 std::lock_guard<std::mutex> lock2(mBufferQueueSchedulerLock); 598 if (mBufferQueueSchedulers.count(create.id()) != 0) { 599 mBufferQueueSchedulers[create.id()]->setSurfaceControl( 600 mLayers[create.id()], mColors[create.id()]); 601 } 602 603 return NO_ERROR; 604} 605 606status_t Replayer::deleteSurfaceControl( 607 const SurfaceDeletion& delete_, const std::shared_ptr<Event>& event) { 608 ALOGV("Deleting %d Surface Control", delete_.id()); 609 event->readyToExecute(); 610 611 std::lock_guard<std::mutex> lock1(mPendingLayersLock); 612 613 mLayersPendingRemoval.push_back(delete_.id()); 614 615 const auto& iterator = mBufferQueueSchedulers.find(delete_.id()); 616 if (iterator != mBufferQueueSchedulers.end()) { 617 (*iterator).second->stopScheduling(); 618 } 619 620 std::lock_guard<std::mutex> lock2(mLayerLock); 621 if (mLayers[delete_.id()] != nullptr) { 622 mComposerClient->destroySurface(mLayers[delete_.id()]->getHandle()); 623 } 624 625 return NO_ERROR; 626} 627 628void Replayer::doDeleteSurfaceControls() { 629 std::lock_guard<std::mutex> lock1(mPendingLayersLock); 630 std::lock_guard<std::mutex> lock2(mLayerLock); 631 if (!mLayersPendingRemoval.empty()) { 632 for (int id : mLayersPendingRemoval) { 633 mLayers.erase(id); 634 mColors.erase(id); 635 mBufferQueueSchedulers.erase(id); 636 } 637 mLayersPendingRemoval.clear(); 638 } 639} 640 641status_t Replayer::injectVSyncEvent( 642 const VSyncEvent& vSyncEvent, const std::shared_ptr<Event>& event) { 643 ALOGV("Injecting VSync Event"); 644 645 doDeleteSurfaceControls(); 646 647 event->readyToExecute(); 648 649 SurfaceComposerClient::injectVSync(vSyncEvent.when()); 650 651 return NO_ERROR; 652} 653 654void Replayer::createDisplay(const DisplayCreation& create, const std::shared_ptr<Event>& event) { 655 ALOGV("Creating display"); 656 event->readyToExecute(); 657 658 std::lock_guard<std::mutex> lock(mDisplayLock); 659 sp<IBinder> display = SurfaceComposerClient::createDisplay( 660 String8(create.name().c_str()), create.is_secure()); 661 mDisplays[create.id()] = display; 662 663 mDisplayCond.notify_all(); 664 665 ALOGV("Done creating display"); 666} 667 668void Replayer::deleteDisplay(const DisplayDeletion& delete_, const std::shared_ptr<Event>& event) { 669 ALOGV("Delete display"); 670 event->readyToExecute(); 671 672 std::lock_guard<std::mutex> lock(mDisplayLock); 673 SurfaceComposerClient::destroyDisplay(mDisplays[delete_.id()]); 674 mDisplays.erase(delete_.id()); 675} 676 677void Replayer::updatePowerMode(const PowerModeUpdate& pmu, const std::shared_ptr<Event>& event) { 678 ALOGV("Updating power mode"); 679 event->readyToExecute(); 680 SurfaceComposerClient::setDisplayPowerMode(mDisplays[pmu.id()], pmu.mode()); 681} 682 683void Replayer::waitUntilTimestamp(int64_t timestamp) { 684 ALOGV("Waiting for %lld nanoseconds...", static_cast<int64_t>(timestamp - mCurrentTime)); 685 std::this_thread::sleep_for(std::chrono::nanoseconds(timestamp - mCurrentTime)); 686} 687 688void Replayer::waitUntilDeferredTransactionLayerExists( 689 const DeferredTransactionChange& dtc, std::unique_lock<std::mutex>& lock) { 690 if (mLayers.count(dtc.layer_id()) == 0 || mLayers[dtc.layer_id()] == nullptr) { 691 mLayerCond.wait(lock, [&] { return (mLayers[dtc.layer_id()] != nullptr); }); 692 } 693} 694 695status_t Replayer::loadSurfaceComposerClient() { 696 mComposerClient = new SurfaceComposerClient; 697 return mComposerClient->initCheck(); 698} 699