Home | History | Annotate | Download | only in libvrflinger
      1 #include "hardware_composer.h"
      2 
      3 #include <binder/IServiceManager.h>
      4 #include <cutils/properties.h>
      5 #include <cutils/sched_policy.h>
      6 #include <fcntl.h>
      7 #include <log/log.h>
      8 #include <poll.h>
      9 #include <stdint.h>
     10 #include <sync/sync.h>
     11 #include <sys/eventfd.h>
     12 #include <sys/prctl.h>
     13 #include <sys/resource.h>
     14 #include <sys/system_properties.h>
     15 #include <sys/timerfd.h>
     16 #include <sys/types.h>
     17 #include <time.h>
     18 #include <unistd.h>
     19 #include <utils/Trace.h>
     20 
     21 #include <algorithm>
     22 #include <chrono>
     23 #include <functional>
     24 #include <map>
     25 #include <sstream>
     26 #include <string>
     27 #include <tuple>
     28 
     29 #include <dvr/dvr_display_types.h>
     30 #include <dvr/performance_client_api.h>
     31 #include <private/dvr/clock_ns.h>
     32 #include <private/dvr/ion_buffer.h>
     33 
     34 using android::hardware::Return;
     35 using android::hardware::Void;
     36 using android::pdx::ErrorStatus;
     37 using android::pdx::LocalHandle;
     38 using android::pdx::Status;
     39 using android::pdx::rpc::EmptyVariant;
     40 using android::pdx::rpc::IfAnyOf;
     41 
     42 using namespace std::chrono_literals;
     43 
     44 namespace android {
     45 namespace dvr {
     46 
     47 namespace {
     48 
     49 const char kDvrPerformanceProperty[] = "sys.dvr.performance";
     50 const char kDvrStandaloneProperty[] = "ro.boot.vr";
     51 
     52 const char kRightEyeOffsetProperty[] = "dvr.right_eye_offset_ns";
     53 
     54 const char kUseExternalDisplayProperty[] = "persist.vr.use_external_display";
     55 
     56 // Surface flinger uses "VSYNC-sf" and "VSYNC-app" for its version of these
     57 // events. Name ours similarly.
     58 const char kVsyncTraceEventName[] = "VSYNC-vrflinger";
     59 
     60 // How long to wait after boot finishes before we turn the display off.
     61 constexpr int kBootFinishedDisplayOffTimeoutSec = 10;
     62 
     63 constexpr int kDefaultDisplayWidth = 1920;
     64 constexpr int kDefaultDisplayHeight = 1080;
     65 constexpr int64_t kDefaultVsyncPeriodNs = 16666667;
     66 // Hardware composer reports dpi as dots per thousand inches (dpi * 1000).
     67 constexpr int kDefaultDpi = 400000;
     68 
     69 // Get time offset from a vsync to when the pose for that vsync should be
     70 // predicted out to. For example, if scanout gets halfway through the frame
     71 // at the halfway point between vsyncs, then this could be half the period.
     72 // With global shutter displays, this should be changed to the offset to when
     73 // illumination begins. Low persistence adds a frame of latency, so we predict
     74 // to the center of the next frame.
     75 inline int64_t GetPosePredictionTimeOffset(int64_t vsync_period_ns) {
     76   return (vsync_period_ns * 150) / 100;
     77 }
     78 
     79 // Attempts to set the scheduler class and partiton for the current thread.
     80 // Returns true on success or false on failure.
     81 bool SetThreadPolicy(const std::string& scheduler_class,
     82                      const std::string& partition) {
     83   int error = dvrSetSchedulerClass(0, scheduler_class.c_str());
     84   if (error < 0) {
     85     ALOGE(
     86         "SetThreadPolicy: Failed to set scheduler class \"%s\" for "
     87         "thread_id=%d: %s",
     88         scheduler_class.c_str(), gettid(), strerror(-error));
     89     return false;
     90   }
     91   error = dvrSetCpuPartition(0, partition.c_str());
     92   if (error < 0) {
     93     ALOGE(
     94         "SetThreadPolicy: Failed to set cpu partiton \"%s\" for thread_id=%d: "
     95         "%s",
     96         partition.c_str(), gettid(), strerror(-error));
     97     return false;
     98   }
     99   return true;
    100 }
    101 
    102 // Utility to generate scoped tracers with arguments.
    103 // TODO(eieio): Move/merge this into utils/Trace.h?
    104 class TraceArgs {
    105  public:
    106   template <typename... Args>
    107   explicit TraceArgs(const char* format, Args&&... args) {
    108     std::array<char, 1024> buffer;
    109     snprintf(buffer.data(), buffer.size(), format, std::forward<Args>(args)...);
    110     atrace_begin(ATRACE_TAG, buffer.data());
    111   }
    112 
    113   ~TraceArgs() { atrace_end(ATRACE_TAG); }
    114 
    115  private:
    116   TraceArgs(const TraceArgs&) = delete;
    117   void operator=(const TraceArgs&) = delete;
    118 };
    119 
    120 // Macro to define a scoped tracer with arguments. Uses PASTE(x, y) macro
    121 // defined in utils/Trace.h.
    122 #define TRACE_FORMAT(format, ...) \
    123   TraceArgs PASTE(__tracer, __LINE__) { format, ##__VA_ARGS__ }
    124 
    125 // Returns "primary" or "external". Useful for writing more readable logs.
    126 const char* GetDisplayName(bool is_primary) {
    127   return is_primary ? "primary" : "external";
    128 }
    129 
    130 }  // anonymous namespace
    131 
    132 HardwareComposer::HardwareComposer()
    133     : initialized_(false), request_display_callback_(nullptr) {}
    134 
    135 HardwareComposer::~HardwareComposer(void) {
    136   UpdatePostThreadState(PostThreadState::Quit, true);
    137   if (post_thread_.joinable())
    138     post_thread_.join();
    139   composer_callback_->SetVsyncService(nullptr);
    140 }
    141 
    142 bool HardwareComposer::Initialize(
    143     Hwc2::Composer* composer, hwc2_display_t primary_display_id,
    144     RequestDisplayCallback request_display_callback) {
    145   if (initialized_) {
    146     ALOGE("HardwareComposer::Initialize: already initialized.");
    147     return false;
    148   }
    149 
    150   is_standalone_device_ = property_get_bool(kDvrStandaloneProperty, false);
    151 
    152   request_display_callback_ = request_display_callback;
    153 
    154   primary_display_ = GetDisplayParams(composer, primary_display_id, true);
    155 
    156   vsync_service_ = new VsyncService;
    157   sp<IServiceManager> sm(defaultServiceManager());
    158   auto result = sm->addService(String16(VsyncService::GetServiceName()),
    159       vsync_service_, false);
    160   LOG_ALWAYS_FATAL_IF(result != android::OK,
    161       "addService(%s) failed", VsyncService::GetServiceName());
    162 
    163   post_thread_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
    164   LOG_ALWAYS_FATAL_IF(
    165       !post_thread_event_fd_,
    166       "HardwareComposer: Failed to create interrupt event fd : %s",
    167       strerror(errno));
    168 
    169   post_thread_ = std::thread(&HardwareComposer::PostThread, this);
    170 
    171   initialized_ = true;
    172 
    173   return initialized_;
    174 }
    175 
    176 void HardwareComposer::Enable() {
    177   UpdatePostThreadState(PostThreadState::Suspended, false);
    178 }
    179 
    180 void HardwareComposer::Disable() {
    181   UpdatePostThreadState(PostThreadState::Suspended, true);
    182 
    183   std::unique_lock<std::mutex> lock(post_thread_mutex_);
    184   post_thread_ready_.wait(lock, [this] {
    185     return !post_thread_resumed_;
    186   });
    187 }
    188 
    189 void HardwareComposer::OnBootFinished() {
    190   std::lock_guard<std::mutex> lock(post_thread_mutex_);
    191   if (boot_finished_)
    192     return;
    193   boot_finished_ = true;
    194   post_thread_wait_.notify_one();
    195   if (is_standalone_device_)
    196     request_display_callback_(true);
    197 }
    198 
    199 // Update the post thread quiescent state based on idle and suspended inputs.
    200 void HardwareComposer::UpdatePostThreadState(PostThreadStateType state,
    201                                              bool suspend) {
    202   std::unique_lock<std::mutex> lock(post_thread_mutex_);
    203 
    204   // Update the votes in the state variable before evaluating the effective
    205   // quiescent state. Any bits set in post_thread_state_ indicate that the post
    206   // thread should be suspended.
    207   if (suspend) {
    208     post_thread_state_ |= state;
    209   } else {
    210     post_thread_state_ &= ~state;
    211   }
    212 
    213   const bool quit = post_thread_state_ & PostThreadState::Quit;
    214   const bool effective_suspend = post_thread_state_ != PostThreadState::Active;
    215   if (quit) {
    216     post_thread_quiescent_ = true;
    217     eventfd_write(post_thread_event_fd_.Get(), 1);
    218     post_thread_wait_.notify_one();
    219   } else if (effective_suspend && !post_thread_quiescent_) {
    220     post_thread_quiescent_ = true;
    221     eventfd_write(post_thread_event_fd_.Get(), 1);
    222   } else if (!effective_suspend && post_thread_quiescent_) {
    223     post_thread_quiescent_ = false;
    224     eventfd_t value;
    225     eventfd_read(post_thread_event_fd_.Get(), &value);
    226     post_thread_wait_.notify_one();
    227   }
    228 }
    229 
    230 void HardwareComposer::CreateComposer() {
    231   if (composer_)
    232     return;
    233   composer_.reset(new Hwc2::impl::Composer("default"));
    234   composer_callback_ = new ComposerCallback;
    235   composer_->registerCallback(composer_callback_);
    236   LOG_ALWAYS_FATAL_IF(!composer_callback_->GotFirstHotplug(),
    237       "Registered composer callback but didn't get hotplug for primary"
    238       " display");
    239   composer_callback_->SetVsyncService(vsync_service_);
    240 }
    241 
    242 void HardwareComposer::OnPostThreadResumed() {
    243   ALOGI("OnPostThreadResumed");
    244   EnableDisplay(*target_display_, true);
    245 
    246   // Trigger target-specific performance mode change.
    247   property_set(kDvrPerformanceProperty, "performance");
    248 }
    249 
    250 void HardwareComposer::OnPostThreadPaused() {
    251   ALOGI("OnPostThreadPaused");
    252   retire_fence_fds_.clear();
    253   layers_.clear();
    254 
    255   // Phones create a new composer client on resume and destroy it on pause.
    256   // Standalones only create the composer client once and then use SetPowerMode
    257   // to control the screen on pause/resume.
    258   if (!is_standalone_device_) {
    259     if (composer_callback_ != nullptr) {
    260       composer_callback_->SetVsyncService(nullptr);
    261       composer_callback_ = nullptr;
    262     }
    263     composer_.reset(nullptr);
    264   } else {
    265     EnableDisplay(*target_display_, false);
    266   }
    267 
    268   // Trigger target-specific performance mode change.
    269   property_set(kDvrPerformanceProperty, "idle");
    270 }
    271 
    272 bool HardwareComposer::PostThreadCondWait(std::unique_lock<std::mutex>& lock,
    273                                           int timeout_sec,
    274                                           const std::function<bool()>& pred) {
    275   auto pred_with_quit = [&] {
    276     return pred() || (post_thread_state_ & PostThreadState::Quit);
    277   };
    278   if (timeout_sec >= 0) {
    279     post_thread_wait_.wait_for(lock, std::chrono::seconds(timeout_sec),
    280                                pred_with_quit);
    281   } else {
    282     post_thread_wait_.wait(lock, pred_with_quit);
    283   }
    284   if (post_thread_state_ & PostThreadState::Quit) {
    285     ALOGI("HardwareComposer::PostThread: Quitting.");
    286     return true;
    287   }
    288   return false;
    289 }
    290 
    291 HWC::Error HardwareComposer::Validate(hwc2_display_t display) {
    292   uint32_t num_types;
    293   uint32_t num_requests;
    294   HWC::Error error =
    295       composer_->validateDisplay(display, &num_types, &num_requests);
    296 
    297   if (error == HWC2_ERROR_HAS_CHANGES) {
    298     ALOGE("Hardware composer has requested composition changes, "
    299           "which we don't support.");
    300     // Accept the changes anyway and see if we can get something on the screen.
    301     error = composer_->acceptDisplayChanges(display);
    302   }
    303 
    304   return error;
    305 }
    306 
    307 bool HardwareComposer::EnableVsync(const DisplayParams& display, bool enabled) {
    308   HWC::Error error = composer_->setVsyncEnabled(display.id,
    309       (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE
    310                                              : HWC2_VSYNC_DISABLE));
    311   if (error != HWC::Error::None) {
    312     ALOGE("Error attempting to %s vsync on %s display: %s",
    313         enabled ? "enable" : "disable", GetDisplayName(display.is_primary),
    314         error.to_string().c_str());
    315   }
    316   return error == HWC::Error::None;
    317 }
    318 
    319 bool HardwareComposer::SetPowerMode(const DisplayParams& display, bool active) {
    320   ALOGI("Turning %s display %s", GetDisplayName(display.is_primary),
    321       active ? "on" : "off");
    322   HWC::PowerMode power_mode = active ? HWC::PowerMode::On : HWC::PowerMode::Off;
    323   HWC::Error error = composer_->setPowerMode(display.id,
    324       power_mode.cast<Hwc2::IComposerClient::PowerMode>());
    325   if (error != HWC::Error::None) {
    326     ALOGE("Error attempting to turn %s display %s: %s",
    327           GetDisplayName(display.is_primary), active ? "on" : "off",
    328         error.to_string().c_str());
    329   }
    330   return error == HWC::Error::None;
    331 }
    332 
    333 bool HardwareComposer::EnableDisplay(const DisplayParams& display,
    334                                      bool enabled) {
    335   bool power_result;
    336   bool vsync_result;
    337   // When turning a display on, we set the power state then set vsync. When
    338   // turning a display off we do it in the opposite order.
    339   if (enabled) {
    340     power_result = SetPowerMode(display, enabled);
    341     vsync_result = EnableVsync(display, enabled);
    342   } else {
    343     vsync_result = EnableVsync(display, enabled);
    344     power_result = SetPowerMode(display, enabled);
    345   }
    346   return power_result && vsync_result;
    347 }
    348 
    349 HWC::Error HardwareComposer::Present(hwc2_display_t display) {
    350   int32_t present_fence;
    351   HWC::Error error = composer_->presentDisplay(display, &present_fence);
    352 
    353   // According to the documentation, this fence is signaled at the time of
    354   // vsync/DMA for physical displays.
    355   if (error == HWC::Error::None) {
    356     retire_fence_fds_.emplace_back(present_fence);
    357   } else {
    358     ATRACE_INT("HardwareComposer: PresentResult", error);
    359   }
    360 
    361   return error;
    362 }
    363 
    364 DisplayParams HardwareComposer::GetDisplayParams(
    365     Hwc2::Composer* composer, hwc2_display_t display, bool is_primary) {
    366   DisplayParams params;
    367   params.id = display;
    368   params.is_primary = is_primary;
    369 
    370   Hwc2::Config config;
    371   HWC::Error error = composer->getActiveConfig(display, &config);
    372 
    373   if (error == HWC::Error::None) {
    374     auto get_attr = [&](hwc2_attribute_t attr, const char* attr_name)
    375         -> std::optional<int32_t> {
    376       int32_t val;
    377       HWC::Error error = composer->getDisplayAttribute(
    378           display, config, (Hwc2::IComposerClient::Attribute)attr, &val);
    379       if (error != HWC::Error::None) {
    380         ALOGE("Failed to get %s display attr %s: %s",
    381             GetDisplayName(is_primary), attr_name,
    382             error.to_string().c_str());
    383         return std::nullopt;
    384       }
    385       return val;
    386     };
    387 
    388     auto width = get_attr(HWC2_ATTRIBUTE_WIDTH, "width");
    389     auto height = get_attr(HWC2_ATTRIBUTE_HEIGHT, "height");
    390 
    391     if (width && height) {
    392       params.width = *width;
    393       params.height = *height;
    394     } else {
    395       ALOGI("Failed to get width and/or height for %s display. Using default"
    396           " size %dx%d.", GetDisplayName(is_primary), kDefaultDisplayWidth,
    397           kDefaultDisplayHeight);
    398       params.width = kDefaultDisplayWidth;
    399       params.height = kDefaultDisplayHeight;
    400     }
    401 
    402     auto vsync_period = get_attr(HWC2_ATTRIBUTE_VSYNC_PERIOD, "vsync period");
    403     if (vsync_period) {
    404       params.vsync_period_ns = *vsync_period;
    405     } else {
    406       ALOGI("Failed to get vsync period for %s display. Using default vsync"
    407           " period %.2fms", GetDisplayName(is_primary),
    408           static_cast<float>(kDefaultVsyncPeriodNs) / 1000000);
    409       params.vsync_period_ns = kDefaultVsyncPeriodNs;
    410     }
    411 
    412     auto dpi_x = get_attr(HWC2_ATTRIBUTE_DPI_X, "DPI X");
    413     auto dpi_y = get_attr(HWC2_ATTRIBUTE_DPI_Y, "DPI Y");
    414     if (dpi_x && dpi_y) {
    415       params.dpi.x = *dpi_x;
    416       params.dpi.y = *dpi_y;
    417     } else {
    418       ALOGI("Failed to get dpi_x and/or dpi_y for %s display. Using default"
    419           " dpi %d.", GetDisplayName(is_primary), kDefaultDpi);
    420       params.dpi.x = kDefaultDpi;
    421       params.dpi.y = kDefaultDpi;
    422     }
    423   } else {
    424     ALOGE("HardwareComposer: Failed to get current %s display config: %d."
    425         " Using default display values.",
    426         GetDisplayName(is_primary), error.value);
    427     params.width = kDefaultDisplayWidth;
    428     params.height = kDefaultDisplayHeight;
    429     params.dpi.x = kDefaultDpi;
    430     params.dpi.y = kDefaultDpi;
    431     params.vsync_period_ns = kDefaultVsyncPeriodNs;
    432   }
    433 
    434   ALOGI(
    435       "HardwareComposer: %s display attributes: width=%d height=%d "
    436       "vsync_period_ns=%d DPI=%dx%d",
    437       GetDisplayName(is_primary),
    438       params.width,
    439       params.height,
    440       params.vsync_period_ns,
    441       params.dpi.x,
    442       params.dpi.y);
    443 
    444   return params;
    445 }
    446 
    447 std::string HardwareComposer::Dump() {
    448   std::unique_lock<std::mutex> lock(post_thread_mutex_);
    449   std::ostringstream stream;
    450 
    451   auto print_display_metrics = [&](const DisplayParams& params) {
    452     stream << GetDisplayName(params.is_primary)
    453            << " display metrics:     " << params.width << "x"
    454            << params.height << " " << (params.dpi.x / 1000.0)
    455            << "x" << (params.dpi.y / 1000.0) << " dpi @ "
    456            << (1000000000.0 / params.vsync_period_ns) << " Hz"
    457            << std::endl;
    458   };
    459 
    460   print_display_metrics(primary_display_);
    461   if (external_display_)
    462     print_display_metrics(*external_display_);
    463 
    464   stream << "Post thread resumed: " << post_thread_resumed_ << std::endl;
    465   stream << "Active layers:       " << layers_.size() << std::endl;
    466   stream << std::endl;
    467 
    468   for (size_t i = 0; i < layers_.size(); i++) {
    469     stream << "Layer " << i << ":";
    470     stream << " type=" << layers_[i].GetCompositionType().to_string();
    471     stream << " surface_id=" << layers_[i].GetSurfaceId();
    472     stream << " buffer_id=" << layers_[i].GetBufferId();
    473     stream << std::endl;
    474   }
    475   stream << std::endl;
    476 
    477   if (post_thread_resumed_) {
    478     stream << "Hardware Composer Debug Info:" << std::endl;
    479     stream << composer_->dumpDebugInfo();
    480   }
    481 
    482   return stream.str();
    483 }
    484 
    485 void HardwareComposer::PostLayers(hwc2_display_t display) {
    486   ATRACE_NAME("HardwareComposer::PostLayers");
    487 
    488   // Setup the hardware composer layers with current buffers.
    489   for (auto& layer : layers_) {
    490     layer.Prepare();
    491   }
    492 
    493   // Now that we have taken in a frame from the application, we have a chance
    494   // to drop the frame before passing the frame along to HWC.
    495   // If the display driver has become backed up, we detect it here and then
    496   // react by skipping this frame to catch up latency.
    497   while (!retire_fence_fds_.empty() &&
    498          (!retire_fence_fds_.front() ||
    499           sync_wait(retire_fence_fds_.front().Get(), 0) == 0)) {
    500     // There are only 2 fences in here, no performance problem to shift the
    501     // array of ints.
    502     retire_fence_fds_.erase(retire_fence_fds_.begin());
    503   }
    504 
    505   const bool is_fence_pending = static_cast<int32_t>(retire_fence_fds_.size()) >
    506                                 post_thread_config_.allowed_pending_fence_count;
    507 
    508   if (is_fence_pending) {
    509     ATRACE_INT("frame_skip_count", ++frame_skip_count_);
    510 
    511     ALOGW_IF(is_fence_pending,
    512              "Warning: dropping a frame to catch up with HWC (pending = %zd)",
    513              retire_fence_fds_.size());
    514 
    515     for (auto& layer : layers_) {
    516       layer.Drop();
    517     }
    518     return;
    519   } else {
    520     // Make the transition more obvious in systrace when the frame skip happens
    521     // above.
    522     ATRACE_INT("frame_skip_count", 0);
    523   }
    524 
    525 #if TRACE > 1
    526   for (size_t i = 0; i < layers_.size(); i++) {
    527     ALOGI("HardwareComposer::PostLayers: layer=%zu buffer_id=%d composition=%s",
    528           i, layers_[i].GetBufferId(),
    529           layers_[i].GetCompositionType().to_string().c_str());
    530   }
    531 #endif
    532 
    533   HWC::Error error = Validate(display);
    534   if (error != HWC::Error::None) {
    535     ALOGE("HardwareComposer::PostLayers: Validate failed: %s display=%" PRIu64,
    536           error.to_string().c_str(), display);
    537     return;
    538   }
    539 
    540   error = Present(display);
    541   if (error != HWC::Error::None) {
    542     ALOGE("HardwareComposer::PostLayers: Present failed: %s",
    543           error.to_string().c_str());
    544     return;
    545   }
    546 
    547   std::vector<Hwc2::Layer> out_layers;
    548   std::vector<int> out_fences;
    549   error = composer_->getReleaseFences(display,
    550                                       &out_layers, &out_fences);
    551   ALOGE_IF(error != HWC::Error::None,
    552            "HardwareComposer::PostLayers: Failed to get release fences: %s",
    553            error.to_string().c_str());
    554 
    555   // Perform post-frame bookkeeping.
    556   uint32_t num_elements = out_layers.size();
    557   for (size_t i = 0; i < num_elements; ++i) {
    558     for (auto& layer : layers_) {
    559       if (layer.GetLayerHandle() == out_layers[i]) {
    560         layer.Finish(out_fences[i]);
    561       }
    562     }
    563   }
    564 }
    565 
    566 void HardwareComposer::SetDisplaySurfaces(
    567     std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces) {
    568   ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd",
    569         surfaces.size());
    570   const bool display_idle = surfaces.size() == 0;
    571   {
    572     std::unique_lock<std::mutex> lock(post_thread_mutex_);
    573     surfaces_ = std::move(surfaces);
    574     surfaces_changed_ = true;
    575   }
    576 
    577   if (request_display_callback_ && !is_standalone_device_)
    578     request_display_callback_(!display_idle);
    579 
    580   // Set idle state based on whether there are any surfaces to handle.
    581   UpdatePostThreadState(PostThreadState::Idle, display_idle);
    582 }
    583 
    584 int HardwareComposer::OnNewGlobalBuffer(DvrGlobalBufferKey key,
    585                                         IonBuffer& ion_buffer) {
    586   if (key == DvrGlobalBuffers::kVsyncBuffer) {
    587     vsync_ring_ = std::make_unique<CPUMappedBroadcastRing<DvrVsyncRing>>(
    588         &ion_buffer, CPUUsageMode::WRITE_OFTEN);
    589 
    590     if (vsync_ring_->IsMapped() == false) {
    591       return -EPERM;
    592     }
    593   }
    594 
    595   if (key == DvrGlobalBuffers::kVrFlingerConfigBufferKey) {
    596     return MapConfigBuffer(ion_buffer);
    597   }
    598 
    599   return 0;
    600 }
    601 
    602 void HardwareComposer::OnDeletedGlobalBuffer(DvrGlobalBufferKey key) {
    603   if (key == DvrGlobalBuffers::kVrFlingerConfigBufferKey) {
    604     ConfigBufferDeleted();
    605   }
    606 }
    607 
    608 int HardwareComposer::MapConfigBuffer(IonBuffer& ion_buffer) {
    609   std::lock_guard<std::mutex> lock(shared_config_mutex_);
    610   shared_config_ring_ = DvrConfigRing();
    611 
    612   if (ion_buffer.width() < DvrConfigRing::MemorySize()) {
    613     ALOGE("HardwareComposer::MapConfigBuffer: invalid buffer size.");
    614     return -EINVAL;
    615   }
    616 
    617   void* buffer_base = 0;
    618   int result = ion_buffer.Lock(ion_buffer.usage(), 0, 0, ion_buffer.width(),
    619                                ion_buffer.height(), &buffer_base);
    620   if (result != 0) {
    621     ALOGE(
    622         "HardwareComposer::MapConfigBuffer: Failed to map vrflinger config "
    623         "buffer.");
    624     return -EPERM;
    625   }
    626 
    627   shared_config_ring_ = DvrConfigRing::Create(buffer_base, ion_buffer.width());
    628   ion_buffer.Unlock();
    629 
    630   return 0;
    631 }
    632 
    633 void HardwareComposer::ConfigBufferDeleted() {
    634   std::lock_guard<std::mutex> lock(shared_config_mutex_);
    635   shared_config_ring_ = DvrConfigRing();
    636 }
    637 
    638 void HardwareComposer::UpdateConfigBuffer() {
    639   std::lock_guard<std::mutex> lock(shared_config_mutex_);
    640   if (!shared_config_ring_.is_valid())
    641     return;
    642   // Copy from latest record in shared_config_ring_ to local copy.
    643   DvrConfig record;
    644   if (shared_config_ring_.GetNewest(&shared_config_ring_sequence_, &record)) {
    645     ALOGI("DvrConfig updated: sequence %u, post offset %d",
    646           shared_config_ring_sequence_, record.frame_post_offset_ns);
    647     ++shared_config_ring_sequence_;
    648     post_thread_config_ = record;
    649   }
    650 }
    651 
    652 int HardwareComposer::PostThreadPollInterruptible(
    653     const pdx::LocalHandle& event_fd, int requested_events, int timeout_ms) {
    654   pollfd pfd[2] = {
    655       {
    656           .fd = event_fd.Get(),
    657           .events = static_cast<short>(requested_events),
    658           .revents = 0,
    659       },
    660       {
    661           .fd = post_thread_event_fd_.Get(),
    662           .events = POLLPRI | POLLIN,
    663           .revents = 0,
    664       },
    665   };
    666   int ret, error;
    667   do {
    668     ret = poll(pfd, 2, timeout_ms);
    669     error = errno;
    670     ALOGW_IF(ret < 0,
    671              "HardwareComposer::PostThreadPollInterruptible: Error during "
    672              "poll(): %s (%d)",
    673              strerror(error), error);
    674   } while (ret < 0 && error == EINTR);
    675 
    676   if (ret < 0) {
    677     return -error;
    678   } else if (ret == 0) {
    679     return -ETIMEDOUT;
    680   } else if (pfd[0].revents != 0) {
    681     return 0;
    682   } else if (pfd[1].revents != 0) {
    683     ALOGI("VrHwcPost thread interrupted: revents=%x", pfd[1].revents);
    684     return kPostThreadInterrupted;
    685   } else {
    686     return 0;
    687   }
    688 }
    689 
    690 // Sleep until the next predicted vsync, returning the predicted vsync
    691 // timestamp.
    692 Status<int64_t> HardwareComposer::WaitForPredictedVSync() {
    693   const int64_t predicted_vsync_time = last_vsync_timestamp_ +
    694       (target_display_->vsync_period_ns * vsync_prediction_interval_);
    695   const int error = SleepUntil(predicted_vsync_time);
    696   if (error < 0) {
    697     ALOGE("HardwareComposer::WaifForVSync:: Failed to sleep: %s",
    698           strerror(-error));
    699     return error;
    700   }
    701   return {predicted_vsync_time};
    702 }
    703 
    704 int HardwareComposer::SleepUntil(int64_t wakeup_timestamp) {
    705   const int timer_fd = vsync_sleep_timer_fd_.Get();
    706   const itimerspec wakeup_itimerspec = {
    707       .it_interval = {.tv_sec = 0, .tv_nsec = 0},
    708       .it_value = NsToTimespec(wakeup_timestamp),
    709   };
    710   int ret =
    711       timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &wakeup_itimerspec, nullptr);
    712   int error = errno;
    713   if (ret < 0) {
    714     ALOGE("HardwareComposer::SleepUntil: Failed to set timerfd: %s",
    715           strerror(error));
    716     return -error;
    717   }
    718 
    719   return PostThreadPollInterruptible(vsync_sleep_timer_fd_, POLLIN,
    720                                      /*timeout_ms*/ -1);
    721 }
    722 
    723 void HardwareComposer::PostThread() {
    724   // NOLINTNEXTLINE(runtime/int)
    725   prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrHwcPost"), 0, 0, 0);
    726 
    727   // Set the scheduler to SCHED_FIFO with high priority. If this fails here
    728   // there may have been a startup timing issue between this thread and
    729   // performanced. Try again later when this thread becomes active.
    730   bool thread_policy_setup =
    731       SetThreadPolicy("graphics:high", "/system/performance");
    732 
    733   // Create a timerfd based on CLOCK_MONOTINIC.
    734   vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0));
    735   LOG_ALWAYS_FATAL_IF(
    736       !vsync_sleep_timer_fd_,
    737       "HardwareComposer: Failed to create vsync sleep timerfd: %s",
    738       strerror(errno));
    739 
    740   struct VsyncEyeOffsets { int64_t left_ns, right_ns; };
    741   bool was_running = false;
    742 
    743   auto get_vsync_eye_offsets = [this]() -> VsyncEyeOffsets {
    744     VsyncEyeOffsets offsets;
    745     offsets.left_ns =
    746         GetPosePredictionTimeOffset(target_display_->vsync_period_ns);
    747 
    748     // TODO(jbates) Query vblank time from device, when such an API is
    749     // available. This value (6.3%) was measured on A00 in low persistence mode.
    750     int64_t vblank_ns = target_display_->vsync_period_ns * 63 / 1000;
    751     offsets.right_ns = (target_display_->vsync_period_ns - vblank_ns) / 2;
    752 
    753     // Check property for overriding right eye offset value.
    754     offsets.right_ns =
    755         property_get_int64(kRightEyeOffsetProperty, offsets.right_ns);
    756 
    757     return offsets;
    758   };
    759 
    760   VsyncEyeOffsets vsync_eye_offsets = get_vsync_eye_offsets();
    761 
    762   if (is_standalone_device_) {
    763     // First, wait until boot finishes.
    764     std::unique_lock<std::mutex> lock(post_thread_mutex_);
    765     if (PostThreadCondWait(lock, -1, [this] { return boot_finished_; })) {
    766       return;
    767     }
    768 
    769     // Then, wait until we're either leaving the quiescent state, or the boot
    770     // finished display off timeout expires.
    771     if (PostThreadCondWait(lock, kBootFinishedDisplayOffTimeoutSec,
    772                            [this] { return !post_thread_quiescent_; })) {
    773       return;
    774     }
    775 
    776     LOG_ALWAYS_FATAL_IF(post_thread_state_ & PostThreadState::Suspended,
    777                         "Vr flinger should own the display by now.");
    778     post_thread_resumed_ = true;
    779     post_thread_ready_.notify_all();
    780     if (!composer_)
    781       CreateComposer();
    782   }
    783 
    784   while (1) {
    785     ATRACE_NAME("HardwareComposer::PostThread");
    786 
    787     // Check for updated config once per vsync.
    788     UpdateConfigBuffer();
    789 
    790     while (post_thread_quiescent_) {
    791       std::unique_lock<std::mutex> lock(post_thread_mutex_);
    792       ALOGI("HardwareComposer::PostThread: Entering quiescent state.");
    793 
    794       if (was_running) {
    795         vsync_trace_parity_ = false;
    796         ATRACE_INT(kVsyncTraceEventName, 0);
    797       }
    798 
    799       // Tear down resources.
    800       OnPostThreadPaused();
    801       was_running = false;
    802       post_thread_resumed_ = false;
    803       post_thread_ready_.notify_all();
    804 
    805       if (PostThreadCondWait(lock, -1,
    806                              [this] { return !post_thread_quiescent_; })) {
    807         // A true return value means we've been asked to quit.
    808         return;
    809       }
    810 
    811       post_thread_resumed_ = true;
    812       post_thread_ready_.notify_all();
    813 
    814       ALOGI("HardwareComposer::PostThread: Exiting quiescent state.");
    815     }
    816 
    817     if (!composer_)
    818       CreateComposer();
    819 
    820     bool target_display_changed = UpdateTargetDisplay();
    821     bool just_resumed_running = !was_running;
    822     was_running = true;
    823 
    824     if (target_display_changed)
    825       vsync_eye_offsets = get_vsync_eye_offsets();
    826 
    827     if (just_resumed_running) {
    828       OnPostThreadResumed();
    829 
    830       // Try to setup the scheduler policy if it failed during startup. Only
    831       // attempt to do this on transitions from inactive to active to avoid
    832       // spamming the system with RPCs and log messages.
    833       if (!thread_policy_setup) {
    834         thread_policy_setup =
    835             SetThreadPolicy("graphics:high", "/system/performance");
    836       }
    837     }
    838 
    839     if (target_display_changed || just_resumed_running) {
    840       // Initialize the last vsync timestamp with the current time. The
    841       // predictor below uses this time + the vsync interval in absolute time
    842       // units for the initial delay. Once the driver starts reporting vsync the
    843       // predictor will sync up with the real vsync.
    844       last_vsync_timestamp_ = GetSystemClockNs();
    845       vsync_prediction_interval_ = 1;
    846       retire_fence_fds_.clear();
    847     }
    848 
    849     int64_t vsync_timestamp = 0;
    850     {
    851       TRACE_FORMAT("wait_vsync|vsync=%u;last_timestamp=%" PRId64
    852                    ";prediction_interval=%d|",
    853                    vsync_count_ + 1, last_vsync_timestamp_,
    854                    vsync_prediction_interval_);
    855 
    856       auto status = WaitForPredictedVSync();
    857       ALOGE_IF(
    858           !status,
    859           "HardwareComposer::PostThread: Failed to wait for vsync event: %s",
    860           status.GetErrorMessage().c_str());
    861 
    862       // If there was an error either sleeping was interrupted due to pausing or
    863       // there was an error getting the latest timestamp.
    864       if (!status)
    865         continue;
    866 
    867       // Predicted vsync timestamp for this interval. This is stable because we
    868       // use absolute time for the wakeup timer.
    869       vsync_timestamp = status.get();
    870     }
    871 
    872     vsync_trace_parity_ = !vsync_trace_parity_;
    873     ATRACE_INT(kVsyncTraceEventName, vsync_trace_parity_ ? 1 : 0);
    874 
    875     // Advance the vsync counter only if the system is keeping up with hardware
    876     // vsync to give clients an indication of the delays.
    877     if (vsync_prediction_interval_ == 1)
    878       ++vsync_count_;
    879 
    880     UpdateLayerConfig();
    881 
    882     // Publish the vsync event.
    883     if (vsync_ring_) {
    884       DvrVsync vsync;
    885       vsync.vsync_count = vsync_count_;
    886       vsync.vsync_timestamp_ns = vsync_timestamp;
    887       vsync.vsync_left_eye_offset_ns = vsync_eye_offsets.left_ns;
    888       vsync.vsync_right_eye_offset_ns = vsync_eye_offsets.right_ns;
    889       vsync.vsync_period_ns = target_display_->vsync_period_ns;
    890 
    891       vsync_ring_->Publish(vsync);
    892     }
    893 
    894     {
    895       // Sleep until shortly before vsync.
    896       ATRACE_NAME("sleep");
    897 
    898       const int64_t display_time_est_ns =
    899           vsync_timestamp + target_display_->vsync_period_ns;
    900       const int64_t now_ns = GetSystemClockNs();
    901       const int64_t sleep_time_ns = display_time_est_ns - now_ns -
    902                                     post_thread_config_.frame_post_offset_ns;
    903       const int64_t wakeup_time_ns =
    904           display_time_est_ns - post_thread_config_.frame_post_offset_ns;
    905 
    906       ATRACE_INT64("sleep_time_ns", sleep_time_ns);
    907       if (sleep_time_ns > 0) {
    908         int error = SleepUntil(wakeup_time_ns);
    909         ALOGE_IF(error < 0 && error != kPostThreadInterrupted,
    910                  "HardwareComposer::PostThread: Failed to sleep: %s",
    911                  strerror(-error));
    912         // If the sleep was interrupted (error == kPostThreadInterrupted),
    913         // we still go through and present this frame because we may have set
    914         // layers earlier and we want to flush the Composer's internal command
    915         // buffer by continuing through to validate and present.
    916       }
    917     }
    918 
    919     {
    920       auto status = composer_callback_->GetVsyncTime(target_display_->id);
    921 
    922       // If we failed to read vsync there might be a problem with the driver.
    923       // Since there's nothing we can do just behave as though we didn't get an
    924       // updated vsync time and let the prediction continue.
    925       const int64_t current_vsync_timestamp =
    926           status ? status.get() : last_vsync_timestamp_;
    927 
    928       const bool vsync_delayed =
    929           last_vsync_timestamp_ == current_vsync_timestamp;
    930       ATRACE_INT("vsync_delayed", vsync_delayed);
    931 
    932       // If vsync was delayed advance the prediction interval and allow the
    933       // fence logic in PostLayers() to skip the frame.
    934       if (vsync_delayed) {
    935         ALOGW(
    936             "HardwareComposer::PostThread: VSYNC timestamp did not advance "
    937             "since last frame: timestamp=%" PRId64 " prediction_interval=%d",
    938             current_vsync_timestamp, vsync_prediction_interval_);
    939         vsync_prediction_interval_++;
    940       } else {
    941         // We have an updated vsync timestamp, reset the prediction interval.
    942         last_vsync_timestamp_ = current_vsync_timestamp;
    943         vsync_prediction_interval_ = 1;
    944       }
    945     }
    946 
    947     PostLayers(target_display_->id);
    948   }
    949 }
    950 
    951 bool HardwareComposer::UpdateTargetDisplay() {
    952   bool target_display_changed = false;
    953   auto displays = composer_callback_->GetDisplays();
    954   if (displays.external_display_was_hotplugged) {
    955     bool was_using_external_display = !target_display_->is_primary;
    956     if (was_using_external_display) {
    957       // The external display was hotplugged, so make sure to ignore any bad
    958       // display errors as we destroy the layers.
    959       for (auto& layer: layers_)
    960         layer.IgnoreBadDisplayErrorsOnDestroy(true);
    961     }
    962 
    963     if (displays.external_display) {
    964       // External display was connected
    965       external_display_ = GetDisplayParams(composer_.get(),
    966           *displays.external_display, /*is_primary*/ false);
    967 
    968       if (property_get_bool(kUseExternalDisplayProperty, false)) {
    969         ALOGI("External display connected. Switching to external display.");
    970         target_display_ = &(*external_display_);
    971         target_display_changed = true;
    972       } else {
    973         ALOGI("External display connected, but sysprop %s is unset, so"
    974               " using primary display.", kUseExternalDisplayProperty);
    975         if (was_using_external_display) {
    976           target_display_ = &primary_display_;
    977           target_display_changed = true;
    978         }
    979       }
    980     } else {
    981       // External display was disconnected
    982       external_display_ = std::nullopt;
    983       if (was_using_external_display) {
    984         ALOGI("External display disconnected. Switching to primary display.");
    985         target_display_ = &primary_display_;
    986         target_display_changed = true;
    987       }
    988     }
    989   }
    990 
    991   if (target_display_changed) {
    992     // If we're switching to the external display, turn the primary display off.
    993     if (!target_display_->is_primary) {
    994       EnableDisplay(primary_display_, false);
    995     }
    996     // If we're switching to the primary display, and the external display is
    997     // still connected, turn the external display off.
    998     else if (target_display_->is_primary && external_display_) {
    999       EnableDisplay(*external_display_, false);
   1000     }
   1001 
   1002     // Turn the new target display on.
   1003     EnableDisplay(*target_display_, true);
   1004 
   1005     // When we switch displays we need to recreate all the layers, so clear the
   1006     // current list, which will trigger layer recreation.
   1007     layers_.clear();
   1008   }
   1009 
   1010   return target_display_changed;
   1011 }
   1012 
   1013 // Checks for changes in the surface stack and updates the layer config to
   1014 // accomodate the new stack.
   1015 void HardwareComposer::UpdateLayerConfig() {
   1016   std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces;
   1017   {
   1018     std::unique_lock<std::mutex> lock(post_thread_mutex_);
   1019 
   1020     if (!surfaces_changed_ && (!layers_.empty() || surfaces_.empty()))
   1021       return;
   1022 
   1023     surfaces = surfaces_;
   1024     surfaces_changed_ = false;
   1025   }
   1026 
   1027   ATRACE_NAME("UpdateLayerConfig_HwLayers");
   1028 
   1029   // Sort the new direct surface list by z-order to determine the relative order
   1030   // of the surfaces. This relative order is used for the HWC z-order value to
   1031   // insulate VrFlinger and HWC z-order semantics from each other.
   1032   std::sort(surfaces.begin(), surfaces.end(), [](const auto& a, const auto& b) {
   1033     return a->z_order() < b->z_order();
   1034   });
   1035 
   1036   // Prepare a new layer stack, pulling in layers from the previous
   1037   // layer stack that are still active and updating their attributes.
   1038   std::vector<Layer> layers;
   1039   size_t layer_index = 0;
   1040   for (const auto& surface : surfaces) {
   1041     // The bottom layer is opaque, other layers blend.
   1042     HWC::BlendMode blending =
   1043         layer_index == 0 ? HWC::BlendMode::None : HWC::BlendMode::Coverage;
   1044 
   1045     // Try to find a layer for this surface in the set of active layers.
   1046     auto search =
   1047         std::lower_bound(layers_.begin(), layers_.end(), surface->surface_id());
   1048     const bool found = search != layers_.end() &&
   1049                        search->GetSurfaceId() == surface->surface_id();
   1050     if (found) {
   1051       // Update the attributes of the layer that may have changed.
   1052       search->SetBlending(blending);
   1053       search->SetZOrder(layer_index);  // Relative z-order.
   1054 
   1055       // Move the existing layer to the new layer set and remove the empty layer
   1056       // object from the current set.
   1057       layers.push_back(std::move(*search));
   1058       layers_.erase(search);
   1059     } else {
   1060       // Insert a layer for the new surface.
   1061       layers.emplace_back(composer_.get(), *target_display_, surface, blending,
   1062           HWC::Composition::Device, layer_index);
   1063     }
   1064 
   1065     ALOGI_IF(
   1066         TRACE,
   1067         "HardwareComposer::UpdateLayerConfig: layer_index=%zu surface_id=%d",
   1068         layer_index, layers[layer_index].GetSurfaceId());
   1069 
   1070     layer_index++;
   1071   }
   1072 
   1073   // Sort the new layer stack by ascending surface id.
   1074   std::sort(layers.begin(), layers.end());
   1075 
   1076   // Replace the previous layer set with the new layer set. The destructor of
   1077   // the previous set will clean up the remaining Layers that are not moved to
   1078   // the new layer set.
   1079   layers_ = std::move(layers);
   1080 
   1081   ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers",
   1082            layers_.size());
   1083 }
   1084 
   1085 std::vector<sp<IVsyncCallback>>::const_iterator
   1086 HardwareComposer::VsyncService::FindCallback(
   1087     const sp<IVsyncCallback>& callback) const {
   1088   sp<IBinder> binder = IInterface::asBinder(callback);
   1089   return std::find_if(callbacks_.cbegin(), callbacks_.cend(),
   1090                       [&](const sp<IVsyncCallback>& callback) {
   1091                         return IInterface::asBinder(callback) == binder;
   1092                       });
   1093 }
   1094 
   1095 status_t HardwareComposer::VsyncService::registerCallback(
   1096     const sp<IVsyncCallback> callback) {
   1097   std::lock_guard<std::mutex> autolock(mutex_);
   1098   if (FindCallback(callback) == callbacks_.cend()) {
   1099     callbacks_.push_back(callback);
   1100   }
   1101   return OK;
   1102 }
   1103 
   1104 status_t HardwareComposer::VsyncService::unregisterCallback(
   1105     const sp<IVsyncCallback> callback) {
   1106   std::lock_guard<std::mutex> autolock(mutex_);
   1107   auto iter = FindCallback(callback);
   1108   if (iter != callbacks_.cend()) {
   1109     callbacks_.erase(iter);
   1110   }
   1111   return OK;
   1112 }
   1113 
   1114 void HardwareComposer::VsyncService::OnVsync(int64_t vsync_timestamp) {
   1115   ATRACE_NAME("VsyncService::OnVsync");
   1116   std::lock_guard<std::mutex> autolock(mutex_);
   1117   for (auto iter = callbacks_.begin(); iter != callbacks_.end();) {
   1118     if ((*iter)->onVsync(vsync_timestamp) == android::DEAD_OBJECT) {
   1119       iter = callbacks_.erase(iter);
   1120     } else {
   1121       ++iter;
   1122     }
   1123   }
   1124 }
   1125 
   1126 Return<void> HardwareComposer::ComposerCallback::onHotplug(
   1127     Hwc2::Display display, IComposerCallback::Connection conn) {
   1128   std::lock_guard<std::mutex> lock(mutex_);
   1129   ALOGI("onHotplug display=%" PRIu64 " conn=%d", display, conn);
   1130 
   1131   bool is_primary = !got_first_hotplug_ || display == primary_display_.id;
   1132 
   1133   // Our first onHotplug callback is always for the primary display.
   1134   if (!got_first_hotplug_) {
   1135     LOG_ALWAYS_FATAL_IF(conn != IComposerCallback::Connection::CONNECTED,
   1136         "Initial onHotplug callback should be primary display connected");
   1137     got_first_hotplug_ = true;
   1138   } else if (is_primary) {
   1139     ALOGE("Ignoring unexpected onHotplug() call for primary display");
   1140     return Void();
   1141   }
   1142 
   1143   if (conn == IComposerCallback::Connection::CONNECTED) {
   1144     if (!is_primary)
   1145       external_display_ = DisplayInfo();
   1146     DisplayInfo& display_info = is_primary ?
   1147         primary_display_ : *external_display_;
   1148     display_info.id = display;
   1149 
   1150     std::array<char, 1024> buffer;
   1151     snprintf(buffer.data(), buffer.size(),
   1152              "/sys/class/graphics/fb%" PRIu64 "/vsync_event", display);
   1153     if (LocalHandle handle{buffer.data(), O_RDONLY}) {
   1154       ALOGI(
   1155           "HardwareComposer::ComposerCallback::onHotplug: Driver supports "
   1156           "vsync_event node for display %" PRIu64,
   1157           display);
   1158       display_info.driver_vsync_event_fd = std::move(handle);
   1159     } else {
   1160       ALOGI(
   1161           "HardwareComposer::ComposerCallback::onHotplug: Driver does not "
   1162           "support vsync_event node for display %" PRIu64,
   1163           display);
   1164     }
   1165   } else if (conn == IComposerCallback::Connection::DISCONNECTED) {
   1166     external_display_ = std::nullopt;
   1167   }
   1168 
   1169   if (!is_primary)
   1170     external_display_was_hotplugged_ = true;
   1171 
   1172   return Void();
   1173 }
   1174 
   1175 Return<void> HardwareComposer::ComposerCallback::onRefresh(
   1176     Hwc2::Display /*display*/) {
   1177   return hardware::Void();
   1178 }
   1179 
   1180 Return<void> HardwareComposer::ComposerCallback::onVsync(Hwc2::Display display,
   1181                                                          int64_t timestamp) {
   1182   TRACE_FORMAT("vsync_callback|display=%" PRIu64 ";timestamp=%" PRId64 "|",
   1183                display, timestamp);
   1184   std::lock_guard<std::mutex> lock(mutex_);
   1185   DisplayInfo* display_info = GetDisplayInfo(display);
   1186   if (display_info) {
   1187     display_info->callback_vsync_timestamp = timestamp;
   1188   }
   1189   if (primary_display_.id == display && vsync_service_ != nullptr) {
   1190     vsync_service_->OnVsync(timestamp);
   1191   }
   1192 
   1193   return Void();
   1194 }
   1195 
   1196 void HardwareComposer::ComposerCallback::SetVsyncService(
   1197     const sp<VsyncService>& vsync_service) {
   1198   std::lock_guard<std::mutex> lock(mutex_);
   1199   vsync_service_ = vsync_service;
   1200 }
   1201 
   1202 HardwareComposer::ComposerCallback::Displays
   1203 HardwareComposer::ComposerCallback::GetDisplays() {
   1204   std::lock_guard<std::mutex> lock(mutex_);
   1205   Displays displays;
   1206   displays.primary_display = primary_display_.id;
   1207   if (external_display_)
   1208     displays.external_display = external_display_->id;
   1209   if (external_display_was_hotplugged_) {
   1210     external_display_was_hotplugged_ = false;
   1211     displays.external_display_was_hotplugged = true;
   1212   }
   1213   return displays;
   1214 }
   1215 
   1216 Status<int64_t> HardwareComposer::ComposerCallback::GetVsyncTime(
   1217     hwc2_display_t display) {
   1218   std::lock_guard<std::mutex> autolock(mutex_);
   1219   DisplayInfo* display_info = GetDisplayInfo(display);
   1220   if (!display_info) {
   1221     ALOGW("Attempt to get vsync time for unknown display %" PRIu64, display);
   1222     return ErrorStatus(EINVAL);
   1223   }
   1224 
   1225   // See if the driver supports direct vsync events.
   1226   LocalHandle& event_fd = display_info->driver_vsync_event_fd;
   1227   if (!event_fd) {
   1228     // Fall back to returning the last timestamp returned by the vsync
   1229     // callback.
   1230     return display_info->callback_vsync_timestamp;
   1231   }
   1232 
   1233   // When the driver supports the vsync_event sysfs node we can use it to
   1234   // determine the latest vsync timestamp, even if the HWC callback has been
   1235   // delayed.
   1236 
   1237   // The driver returns data in the form "VSYNC=<timestamp ns>".
   1238   std::array<char, 32> data;
   1239   data.fill('\0');
   1240 
   1241   // Seek back to the beginning of the event file.
   1242   int ret = lseek(event_fd.Get(), 0, SEEK_SET);
   1243   if (ret < 0) {
   1244     const int error = errno;
   1245     ALOGE(
   1246         "HardwareComposer::ComposerCallback::GetVsyncTime: Failed to seek "
   1247         "vsync event fd: %s",
   1248         strerror(error));
   1249     return ErrorStatus(error);
   1250   }
   1251 
   1252   // Read the vsync event timestamp.
   1253   ret = read(event_fd.Get(), data.data(), data.size());
   1254   if (ret < 0) {
   1255     const int error = errno;
   1256     ALOGE_IF(error != EAGAIN,
   1257              "HardwareComposer::ComposerCallback::GetVsyncTime: Error "
   1258              "while reading timestamp: %s",
   1259              strerror(error));
   1260     return ErrorStatus(error);
   1261   }
   1262 
   1263   int64_t timestamp;
   1264   ret = sscanf(data.data(), "VSYNC=%" PRIu64,
   1265                reinterpret_cast<uint64_t*>(&timestamp));
   1266   if (ret < 0) {
   1267     const int error = errno;
   1268     ALOGE(
   1269         "HardwareComposer::ComposerCallback::GetVsyncTime: Error while "
   1270         "parsing timestamp: %s",
   1271         strerror(error));
   1272     return ErrorStatus(error);
   1273   }
   1274 
   1275   return {timestamp};
   1276 }
   1277 
   1278 HardwareComposer::ComposerCallback::DisplayInfo*
   1279 HardwareComposer::ComposerCallback::GetDisplayInfo(hwc2_display_t display) {
   1280   if (display == primary_display_.id) {
   1281     return &primary_display_;
   1282   } else if (external_display_ && display == external_display_->id) {
   1283     return &(*external_display_);
   1284   }
   1285   return nullptr;
   1286 }
   1287 
   1288 void Layer::Reset() {
   1289   if (hardware_composer_layer_) {
   1290     HWC::Error error =
   1291         composer_->destroyLayer(display_params_.id, hardware_composer_layer_);
   1292     if (error != HWC::Error::None &&
   1293         (!ignore_bad_display_errors_on_destroy_ ||
   1294          error != HWC::Error::BadDisplay)) {
   1295       ALOGE("destroyLayer() failed for display %" PRIu64 ", layer %" PRIu64
   1296           ". error: %s", display_params_.id, hardware_composer_layer_,
   1297           error.to_string().c_str());
   1298     }
   1299     hardware_composer_layer_ = 0;
   1300   }
   1301 
   1302   z_order_ = 0;
   1303   blending_ = HWC::BlendMode::None;
   1304   composition_type_ = HWC::Composition::Invalid;
   1305   target_composition_type_ = composition_type_;
   1306   source_ = EmptyVariant{};
   1307   acquire_fence_.Close();
   1308   surface_rect_functions_applied_ = false;
   1309   pending_visibility_settings_ = true;
   1310   cached_buffer_map_.clear();
   1311   ignore_bad_display_errors_on_destroy_ = false;
   1312 }
   1313 
   1314 Layer::Layer(Hwc2::Composer* composer, const DisplayParams& display_params,
   1315              const std::shared_ptr<DirectDisplaySurface>& surface,
   1316              HWC::BlendMode blending, HWC::Composition composition_type,
   1317              size_t z_order)
   1318     : composer_(composer),
   1319       display_params_(display_params),
   1320       z_order_{z_order},
   1321       blending_{blending},
   1322       target_composition_type_{composition_type},
   1323       source_{SourceSurface{surface}} {
   1324   CommonLayerSetup();
   1325 }
   1326 
   1327 Layer::Layer(Hwc2::Composer* composer, const DisplayParams& display_params,
   1328              const std::shared_ptr<IonBuffer>& buffer, HWC::BlendMode blending,
   1329              HWC::Composition composition_type, size_t z_order)
   1330     : composer_(composer),
   1331       display_params_(display_params),
   1332       z_order_{z_order},
   1333       blending_{blending},
   1334       target_composition_type_{composition_type},
   1335       source_{SourceBuffer{buffer}} {
   1336   CommonLayerSetup();
   1337 }
   1338 
   1339 Layer::~Layer() { Reset(); }
   1340 
   1341 Layer::Layer(Layer&& other) noexcept { *this = std::move(other); }
   1342 
   1343 Layer& Layer::operator=(Layer&& other) noexcept {
   1344   if (this != &other) {
   1345     Reset();
   1346     using std::swap;
   1347     swap(composer_, other.composer_);
   1348     swap(display_params_, other.display_params_);
   1349     swap(hardware_composer_layer_, other.hardware_composer_layer_);
   1350     swap(z_order_, other.z_order_);
   1351     swap(blending_, other.blending_);
   1352     swap(composition_type_, other.composition_type_);
   1353     swap(target_composition_type_, other.target_composition_type_);
   1354     swap(source_, other.source_);
   1355     swap(acquire_fence_, other.acquire_fence_);
   1356     swap(surface_rect_functions_applied_,
   1357          other.surface_rect_functions_applied_);
   1358     swap(pending_visibility_settings_, other.pending_visibility_settings_);
   1359     swap(cached_buffer_map_, other.cached_buffer_map_);
   1360     swap(ignore_bad_display_errors_on_destroy_,
   1361          other.ignore_bad_display_errors_on_destroy_);
   1362   }
   1363   return *this;
   1364 }
   1365 
   1366 void Layer::UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer) {
   1367   if (source_.is<SourceBuffer>())
   1368     std::get<SourceBuffer>(source_) = {buffer};
   1369 }
   1370 
   1371 void Layer::SetBlending(HWC::BlendMode blending) {
   1372   if (blending_ != blending) {
   1373     blending_ = blending;
   1374     pending_visibility_settings_ = true;
   1375   }
   1376 }
   1377 
   1378 void Layer::SetZOrder(size_t z_order) {
   1379   if (z_order_ != z_order) {
   1380     z_order_ = z_order;
   1381     pending_visibility_settings_ = true;
   1382   }
   1383 }
   1384 
   1385 IonBuffer* Layer::GetBuffer() {
   1386   struct Visitor {
   1387     IonBuffer* operator()(SourceSurface& source) { return source.GetBuffer(); }
   1388     IonBuffer* operator()(SourceBuffer& source) { return source.GetBuffer(); }
   1389     IonBuffer* operator()(EmptyVariant) { return nullptr; }
   1390   };
   1391   return source_.Visit(Visitor{});
   1392 }
   1393 
   1394 void Layer::UpdateVisibilitySettings() {
   1395   if (pending_visibility_settings_) {
   1396     pending_visibility_settings_ = false;
   1397 
   1398     HWC::Error error;
   1399 
   1400     error = composer_->setLayerBlendMode(
   1401         display_params_.id, hardware_composer_layer_,
   1402         blending_.cast<Hwc2::IComposerClient::BlendMode>());
   1403     ALOGE_IF(error != HWC::Error::None,
   1404              "Layer::UpdateLayerSettings: Error setting layer blend mode: %s",
   1405              error.to_string().c_str());
   1406 
   1407     error = composer_->setLayerZOrder(display_params_.id,
   1408         hardware_composer_layer_, z_order_);
   1409     ALOGE_IF(error != HWC::Error::None,
   1410              "Layer::UpdateLayerSettings: Error setting z_ order: %s",
   1411              error.to_string().c_str());
   1412   }
   1413 }
   1414 
   1415 void Layer::UpdateLayerSettings() {
   1416   HWC::Error error;
   1417 
   1418   UpdateVisibilitySettings();
   1419 
   1420   // TODO(eieio): Use surface attributes or some other mechanism to control
   1421   // the layer display frame.
   1422   error = composer_->setLayerDisplayFrame(
   1423       display_params_.id, hardware_composer_layer_,
   1424       {0, 0, display_params_.width, display_params_.height});
   1425   ALOGE_IF(error != HWC::Error::None,
   1426            "Layer::UpdateLayerSettings: Error setting layer display frame: %s",
   1427            error.to_string().c_str());
   1428 
   1429   error = composer_->setLayerVisibleRegion(
   1430       display_params_.id, hardware_composer_layer_,
   1431       {{0, 0, display_params_.width, display_params_.height}});
   1432   ALOGE_IF(error != HWC::Error::None,
   1433            "Layer::UpdateLayerSettings: Error setting layer visible region: %s",
   1434            error.to_string().c_str());
   1435 
   1436   error = composer_->setLayerPlaneAlpha(display_params_.id,
   1437       hardware_composer_layer_, 1.0f);
   1438   ALOGE_IF(error != HWC::Error::None,
   1439            "Layer::UpdateLayerSettings: Error setting layer plane alpha: %s",
   1440            error.to_string().c_str());
   1441 }
   1442 
   1443 void Layer::CommonLayerSetup() {
   1444   HWC::Error error = composer_->createLayer(display_params_.id,
   1445                                             &hardware_composer_layer_);
   1446   ALOGE_IF(error != HWC::Error::None,
   1447            "Layer::CommonLayerSetup: Failed to create layer on primary "
   1448            "display: %s",
   1449            error.to_string().c_str());
   1450   UpdateLayerSettings();
   1451 }
   1452 
   1453 bool Layer::CheckAndUpdateCachedBuffer(std::size_t slot, int buffer_id) {
   1454   auto search = cached_buffer_map_.find(slot);
   1455   if (search != cached_buffer_map_.end() && search->second == buffer_id)
   1456     return true;
   1457 
   1458   // Assign or update the buffer slot.
   1459   if (buffer_id >= 0)
   1460     cached_buffer_map_[slot] = buffer_id;
   1461   return false;
   1462 }
   1463 
   1464 void Layer::Prepare() {
   1465   int right, bottom, id;
   1466   sp<GraphicBuffer> handle;
   1467   std::size_t slot;
   1468 
   1469   // Acquire the next buffer according to the type of source.
   1470   IfAnyOf<SourceSurface, SourceBuffer>::Call(&source_, [&](auto& source) {
   1471     std::tie(right, bottom, id, handle, acquire_fence_, slot) =
   1472         source.Acquire();
   1473   });
   1474 
   1475   TRACE_FORMAT("Layer::Prepare|buffer_id=%d;slot=%zu|", id, slot);
   1476 
   1477   // Update any visibility (blending, z-order) changes that occurred since
   1478   // last prepare.
   1479   UpdateVisibilitySettings();
   1480 
   1481   // When a layer is first setup there may be some time before the first
   1482   // buffer arrives. Setup the HWC layer as a solid color to stall for time
   1483   // until the first buffer arrives. Once the first buffer arrives there will
   1484   // always be a buffer for the frame even if it is old.
   1485   if (!handle.get()) {
   1486     if (composition_type_ == HWC::Composition::Invalid) {
   1487       composition_type_ = HWC::Composition::SolidColor;
   1488       composer_->setLayerCompositionType(
   1489           display_params_.id, hardware_composer_layer_,
   1490           composition_type_.cast<Hwc2::IComposerClient::Composition>());
   1491       Hwc2::IComposerClient::Color layer_color = {0, 0, 0, 0};
   1492       composer_->setLayerColor(display_params_.id, hardware_composer_layer_,
   1493                                layer_color);
   1494     } else {
   1495       // The composition type is already set. Nothing else to do until a
   1496       // buffer arrives.
   1497     }
   1498   } else {
   1499     if (composition_type_ != target_composition_type_) {
   1500       composition_type_ = target_composition_type_;
   1501       composer_->setLayerCompositionType(
   1502           display_params_.id, hardware_composer_layer_,
   1503           composition_type_.cast<Hwc2::IComposerClient::Composition>());
   1504     }
   1505 
   1506     // See if the HWC cache already has this buffer.
   1507     const bool cached = CheckAndUpdateCachedBuffer(slot, id);
   1508     if (cached)
   1509       handle = nullptr;
   1510 
   1511     HWC::Error error{HWC::Error::None};
   1512     error =
   1513         composer_->setLayerBuffer(display_params_.id, hardware_composer_layer_,
   1514                                   slot, handle, acquire_fence_.Get());
   1515 
   1516     ALOGE_IF(error != HWC::Error::None,
   1517              "Layer::Prepare: Error setting layer buffer: %s",
   1518              error.to_string().c_str());
   1519 
   1520     if (!surface_rect_functions_applied_) {
   1521       const float float_right = right;
   1522       const float float_bottom = bottom;
   1523       error = composer_->setLayerSourceCrop(display_params_.id,
   1524                                             hardware_composer_layer_,
   1525                                             {0, 0, float_right, float_bottom});
   1526 
   1527       ALOGE_IF(error != HWC::Error::None,
   1528                "Layer::Prepare: Error setting layer source crop: %s",
   1529                error.to_string().c_str());
   1530 
   1531       surface_rect_functions_applied_ = true;
   1532     }
   1533   }
   1534 }
   1535 
   1536 void Layer::Finish(int release_fence_fd) {
   1537   IfAnyOf<SourceSurface, SourceBuffer>::Call(
   1538       &source_, [release_fence_fd](auto& source) {
   1539         source.Finish(LocalHandle(release_fence_fd));
   1540       });
   1541 }
   1542 
   1543 void Layer::Drop() { acquire_fence_.Close(); }
   1544 
   1545 }  // namespace dvr
   1546 }  // namespace android
   1547