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 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::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 85Replayer::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 103status_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 161status_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 174void Replayer::stopAutoReplayHandler(int /*signal*/) { 175 if (sReplayingManually) { 176 SurfaceComposerClient::enableVSyncInjections(false); 177 exit(0); 178 } 179 180 sReplayingManually.store(true); 181} 182 183std::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 193bool 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 198void 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 275status_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.kSurfaceDeletion: { 290 std::thread(&Replayer::deleteSurfaceControl, this, increment.surface_deletion(), event) 291 .detach(); 292 } break; 293 case increment.kBufferUpdate: { 294 std::lock_guard<std::mutex> lock1(mLayerLock); 295 std::lock_guard<std::mutex> lock2(mBufferQueueSchedulerLock); 296 297 Dimensions dimensions(increment.buffer_update().w(), increment.buffer_update().h()); 298 BufferEvent bufferEvent(event, dimensions); 299 300 auto layerId = increment.buffer_update().id(); 301 if (mBufferQueueSchedulers.count(layerId) == 0) { 302 mBufferQueueSchedulers[layerId] = std::make_shared<BufferQueueScheduler>( 303 mLayers[layerId], mColors[layerId], layerId); 304 mBufferQueueSchedulers[layerId]->addEvent(bufferEvent); 305 306 std::thread(&BufferQueueScheduler::startScheduling, 307 mBufferQueueSchedulers[increment.buffer_update().id()].get()) 308 .detach(); 309 } else { 310 auto bqs = mBufferQueueSchedulers[increment.buffer_update().id()]; 311 bqs->addEvent(bufferEvent); 312 } 313 } break; 314 case increment.kVsyncEvent: { 315 std::thread(&Replayer::injectVSyncEvent, this, increment.vsync_event(), event).detach(); 316 } break; 317 case increment.kDisplayCreation: { 318 std::thread(&Replayer::createDisplay, this, increment.display_creation(), event) 319 .detach(); 320 } break; 321 case increment.kDisplayDeletion: { 322 std::thread(&Replayer::deleteDisplay, this, increment.display_deletion(), event) 323 .detach(); 324 } break; 325 case increment.kPowerModeUpdate: { 326 std::thread(&Replayer::updatePowerMode, this, increment.power_mode_update(), event) 327 .detach(); 328 } break; 329 default: 330 ALOGE("Unknown Increment Type: %d", increment.increment_case()); 331 status = BAD_VALUE; 332 break; 333 } 334 335 return status; 336} 337 338status_t Replayer::doTransaction(const Transaction& t, const std::shared_ptr<Event>& event) { 339 ALOGV("Started Transaction"); 340 341 SurfaceComposerClient::Transaction liveTransaction; 342 343 status_t status = NO_ERROR; 344 345 status = doSurfaceTransaction(liveTransaction, t.surface_change()); 346 doDisplayTransaction(liveTransaction, t.display_change()); 347 348 if (t.animation()) { 349 liveTransaction.setAnimationTransaction(); 350 } 351 352 event->readyToExecute(); 353 354 liveTransaction.apply(t.synchronous()); 355 356 ALOGV("Ended Transaction"); 357 358 return status; 359} 360 361status_t Replayer::doSurfaceTransaction( 362 SurfaceComposerClient::Transaction& transaction, 363 const SurfaceChanges& surfaceChanges) { 364 status_t status = NO_ERROR; 365 366 for (const SurfaceChange& change : surfaceChanges) { 367 std::unique_lock<std::mutex> lock(mLayerLock); 368 if (mLayers[change.id()] == nullptr) { 369 mLayerCond.wait(lock, [&] { return (mLayers[change.id()] != nullptr); }); 370 } 371 372 switch (change.SurfaceChange_case()) { 373 case SurfaceChange::SurfaceChangeCase::kPosition: 374 setPosition(transaction, change.id(), change.position()); 375 break; 376 case SurfaceChange::SurfaceChangeCase::kSize: 377 setSize(transaction, change.id(), change.size()); 378 break; 379 case SurfaceChange::SurfaceChangeCase::kAlpha: 380 setAlpha(transaction, change.id(), change.alpha()); 381 break; 382 case SurfaceChange::SurfaceChangeCase::kLayer: 383 setLayer(transaction, change.id(), change.layer()); 384 break; 385 case SurfaceChange::SurfaceChangeCase::kCrop: 386 setCrop(transaction, change.id(), change.crop()); 387 break; 388 case SurfaceChange::SurfaceChangeCase::kMatrix: 389 setMatrix(transaction, change.id(), change.matrix()); 390 break; 391 case SurfaceChange::SurfaceChangeCase::kFinalCrop: 392 setFinalCrop(transaction, change.id(), change.final_crop()); 393 break; 394 case SurfaceChange::SurfaceChangeCase::kOverrideScalingMode: 395 setOverrideScalingMode(transaction, change.id(), 396 change.override_scaling_mode()); 397 break; 398 case SurfaceChange::SurfaceChangeCase::kTransparentRegionHint: 399 setTransparentRegionHint(transaction, change.id(), 400 change.transparent_region_hint()); 401 break; 402 case SurfaceChange::SurfaceChangeCase::kLayerStack: 403 setLayerStack(transaction, change.id(), change.layer_stack()); 404 break; 405 case SurfaceChange::SurfaceChangeCase::kHiddenFlag: 406 setHiddenFlag(transaction, change.id(), change.hidden_flag()); 407 break; 408 case SurfaceChange::SurfaceChangeCase::kOpaqueFlag: 409 setOpaqueFlag(transaction, change.id(), change.opaque_flag()); 410 break; 411 case SurfaceChange::SurfaceChangeCase::kSecureFlag: 412 setSecureFlag(transaction, change.id(), change.secure_flag()); 413 break; 414 case SurfaceChange::SurfaceChangeCase::kDeferredTransaction: 415 waitUntilDeferredTransactionLayerExists(change.deferred_transaction(), lock); 416 setDeferredTransaction(transaction, change.id(), 417 change.deferred_transaction()); 418 break; 419 default: 420 status = 1; 421 break; 422 } 423 424 if (status != NO_ERROR) { 425 ALOGE("Unknown Transaction Code"); 426 return status; 427 } 428 } 429 return status; 430} 431 432void Replayer::doDisplayTransaction(SurfaceComposerClient::Transaction& t, 433 const DisplayChanges& displayChanges) { 434 for (const DisplayChange& change : displayChanges) { 435 ALOGV("Doing display transaction"); 436 std::unique_lock<std::mutex> lock(mDisplayLock); 437 if (mDisplays[change.id()] == nullptr) { 438 mDisplayCond.wait(lock, [&] { return (mDisplays[change.id()] != nullptr); }); 439 } 440 441 switch (change.DisplayChange_case()) { 442 case DisplayChange::DisplayChangeCase::kSurface: 443 setDisplaySurface(t, change.id(), change.surface()); 444 break; 445 case DisplayChange::DisplayChangeCase::kLayerStack: 446 setDisplayLayerStack(t, change.id(), change.layer_stack()); 447 break; 448 case DisplayChange::DisplayChangeCase::kSize: 449 setDisplaySize(t, change.id(), change.size()); 450 break; 451 case DisplayChange::DisplayChangeCase::kProjection: 452 setDisplayProjection(t, change.id(), change.projection()); 453 break; 454 default: 455 break; 456 } 457 } 458} 459 460void Replayer::setPosition(SurfaceComposerClient::Transaction& t, 461 layer_id id, const PositionChange& pc) { 462 ALOGV("Layer %d: Setting Position -- x=%f, y=%f", id, pc.x(), pc.y()); 463 t.setPosition(mLayers[id], pc.x(), pc.y()); 464} 465 466void Replayer::setSize(SurfaceComposerClient::Transaction& t, 467 layer_id id, const SizeChange& sc) { 468 ALOGV("Layer %d: Setting Size -- w=%u, h=%u", id, sc.w(), sc.h()); 469 t.setSize(mLayers[id], sc.w(), sc.h()); 470} 471 472void Replayer::setLayer(SurfaceComposerClient::Transaction& t, 473 layer_id id, const LayerChange& lc) { 474 ALOGV("Layer %d: Setting Layer -- layer=%d", id, lc.layer()); 475 t.setLayer(mLayers[id], lc.layer()); 476} 477 478void Replayer::setAlpha(SurfaceComposerClient::Transaction& t, 479 layer_id id, const AlphaChange& ac) { 480 ALOGV("Layer %d: Setting Alpha -- alpha=%f", id, ac.alpha()); 481 t.setAlpha(mLayers[id], ac.alpha()); 482} 483 484void Replayer::setCrop(SurfaceComposerClient::Transaction& t, 485 layer_id id, const CropChange& cc) { 486 ALOGV("Layer %d: Setting Crop -- left=%d, top=%d, right=%d, bottom=%d", id, 487 cc.rectangle().left(), cc.rectangle().top(), cc.rectangle().right(), 488 cc.rectangle().bottom()); 489 490 Rect r = Rect(cc.rectangle().left(), cc.rectangle().top(), cc.rectangle().right(), 491 cc.rectangle().bottom()); 492 t.setCrop(mLayers[id], r); 493} 494 495void Replayer::setFinalCrop(SurfaceComposerClient::Transaction& t, 496 layer_id id, const FinalCropChange& fcc) { 497 ALOGV("Layer %d: Setting Final Crop -- left=%d, top=%d, right=%d, bottom=%d", id, 498 fcc.rectangle().left(), fcc.rectangle().top(), fcc.rectangle().right(), 499 fcc.rectangle().bottom()); 500 Rect r = Rect(fcc.rectangle().left(), fcc.rectangle().top(), fcc.rectangle().right(), 501 fcc.rectangle().bottom()); 502 t.setFinalCrop(mLayers[id], r); 503} 504 505void Replayer::setMatrix(SurfaceComposerClient::Transaction& t, 506 layer_id id, const MatrixChange& mc) { 507 ALOGV("Layer %d: Setting Matrix -- dsdx=%f, dtdx=%f, dsdy=%f, dtdy=%f", id, mc.dsdx(), 508 mc.dtdx(), mc.dsdy(), mc.dtdy()); 509 t.setMatrix(mLayers[id], mc.dsdx(), mc.dtdx(), mc.dsdy(), mc.dtdy()); 510} 511 512void Replayer::setOverrideScalingMode(SurfaceComposerClient::Transaction& t, 513 layer_id id, const OverrideScalingModeChange& osmc) { 514 ALOGV("Layer %d: Setting Override Scaling Mode -- mode=%d", id, osmc.override_scaling_mode()); 515 t.setOverrideScalingMode(mLayers[id], osmc.override_scaling_mode()); 516} 517 518void Replayer::setTransparentRegionHint(SurfaceComposerClient::Transaction& t, 519 layer_id id, const TransparentRegionHintChange& trhc) { 520 ALOGV("Setting Transparent Region Hint"); 521 Region re = Region(); 522 523 for (const auto& r : trhc.region()) { 524 Rect rect = Rect(r.left(), r.top(), r.right(), r.bottom()); 525 re.merge(rect); 526 } 527 528 t.setTransparentRegionHint(mLayers[id], re); 529} 530 531void Replayer::setLayerStack(SurfaceComposerClient::Transaction& t, 532 layer_id id, const LayerStackChange& lsc) { 533 ALOGV("Layer %d: Setting LayerStack -- layer_stack=%d", id, lsc.layer_stack()); 534 t.setLayerStack(mLayers[id], lsc.layer_stack()); 535} 536 537void Replayer::setHiddenFlag(SurfaceComposerClient::Transaction& t, 538 layer_id id, const HiddenFlagChange& hfc) { 539 ALOGV("Layer %d: Setting Hidden Flag -- hidden_flag=%d", id, hfc.hidden_flag()); 540 layer_id flag = hfc.hidden_flag() ? layer_state_t::eLayerHidden : 0; 541 542 t.setFlags(mLayers[id], flag, layer_state_t::eLayerHidden); 543} 544 545void Replayer::setOpaqueFlag(SurfaceComposerClient::Transaction& t, 546 layer_id id, const OpaqueFlagChange& ofc) { 547 ALOGV("Layer %d: Setting Opaque Flag -- opaque_flag=%d", id, ofc.opaque_flag()); 548 layer_id flag = ofc.opaque_flag() ? layer_state_t::eLayerOpaque : 0; 549 550 t.setFlags(mLayers[id], flag, layer_state_t::eLayerOpaque); 551} 552 553void Replayer::setSecureFlag(SurfaceComposerClient::Transaction& t, 554 layer_id id, const SecureFlagChange& sfc) { 555 ALOGV("Layer %d: Setting Secure Flag -- secure_flag=%d", id, sfc.secure_flag()); 556 layer_id flag = sfc.secure_flag() ? layer_state_t::eLayerSecure : 0; 557 558 t.setFlags(mLayers[id], flag, layer_state_t::eLayerSecure); 559} 560 561void Replayer::setDeferredTransaction(SurfaceComposerClient::Transaction& t, 562 layer_id id, const DeferredTransactionChange& dtc) { 563 ALOGV("Layer %d: Setting Deferred Transaction -- layer_id=%d, " 564 "frame_number=%llu", 565 id, dtc.layer_id(), dtc.frame_number()); 566 if (mLayers.count(dtc.layer_id()) == 0 || mLayers[dtc.layer_id()] == nullptr) { 567 ALOGE("Layer %d not found in Deferred Transaction", dtc.layer_id()); 568 return; 569 } 570 571 auto handle = mLayers[dtc.layer_id()]->getHandle(); 572 573 t.deferTransactionUntil(mLayers[id], handle, dtc.frame_number()); 574} 575 576void Replayer::setDisplaySurface(SurfaceComposerClient::Transaction& t, 577 display_id id, const DispSurfaceChange& /*dsc*/) { 578 sp<IGraphicBufferProducer> outProducer; 579 sp<IGraphicBufferConsumer> outConsumer; 580 BufferQueue::createBufferQueue(&outProducer, &outConsumer); 581 582 t.setDisplaySurface(mDisplays[id], outProducer); 583} 584 585void Replayer::setDisplayLayerStack(SurfaceComposerClient::Transaction& t, 586 display_id id, const LayerStackChange& lsc) { 587 t.setDisplayLayerStack(mDisplays[id], lsc.layer_stack()); 588} 589 590void Replayer::setDisplaySize(SurfaceComposerClient::Transaction& t, 591 display_id id, const SizeChange& sc) { 592 t.setDisplaySize(mDisplays[id], sc.w(), sc.h()); 593} 594 595void Replayer::setDisplayProjection(SurfaceComposerClient::Transaction& t, 596 display_id id, const ProjectionChange& pc) { 597 Rect viewport = Rect(pc.viewport().left(), pc.viewport().top(), pc.viewport().right(), 598 pc.viewport().bottom()); 599 Rect frame = Rect(pc.frame().left(), pc.frame().top(), pc.frame().right(), pc.frame().bottom()); 600 601 t.setDisplayProjection(mDisplays[id], pc.orientation(), viewport, frame); 602} 603 604status_t Replayer::createSurfaceControl( 605 const SurfaceCreation& create, const std::shared_ptr<Event>& event) { 606 event->readyToExecute(); 607 608 ALOGV("Creating Surface Control: ID: %d", create.id()); 609 sp<SurfaceControl> surfaceControl = mComposerClient->createSurface( 610 String8(create.name().c_str()), create.w(), create.h(), PIXEL_FORMAT_RGBA_8888, 0); 611 612 if (surfaceControl == nullptr) { 613 ALOGE("CreateSurfaceControl: unable to create surface control"); 614 return BAD_VALUE; 615 } 616 617 std::lock_guard<std::mutex> lock1(mLayerLock); 618 auto& layer = mLayers[create.id()]; 619 layer = surfaceControl; 620 621 mColors[create.id()] = HSV(rand() % 360, 1, 1); 622 623 mLayerCond.notify_all(); 624 625 std::lock_guard<std::mutex> lock2(mBufferQueueSchedulerLock); 626 if (mBufferQueueSchedulers.count(create.id()) != 0) { 627 mBufferQueueSchedulers[create.id()]->setSurfaceControl( 628 mLayers[create.id()], mColors[create.id()]); 629 } 630 631 return NO_ERROR; 632} 633 634status_t Replayer::deleteSurfaceControl( 635 const SurfaceDeletion& delete_, const std::shared_ptr<Event>& event) { 636 ALOGV("Deleting %d Surface Control", delete_.id()); 637 event->readyToExecute(); 638 639 std::lock_guard<std::mutex> lock1(mPendingLayersLock); 640 641 mLayersPendingRemoval.push_back(delete_.id()); 642 643 const auto& iterator = mBufferQueueSchedulers.find(delete_.id()); 644 if (iterator != mBufferQueueSchedulers.end()) { 645 (*iterator).second->stopScheduling(); 646 } 647 648 std::lock_guard<std::mutex> lock2(mLayerLock); 649 if (mLayers[delete_.id()] != nullptr) { 650 mComposerClient->destroySurface(mLayers[delete_.id()]->getHandle()); 651 } 652 653 return NO_ERROR; 654} 655 656void Replayer::doDeleteSurfaceControls() { 657 std::lock_guard<std::mutex> lock1(mPendingLayersLock); 658 std::lock_guard<std::mutex> lock2(mLayerLock); 659 if (!mLayersPendingRemoval.empty()) { 660 for (int id : mLayersPendingRemoval) { 661 mLayers.erase(id); 662 mColors.erase(id); 663 mBufferQueueSchedulers.erase(id); 664 } 665 mLayersPendingRemoval.clear(); 666 } 667} 668 669status_t Replayer::injectVSyncEvent( 670 const VSyncEvent& vSyncEvent, const std::shared_ptr<Event>& event) { 671 ALOGV("Injecting VSync Event"); 672 673 doDeleteSurfaceControls(); 674 675 event->readyToExecute(); 676 677 SurfaceComposerClient::injectVSync(vSyncEvent.when()); 678 679 return NO_ERROR; 680} 681 682void Replayer::createDisplay(const DisplayCreation& create, const std::shared_ptr<Event>& event) { 683 ALOGV("Creating display"); 684 event->readyToExecute(); 685 686 std::lock_guard<std::mutex> lock(mDisplayLock); 687 sp<IBinder> display = SurfaceComposerClient::createDisplay( 688 String8(create.name().c_str()), create.is_secure()); 689 mDisplays[create.id()] = display; 690 691 mDisplayCond.notify_all(); 692 693 ALOGV("Done creating display"); 694} 695 696void Replayer::deleteDisplay(const DisplayDeletion& delete_, const std::shared_ptr<Event>& event) { 697 ALOGV("Delete display"); 698 event->readyToExecute(); 699 700 std::lock_guard<std::mutex> lock(mDisplayLock); 701 SurfaceComposerClient::destroyDisplay(mDisplays[delete_.id()]); 702 mDisplays.erase(delete_.id()); 703} 704 705void Replayer::updatePowerMode(const PowerModeUpdate& pmu, const std::shared_ptr<Event>& event) { 706 ALOGV("Updating power mode"); 707 event->readyToExecute(); 708 SurfaceComposerClient::setDisplayPowerMode(mDisplays[pmu.id()], pmu.mode()); 709} 710 711void Replayer::waitUntilTimestamp(int64_t timestamp) { 712 ALOGV("Waiting for %lld nanoseconds...", static_cast<int64_t>(timestamp - mCurrentTime)); 713 std::this_thread::sleep_for(std::chrono::nanoseconds(timestamp - mCurrentTime)); 714} 715 716void Replayer::waitUntilDeferredTransactionLayerExists( 717 const DeferredTransactionChange& dtc, std::unique_lock<std::mutex>& lock) { 718 if (mLayers.count(dtc.layer_id()) == 0 || mLayers[dtc.layer_id()] == nullptr) { 719 mLayerCond.wait(lock, [&] { return (mLayers[dtc.layer_id()] != nullptr); }); 720 } 721} 722 723status_t Replayer::loadSurfaceComposerClient() { 724 mComposerClient = new SurfaceComposerClient; 725 return mComposerClient->initCheck(); 726} 727