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 <sync/sync.h>
9#include <sys/eventfd.h>
10#include <sys/prctl.h>
11#include <sys/resource.h>
12#include <sys/system_properties.h>
13#include <sys/timerfd.h>
14#include <time.h>
15#include <unistd.h>
16#include <utils/Trace.h>
17
18#include <algorithm>
19#include <chrono>
20#include <functional>
21#include <map>
22
23#include <dvr/dvr_display_types.h>
24#include <dvr/performance_client_api.h>
25#include <private/dvr/clock_ns.h>
26#include <private/dvr/ion_buffer.h>
27#include <private/dvr/pose_client_internal.h>
28
29using android::pdx::LocalHandle;
30using android::pdx::rpc::EmptyVariant;
31using android::pdx::rpc::IfAnyOf;
32
33using namespace std::chrono_literals;
34
35namespace android {
36namespace dvr {
37
38namespace {
39
40// If the number of pending fences goes over this count at the point when we
41// are about to submit a new frame to HWC, we will drop the frame. This should
42// be a signal that the display driver has begun queuing frames. Note that with
43// smart displays (with RAM), the fence is signaled earlier than the next vsync,
44// at the point when the DMA to the display completes. Currently we use a smart
45// display and the EDS timing coincides with zero pending fences, so this is 0.
46constexpr int kAllowedPendingFenceCount = 0;
47
48// Offset before vsync to submit frames to hardware composer.
49constexpr int64_t kFramePostOffsetNs = 4000000;  // 4ms
50
51const char kBacklightBrightnessSysFile[] =
52    "/sys/class/leds/lcd-backlight/brightness";
53
54const char kPrimaryDisplayVSyncEventFile[] =
55    "/sys/class/graphics/fb0/vsync_event";
56
57const char kPrimaryDisplayWaitPPEventFile[] = "/sys/class/graphics/fb0/wait_pp";
58
59const char kDvrPerformanceProperty[] = "sys.dvr.performance";
60
61const char kRightEyeOffsetProperty[] = "dvr.right_eye_offset_ns";
62
63// Get time offset from a vsync to when the pose for that vsync should be
64// predicted out to. For example, if scanout gets halfway through the frame
65// at the halfway point between vsyncs, then this could be half the period.
66// With global shutter displays, this should be changed to the offset to when
67// illumination begins. Low persistence adds a frame of latency, so we predict
68// to the center of the next frame.
69inline int64_t GetPosePredictionTimeOffset(int64_t vsync_period_ns) {
70  return (vsync_period_ns * 150) / 100;
71}
72
73// Attempts to set the scheduler class and partiton for the current thread.
74// Returns true on success or false on failure.
75bool SetThreadPolicy(const std::string& scheduler_class,
76                     const std::string& partition) {
77  int error = dvrSetSchedulerClass(0, scheduler_class.c_str());
78  if (error < 0) {
79    ALOGE(
80        "SetThreadPolicy: Failed to set scheduler class \"%s\" for "
81        "thread_id=%d: %s",
82        scheduler_class.c_str(), gettid(), strerror(-error));
83    return false;
84  }
85  error = dvrSetCpuPartition(0, partition.c_str());
86  if (error < 0) {
87    ALOGE(
88        "SetThreadPolicy: Failed to set cpu partiton \"%s\" for thread_id=%d: "
89        "%s",
90        partition.c_str(), gettid(), strerror(-error));
91    return false;
92  }
93  return true;
94}
95
96}  // anonymous namespace
97
98// Layer static data.
99Hwc2::Composer* Layer::hwc2_hidl_;
100const HWCDisplayMetrics* Layer::display_metrics_;
101
102// HardwareComposer static data;
103constexpr size_t HardwareComposer::kMaxHardwareLayers;
104
105HardwareComposer::HardwareComposer()
106    : HardwareComposer(nullptr, RequestDisplayCallback()) {}
107
108HardwareComposer::HardwareComposer(
109    Hwc2::Composer* hwc2_hidl, RequestDisplayCallback request_display_callback)
110    : initialized_(false),
111      hwc2_hidl_(hwc2_hidl),
112      request_display_callback_(request_display_callback),
113      callbacks_(new ComposerCallback) {}
114
115HardwareComposer::~HardwareComposer(void) {
116  UpdatePostThreadState(PostThreadState::Quit, true);
117  if (post_thread_.joinable())
118    post_thread_.join();
119}
120
121bool HardwareComposer::Initialize() {
122  if (initialized_) {
123    ALOGE("HardwareComposer::Initialize: already initialized.");
124    return false;
125  }
126
127  HWC::Error error = HWC::Error::None;
128
129  Hwc2::Config config;
130  error = hwc2_hidl_->getActiveConfig(HWC_DISPLAY_PRIMARY, &config);
131
132  if (error != HWC::Error::None) {
133    ALOGE("HardwareComposer: Failed to get current display config : %d",
134          config);
135    return false;
136  }
137
138  error =
139      GetDisplayMetrics(HWC_DISPLAY_PRIMARY, config, &native_display_metrics_);
140
141  if (error != HWC::Error::None) {
142    ALOGE(
143        "HardwareComposer: Failed to get display attributes for current "
144        "configuration : %d",
145        error.value);
146    return false;
147  }
148
149  ALOGI(
150      "HardwareComposer: primary display attributes: width=%d height=%d "
151      "vsync_period_ns=%d DPI=%dx%d",
152      native_display_metrics_.width, native_display_metrics_.height,
153      native_display_metrics_.vsync_period_ns, native_display_metrics_.dpi.x,
154      native_display_metrics_.dpi.y);
155
156  // Set the display metrics but never use rotation to avoid the long latency of
157  // rotation processing in hwc.
158  display_transform_ = HWC_TRANSFORM_NONE;
159  display_metrics_ = native_display_metrics_;
160
161  // Pass hwc instance and metrics to setup globals for Layer.
162  Layer::InitializeGlobals(hwc2_hidl_, &native_display_metrics_);
163
164  post_thread_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
165  LOG_ALWAYS_FATAL_IF(
166      !post_thread_event_fd_,
167      "HardwareComposer: Failed to create interrupt event fd : %s",
168      strerror(errno));
169
170  post_thread_ = std::thread(&HardwareComposer::PostThread, this);
171
172  initialized_ = true;
173
174  return initialized_;
175}
176
177void HardwareComposer::Enable() {
178  UpdatePostThreadState(PostThreadState::Suspended, false);
179}
180
181void HardwareComposer::Disable() {
182  UpdatePostThreadState(PostThreadState::Suspended, true);
183}
184
185// Update the post thread quiescent state based on idle and suspended inputs.
186void HardwareComposer::UpdatePostThreadState(PostThreadStateType state,
187                                             bool suspend) {
188  std::unique_lock<std::mutex> lock(post_thread_mutex_);
189
190  // Update the votes in the state variable before evaluating the effective
191  // quiescent state. Any bits set in post_thread_state_ indicate that the post
192  // thread should be suspended.
193  if (suspend) {
194    post_thread_state_ |= state;
195  } else {
196    post_thread_state_ &= ~state;
197  }
198
199  const bool quit = post_thread_state_ & PostThreadState::Quit;
200  const bool effective_suspend = post_thread_state_ != PostThreadState::Active;
201  if (quit) {
202    post_thread_quiescent_ = true;
203    eventfd_write(post_thread_event_fd_.Get(), 1);
204    post_thread_wait_.notify_one();
205  } else if (effective_suspend && !post_thread_quiescent_) {
206    post_thread_quiescent_ = true;
207    eventfd_write(post_thread_event_fd_.Get(), 1);
208  } else if (!effective_suspend && post_thread_quiescent_) {
209    post_thread_quiescent_ = false;
210    eventfd_t value;
211    eventfd_read(post_thread_event_fd_.Get(), &value);
212    post_thread_wait_.notify_one();
213  }
214
215  // Wait until the post thread is in the requested state.
216  post_thread_ready_.wait(lock, [this, effective_suspend] {
217    return effective_suspend != post_thread_resumed_;
218  });
219}
220
221void HardwareComposer::OnPostThreadResumed() {
222  hwc2_hidl_->resetCommands();
223
224  // Connect to pose service.
225  pose_client_ = dvrPoseCreate();
226  ALOGE_IF(!pose_client_, "HardwareComposer: Failed to create pose client");
227
228  // HIDL HWC seems to have an internal race condition. If we submit a frame too
229  // soon after turning on VSync we don't get any VSync signals. Give poor HWC
230  // implementations a chance to enable VSync before we continue.
231  EnableVsync(false);
232  std::this_thread::sleep_for(100ms);
233  EnableVsync(true);
234  std::this_thread::sleep_for(100ms);
235
236  // TODO(skiazyk): We need to do something about accessing this directly,
237  // supposedly there is a backlight service on the way.
238  // TODO(steventhomas): When we change the backlight setting, will surface
239  // flinger (or something else) set it back to its original value once we give
240  // control of the display back to surface flinger?
241  SetBacklightBrightness(255);
242
243  // Trigger target-specific performance mode change.
244  property_set(kDvrPerformanceProperty, "performance");
245}
246
247void HardwareComposer::OnPostThreadPaused() {
248  retire_fence_fds_.clear();
249  display_surfaces_.clear();
250
251  for (size_t i = 0; i < kMaxHardwareLayers; ++i) {
252    layers_[i].Reset();
253  }
254  active_layer_count_ = 0;
255
256  if (pose_client_) {
257    dvrPoseDestroy(pose_client_);
258    pose_client_ = nullptr;
259  }
260
261  EnableVsync(false);
262
263  hwc2_hidl_->resetCommands();
264
265  // Trigger target-specific performance mode change.
266  property_set(kDvrPerformanceProperty, "idle");
267}
268
269HWC::Error HardwareComposer::Validate(hwc2_display_t display) {
270  uint32_t num_types;
271  uint32_t num_requests;
272  HWC::Error error =
273      hwc2_hidl_->validateDisplay(display, &num_types, &num_requests);
274
275  if (error == HWC2_ERROR_HAS_CHANGES) {
276    // TODO(skiazyk): We might need to inspect the requested changes first, but
277    // so far it seems like we shouldn't ever hit a bad state.
278    // error = hwc2_funcs_.accept_display_changes_fn_(hardware_composer_device_,
279    //                                               display);
280    error = hwc2_hidl_->acceptDisplayChanges(display);
281  }
282
283  return error;
284}
285
286int32_t HardwareComposer::EnableVsync(bool enabled) {
287  return (int32_t)hwc2_hidl_->setVsyncEnabled(
288      HWC_DISPLAY_PRIMARY,
289      (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE
290                                             : HWC2_VSYNC_DISABLE));
291}
292
293HWC::Error HardwareComposer::Present(hwc2_display_t display) {
294  int32_t present_fence;
295  HWC::Error error = hwc2_hidl_->presentDisplay(display, &present_fence);
296
297  // According to the documentation, this fence is signaled at the time of
298  // vsync/DMA for physical displays.
299  if (error == HWC::Error::None) {
300    ATRACE_INT("HardwareComposer: VsyncFence", present_fence);
301    retire_fence_fds_.emplace_back(present_fence);
302  } else {
303    ATRACE_INT("HardwareComposer: PresentResult", error);
304  }
305
306  return error;
307}
308
309HWC::Error HardwareComposer::GetDisplayAttribute(hwc2_display_t display,
310                                                 hwc2_config_t config,
311                                                 hwc2_attribute_t attribute,
312                                                 int32_t* out_value) const {
313  return hwc2_hidl_->getDisplayAttribute(
314      display, config, (Hwc2::IComposerClient::Attribute)attribute, out_value);
315}
316
317HWC::Error HardwareComposer::GetDisplayMetrics(
318    hwc2_display_t display, hwc2_config_t config,
319    HWCDisplayMetrics* out_metrics) const {
320  HWC::Error error;
321
322  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_WIDTH,
323                              &out_metrics->width);
324  if (error != HWC::Error::None) {
325    ALOGE(
326        "HardwareComposer::GetDisplayMetrics: Failed to get display width: %s",
327        error.to_string().c_str());
328    return error;
329  }
330
331  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_HEIGHT,
332                              &out_metrics->height);
333  if (error != HWC::Error::None) {
334    ALOGE(
335        "HardwareComposer::GetDisplayMetrics: Failed to get display height: %s",
336        error.to_string().c_str());
337    return error;
338  }
339
340  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_VSYNC_PERIOD,
341                              &out_metrics->vsync_period_ns);
342  if (error != HWC::Error::None) {
343    ALOGE(
344        "HardwareComposer::GetDisplayMetrics: Failed to get display height: %s",
345        error.to_string().c_str());
346    return error;
347  }
348
349  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_X,
350                              &out_metrics->dpi.x);
351  if (error != HWC::Error::None) {
352    ALOGE(
353        "HardwareComposer::GetDisplayMetrics: Failed to get display DPI X: %s",
354        error.to_string().c_str());
355    return error;
356  }
357
358  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_Y,
359                              &out_metrics->dpi.y);
360  if (error != HWC::Error::None) {
361    ALOGE(
362        "HardwareComposer::GetDisplayMetrics: Failed to get display DPI Y: %s",
363        error.to_string().c_str());
364    return error;
365  }
366
367  return HWC::Error::None;
368}
369
370std::string HardwareComposer::Dump() { return hwc2_hidl_->dumpDebugInfo(); }
371
372void HardwareComposer::PostLayers() {
373  ATRACE_NAME("HardwareComposer::PostLayers");
374
375  // Setup the hardware composer layers with current buffers.
376  for (size_t i = 0; i < active_layer_count_; i++) {
377    layers_[i].Prepare();
378  }
379
380  HWC::Error error = Validate(HWC_DISPLAY_PRIMARY);
381  if (error != HWC::Error::None) {
382    ALOGE("HardwareComposer::PostLayers: Validate failed: %s",
383          error.to_string().c_str());
384    return;
385  }
386
387  // Now that we have taken in a frame from the application, we have a chance
388  // to drop the frame before passing the frame along to HWC.
389  // If the display driver has become backed up, we detect it here and then
390  // react by skipping this frame to catch up latency.
391  while (!retire_fence_fds_.empty() &&
392         (!retire_fence_fds_.front() ||
393          sync_wait(retire_fence_fds_.front().Get(), 0) == 0)) {
394    // There are only 2 fences in here, no performance problem to shift the
395    // array of ints.
396    retire_fence_fds_.erase(retire_fence_fds_.begin());
397  }
398
399  const bool is_frame_pending = IsFramePendingInDriver();
400  const bool is_fence_pending =
401      retire_fence_fds_.size() > kAllowedPendingFenceCount;
402
403  if (is_fence_pending || is_frame_pending) {
404    ATRACE_INT("frame_skip_count", ++frame_skip_count_);
405
406    ALOGW_IF(is_frame_pending, "Warning: frame already queued, dropping frame");
407    ALOGW_IF(is_fence_pending,
408             "Warning: dropping a frame to catch up with HWC (pending = %zd)",
409             retire_fence_fds_.size());
410
411    for (size_t i = 0; i < active_layer_count_; i++) {
412      layers_[i].Drop();
413    }
414    return;
415  } else {
416    // Make the transition more obvious in systrace when the frame skip happens
417    // above.
418    ATRACE_INT("frame_skip_count", 0);
419  }
420
421#if TRACE
422  for (size_t i = 0; i < active_layer_count_; i++)
423    ALOGI("HardwareComposer::PostLayers: layer=%zu composition=%s", i,
424          layers_[i].GetCompositionType().to_string().c_str());
425#endif
426
427  error = Present(HWC_DISPLAY_PRIMARY);
428  if (error != HWC::Error::None) {
429    ALOGE("HardwareComposer::PostLayers: Present failed: %s",
430          error.to_string().c_str());
431    return;
432  }
433
434  std::vector<Hwc2::Layer> out_layers;
435  std::vector<int> out_fences;
436  error = hwc2_hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers,
437                                       &out_fences);
438  ALOGE_IF(error != HWC::Error::None,
439           "HardwareComposer::PostLayers: Failed to get release fences: %s",
440           error.to_string().c_str());
441
442  // Perform post-frame bookkeeping. Unused layers are a no-op.
443  uint32_t num_elements = out_layers.size();
444  for (size_t i = 0; i < num_elements; ++i) {
445    for (size_t j = 0; j < active_layer_count_; ++j) {
446      if (layers_[j].GetLayerHandle() == out_layers[i]) {
447        layers_[j].Finish(out_fences[i]);
448      }
449    }
450  }
451}
452
453void HardwareComposer::SetDisplaySurfaces(
454    std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces) {
455  ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd",
456        surfaces.size());
457  const bool display_idle = surfaces.size() == 0;
458  {
459    std::unique_lock<std::mutex> lock(post_thread_mutex_);
460    pending_surfaces_ = std::move(surfaces);
461  }
462
463  // Set idle state based on whether there are any surfaces to handle.
464  UpdatePostThreadState(PostThreadState::Idle, display_idle);
465
466  // XXX: TEMPORARY
467  // Request control of the display based on whether there are any surfaces to
468  // handle. This callback sets the post thread active state once the transition
469  // is complete in SurfaceFlinger.
470  // TODO(eieio): Unify the control signal used to move SurfaceFlinger into VR
471  // mode. Currently this is hooked up to persistent VR mode, but perhaps this
472  // makes more sense to control it from VrCore, which could in turn base its
473  // decision on persistent VR mode.
474  if (request_display_callback_)
475    request_display_callback_(!display_idle);
476}
477
478int HardwareComposer::PostThreadPollInterruptible(
479    const pdx::LocalHandle& event_fd, int requested_events) {
480  pollfd pfd[2] = {
481      {
482          .fd = event_fd.Get(),
483          .events = static_cast<short>(requested_events),
484          .revents = 0,
485      },
486      {
487          .fd = post_thread_event_fd_.Get(),
488          .events = POLLPRI | POLLIN,
489          .revents = 0,
490      },
491  };
492  int ret, error;
493  do {
494    ret = poll(pfd, 2, -1);
495    error = errno;
496    ALOGW_IF(ret < 0,
497             "HardwareComposer::PostThreadPollInterruptible: Error during "
498             "poll(): %s (%d)",
499             strerror(error), error);
500  } while (ret < 0 && error == EINTR);
501
502  if (ret < 0) {
503    return -error;
504  } else if (pfd[0].revents != 0) {
505    return 0;
506  } else if (pfd[1].revents != 0) {
507    ALOGI("VrHwcPost thread interrupted");
508    return kPostThreadInterrupted;
509  } else {
510    return 0;
511  }
512}
513
514// Reads the value of the display driver wait_pingpong state. Returns 0 or 1
515// (the value of the state) on success or a negative error otherwise.
516// TODO(eieio): This is pretty driver specific, this should be moved to a
517// separate class eventually.
518int HardwareComposer::ReadWaitPPState() {
519  // Gracefully handle when the kernel does not support this feature.
520  if (!primary_display_wait_pp_fd_)
521    return 0;
522
523  const int wait_pp_fd = primary_display_wait_pp_fd_.Get();
524  int ret, error;
525
526  ret = lseek(wait_pp_fd, 0, SEEK_SET);
527  if (ret < 0) {
528    error = errno;
529    ALOGE("HardwareComposer::ReadWaitPPState: Failed to seek wait_pp fd: %s",
530          strerror(error));
531    return -error;
532  }
533
534  char data = -1;
535  ret = read(wait_pp_fd, &data, sizeof(data));
536  if (ret < 0) {
537    error = errno;
538    ALOGE("HardwareComposer::ReadWaitPPState: Failed to read wait_pp state: %s",
539          strerror(error));
540    return -error;
541  }
542
543  switch (data) {
544    case '0':
545      return 0;
546    case '1':
547      return 1;
548    default:
549      ALOGE(
550          "HardwareComposer::ReadWaitPPState: Unexpected value for wait_pp: %d",
551          data);
552      return -EINVAL;
553  }
554}
555
556// Reads the timestamp of the last vsync from the display driver.
557// TODO(eieio): This is pretty driver specific, this should be moved to a
558// separate class eventually.
559int HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) {
560  const int event_fd = primary_display_vsync_event_fd_.Get();
561  int ret, error;
562
563  // The driver returns data in the form "VSYNC=<timestamp ns>".
564  std::array<char, 32> data;
565  data.fill('\0');
566
567  // Seek back to the beginning of the event file.
568  ret = lseek(event_fd, 0, SEEK_SET);
569  if (ret < 0) {
570    error = errno;
571    ALOGE(
572        "HardwareComposer::ReadVSyncTimestamp: Failed to seek vsync event fd: "
573        "%s",
574        strerror(error));
575    return -error;
576  }
577
578  // Read the vsync event timestamp.
579  ret = read(event_fd, data.data(), data.size());
580  if (ret < 0) {
581    error = errno;
582    ALOGE_IF(
583        error != EAGAIN,
584        "HardwareComposer::ReadVSyncTimestamp: Error while reading timestamp: "
585        "%s",
586        strerror(error));
587    return -error;
588  }
589
590  ret = sscanf(data.data(), "VSYNC=%" PRIu64,
591               reinterpret_cast<uint64_t*>(timestamp));
592  if (ret < 0) {
593    error = errno;
594    ALOGE(
595        "HardwareComposer::ReadVSyncTimestamp: Error while parsing timestamp: "
596        "%s",
597        strerror(error));
598    return -error;
599  }
600
601  return 0;
602}
603
604// Blocks until the next vsync event is signaled by the display driver.
605// TODO(eieio): This is pretty driver specific, this should be moved to a
606// separate class eventually.
607int HardwareComposer::BlockUntilVSync() {
608  // Vsync is signaled by POLLPRI on the fb vsync node.
609  return PostThreadPollInterruptible(primary_display_vsync_event_fd_, POLLPRI);
610}
611
612// Waits for the next vsync and returns the timestamp of the vsync event. If
613// vsync already passed since the last call, returns the latest vsync timestamp
614// instead of blocking. This method updates the last_vsync_timeout_ in the
615// process.
616//
617// TODO(eieio): This is pretty driver specific, this should be moved to a
618// separate class eventually.
619int HardwareComposer::WaitForVSync(int64_t* timestamp) {
620  int error;
621
622  // Get the current timestamp and decide what to do.
623  while (true) {
624    int64_t current_vsync_timestamp;
625    error = ReadVSyncTimestamp(&current_vsync_timestamp);
626    if (error < 0 && error != -EAGAIN)
627      return error;
628
629    if (error == -EAGAIN) {
630      // Vsync was turned off, wait for the next vsync event.
631      error = BlockUntilVSync();
632      if (error < 0 || error == kPostThreadInterrupted)
633        return error;
634
635      // Try again to get the timestamp for this new vsync interval.
636      continue;
637    }
638
639    // Check that we advanced to a later vsync interval.
640    if (TimestampGT(current_vsync_timestamp, last_vsync_timestamp_)) {
641      *timestamp = last_vsync_timestamp_ = current_vsync_timestamp;
642      return 0;
643    }
644
645    // See how close we are to the next expected vsync. If we're within 1ms,
646    // sleep for 1ms and try again.
647    const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
648    const int64_t threshold_ns = 1000000;  // 1ms
649
650    const int64_t next_vsync_est = last_vsync_timestamp_ + ns_per_frame;
651    const int64_t distance_to_vsync_est = next_vsync_est - GetSystemClockNs();
652
653    if (distance_to_vsync_est > threshold_ns) {
654      // Wait for vsync event notification.
655      error = BlockUntilVSync();
656      if (error < 0 || error == kPostThreadInterrupted)
657        return error;
658    } else {
659      // Sleep for a short time (1 millisecond) before retrying.
660      error = SleepUntil(GetSystemClockNs() + threshold_ns);
661      if (error < 0 || error == kPostThreadInterrupted)
662        return error;
663    }
664  }
665}
666
667int HardwareComposer::SleepUntil(int64_t wakeup_timestamp) {
668  const int timer_fd = vsync_sleep_timer_fd_.Get();
669  const itimerspec wakeup_itimerspec = {
670      .it_interval = {.tv_sec = 0, .tv_nsec = 0},
671      .it_value = NsToTimespec(wakeup_timestamp),
672  };
673  int ret =
674      timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &wakeup_itimerspec, nullptr);
675  int error = errno;
676  if (ret < 0) {
677    ALOGE("HardwareComposer::SleepUntil: Failed to set timerfd: %s",
678          strerror(error));
679    return -error;
680  }
681
682  return PostThreadPollInterruptible(vsync_sleep_timer_fd_, POLLIN);
683}
684
685void HardwareComposer::PostThread() {
686  // NOLINTNEXTLINE(runtime/int)
687  prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrHwcPost"), 0, 0, 0);
688
689  // Set the scheduler to SCHED_FIFO with high priority. If this fails here
690  // there may have been a startup timing issue between this thread and
691  // performanced. Try again later when this thread becomes active.
692  bool thread_policy_setup =
693      SetThreadPolicy("graphics:high", "/system/performance");
694
695#if ENABLE_BACKLIGHT_BRIGHTNESS
696  // TODO(hendrikw): This isn't required at the moment. It's possible that there
697  //                 is another method to access this when needed.
698  // Open the backlight brightness control sysfs node.
699  backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR);
700  ALOGW_IF(!backlight_brightness_fd_,
701           "HardwareComposer: Failed to open backlight brightness control: %s",
702           strerror(errno));
703#endif  // ENABLE_BACKLIGHT_BRIGHTNESS
704
705  // Open the vsync event node for the primary display.
706  // TODO(eieio): Move this into a platform-specific class.
707  primary_display_vsync_event_fd_ =
708      LocalHandle(kPrimaryDisplayVSyncEventFile, O_RDONLY);
709  ALOGE_IF(!primary_display_vsync_event_fd_,
710           "HardwareComposer: Failed to open vsync event node for primary "
711           "display: %s",
712           strerror(errno));
713
714  // Open the wait pingpong status node for the primary display.
715  // TODO(eieio): Move this into a platform-specific class.
716  primary_display_wait_pp_fd_ =
717      LocalHandle(kPrimaryDisplayWaitPPEventFile, O_RDONLY);
718  ALOGW_IF(
719      !primary_display_wait_pp_fd_,
720      "HardwareComposer: Failed to open wait_pp node for primary display: %s",
721      strerror(errno));
722
723  // Create a timerfd based on CLOCK_MONOTINIC.
724  vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0));
725  LOG_ALWAYS_FATAL_IF(
726      !vsync_sleep_timer_fd_,
727      "HardwareComposer: Failed to create vsync sleep timerfd: %s",
728      strerror(errno));
729
730  const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
731  const int64_t photon_offset_ns = GetPosePredictionTimeOffset(ns_per_frame);
732
733  // TODO(jbates) Query vblank time from device, when such an API is available.
734  // This value (6.3%) was measured on A00 in low persistence mode.
735  int64_t vblank_ns = ns_per_frame * 63 / 1000;
736  int64_t right_eye_photon_offset_ns = (ns_per_frame - vblank_ns) / 2;
737
738  // Check property for overriding right eye offset value.
739  right_eye_photon_offset_ns =
740      property_get_int64(kRightEyeOffsetProperty, right_eye_photon_offset_ns);
741
742  bool was_running = false;
743
744  while (1) {
745    ATRACE_NAME("HardwareComposer::PostThread");
746
747    while (post_thread_quiescent_) {
748      std::unique_lock<std::mutex> lock(post_thread_mutex_);
749      ALOGI("HardwareComposer::PostThread: Entering quiescent state.");
750
751      // Tear down resources.
752      OnPostThreadPaused();
753
754      was_running = false;
755      post_thread_resumed_ = false;
756      post_thread_ready_.notify_all();
757
758      if (post_thread_state_ & PostThreadState::Quit) {
759        ALOGI("HardwareComposer::PostThread: Quitting.");
760        return;
761      }
762
763      post_thread_wait_.wait(lock, [this] { return !post_thread_quiescent_; });
764
765      post_thread_resumed_ = true;
766      post_thread_ready_.notify_all();
767
768      ALOGI("HardwareComposer::PostThread: Exiting quiescent state.");
769    }
770
771    if (!was_running) {
772      // Setup resources.
773      OnPostThreadResumed();
774      was_running = true;
775
776      // Try to setup the scheduler policy if it failed during startup. Only
777      // attempt to do this on transitions from inactive to active to avoid
778      // spamming the system with RPCs and log messages.
779      if (!thread_policy_setup) {
780        thread_policy_setup =
781            SetThreadPolicy("graphics:high", "/system/performance");
782      }
783    }
784
785    int64_t vsync_timestamp = 0;
786    {
787      std::array<char, 128> buf;
788      snprintf(buf.data(), buf.size(), "wait_vsync|vsync=%d|",
789               vsync_count_ + 1);
790      ATRACE_NAME(buf.data());
791
792      const int error = WaitForVSync(&vsync_timestamp);
793      ALOGE_IF(
794          error < 0,
795          "HardwareComposer::PostThread: Failed to wait for vsync event: %s",
796          strerror(-error));
797      // Don't bother processing this frame if a pause was requested
798      if (error == kPostThreadInterrupted)
799        continue;
800    }
801
802    ++vsync_count_;
803
804    if (pose_client_) {
805      // Signal the pose service with vsync info.
806      // Display timestamp is in the middle of scanout.
807      privateDvrPoseNotifyVsync(pose_client_, vsync_count_,
808                                vsync_timestamp + photon_offset_ns,
809                                ns_per_frame, right_eye_photon_offset_ns);
810    }
811
812    const bool layer_config_changed = UpdateLayerConfig();
813
814    // Signal all of the vsync clients. Because absolute time is used for the
815    // wakeup time below, this can take a little time if necessary.
816    if (vsync_callback_)
817      vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp,
818                      /*frame_time_estimate*/ 0, vsync_count_);
819
820    {
821      // Sleep until shortly before vsync.
822      ATRACE_NAME("sleep");
823
824      const int64_t display_time_est_ns = vsync_timestamp + ns_per_frame;
825      const int64_t now_ns = GetSystemClockNs();
826      const int64_t sleep_time_ns =
827          display_time_est_ns - now_ns - kFramePostOffsetNs;
828      const int64_t wakeup_time_ns = display_time_est_ns - kFramePostOffsetNs;
829
830      ATRACE_INT64("sleep_time_ns", sleep_time_ns);
831      if (sleep_time_ns > 0) {
832        int error = SleepUntil(wakeup_time_ns);
833        ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s",
834                 strerror(-error));
835        if (error == kPostThreadInterrupted) {
836          if (layer_config_changed) {
837            // If the layer config changed we need to validateDisplay() even if
838            // we're going to drop the frame, to flush the Composer object's
839            // internal command buffer and apply our layer changes.
840            Validate(HWC_DISPLAY_PRIMARY);
841          }
842          continue;
843        }
844      }
845    }
846
847    PostLayers();
848  }
849}
850
851// Checks for changes in the surface stack and updates the layer config to
852// accomodate the new stack.
853bool HardwareComposer::UpdateLayerConfig() {
854  std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces;
855  {
856    std::unique_lock<std::mutex> lock(post_thread_mutex_);
857    if (pending_surfaces_.empty())
858      return false;
859
860    surfaces = std::move(pending_surfaces_);
861  }
862
863  ATRACE_NAME("UpdateLayerConfig_HwLayers");
864
865  display_surfaces_.clear();
866
867  Layer* target_layer;
868  size_t layer_index;
869  for (layer_index = 0;
870       layer_index < std::min(surfaces.size(), kMaxHardwareLayers);
871       layer_index++) {
872    // The bottom layer is opaque, other layers blend.
873    HWC::BlendMode blending =
874        layer_index == 0 ? HWC::BlendMode::None : HWC::BlendMode::Coverage;
875    layers_[layer_index].Setup(surfaces[layer_index], blending,
876                               display_transform_, HWC::Composition::Device,
877                               layer_index);
878    display_surfaces_.push_back(surfaces[layer_index]);
879  }
880
881  // Clear unused layers.
882  for (size_t i = layer_index; i < kMaxHardwareLayers; i++)
883    layers_[i].Reset();
884
885  active_layer_count_ = layer_index;
886  ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers",
887           active_layer_count_);
888
889  // Any surfaces left over could not be assigned a hardware layer and will
890  // not be displayed.
891  ALOGW_IF(surfaces.size() != display_surfaces_.size(),
892           "HardwareComposer::UpdateLayerConfig: More surfaces than layers: "
893           "pending_surfaces=%zu display_surfaces=%zu",
894           surfaces.size(), display_surfaces_.size());
895
896  return true;
897}
898
899void HardwareComposer::SetVSyncCallback(VSyncCallback callback) {
900  vsync_callback_ = callback;
901}
902
903void HardwareComposer::HwcRefresh(hwc2_callback_data_t /*data*/,
904                                  hwc2_display_t /*display*/) {
905  // TODO(eieio): implement invalidate callbacks.
906}
907
908void HardwareComposer::HwcVSync(hwc2_callback_data_t /*data*/,
909                                hwc2_display_t /*display*/,
910                                int64_t /*timestamp*/) {
911  ATRACE_NAME(__PRETTY_FUNCTION__);
912  // Intentionally empty. HWC may require a callback to be set to enable vsync
913  // signals. We bypass this callback thread by monitoring the vsync event
914  // directly, but signals still need to be enabled.
915}
916
917void HardwareComposer::HwcHotplug(hwc2_callback_data_t /*callbackData*/,
918                                  hwc2_display_t /*display*/,
919                                  hwc2_connection_t /*connected*/) {
920  // TODO(eieio): implement display hotplug callbacks.
921}
922
923void HardwareComposer::OnHardwareComposerRefresh() {
924  // TODO(steventhomas): Handle refresh.
925}
926
927void HardwareComposer::SetBacklightBrightness(int brightness) {
928  if (backlight_brightness_fd_) {
929    std::array<char, 32> text;
930    const int length = snprintf(text.data(), text.size(), "%d", brightness);
931    write(backlight_brightness_fd_.Get(), text.data(), length);
932  }
933}
934
935void Layer::InitializeGlobals(Hwc2::Composer* hwc2_hidl,
936                              const HWCDisplayMetrics* metrics) {
937  hwc2_hidl_ = hwc2_hidl;
938  display_metrics_ = metrics;
939}
940
941void Layer::Reset() {
942  if (hwc2_hidl_ != nullptr && hardware_composer_layer_) {
943    hwc2_hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_);
944    hardware_composer_layer_ = 0;
945  }
946
947  z_order_ = 0;
948  blending_ = HWC::BlendMode::None;
949  transform_ = HWC::Transform::None;
950  composition_type_ = HWC::Composition::Invalid;
951  target_composition_type_ = composition_type_;
952  source_ = EmptyVariant{};
953  acquire_fence_.Close();
954  surface_rect_functions_applied_ = false;
955}
956
957void Layer::Setup(const std::shared_ptr<DirectDisplaySurface>& surface,
958                  HWC::BlendMode blending, HWC::Transform transform,
959                  HWC::Composition composition_type, size_t z_order) {
960  Reset();
961  z_order_ = z_order;
962  blending_ = blending;
963  transform_ = transform;
964  composition_type_ = HWC::Composition::Invalid;
965  target_composition_type_ = composition_type;
966  source_ = SourceSurface{surface};
967  CommonLayerSetup();
968}
969
970void Layer::Setup(const std::shared_ptr<IonBuffer>& buffer,
971                  HWC::BlendMode blending, HWC::Transform transform,
972                  HWC::Composition composition_type, size_t z_order) {
973  Reset();
974  z_order_ = z_order;
975  blending_ = blending;
976  transform_ = transform;
977  composition_type_ = HWC::Composition::Invalid;
978  target_composition_type_ = composition_type;
979  source_ = SourceBuffer{buffer};
980  CommonLayerSetup();
981}
982
983void Layer::UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer) {
984  if (source_.is<SourceBuffer>())
985    std::get<SourceBuffer>(source_) = {buffer};
986}
987
988void Layer::SetBlending(HWC::BlendMode blending) { blending_ = blending; }
989void Layer::SetZOrder(size_t z_order) { z_order_ = z_order; }
990
991IonBuffer* Layer::GetBuffer() {
992  struct Visitor {
993    IonBuffer* operator()(SourceSurface& source) { return source.GetBuffer(); }
994    IonBuffer* operator()(SourceBuffer& source) { return source.GetBuffer(); }
995    IonBuffer* operator()(EmptyVariant) { return nullptr; }
996  };
997  return source_.Visit(Visitor{});
998}
999
1000void Layer::UpdateLayerSettings() {
1001  if (!IsLayerSetup()) {
1002    ALOGE(
1003        "HardwareComposer::Layer::UpdateLayerSettings: Attempt to update "
1004        "unused Layer!");
1005    return;
1006  }
1007
1008  HWC::Error error;
1009  hwc2_display_t display = HWC_DISPLAY_PRIMARY;
1010
1011  error = hwc2_hidl_->setLayerCompositionType(
1012      display, hardware_composer_layer_,
1013      composition_type_.cast<Hwc2::IComposerClient::Composition>());
1014  ALOGE_IF(
1015      error != HWC::Error::None,
1016      "Layer::UpdateLayerSettings: Error setting layer composition type: %s",
1017      error.to_string().c_str());
1018
1019  error = hwc2_hidl_->setLayerBlendMode(
1020      display, hardware_composer_layer_,
1021      blending_.cast<Hwc2::IComposerClient::BlendMode>());
1022  ALOGE_IF(error != HWC::Error::None,
1023           "Layer::UpdateLayerSettings: Error setting layer blend mode: %s",
1024           error.to_string().c_str());
1025
1026  // TODO(eieio): Use surface attributes or some other mechanism to control
1027  // the layer display frame.
1028  error = hwc2_hidl_->setLayerDisplayFrame(
1029      display, hardware_composer_layer_,
1030      {0, 0, display_metrics_->width, display_metrics_->height});
1031  ALOGE_IF(error != HWC::Error::None,
1032           "Layer::UpdateLayerSettings: Error setting layer display frame: %s",
1033           error.to_string().c_str());
1034
1035  error = hwc2_hidl_->setLayerVisibleRegion(
1036      display, hardware_composer_layer_,
1037      {{0, 0, display_metrics_->width, display_metrics_->height}});
1038  ALOGE_IF(error != HWC::Error::None,
1039           "Layer::UpdateLayerSettings: Error setting layer visible region: %s",
1040           error.to_string().c_str());
1041
1042  error =
1043      hwc2_hidl_->setLayerPlaneAlpha(display, hardware_composer_layer_, 1.0f);
1044  ALOGE_IF(error != HWC::Error::None,
1045           "Layer::UpdateLayerSettings: Error setting layer plane alpha: %s",
1046           error.to_string().c_str());
1047
1048  error =
1049      hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_, z_order_);
1050  ALOGE_IF(error != HWC::Error::None,
1051           "Layer::UpdateLayerSettings: Error setting z_ order: %s",
1052           error.to_string().c_str());
1053}
1054
1055void Layer::CommonLayerSetup() {
1056  HWC::Error error =
1057      hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY, &hardware_composer_layer_);
1058  ALOGE_IF(
1059      error != HWC::Error::None,
1060      "Layer::CommonLayerSetup: Failed to create layer on primary display: %s",
1061      error.to_string().c_str());
1062  UpdateLayerSettings();
1063}
1064
1065void Layer::Prepare() {
1066  int right, bottom;
1067  sp<GraphicBuffer> handle;
1068
1069  // Acquire the next buffer according to the type of source.
1070  IfAnyOf<SourceSurface, SourceBuffer>::Call(&source_, [&](auto& source) {
1071    std::tie(right, bottom, handle, acquire_fence_) = source.Acquire();
1072  });
1073
1074  // When a layer is first setup there may be some time before the first buffer
1075  // arrives. Setup the HWC layer as a solid color to stall for time until the
1076  // first buffer arrives. Once the first buffer arrives there will always be a
1077  // buffer for the frame even if it is old.
1078  if (!handle.get()) {
1079    if (composition_type_ == HWC::Composition::Invalid) {
1080      composition_type_ = HWC::Composition::SolidColor;
1081      hwc2_hidl_->setLayerCompositionType(
1082          HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1083          composition_type_.cast<Hwc2::IComposerClient::Composition>());
1084      Hwc2::IComposerClient::Color layer_color = {0, 0, 0, 0};
1085      hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1086                                layer_color);
1087    } else {
1088      // The composition type is already set. Nothing else to do until a
1089      // buffer arrives.
1090    }
1091  } else {
1092    if (composition_type_ != target_composition_type_) {
1093      composition_type_ = target_composition_type_;
1094      hwc2_hidl_->setLayerCompositionType(
1095          HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1096          composition_type_.cast<Hwc2::IComposerClient::Composition>());
1097    }
1098
1099    HWC::Error error{HWC::Error::None};
1100    error = hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
1101                                       hardware_composer_layer_, 0, handle,
1102                                       acquire_fence_.Get());
1103
1104    ALOGE_IF(error != HWC::Error::None,
1105             "Layer::Prepare: Error setting layer buffer: %s",
1106             error.to_string().c_str());
1107
1108    if (!surface_rect_functions_applied_) {
1109      const float float_right = right;
1110      const float float_bottom = bottom;
1111      error = hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
1112                                             hardware_composer_layer_,
1113                                             {0, 0, float_right, float_bottom});
1114
1115      ALOGE_IF(error != HWC::Error::None,
1116               "Layer::Prepare: Error setting layer source crop: %s",
1117               error.to_string().c_str());
1118
1119      surface_rect_functions_applied_ = true;
1120    }
1121  }
1122}
1123
1124void Layer::Finish(int release_fence_fd) {
1125  IfAnyOf<SourceSurface, SourceBuffer>::Call(
1126      &source_, [release_fence_fd](auto& source) {
1127        source.Finish(LocalHandle(release_fence_fd));
1128      });
1129}
1130
1131void Layer::Drop() { acquire_fence_.Close(); }
1132
1133}  // namespace dvr
1134}  // namespace android
1135