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