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