Home | History | Annotate | Download | only in replayer
      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