hardware_composer.cpp revision 1f42e3a02c4f9a1ba1916a2f0e47082bedb73e41
1#include "hardware_composer.h"
2
3#include <log/log.h>
4#include <cutils/properties.h>
5#include <cutils/sched_policy.h>
6#include <fcntl.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 <unistd.h>
15#include <utils/Trace.h>
16
17#include <algorithm>
18#include <functional>
19#include <map>
20
21#include <dvr/performance_client_api.h>
22#include <private/dvr/clock_ns.h>
23#include <private/dvr/display_types.h>
24#include <private/dvr/pose_client_internal.h>
25#include <private/dvr/sync_util.h>
26
27#include "debug_hud_data.h"
28#include "screenshot_service.h"
29
30using android::pdx::LocalHandle;
31
32namespace android {
33namespace dvr {
34
35namespace {
36
37// If the number of pending fences goes over this count at the point when we
38// are about to submit a new frame to HWC, we will drop the frame. This should
39// be a signal that the display driver has begun queuing frames. Note that with
40// smart displays (with RAM), the fence is signaled earlier than the next vsync,
41// at the point when the DMA to the display completes. Currently we use a smart
42// display and the EDS timing coincides with zero pending fences, so this is 0.
43constexpr int kAllowedPendingFenceCount = 0;
44
45// If we think we're going to miss vsync by more than this amount, skip the
46// frame.
47constexpr int64_t kFrameSkipThresholdNs = 4000000;  // 4ms
48
49// Counter PostLayers() deficiency by requiring apps to produce a frame at least
50// 2.5ms before vsync. See b/28881672.
51constexpr int64_t kFrameTimeEstimateMin = 2500000;  // 2.5ms
52
53constexpr size_t kDefaultDisplayConfigCount = 32;
54
55constexpr float kMetersPerInch = 0.0254f;
56
57const char kBacklightBrightnessSysFile[] =
58    "/sys/class/leds/lcd-backlight/brightness";
59
60const char kPrimaryDisplayVSyncEventFile[] =
61    "/sys/class/graphics/fb0/vsync_event";
62
63const char kPrimaryDisplayWaitPPEventFile[] = "/sys/class/graphics/fb0/wait_pp";
64
65const char kDvrPerformanceProperty[] = "sys.dvr.performance";
66
67const char kRightEyeOffsetProperty[] = "dreamos.right_eye_offset_ns";
68
69// Returns our best guess for the time the compositor will spend rendering the
70// next frame.
71int64_t GuessFrameTime(int compositor_visible_layer_count) {
72  // The cost of asynchronous EDS and lens warp is currently measured at 2.5ms
73  // for one layer and 7ms for two layers, but guess a higher frame time to
74  // account for CPU overhead. This guess is only used before we've measured the
75  // actual time to render a frame for the current compositor configuration.
76  switch (compositor_visible_layer_count) {
77    case 0:
78      return 500000;  // .5ms
79    case 1:
80      return 5000000;  // 5ms
81    default:
82      return 10500000;  // 10.5ms
83  }
84}
85
86// Get time offset from a vsync to when the pose for that vsync should be
87// predicted out to. For example, if scanout gets halfway through the frame
88// at the halfway point between vsyncs, then this could be half the period.
89// With global shutter displays, this should be changed to the offset to when
90// illumination begins. Low persistence adds a frame of latency, so we predict
91// to the center of the next frame.
92inline int64_t GetPosePredictionTimeOffset(int64_t vsync_period_ns) {
93  return (vsync_period_ns * 150) / 100;
94}
95
96}  // anonymous namespace
97
98HardwareComposer::HardwareComposer()
99  : HardwareComposer(nullptr) {
100}
101
102HardwareComposer::HardwareComposer(Hwc2::Composer* hwc2_hidl)
103    : initialized_(false),
104      hwc2_hidl_(hwc2_hidl),
105      display_transform_(HWC_TRANSFORM_NONE),
106      active_surfaces_updated_(false),
107      active_layer_count_(0),
108      gpu_layer_(nullptr),
109      post_thread_enabled_(false),
110      post_thread_running_(false),
111      post_thread_quit_requested_(false),
112      post_thread_interrupt_event_fd_(-1),
113      backlight_brightness_fd_(-1),
114      primary_display_vsync_event_fd_(-1),
115      primary_display_wait_pp_fd_(-1),
116      vsync_sleep_timer_fd_(-1),
117      last_vsync_timestamp_(0),
118      vsync_count_(0),
119      frame_skip_count_(0),
120      pose_client_(nullptr) {
121  std::transform(layer_storage_.begin(), layer_storage_.end(), layers_.begin(),
122                 [](auto& layer) { return &layer; });
123
124  callbacks_ = new ComposerCallback;
125}
126
127HardwareComposer::~HardwareComposer(void) {
128  std::unique_lock<std::mutex> lock(post_thread_mutex_);
129  if (post_thread_.joinable()) {
130    post_thread_quit_requested_ = true;
131    post_thread_cond_var_.notify_all();
132    post_thread_.join();
133  }
134}
135
136bool HardwareComposer::Initialize() {
137  if (initialized_) {
138    ALOGE("HardwareComposer::Initialize: already initialized.");
139    return false;
140  }
141
142  int32_t ret = HWC2_ERROR_NONE;
143
144  Hwc2::Config config;
145  ret = (int32_t)hwc2_hidl_->getActiveConfig(HWC_DISPLAY_PRIMARY, &config);
146
147  if (ret != HWC2_ERROR_NONE) {
148    ALOGE("HardwareComposer: Failed to get current display config : %d",
149          config);
150    return false;
151  }
152
153  ret =
154      GetDisplayMetrics(HWC_DISPLAY_PRIMARY, config, &native_display_metrics_);
155
156  if (ret != HWC2_ERROR_NONE) {
157    ALOGE(
158        "HardwareComposer: Failed to get display attributes for current "
159        "configuration : %d",
160        ret);
161    return false;
162  }
163
164  ALOGI(
165      "HardwareComposer: primary display attributes: width=%d height=%d "
166      "vsync_period_ns=%d DPI=%dx%d",
167      native_display_metrics_.width, native_display_metrics_.height,
168      native_display_metrics_.vsync_period_ns, native_display_metrics_.dpi.x,
169      native_display_metrics_.dpi.y);
170
171  // Set the display metrics but never use rotation to avoid the long latency of
172  // rotation processing in hwc.
173  display_transform_ = HWC_TRANSFORM_NONE;
174  display_metrics_ = native_display_metrics_;
175
176  post_thread_interrupt_event_fd_.Reset(
177      eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
178  LOG_ALWAYS_FATAL_IF(
179      !post_thread_interrupt_event_fd_,
180      "HardwareComposer: Failed to create interrupt event fd : %s",
181      strerror(errno));
182
183  post_thread_ = std::thread(&HardwareComposer::PostThread, this);
184
185  initialized_ = true;
186
187  return initialized_;
188}
189
190void HardwareComposer::Enable() {
191  std::lock_guard<std::mutex> lock(post_thread_mutex_);
192  post_thread_enabled_ = true;
193  post_thread_cond_var_.notify_all();
194}
195
196void HardwareComposer::Disable() {
197  std::unique_lock<std::mutex> lock(post_thread_mutex_);
198  post_thread_enabled_ = false;
199  if (post_thread_running_) {
200    // Write to the interrupt fd to get fast interrupt of the post thread
201    int error = eventfd_write(post_thread_interrupt_event_fd_.Get(), 1);
202    ALOGW_IF(error,
203             "HardwareComposer::Disable: could not write post "
204             "thread interrupt event fd : %s",
205             strerror(errno));
206
207    post_thread_cond_var_.wait(lock, [this] { return !post_thread_running_; });
208
209    // Read the interrupt fd to clear its state
210    uint64_t interrupt_count= 0;
211    error = eventfd_read(post_thread_interrupt_event_fd_.Get(),
212                         &interrupt_count);
213    ALOGW_IF(error,
214             "HardwareComposer::Disable: could not read post "
215             "thread interrupt event fd : %s",
216             strerror(errno));
217  }
218}
219
220bool HardwareComposer::PostThreadHasWork() {
221  return !display_surfaces_.empty() ||
222      (active_surfaces_updated_ && !active_surfaces_.empty());
223}
224
225void HardwareComposer::OnPostThreadResumed() {
226  constexpr int format = HAL_PIXEL_FORMAT_RGBA_8888;
227  constexpr int usage =
228      GRALLOC_USAGE_HW_FB | GRALLOC_USAGE_HW_COMPOSER | GRALLOC_USAGE_HW_RENDER;
229
230  framebuffer_target_ = std::make_shared<IonBuffer>(
231      native_display_metrics_.width, native_display_metrics_.height, format,
232      usage);
233
234  // Associate each Layer instance with a hardware composer layer.
235  for (auto layer : layers_) {
236    layer->Initialize(hwc2_hidl_.get(), &native_display_metrics_);
237  }
238
239  // Connect to pose service.
240  pose_client_ = dvrPoseCreate();
241  ALOGE_IF(!pose_client_, "HardwareComposer: Failed to create pose client");
242
243  EnableVsync(true);
244
245  // TODO(skiazyk): We need to do something about accessing this directly,
246  // supposedly there is a backlight service on the way.
247  // TODO(steventhomas): When we change the backlight setting, will surface
248  // flinger (or something else) set it back to its original value once we give
249  // control of the display back to surface flinger?
250  SetBacklightBrightness(255);
251
252  // Initialize the GPU compositor.
253  LOG_ALWAYS_FATAL_IF(!compositor_.Initialize(GetHmdDisplayMetrics()),
254                      "Failed to initialize the compositor");
255
256  // Trigger target-specific performance mode change.
257  property_set(kDvrPerformanceProperty, "performance");
258}
259
260void HardwareComposer::OnPostThreadPaused() {
261  retire_fence_fds_.clear();
262  gpu_layer_ = nullptr;
263
264  // We have to destroy the layers to fully clear hwc device state before
265  // handing off back to surface flinger
266  for (size_t i = 0; i < kMaxHardwareLayers; ++i) {
267    layers_[i]->Reset();
268  }
269
270  active_layer_count_ = 0;
271
272  framebuffer_target_.reset();
273
274  display_surfaces_.clear();
275  compositor_surfaces_.clear();
276
277  // Since we're clearing display_surfaces_ we'll need an update.
278  active_surfaces_updated_ = true;
279
280  if (pose_client_) {
281    dvrPoseDestroy(pose_client_);
282    pose_client_ = nullptr;
283  }
284
285  EnableVsync(false);
286
287  frame_time_history_.ResetWithSeed(GuessFrameTime(0));
288  frame_time_backlog_.clear();
289
290  compositor_.Shutdown();
291
292  // Trigger target-specific performance mode change.
293  property_set(kDvrPerformanceProperty, "idle");
294}
295
296DisplayMetrics HardwareComposer::GetHmdDisplayMetrics() const {
297  vec2i screen_size(display_metrics_.width, display_metrics_.height);
298  DisplayOrientation orientation =
299      (display_metrics_.width > display_metrics_.height
300           ? DisplayOrientation::kLandscape
301           : DisplayOrientation::kPortrait);
302  float dpi_x = static_cast<float>(display_metrics_.dpi.x) / 1000.0f;
303  float dpi_y = static_cast<float>(display_metrics_.dpi.y) / 1000.0f;
304  float meters_per_pixel_x = kMetersPerInch / dpi_x;
305  float meters_per_pixel_y = kMetersPerInch / dpi_y;
306  vec2 meters_per_pixel(meters_per_pixel_x, meters_per_pixel_y);
307  double frame_duration_s =
308      static_cast<double>(display_metrics_.vsync_period_ns) / 1000000000.0;
309  // TODO(hendrikw): Hard coding to 3mm.  The Pixel is actually 4mm, but it
310  //                 seems that their tray to lens distance is wrong too, which
311  //                 offsets this, at least for the pixel.
312  float border_size = 0.003f;
313  return DisplayMetrics(screen_size, meters_per_pixel, border_size,
314                        static_cast<float>(frame_duration_s), orientation);
315}
316
317int32_t HardwareComposer::Validate(hwc2_display_t display) {
318  uint32_t num_types;
319  uint32_t num_requests;
320  int32_t error =
321      (int32_t)hwc2_hidl_->validateDisplay(display, &num_types, &num_requests);
322
323  if (error == HWC2_ERROR_HAS_CHANGES) {
324    // TODO(skiazyk): We might need to inspect the requested changes first, but
325    // so far it seems like we shouldn't ever hit a bad state.
326    // error = hwc2_funcs_.accept_display_changes_fn_(hardware_composer_device_,
327    //                                               display);
328    error = (int32_t)hwc2_hidl_->acceptDisplayChanges(display);
329  }
330
331  return error;
332}
333
334int32_t HardwareComposer::EnableVsync(bool enabled) {
335  return (int32_t)hwc2_hidl_->setVsyncEnabled(
336      HWC_DISPLAY_PRIMARY,
337      (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE
338                                             : HWC2_VSYNC_DISABLE));
339}
340
341int32_t HardwareComposer::Present(hwc2_display_t display) {
342  int32_t present_fence;
343  int32_t error = (int32_t)hwc2_hidl_->presentDisplay(display, &present_fence);
344
345  // According to the documentation, this fence is signaled at the time of
346  // vsync/DMA for physical displays.
347  if (error == HWC2_ERROR_NONE) {
348    ATRACE_INT("HardwareComposer: VsyncFence", present_fence);
349    retire_fence_fds_.emplace_back(present_fence);
350  } else {
351    ATRACE_INT("HardwareComposer: PresentResult", error);
352  }
353
354  return error;
355}
356
357int32_t HardwareComposer::GetDisplayAttribute(hwc2_display_t display,
358                                              hwc2_config_t config,
359                                              hwc2_attribute_t attribute,
360                                              int32_t* out_value) const {
361  return (int32_t)hwc2_hidl_->getDisplayAttribute(
362      display, config, (Hwc2::IComposerClient::Attribute)attribute, out_value);
363}
364
365int32_t HardwareComposer::GetDisplayMetrics(
366    hwc2_display_t display, hwc2_config_t config,
367    HWCDisplayMetrics* out_metrics) const {
368  int32_t ret = HWC2_ERROR_NONE;
369
370  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_WIDTH,
371                            &out_metrics->width);
372  if (ret != HWC2_ERROR_NONE) {
373    ALOGE("HardwareComposer: Failed to get display width");
374    return ret;
375  }
376
377  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_HEIGHT,
378                            &out_metrics->height);
379  if (ret != HWC2_ERROR_NONE) {
380    ALOGE("HardwareComposer: Failed to get display height");
381    return ret;
382  }
383
384  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_VSYNC_PERIOD,
385                            &out_metrics->vsync_period_ns);
386  if (ret != HWC2_ERROR_NONE) {
387    ALOGE("HardwareComposer: Failed to get display height");
388    return ret;
389  }
390
391  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_X,
392                            &out_metrics->dpi.x);
393  if (ret != HWC2_ERROR_NONE) {
394    ALOGE("HardwareComposer: Failed to get display DPI X");
395    return ret;
396  }
397
398  ret = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_Y,
399                            &out_metrics->dpi.y);
400  if (ret != HWC2_ERROR_NONE) {
401    ALOGE("HardwareComposer: Failed to get display DPI Y");
402    return ret;
403  }
404
405  return HWC2_ERROR_NONE;
406}
407
408void HardwareComposer::Dump(char* buffer, uint32_t* out_size) {
409  std::string debug_str = hwc2_hidl_->dumpDebugInfo();
410  ALOGI("%s", debug_str.c_str());
411
412  if (buffer == nullptr) {
413    *out_size = debug_str.size();
414  } else {
415    std::copy(debug_str.begin(), debug_str.begin() + *out_size, buffer);
416  }
417}
418
419// TODO(skiazyk): Figure out what to do with `is_geometry_changed`. There does
420// not seem to be any equivalent in the HWC2 API, but that doesn't mean its not
421// there.
422void HardwareComposer::PostLayers(bool /*is_geometry_changed*/) {
423  ATRACE_NAME("HardwareComposer::PostLayers");
424
425  // Setup the hardware composer layers with current buffers.
426  for (size_t i = 0; i < active_layer_count_; i++) {
427    layers_[i]->Prepare();
428  }
429
430  // Now that we have taken in a frame from the application, we have a chance
431  // to drop the frame before passing the frame along to HWC.
432  // If the display driver has become backed up, we detect it here and then
433  // react by skipping this frame to catch up latency.
434  while (!retire_fence_fds_.empty() &&
435         (!retire_fence_fds_.front() ||
436          sync_wait(retire_fence_fds_.front().Get(), 0) == 0)) {
437    // There are only 2 fences in here, no performance problem to shift the
438    // array of ints.
439    retire_fence_fds_.erase(retire_fence_fds_.begin());
440  }
441
442  const bool is_frame_pending = IsFramePendingInDriver();
443  const bool is_fence_pending =
444      retire_fence_fds_.size() > kAllowedPendingFenceCount;
445
446  if (is_fence_pending || is_frame_pending) {
447    ATRACE_INT("frame_skip_count", ++frame_skip_count_);
448
449    ALOGW_IF(is_frame_pending, "Warning: frame already queued, dropping frame");
450    ALOGW_IF(is_fence_pending,
451             "Warning: dropping a frame to catch up with HWC (pending = %zd)",
452             retire_fence_fds_.size());
453
454    for (size_t i = 0; i < active_layer_count_; i++) {
455      layers_[i]->Drop();
456    }
457    return;
458  } else {
459    // Make the transition more obvious in systrace when the frame skip happens
460    // above.
461    ATRACE_INT("frame_skip_count", 0);
462  }
463
464#if TRACE
465  for (size_t i = 0; i < active_layer_count_; i++)
466    ALOGI("HardwareComposer::PostLayers: dl[%zu] ctype=0x%08x", i,
467          layers_[i]->GetCompositionType());
468#endif
469
470  int32_t ret = HWC2_ERROR_NONE;
471
472  std::vector<Hwc2::IComposerClient::Rect> full_region(1);
473  full_region[0].left = 0;
474  full_region[0].top = 0;
475  full_region[0].right = framebuffer_target_->width();
476  full_region[0].bottom = framebuffer_target_->height();
477
478  ALOGE_IF(ret, "Error setting client target : %d", ret);
479
480  ret = Validate(HWC_DISPLAY_PRIMARY);
481  if (ret) {
482    ALOGE("HardwareComposer::Validate failed; ret=%d", ret);
483    return;
484  }
485
486  ret = Present(HWC_DISPLAY_PRIMARY);
487  if (ret) {
488    ALOGE("HardwareComposer::Present failed; ret=%d", ret);
489    return;
490  }
491
492  std::vector<Hwc2::Layer> out_layers;
493  std::vector<int> out_fences;
494  ret = (int32_t)hwc2_hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers,
495                                              &out_fences);
496  uint32_t num_elements = out_layers.size();
497
498  ALOGE_IF(ret, "HardwareComposer: GetReleaseFences failed; ret=%d", ret);
499
500  // Perform post-frame bookkeeping. Unused layers are a no-op.
501  for (size_t i = 0; i < num_elements; ++i) {
502    for (size_t j = 0; j < active_layer_count_; ++j) {
503      if (layers_[j]->GetLayerHandle() == out_layers[i]) {
504        layers_[j]->Finish(out_fences[i]);
505      }
506    }
507  }
508}
509
510void HardwareComposer::SetDisplaySurfaces(
511    std::vector<std::shared_ptr<DisplaySurface>> surfaces) {
512  ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd",
513        surfaces.size());
514  std::unique_lock<std::mutex> lock(post_thread_mutex_);
515  active_surfaces_ = std::move(surfaces);
516  active_surfaces_updated_ = true;
517  if (post_thread_enabled_)
518    post_thread_cond_var_.notify_all();
519}
520
521int HardwareComposer::PostThreadPollInterruptible(int event_fd,
522                                                  int requested_events) {
523  pollfd pfd[2] = {
524      {
525          .fd = event_fd,
526          .events = static_cast<short>(requested_events),
527          .revents = 0,
528      },
529      {
530          .fd = post_thread_interrupt_event_fd_.Get(),
531          .events = POLLPRI | POLLIN,
532          .revents = 0,
533      },
534  };
535  int ret, error;
536  do {
537    ret = poll(pfd, 2, -1);
538    error = errno;
539    ALOGW_IF(ret < 0,
540             "HardwareComposer::PostThreadPollInterruptible: Error during "
541             "poll(): %s (%d)",
542             strerror(error), error);
543  } while (ret < 0 && error == EINTR);
544
545  if (ret < 0) {
546    return -error;
547  } else if (pfd[0].revents != 0) {
548    return 0;
549  } else if (pfd[1].revents != 0) {
550    ALOGI("VrHwcPost thread interrupted");
551    return kPostThreadInterrupted;
552  } else {
553    return 0;
554  }
555}
556
557// Reads the value of the display driver wait_pingpong state. Returns 0 or 1
558// (the value of the state) on success or a negative error otherwise.
559// TODO(eieio): This is pretty driver specific, this should be moved to a
560// separate class eventually.
561int HardwareComposer::ReadWaitPPState() {
562  // Gracefully handle when the kernel does not support this feature.
563  if (!primary_display_wait_pp_fd_)
564    return 0;
565
566  const int wait_pp_fd = primary_display_wait_pp_fd_.Get();
567  int ret, error;
568
569  ret = lseek(wait_pp_fd, 0, SEEK_SET);
570  if (ret < 0) {
571    error = errno;
572    ALOGE("HardwareComposer::ReadWaitPPState: Failed to seek wait_pp fd: %s",
573          strerror(error));
574    return -error;
575  }
576
577  char data = -1;
578  ret = read(wait_pp_fd, &data, sizeof(data));
579  if (ret < 0) {
580    error = errno;
581    ALOGE("HardwareComposer::ReadWaitPPState: Failed to read wait_pp state: %s",
582          strerror(error));
583    return -error;
584  }
585
586  switch (data) {
587    case '0':
588      return 0;
589    case '1':
590      return 1;
591    default:
592      ALOGE(
593          "HardwareComposer::ReadWaitPPState: Unexpected value for wait_pp: %d",
594          data);
595      return -EINVAL;
596  }
597}
598
599// Reads the timestamp of the last vsync from the display driver.
600// TODO(eieio): This is pretty driver specific, this should be moved to a
601// separate class eventually.
602int HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) {
603  const int event_fd = primary_display_vsync_event_fd_.Get();
604  int ret, error;
605
606  // The driver returns data in the form "VSYNC=<timestamp ns>".
607  std::array<char, 32> data;
608  data.fill('\0');
609
610  // Seek back to the beginning of the event file.
611  ret = lseek(event_fd, 0, SEEK_SET);
612  if (ret < 0) {
613    error = errno;
614    ALOGE(
615        "HardwareComposer::ReadVSyncTimestamp: Failed to seek vsync event fd: "
616        "%s",
617        strerror(error));
618    return -error;
619  }
620
621  // Read the vsync event timestamp.
622  ret = read(event_fd, data.data(), data.size());
623  if (ret < 0) {
624    error = errno;
625    ALOGE_IF(
626        error != EAGAIN,
627        "HardwareComposer::ReadVSyncTimestamp: Error while reading timestamp: "
628        "%s",
629        strerror(error));
630    return -error;
631  }
632
633  ret = sscanf(data.data(), "VSYNC=%" PRIu64,
634               reinterpret_cast<uint64_t*>(timestamp));
635  if (ret < 0) {
636    error = errno;
637    ALOGE(
638        "HardwareComposer::ReadVSyncTimestamp: Error while parsing timestamp: "
639        "%s",
640        strerror(error));
641    return -error;
642  }
643
644  return 0;
645}
646
647// Blocks until the next vsync event is signaled by the display driver.
648// TODO(eieio): This is pretty driver specific, this should be moved to a
649// separate class eventually.
650int HardwareComposer::BlockUntilVSync() {
651  return PostThreadPollInterruptible(primary_display_vsync_event_fd_.Get(),
652                                     // There will be a POLLPRI event on vsync
653                                     POLLPRI);
654}
655
656// Waits for the next vsync and returns the timestamp of the vsync event. If
657// vsync already passed since the last call, returns the latest vsync timestamp
658// instead of blocking. This method updates the last_vsync_timeout_ in the
659// process.
660//
661// TODO(eieio): This is pretty driver specific, this should be moved to a
662// separate class eventually.
663int HardwareComposer::WaitForVSync(int64_t* timestamp) {
664  int error;
665
666  // Get the current timestamp and decide what to do.
667  while (true) {
668    int64_t current_vsync_timestamp;
669    error = ReadVSyncTimestamp(&current_vsync_timestamp);
670    if (error < 0 && error != -EAGAIN)
671      return error;
672
673    if (error == -EAGAIN) {
674      // Vsync was turned off, wait for the next vsync event.
675      error = BlockUntilVSync();
676      if (error < 0 || error == kPostThreadInterrupted)
677        return error;
678
679      // Try again to get the timestamp for this new vsync interval.
680      continue;
681    }
682
683    // Check that we advanced to a later vsync interval.
684    if (TimestampGT(current_vsync_timestamp, last_vsync_timestamp_)) {
685      *timestamp = last_vsync_timestamp_ = current_vsync_timestamp;
686      return 0;
687    }
688
689    // See how close we are to the next expected vsync. If we're within 1ms,
690    // sleep for 1ms and try again.
691    const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
692    const int64_t threshold_ns = 1000000;
693
694    const int64_t next_vsync_est = last_vsync_timestamp_ + ns_per_frame;
695    const int64_t distance_to_vsync_est = next_vsync_est - GetSystemClockNs();
696
697    if (distance_to_vsync_est > threshold_ns) {
698      // Wait for vsync event notification.
699      error = BlockUntilVSync();
700      if (error < 0 || error == kPostThreadInterrupted)
701        return error;
702    } else {
703      // Sleep for a short time (1 millisecond) before retrying.
704      error = SleepUntil(GetSystemClockNs() + 1000000);
705      if (error < 0 || error == kPostThreadInterrupted)
706        return error;
707    }
708  }
709}
710
711int HardwareComposer::SleepUntil(int64_t wakeup_timestamp) {
712  const int timer_fd = vsync_sleep_timer_fd_.Get();
713  const itimerspec wakeup_itimerspec = {
714      .it_interval = {.tv_sec = 0, .tv_nsec = 0},
715      .it_value = NsToTimespec(wakeup_timestamp),
716  };
717  int ret =
718      timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &wakeup_itimerspec, nullptr);
719  int error = errno;
720  if (ret < 0) {
721    ALOGE("HardwareComposer::SleepUntil: Failed to set timerfd: %s",
722          strerror(error));
723    return -error;
724  }
725
726  return PostThreadPollInterruptible(timer_fd, POLLIN);
727}
728
729void HardwareComposer::PostThread() {
730  // NOLINTNEXTLINE(runtime/int)
731  prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrHwcPost"), 0, 0, 0);
732
733  // Set the scheduler to SCHED_FIFO with high priority.
734  int error = dvrSetSchedulerClass(0, "graphics:high");
735  LOG_ALWAYS_FATAL_IF(
736      error < 0,
737      "HardwareComposer::PostThread: Failed to set scheduler class: %s",
738      strerror(-error));
739  error = dvrSetCpuPartition(0, "/system/performance");
740  LOG_ALWAYS_FATAL_IF(
741      error < 0,
742      "HardwareComposer::PostThread: Failed to set cpu partition: %s",
743      strerror(-error));
744
745#if ENABLE_BACKLIGHT_BRIGHTNESS
746  // TODO(hendrikw): This isn't required at the moment. It's possible that there
747  //                 is another method to access this when needed.
748  // Open the backlight brightness control sysfs node.
749  backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR);
750  ALOGW_IF(!backlight_brightness_fd_,
751           "HardwareComposer: Failed to open backlight brightness control: %s",
752           strerror(errno));
753#endif // ENABLE_BACKLIGHT_BRIGHTNESS
754
755  // Open the vsync event node for the primary display.
756  // TODO(eieio): Move this into a platform-specific class.
757  primary_display_vsync_event_fd_ =
758      LocalHandle(kPrimaryDisplayVSyncEventFile, O_RDONLY);
759  ALOGE_IF(!primary_display_vsync_event_fd_,
760           "HardwareComposer: Failed to open vsync event node for primary "
761           "display: %s",
762           strerror(errno));
763
764  // Open the wait pingpong status node for the primary display.
765  // TODO(eieio): Move this into a platform-specific class.
766  primary_display_wait_pp_fd_ =
767      LocalHandle(kPrimaryDisplayWaitPPEventFile, O_RDONLY);
768  ALOGW_IF(
769      !primary_display_wait_pp_fd_,
770      "HardwareComposer: Failed to open wait_pp node for primary display: %s",
771      strerror(errno));
772
773  // Create a timerfd based on CLOCK_MONOTINIC.
774  vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0));
775  LOG_ALWAYS_FATAL_IF(
776      !vsync_sleep_timer_fd_,
777      "HardwareComposer: Failed to create vsync sleep timerfd: %s",
778      strerror(errno));
779
780  const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
781  const int64_t photon_offset_ns = GetPosePredictionTimeOffset(ns_per_frame);
782
783  // TODO(jbates) Query vblank time from device, when such an API is available.
784  // This value (6.3%) was measured on A00 in low persistence mode.
785  int64_t vblank_ns = ns_per_frame * 63 / 1000;
786  int64_t right_eye_photon_offset_ns = (ns_per_frame - vblank_ns) / 2;
787
788  // Check property for overriding right eye offset value.
789  right_eye_photon_offset_ns =
790      property_get_int64(kRightEyeOffsetProperty, right_eye_photon_offset_ns);
791
792  compositor_surfaces_.reserve(2);
793
794  constexpr int kFrameTimeBacklogMax = 2;
795  frame_time_backlog_.reserve(kFrameTimeBacklogMax);
796
797  // Storage for retrieving fence info.
798  FenceInfoBuffer fence_info_buffer;
799
800  bool was_running = false;
801
802  while (1) {
803    ATRACE_NAME("HardwareComposer::PostThread");
804
805    {
806      std::unique_lock<std::mutex> lock(post_thread_mutex_);
807      while (!post_thread_enabled_ || post_thread_quit_requested_ ||
808             !PostThreadHasWork()) {
809        if (was_running) {
810          const char* pause_reason = "unknown";
811          if (!post_thread_enabled_)
812            pause_reason = "disabled";
813          else if (post_thread_quit_requested_)
814            pause_reason = "quit requested";
815          else if (!PostThreadHasWork())
816            pause_reason = "no work";
817          ALOGI("VrHwcPost thread paused. Reason: %s.", pause_reason);
818          OnPostThreadPaused();
819          was_running = false;
820        }
821        post_thread_running_ = false;
822        post_thread_cond_var_.notify_all();
823        if (post_thread_quit_requested_)
824          return;
825        post_thread_cond_var_.wait(lock);
826      }
827      post_thread_running_ = true;
828    }
829
830    if (!was_running) {
831      ALOGI("VrHwcPost thread resumed");
832      OnPostThreadResumed();
833      was_running = true;
834    }
835
836    int64_t vsync_timestamp = 0;
837    {
838      std::array<char, 128> buf;
839      snprintf(buf.data(), buf.size(), "wait_vsync|vsync=%d|",
840               vsync_count_ + 1);
841      ATRACE_NAME(buf.data());
842
843      error = WaitForVSync(&vsync_timestamp);
844      ALOGE_IF(
845          error < 0,
846          "HardwareComposer::PostThread: Failed to wait for vsync event: %s",
847          strerror(-error));
848      // Don't bother processing this frame if a pause was requested
849      if (error == kPostThreadInterrupted)
850        continue;
851    }
852
853    ++vsync_count_;
854
855    if (pose_client_) {
856      // Signal the pose service with vsync info.
857      // Display timestamp is in the middle of scanout.
858      privateDvrPoseNotifyVsync(pose_client_, vsync_count_,
859                                vsync_timestamp + photon_offset_ns,
860                                ns_per_frame, right_eye_photon_offset_ns);
861    }
862
863    bool layer_config_changed = UpdateLayerConfig();
864
865    if (!was_running || layer_config_changed) {
866      frame_time_history_.ResetWithSeed(
867          GuessFrameTime(compositor_surfaces_.size()));
868      frame_time_backlog_.clear();
869    } else {
870      UpdateFrameTimeHistory(&frame_time_backlog_, kFrameTimeBacklogMax,
871                             &fence_info_buffer, &frame_time_history_);
872    }
873
874    // Get our current best estimate at how long the next frame will take to
875    // render, based on how long previous frames took to render. Use this
876    // estimate to decide when to wake up for EDS.
877    int64_t frame_time_estimate =
878        frame_time_history_.GetSampleCount() == 0
879            ? GuessFrameTime(compositor_surfaces_.size())
880            : frame_time_history_.GetAverage();
881    frame_time_estimate = std::max(frame_time_estimate, kFrameTimeEstimateMin);
882    DebugHudData::data.hwc_latency = frame_time_estimate;
883
884    // Signal all of the vsync clients. Because absolute time is used for the
885    // wakeup time below, this can take a little time if necessary.
886    if (vsync_callback_)
887      vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp, frame_time_estimate,
888                      vsync_count_);
889
890    {
891      // Sleep until async EDS wakeup time.
892      ATRACE_NAME("sleep");
893
894      int64_t display_time_est = vsync_timestamp + ns_per_frame;
895      int64_t now = GetSystemClockNs();
896      int64_t frame_finish_time_est = now + frame_time_estimate;
897      int64_t sleep_time_ns = display_time_est - now - frame_time_estimate;
898
899      ATRACE_INT64("sleep_time_ns", sleep_time_ns);
900      if (frame_finish_time_est - display_time_est >= kFrameSkipThresholdNs) {
901        ATRACE_INT("frame_skip_count", ++frame_skip_count_);
902        ALOGE(
903            "HardwareComposer::PostThread: Missed frame schedule, drop "
904            "frame. Expected frame miss: %.1fms",
905            static_cast<double>(frame_finish_time_est - display_time_est) /
906                1000000);
907
908        // There are several reasons we might skip a frame, but one possibility
909        // is we mispredicted the frame time. Clear out the frame time history.
910        frame_time_history_.ResetWithSeed(
911            GuessFrameTime(compositor_surfaces_.size()));
912        frame_time_backlog_.clear();
913        DebugHudData::data.hwc_frame_stats.SkipFrame();
914
915        continue;
916      } else {
917        // Make the transition more obvious in systrace when the frame skip
918        // happens above.
919        ATRACE_INT("frame_skip_count", 0);
920      }
921
922      if (sleep_time_ns > 0) {
923        error = SleepUntil(display_time_est - frame_time_estimate);
924        ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s",
925                 strerror(-error));
926        if (error == kPostThreadInterrupted)
927          continue;
928      }
929    }
930
931    DebugHudData::data.hwc_frame_stats.AddFrame();
932
933    int64_t frame_start_time = GetSystemClockNs();
934
935    // Setup the output buffer for the compositor. This needs to happen before
936    // you draw with the compositor.
937    if (gpu_layer_ != nullptr) {
938      gpu_layer_->UpdateDirectBuffer(compositor_.GetBuffer());
939    }
940
941    // Call PostLayers now before performing the GL code for the compositor to
942    // avoid missing the deadline that can cause the lower-level hwc to get
943    // permanently backed up.
944    PostLayers(layer_config_changed);
945
946    PostCompositorBuffers();
947
948    if (gpu_layer_ != nullptr) {
949      // Note, with scanline racing, this draw is timed along with the post
950      // layers to finish just in time.
951      LocalHandle frame_fence_fd;
952      compositor_.DrawFrame(vsync_count_ + 1, &frame_fence_fd);
953      if (frame_fence_fd) {
954        LOG_ALWAYS_FATAL_IF(frame_time_backlog_.size() >= kFrameTimeBacklogMax,
955                            "Frame time backlog exceeds capacity");
956        frame_time_backlog_.push_back(
957            {frame_start_time, std::move(frame_fence_fd)});
958      }
959    } else if (!layer_config_changed) {
960      frame_time_history_.AddSample(GetSystemClockNs() - frame_start_time);
961    }
962
963    HandlePendingScreenshots();
964  }
965}
966
967bool HardwareComposer::UpdateLayerConfig() {
968  std::vector<std::shared_ptr<DisplaySurface>> old_display_surfaces;
969  {
970    std::lock_guard<std::mutex> lock(post_thread_mutex_);
971    if (!active_surfaces_updated_)
972      return false;
973    old_display_surfaces = display_surfaces_;
974    display_surfaces_ = active_surfaces_;
975    active_surfaces_updated_ = false;
976  }
977
978  DebugHudData::data.ResetLayers();
979
980  // Figure out whether we need to update hardware layers. If this surface
981  // change does not add or remove hardware layers we can avoid display hiccups
982  // by gracefully updating only the GPU compositor layers.
983  int old_gpu_layer_count = 0;
984  int new_gpu_layer_count = 0;
985  bool hardware_layers_need_update = false;
986  // Look for new hardware layers and count new GPU layers.
987  for (const auto& surface : display_surfaces_) {
988    if (!(surface->flags() &
989          DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
990      ++new_gpu_layer_count;
991    else if (std::find(old_display_surfaces.begin(), old_display_surfaces.end(),
992                       surface) == old_display_surfaces.end())
993      // This is a new hardware layer, we need to update.
994      hardware_layers_need_update = true;
995  }
996  // Look for deleted hardware layers or compositor layers.
997  for (const auto& surface : old_display_surfaces) {
998    if (!(surface->flags() &
999          DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION))
1000      ++old_gpu_layer_count;
1001    else if (std::find(display_surfaces_.begin(), display_surfaces_.end(),
1002                       surface) == display_surfaces_.end())
1003      // This is a deleted hardware layer, we need to update.
1004      hardware_layers_need_update = true;
1005  }
1006  // Check for compositor hardware layer transition.
1007  if ((!old_gpu_layer_count && new_gpu_layer_count) ||
1008      (old_gpu_layer_count && !new_gpu_layer_count))
1009    hardware_layers_need_update = true;
1010
1011  // Set the chosen layer order for all surfaces.
1012  for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1013    display_surfaces_[i]->SetLayerOrder(static_cast<int>(i));
1014  }
1015
1016  // Update compositor layers.
1017  {
1018    ATRACE_NAME("UpdateLayerConfig_GpuLayers");
1019    compositor_.UpdateSurfaces(display_surfaces_);
1020    compositor_surfaces_.clear();
1021    for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1022      const auto& surface = display_surfaces_[i];
1023      if (!(surface->flags() &
1024            DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION)) {
1025        compositor_surfaces_.push_back(surface);
1026      }
1027    }
1028  }
1029
1030  if (!hardware_layers_need_update)
1031    return true;
1032
1033  // Update hardware layers.
1034
1035  ATRACE_NAME("UpdateLayerConfig_HwLayers");
1036
1037  // Update the display layers in a non-destructive fashion.
1038
1039  // Create a map from surface id to hardware layer
1040  std::map<int, Layer*> display_surface_layers;
1041
1042  for (size_t i = 0; i < active_layer_count_; ++i) {
1043    auto layer = layers_[i];
1044    int surface_id = layer->GetSurfaceId();
1045
1046    auto found =
1047        std::find_if(display_surfaces_.begin(), display_surfaces_.end(),
1048                     [surface_id](const auto& surface) {
1049                       return surface->surface_id() == surface_id;
1050                     });
1051
1052    if (found != display_surfaces_.end()) {
1053      display_surface_layers[surface_id] = layer;
1054    }
1055  }
1056
1057  bool has_gpu_layer = std::any_of(
1058      display_surfaces_.begin(), display_surfaces_.end(),
1059      [](const auto& surface) {
1060        return !(surface->flags() &
1061                 DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION);
1062      });
1063
1064  if (!has_gpu_layer) {
1065    gpu_layer_ = nullptr;
1066  }
1067
1068  auto is_layer_active = [&display_surface_layers, has_gpu_layer](auto layer) {
1069    int surface_id = layer->GetSurfaceId();
1070    if (surface_id >= 0) {
1071      return display_surface_layers.count(surface_id) > 0;
1072    } else {
1073      return has_gpu_layer;
1074    }
1075  };
1076
1077  // Compress the in-use layers to the top of the list
1078  auto part = std::partition(
1079      layers_.begin(), layers_.begin() + active_layer_count_, is_layer_active);
1080
1081  size_t new_active_layer_count = part - layers_.begin();
1082
1083  // Clear any unused layers
1084  for (size_t i = new_active_layer_count; i < active_layer_count_; ++i) {
1085    layers_[i]->Reset();
1086  }
1087
1088  active_layer_count_ = new_active_layer_count;
1089
1090  bool gpu_layer_applied = false;
1091
1092  // Create/update all of the hardware layers
1093  for (size_t i = 0; i < display_surfaces_.size(); ++i) {
1094    const auto& surface = display_surfaces_[i];
1095    bool is_hw_surface =
1096        surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_DISABLE_SYSTEM_DISTORTION;
1097    hwc2_blend_mode_t blending =
1098        i == 0 ? HWC2_BLEND_MODE_NONE : HWC2_BLEND_MODE_COVERAGE;
1099
1100    DebugHudData::data.SetLayerInfo(
1101        i, surface->width(), surface->height(),
1102        !!(surface->flags() & DVR_DISPLAY_SURFACE_FLAGS_GEOMETRY_SEPARATE_2));
1103
1104    if (!is_hw_surface && gpu_layer_applied) {
1105      continue;
1106    }
1107
1108    Layer* target_layer;
1109    bool existing_layer = false;
1110
1111    if (is_hw_surface) {
1112      auto it = display_surface_layers.find(surface->surface_id());
1113
1114      if (it != display_surface_layers.end()) {
1115        target_layer = it->second;
1116        existing_layer = true;
1117      }
1118    } else if (gpu_layer_ != nullptr) {
1119      target_layer = gpu_layer_;
1120      existing_layer = true;
1121    }
1122
1123    if (!existing_layer) {
1124      if (active_layer_count_ >= kMaxHardwareLayers) {
1125        ALOGI("HardwareComposer: More than %d hardware layers requested.",
1126              kMaxHardwareLayers);
1127        break;
1128      } else {
1129        target_layer = layers_[active_layer_count_];
1130        ++active_layer_count_;
1131      }
1132
1133      ALOGD_IF(TRACE,
1134               "HardwareComposer::UpdateLayerConfig: (new) surface_id=%d -> "
1135               "layer=%zd",
1136               surface->surface_id(), i);
1137
1138      if (is_hw_surface) {
1139        target_layer->Setup(surface, blending, display_transform_,
1140                            HWC2_COMPOSITION_DEVICE, i);
1141      } else {
1142        gpu_layer_ = target_layer;
1143        target_layer->Setup(compositor_.GetBuffer(), blending,
1144                            display_transform_, HWC2_COMPOSITION_DEVICE, i);
1145      }
1146    } else {
1147      ALOGD_IF(TRACE,
1148               "HardwareComposer::UpdateLayerConfig: (retained) surface_id=%d "
1149               "-> layer=%zd",
1150               surface->surface_id(), i);
1151
1152      target_layer->SetBlending(blending);
1153      target_layer->SetZOrderIndex(i);
1154      target_layer->UpdateLayerSettings();
1155    }
1156
1157    gpu_layer_applied = !is_hw_surface;
1158  }
1159
1160  ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers",
1161           active_layer_count_);
1162
1163  return true;
1164}
1165
1166void HardwareComposer::PostCompositorBuffers() {
1167  ATRACE_NAME("PostCompositorBuffers");
1168  for (const auto& surface : compositor_surfaces_) {
1169    compositor_.PostBuffer(surface);
1170  }
1171}
1172
1173void HardwareComposer::UpdateFrameTimeHistory(
1174    std::vector<FrameTimeMeasurementRecord>* backlog, int backlog_max,
1175    FenceInfoBuffer* fence_info_buffer, FrameTimeHistory* history) {
1176  while (!backlog->empty()) {
1177    const auto& frame_time_record = backlog->front();
1178    int64_t end_time = 0;
1179    bool frame_finished = CheckFrameFinished(frame_time_record.fence.Get(),
1180                                             fence_info_buffer, &end_time);
1181    if (frame_finished) {
1182      int64_t frame_duration = end_time - frame_time_record.start_time;
1183      history->AddSample(frame_duration);
1184      // Our backlog is tiny (2 elements), so erasing from the front is ok
1185      backlog->erase(backlog->begin());
1186    } else {
1187      break;
1188    }
1189  }
1190
1191  if (backlog->size() == static_cast<size_t>(backlog_max)) {
1192    // Yikes, something must've gone wrong if our oldest frame hasn't finished
1193    // yet. Give up on waiting for it.
1194    const auto& stale_frame_time_record = backlog->front();
1195    int64_t frame_duration =
1196        GetSystemClockNs() - stale_frame_time_record.start_time;
1197    backlog->erase(backlog->begin());
1198    history->AddSample(frame_duration);
1199    ALOGW("Frame didn't finish after %.1fms",
1200          static_cast<double>(frame_duration) / 1000000);
1201  }
1202}
1203
1204bool HardwareComposer::CheckFrameFinished(int frame_fence_fd,
1205                                          FenceInfoBuffer* fence_info_buffer,
1206                                          int64_t* timestamp) {
1207  int result = -1;
1208  int sync_result = sync_wait(frame_fence_fd, 0);
1209  if (sync_result == 0) {
1210    result =
1211        GetFenceSignaledTimestamp(frame_fence_fd, fence_info_buffer, timestamp);
1212    if (result < 0) {
1213      ALOGE("Failed getting signaled timestamp from fence");
1214    }
1215  } else if (errno != ETIME) {
1216    ALOGE("sync_wait on frame fence failed");
1217  }
1218  return result >= 0;
1219}
1220
1221void HardwareComposer::HandlePendingScreenshots() {
1222  // Take a screenshot of the requested layer, if available.
1223  // TODO(eieio): Look into using virtual displays to composite the layer stack
1224  // into a single output buffer that can be returned to the screenshot clients.
1225  if (active_layer_count_ > 0) {
1226    if (auto screenshot_service = ScreenshotService::GetInstance()) {
1227      if (screenshot_service->IsScreenshotRequestPending()) {
1228        ATRACE_NAME("screenshot");
1229        screenshot_service->TakeIfNeeded(layers_, compositor_);
1230      }
1231    } else {
1232      ALOGW(
1233          "HardwareComposer::HandlePendingScreenshots: Failed to get "
1234          "screenshot service!");
1235    }
1236  }
1237}
1238
1239void HardwareComposer::SetVSyncCallback(VSyncCallback callback) {
1240  vsync_callback_ = callback;
1241}
1242
1243void HardwareComposer::HwcRefresh(hwc2_callback_data_t /*data*/,
1244                                  hwc2_display_t /*display*/) {
1245  // TODO(eieio): implement invalidate callbacks.
1246}
1247
1248void HardwareComposer::HwcVSync(hwc2_callback_data_t /*data*/,
1249                                hwc2_display_t /*display*/,
1250                                int64_t /*timestamp*/) {
1251  ATRACE_NAME(__PRETTY_FUNCTION__);
1252  // Intentionally empty. HWC may require a callback to be set to enable vsync
1253  // signals. We bypass this callback thread by monitoring the vsync event
1254  // directly, but signals still need to be enabled.
1255}
1256
1257void HardwareComposer::HwcHotplug(hwc2_callback_data_t /*callbackData*/,
1258                                  hwc2_display_t /*display*/,
1259                                  hwc2_connection_t /*connected*/) {
1260  // TODO(eieio): implement display hotplug callbacks.
1261}
1262
1263void HardwareComposer::OnHardwareComposerRefresh() {
1264  // TODO(steventhomas): Handle refresh.
1265}
1266
1267void HardwareComposer::SetBacklightBrightness(int brightness) {
1268  if (backlight_brightness_fd_) {
1269    std::array<char, 32> text;
1270    const int length = snprintf(text.data(), text.size(), "%d", brightness);
1271    write(backlight_brightness_fd_.Get(), text.data(), length);
1272  }
1273}
1274
1275Layer::Layer()
1276    : hwc2_hidl_(nullptr),
1277      surface_index_(-1),
1278      hardware_composer_layer_(0),
1279      display_metrics_(nullptr),
1280      blending_(HWC2_BLEND_MODE_NONE),
1281      transform_(HWC_TRANSFORM_NONE),
1282      composition_type_(HWC2_COMPOSITION_DEVICE),
1283      surface_rect_functions_applied_(false) {}
1284
1285void Layer::Initialize(Hwc2::Composer* hwc2_hidl, HWCDisplayMetrics* metrics) {
1286  hwc2_hidl_ = hwc2_hidl;
1287  display_metrics_ = metrics;
1288}
1289
1290void Layer::Reset() {
1291  const int ret = acquired_buffer_.Release(std::move(release_fence_));
1292  ALOGE_IF(ret < 0, "Layer::Reset: failed to release buffer: %s",
1293           strerror(-ret));
1294
1295  if (hwc2_hidl_ != nullptr && hardware_composer_layer_) {
1296    hwc2_hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_);
1297    hardware_composer_layer_ = 0;
1298  }
1299
1300  surface_index_ = static_cast<size_t>(-1);
1301  blending_ = HWC2_BLEND_MODE_NONE;
1302  transform_ = HWC_TRANSFORM_NONE;
1303  composition_type_ = HWC2_COMPOSITION_DEVICE;
1304  direct_buffer_ = nullptr;
1305  surface_ = nullptr;
1306  acquire_fence_fd_.Close();
1307  surface_rect_functions_applied_ = false;
1308}
1309
1310void Layer::Setup(const std::shared_ptr<DisplaySurface>& surface,
1311                  hwc2_blend_mode_t blending, hwc_transform_t transform,
1312                  hwc2_composition_t composition_type, size_t index) {
1313  Reset();
1314  surface_index_ = index;
1315  surface_ = surface;
1316  blending_ = blending;
1317  transform_ = transform;
1318  composition_type_ = composition_type;
1319  CommonLayerSetup();
1320}
1321
1322void Layer::Setup(const std::shared_ptr<IonBuffer>& buffer,
1323                  hwc2_blend_mode_t blending, hwc_transform_t transform,
1324                  hwc2_composition_t composition_type, size_t z_order) {
1325  Reset();
1326  surface_index_ = z_order;
1327  direct_buffer_ = buffer;
1328  blending_ = blending;
1329  transform_ = transform;
1330  composition_type_ = composition_type;
1331  CommonLayerSetup();
1332}
1333
1334void Layer::UpdateDirectBuffer(const std::shared_ptr<IonBuffer>& buffer) {
1335  direct_buffer_ = buffer;
1336}
1337
1338void Layer::SetBlending(hwc2_blend_mode_t blending) { blending_ = blending; }
1339
1340void Layer::SetZOrderIndex(int z_index) { surface_index_ = z_index; }
1341
1342IonBuffer* Layer::GetBuffer() {
1343  if (direct_buffer_)
1344    return direct_buffer_.get();
1345  else if (acquired_buffer_.IsAvailable())
1346    return acquired_buffer_.buffer()->buffer();
1347  else
1348    return nullptr;
1349}
1350
1351void Layer::UpdateLayerSettings() {
1352  if (!IsLayerSetup()) {
1353    ALOGE("HardwareComposer: Trying to update layers data on an unused layer.");
1354    return;
1355  }
1356
1357  int32_t ret = HWC2_ERROR_NONE;
1358
1359  hwc2_display_t display = HWC_DISPLAY_PRIMARY;
1360
1361  ret = (int32_t)hwc2_hidl_->setLayerCompositionType(
1362      display, hardware_composer_layer_,
1363      (Hwc2::IComposerClient::Composition)composition_type_);
1364  ALOGE_IF(ret, "HardwareComposer: Error setting layer composition type : %d",
1365           ret);
1366  // ret = (int32_t) hwc2_hidl_->setLayerTransform(display,
1367  // hardware_composer_layer_,
1368  //                                    (Hwc2::IComposerClient::Transform)
1369  //                                    transform_);
1370  // ALOGE_IF(ret, "HardwareComposer: Error setting layer transform : %d", ret);
1371
1372  // ret = hwc2_funcs_->set_layer_blend_mode_fn_(
1373  //    hardware_composer_device_, display, hardware_composer_layer_,
1374  //    blending_);
1375  ret = (int32_t)hwc2_hidl_->setLayerBlendMode(
1376      display, hardware_composer_layer_,
1377      (Hwc2::IComposerClient::BlendMode)blending_);
1378  ALOGE_IF(ret, "HardwareComposer: Error setting layer blend mode : %d", ret);
1379
1380  Hwc2::IComposerClient::Rect display_frame;
1381  display_frame.left = 0;
1382  display_frame.top = 0;
1383  display_frame.right = display_metrics_->width;
1384  display_frame.bottom = display_metrics_->height;
1385  ret = (int32_t)hwc2_hidl_->setLayerDisplayFrame(
1386      display, hardware_composer_layer_, display_frame);
1387  ALOGE_IF(ret, "HardwareComposer: Error setting layer display frame : %d",
1388           ret);
1389
1390  std::vector<Hwc2::IComposerClient::Rect> visible_region(1);
1391  visible_region[0] = display_frame;
1392  ret = (int32_t)hwc2_hidl_->setLayerVisibleRegion(
1393      display, hardware_composer_layer_, visible_region);
1394  ALOGE_IF(ret, "HardwareComposer: Error setting layer visible region : %d",
1395           ret);
1396
1397  ret = (int32_t)hwc2_hidl_->setLayerPlaneAlpha(display,
1398                                                hardware_composer_layer_, 1.0f);
1399  ALOGE_IF(ret, "HardwareComposer: Error setting layer plane alpha : %d", ret);
1400
1401  ret = (int32_t)hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_,
1402                                            surface_index_);
1403  ALOGE_IF(ret, "HardwareComposer: Error, setting z order index : %d", ret);
1404}
1405
1406void Layer::CommonLayerSetup() {
1407  int32_t ret = (int32_t)hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY,
1408                                                 &hardware_composer_layer_);
1409
1410  ALOGE_IF(ret,
1411           "HardwareComposer: Failed to create layer on primary display : %d",
1412           ret);
1413
1414  UpdateLayerSettings();
1415}
1416
1417void Layer::Prepare() {
1418  int right, bottom;
1419  sp<GraphicBuffer> handle;
1420
1421  if (surface_) {
1422    // Only update the acquired buffer when one is either available or this is
1423    // the first time through.
1424    if (surface_->IsBufferAvailable()) {
1425      // If we previously set this to a solid color layer to stall for time,
1426      // revert it to a device layer.
1427      if (acquired_buffer_.IsEmpty() &&
1428          composition_type_ != HWC2_COMPOSITION_DEVICE) {
1429        composition_type_ = HWC2_COMPOSITION_DEVICE;
1430        hwc2_hidl_->setLayerCompositionType(
1431            HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1432            (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_DEVICE);
1433      }
1434
1435      DebugHudData::data.AddLayerFrame(surface_index_);
1436      acquired_buffer_.Release(std::move(release_fence_));
1437      acquired_buffer_ = surface_->AcquireCurrentBuffer();
1438
1439      // Basic latency stopgap for when the application misses a frame:
1440      // If the application recovers on the 2nd or 3rd (etc) frame after
1441      // missing, this code will skip a frame to catch up by checking if
1442      // the next frame is also available.
1443      if (surface_->IsBufferAvailable()) {
1444        DebugHudData::data.SkipLayerFrame(surface_index_);
1445        ATRACE_NAME("DropToCatchUp");
1446        ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
1447        acquired_buffer_ = surface_->AcquireCurrentBuffer();
1448      }
1449      ATRACE_ASYNC_END("BufferPost", acquired_buffer_.buffer()->id());
1450    } else if (acquired_buffer_.IsEmpty()) {
1451      // While we are waiting for a buffer, set this to be an empty layer
1452      if (composition_type_ != HWC2_COMPOSITION_SOLID_COLOR) {
1453        composition_type_ = HWC2_COMPOSITION_SOLID_COLOR;
1454        hwc2_hidl_->setLayerCompositionType(
1455            HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1456            (Hwc2::IComposerClient::Composition)HWC2_COMPOSITION_SOLID_COLOR);
1457
1458        Hwc2::IComposerClient::Color layer_color = {
1459            0, 0, 0, 0,
1460        };
1461        hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
1462                                  layer_color);
1463      }
1464      return;
1465    }
1466    right = acquired_buffer_.buffer()->width();
1467    bottom = acquired_buffer_.buffer()->height();
1468    handle = acquired_buffer_.buffer()->buffer()->buffer();
1469    acquire_fence_fd_.Reset(acquired_buffer_.ClaimAcquireFence().Release());
1470  } else {
1471    // TODO(jwcai) Note: this is the GPU compositor's layer, and we need the
1472    // mechanism to accept distorted layers from VrCore.
1473    right = direct_buffer_->width();
1474    bottom = direct_buffer_->height();
1475    handle = direct_buffer_->buffer();
1476    acquire_fence_fd_.Close();
1477  }
1478
1479  int32_t ret = HWC2_ERROR_NONE;
1480
1481  if (composition_type_ == HWC2_COMPOSITION_DEVICE) {
1482    ret = (int32_t)hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
1483                                              hardware_composer_layer_, 0,
1484                                              handle,
1485                                              acquire_fence_fd_.Get());
1486
1487    ALOGE_IF(ret, "HardwareComposer: Error setting layer buffer : %d", ret);
1488  }
1489
1490  if (!surface_rect_functions_applied_) {
1491    Hwc2::IComposerClient::FRect crop_rect = {
1492        0, 0, static_cast<float>(right), static_cast<float>(bottom),
1493    };
1494    hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
1495                                   hardware_composer_layer_, crop_rect);
1496
1497    ALOGE_IF(ret, "HardwareComposer: Error setting layer source crop : %d",
1498             ret);
1499
1500// TODO(skiazyk): why is this ifdef'd out. Is if a driver-specific issue where
1501// it must/cannot be called?
1502#ifdef QCOM_BSP
1503    hwc_rect_t damage_rect = {
1504        0, 0, right, bottom,
1505    };
1506    hwc_region_t damage = {
1507        1, &damage_rect,
1508    };
1509    // ret = hwc2_funcs_->set_layer_surface_damage(
1510    //    hardware_composer_device_, HWC_DISPLAY_PRIMARY,
1511    //    hardware_composer_layer_, damage);
1512    // uses a std::vector as the listing
1513    // hwc2_hidl_->setLayerSurfaceDamage(HWC_DISPLAY_PRIMARY,
1514    // hardware_composer_layer_, vector here);
1515
1516    ALOGE_IF(ret, "HardwareComposer: Error settings layer surface damage : %d",
1517             ret);
1518#endif
1519
1520    surface_rect_functions_applied_ = true;
1521  }
1522}
1523
1524void Layer::Finish(int release_fence_fd) {
1525  release_fence_.Reset(release_fence_fd);
1526}
1527
1528void Layer::Drop() { acquire_fence_fd_.Close(); }
1529
1530}  // namespace dvr
1531}  // namespace android
1532