#include "hardware_composer.h"

#include <cutils/properties.h>
#include <cutils/sched_policy.h>
#include <fcntl.h>
#include <log/log.h>
#include <poll.h>
#include <sync/sync.h>
#include <sys/eventfd.h>
#include <sys/prctl.h>
#include <sys/resource.h>
#include <sys/system_properties.h>
#include <sys/timerfd.h>
#include <time.h>
#include <unistd.h>
#include <utils/Trace.h>

#include <algorithm>
#include <chrono>
#include <functional>
#include <map>
#include <sstream>
#include <string>
#include <tuple>

#include <dvr/dvr_display_types.h>
#include <dvr/performance_client_api.h>
#include <private/dvr/clock_ns.h>
#include <private/dvr/ion_buffer.h>

using android::pdx::LocalHandle;
using android::pdx::rpc::EmptyVariant;
using android::pdx::rpc::IfAnyOf;

using namespace std::chrono_literals;

namespace android {
namespace dvr {

namespace {

const char kBacklightBrightnessSysFile[] =
    "/sys/class/leds/lcd-backlight/brightness";

const char kPrimaryDisplayVSyncEventFile[] =
    "/sys/class/graphics/fb0/vsync_event";

const char kPrimaryDisplayWaitPPEventFile[] = "/sys/class/graphics/fb0/wait_pp";

const char kDvrPerformanceProperty[] = "sys.dvr.performance";

const char kRightEyeOffsetProperty[] = "dvr.right_eye_offset_ns";

// Get time offset from a vsync to when the pose for that vsync should be
// predicted out to. For example, if scanout gets halfway through the frame
// at the halfway point between vsyncs, then this could be half the period.
// With global shutter displays, this should be changed to the offset to when
// illumination begins. Low persistence adds a frame of latency, so we predict
// to the center of the next frame.
inline int64_t GetPosePredictionTimeOffset(int64_t vsync_period_ns) {
  return (vsync_period_ns * 150) / 100;
}

// Attempts to set the scheduler class and partiton for the current thread.
// Returns true on success or false on failure.
bool SetThreadPolicy(const std::string& scheduler_class,
                     const std::string& partition) {
  int error = dvrSetSchedulerClass(0, scheduler_class.c_str());
  if (error < 0) {
    ALOGE(
        "SetThreadPolicy: Failed to set scheduler class \"%s\" for "
        "thread_id=%d: %s",
        scheduler_class.c_str(), gettid(), strerror(-error));
    return false;
  }
  error = dvrSetCpuPartition(0, partition.c_str());
  if (error < 0) {
    ALOGE(
        "SetThreadPolicy: Failed to set cpu partiton \"%s\" for thread_id=%d: "
        "%s",
        partition.c_str(), gettid(), strerror(-error));
    return false;
  }
  return true;
}

}  // anonymous namespace

// Layer static data.
Hwc2::Composer* Layer::hwc2_hidl_;
const HWCDisplayMetrics* Layer::display_metrics_;

// HardwareComposer static data;
constexpr size_t HardwareComposer::kMaxHardwareLayers;

HardwareComposer::HardwareComposer()
    : HardwareComposer(nullptr, RequestDisplayCallback()) {}

HardwareComposer::HardwareComposer(
    Hwc2::Composer* hwc2_hidl, RequestDisplayCallback request_display_callback)
    : initialized_(false),
      hwc2_hidl_(hwc2_hidl),
      request_display_callback_(request_display_callback),
      callbacks_(new ComposerCallback) {}

HardwareComposer::~HardwareComposer(void) {
  UpdatePostThreadState(PostThreadState::Quit, true);
  if (post_thread_.joinable())
    post_thread_.join();
}

bool HardwareComposer::Initialize() {
  if (initialized_) {
    ALOGE("HardwareComposer::Initialize: already initialized.");
    return false;
  }

  HWC::Error error = HWC::Error::None;

  Hwc2::Config config;
  error = hwc2_hidl_->getActiveConfig(HWC_DISPLAY_PRIMARY, &config);

  if (error != HWC::Error::None) {
    ALOGE("HardwareComposer: Failed to get current display config : %d",
          config);
    return false;
  }

  error =
      GetDisplayMetrics(HWC_DISPLAY_PRIMARY, config, &native_display_metrics_);

  if (error != HWC::Error::None) {
    ALOGE(
        "HardwareComposer: Failed to get display attributes for current "
        "configuration : %d",
        error.value);
    return false;
  }

  ALOGI(
      "HardwareComposer: primary display attributes: width=%d height=%d "
      "vsync_period_ns=%d DPI=%dx%d",
      native_display_metrics_.width, native_display_metrics_.height,
      native_display_metrics_.vsync_period_ns, native_display_metrics_.dpi.x,
      native_display_metrics_.dpi.y);

  // Set the display metrics but never use rotation to avoid the long latency of
  // rotation processing in hwc.
  display_transform_ = HWC_TRANSFORM_NONE;
  display_metrics_ = native_display_metrics_;

  // Pass hwc instance and metrics to setup globals for Layer.
  Layer::InitializeGlobals(hwc2_hidl_, &native_display_metrics_);

  post_thread_event_fd_.Reset(eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK));
  LOG_ALWAYS_FATAL_IF(
      !post_thread_event_fd_,
      "HardwareComposer: Failed to create interrupt event fd : %s",
      strerror(errno));

  post_thread_ = std::thread(&HardwareComposer::PostThread, this);

  initialized_ = true;

  return initialized_;
}

void HardwareComposer::Enable() {
  UpdatePostThreadState(PostThreadState::Suspended, false);
}

void HardwareComposer::Disable() {
  UpdatePostThreadState(PostThreadState::Suspended, true);
}

// Update the post thread quiescent state based on idle and suspended inputs.
void HardwareComposer::UpdatePostThreadState(PostThreadStateType state,
                                             bool suspend) {
  std::unique_lock<std::mutex> lock(post_thread_mutex_);

  // Update the votes in the state variable before evaluating the effective
  // quiescent state. Any bits set in post_thread_state_ indicate that the post
  // thread should be suspended.
  if (suspend) {
    post_thread_state_ |= state;
  } else {
    post_thread_state_ &= ~state;
  }

  const bool quit = post_thread_state_ & PostThreadState::Quit;
  const bool effective_suspend = post_thread_state_ != PostThreadState::Active;
  if (quit) {
    post_thread_quiescent_ = true;
    eventfd_write(post_thread_event_fd_.Get(), 1);
    post_thread_wait_.notify_one();
  } else if (effective_suspend && !post_thread_quiescent_) {
    post_thread_quiescent_ = true;
    eventfd_write(post_thread_event_fd_.Get(), 1);
  } else if (!effective_suspend && post_thread_quiescent_) {
    post_thread_quiescent_ = false;
    eventfd_t value;
    eventfd_read(post_thread_event_fd_.Get(), &value);
    post_thread_wait_.notify_one();
  }

  // Wait until the post thread is in the requested state.
  post_thread_ready_.wait(lock, [this, effective_suspend] {
    return effective_suspend != post_thread_resumed_;
  });
}

void HardwareComposer::OnPostThreadResumed() {
  hwc2_hidl_->resetCommands();

  // HIDL HWC seems to have an internal race condition. If we submit a frame too
  // soon after turning on VSync we don't get any VSync signals. Give poor HWC
  // implementations a chance to enable VSync before we continue.
  EnableVsync(false);
  std::this_thread::sleep_for(100ms);
  EnableVsync(true);
  std::this_thread::sleep_for(100ms);

  // TODO(skiazyk): We need to do something about accessing this directly,
  // supposedly there is a backlight service on the way.
  // TODO(steventhomas): When we change the backlight setting, will surface
  // flinger (or something else) set it back to its original value once we give
  // control of the display back to surface flinger?
  SetBacklightBrightness(255);

  // Trigger target-specific performance mode change.
  property_set(kDvrPerformanceProperty, "performance");
}

void HardwareComposer::OnPostThreadPaused() {
  retire_fence_fds_.clear();
  display_surfaces_.clear();

  for (size_t i = 0; i < kMaxHardwareLayers; ++i) {
    layers_[i].Reset();
  }
  active_layer_count_ = 0;

  EnableVsync(false);

  hwc2_hidl_->resetCommands();

  // Trigger target-specific performance mode change.
  property_set(kDvrPerformanceProperty, "idle");
}

HWC::Error HardwareComposer::Validate(hwc2_display_t display) {
  uint32_t num_types;
  uint32_t num_requests;
  HWC::Error error =
      hwc2_hidl_->validateDisplay(display, &num_types, &num_requests);

  if (error == HWC2_ERROR_HAS_CHANGES) {
    // TODO(skiazyk): We might need to inspect the requested changes first, but
    // so far it seems like we shouldn't ever hit a bad state.
    // error = hwc2_funcs_.accept_display_changes_fn_(hardware_composer_device_,
    //                                               display);
    error = hwc2_hidl_->acceptDisplayChanges(display);
  }

  return error;
}

int32_t HardwareComposer::EnableVsync(bool enabled) {
  return (int32_t)hwc2_hidl_->setVsyncEnabled(
      HWC_DISPLAY_PRIMARY,
      (Hwc2::IComposerClient::Vsync)(enabled ? HWC2_VSYNC_ENABLE
                                             : HWC2_VSYNC_DISABLE));
}

HWC::Error HardwareComposer::Present(hwc2_display_t display) {
  int32_t present_fence;
  HWC::Error error = hwc2_hidl_->presentDisplay(display, &present_fence);

  // According to the documentation, this fence is signaled at the time of
  // vsync/DMA for physical displays.
  if (error == HWC::Error::None) {
    ATRACE_INT("HardwareComposer: VsyncFence", present_fence);
    retire_fence_fds_.emplace_back(present_fence);
  } else {
    ATRACE_INT("HardwareComposer: PresentResult", error);
  }

  return error;
}

HWC::Error HardwareComposer::GetDisplayAttribute(hwc2_display_t display,
                                                 hwc2_config_t config,
                                                 hwc2_attribute_t attribute,
                                                 int32_t* out_value) const {
  return hwc2_hidl_->getDisplayAttribute(
      display, config, (Hwc2::IComposerClient::Attribute)attribute, out_value);
}

HWC::Error HardwareComposer::GetDisplayMetrics(
    hwc2_display_t display, hwc2_config_t config,
    HWCDisplayMetrics* out_metrics) const {
  HWC::Error error;

  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_WIDTH,
                              &out_metrics->width);
  if (error != HWC::Error::None) {
    ALOGE(
        "HardwareComposer::GetDisplayMetrics: Failed to get display width: %s",
        error.to_string().c_str());
    return error;
  }

  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_HEIGHT,
                              &out_metrics->height);
  if (error != HWC::Error::None) {
    ALOGE(
        "HardwareComposer::GetDisplayMetrics: Failed to get display height: %s",
        error.to_string().c_str());
    return error;
  }

  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_VSYNC_PERIOD,
                              &out_metrics->vsync_period_ns);
  if (error != HWC::Error::None) {
    ALOGE(
        "HardwareComposer::GetDisplayMetrics: Failed to get display height: %s",
        error.to_string().c_str());
    return error;
  }

  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_X,
                              &out_metrics->dpi.x);
  if (error != HWC::Error::None) {
    ALOGE(
        "HardwareComposer::GetDisplayMetrics: Failed to get display DPI X: %s",
        error.to_string().c_str());
    return error;
  }

  error = GetDisplayAttribute(display, config, HWC2_ATTRIBUTE_DPI_Y,
                              &out_metrics->dpi.y);
  if (error != HWC::Error::None) {
    ALOGE(
        "HardwareComposer::GetDisplayMetrics: Failed to get display DPI Y: %s",
        error.to_string().c_str());
    return error;
  }

  return HWC::Error::None;
}

std::string HardwareComposer::Dump() {
  std::unique_lock<std::mutex> lock(post_thread_mutex_);
  std::ostringstream stream;

  stream << "Display metrics:     " << display_metrics_.width << "x"
         << display_metrics_.height << " " << (display_metrics_.dpi.x / 1000.0)
         << "x" << (display_metrics_.dpi.y / 1000.0) << " dpi @ "
         << (1000000000.0 / display_metrics_.vsync_period_ns) << " Hz"
         << std::endl;

  stream << "Post thread resumed: " << post_thread_resumed_ << std::endl;
  stream << "Active layers:       " << active_layer_count_ << std::endl;
  stream << std::endl;

  for (size_t i = 0; i < active_layer_count_; i++) {
    stream << "Layer " << i << ":";
    stream << " type=" << layers_[i].GetCompositionType().to_string();
    stream << " surface_id=" << layers_[i].GetSurfaceId();
    stream << " buffer_id=" << layers_[i].GetBufferId();
    stream << std::endl;
  }
  stream << std::endl;

  if (post_thread_resumed_) {
    stream << "Hardware Composer Debug Info:" << std::endl;
    stream << hwc2_hidl_->dumpDebugInfo();
  }

  return stream.str();
}

void HardwareComposer::PostLayers() {
  ATRACE_NAME("HardwareComposer::PostLayers");

  // Setup the hardware composer layers with current buffers.
  for (size_t i = 0; i < active_layer_count_; i++) {
    layers_[i].Prepare();
  }

  HWC::Error error = Validate(HWC_DISPLAY_PRIMARY);
  if (error != HWC::Error::None) {
    ALOGE("HardwareComposer::PostLayers: Validate failed: %s",
          error.to_string().c_str());
    return;
  }

  // Now that we have taken in a frame from the application, we have a chance
  // to drop the frame before passing the frame along to HWC.
  // If the display driver has become backed up, we detect it here and then
  // react by skipping this frame to catch up latency.
  while (!retire_fence_fds_.empty() &&
         (!retire_fence_fds_.front() ||
          sync_wait(retire_fence_fds_.front().Get(), 0) == 0)) {
    // There are only 2 fences in here, no performance problem to shift the
    // array of ints.
    retire_fence_fds_.erase(retire_fence_fds_.begin());
  }

  const bool is_frame_pending = IsFramePendingInDriver();
  const bool is_fence_pending = retire_fence_fds_.size() >
                                post_thread_config_.allowed_pending_fence_count;

  if (is_fence_pending || is_frame_pending) {
    ATRACE_INT("frame_skip_count", ++frame_skip_count_);

    ALOGW_IF(is_frame_pending, "Warning: frame already queued, dropping frame");
    ALOGW_IF(is_fence_pending,
             "Warning: dropping a frame to catch up with HWC (pending = %zd)",
             retire_fence_fds_.size());

    for (size_t i = 0; i < active_layer_count_; i++) {
      layers_[i].Drop();
    }
    return;
  } else {
    // Make the transition more obvious in systrace when the frame skip happens
    // above.
    ATRACE_INT("frame_skip_count", 0);
  }

#if TRACE > 1
  for (size_t i = 0; i < active_layer_count_; i++) {
    ALOGI("HardwareComposer::PostLayers: layer=%zu buffer_id=%d composition=%s",
          i, layers_[i].GetBufferId(),
          layers_[i].GetCompositionType().to_string().c_str());
  }
#endif

  error = Present(HWC_DISPLAY_PRIMARY);
  if (error != HWC::Error::None) {
    ALOGE("HardwareComposer::PostLayers: Present failed: %s",
          error.to_string().c_str());
    return;
  }

  std::vector<Hwc2::Layer> out_layers;
  std::vector<int> out_fences;
  error = hwc2_hidl_->getReleaseFences(HWC_DISPLAY_PRIMARY, &out_layers,
                                       &out_fences);
  ALOGE_IF(error != HWC::Error::None,
           "HardwareComposer::PostLayers: Failed to get release fences: %s",
           error.to_string().c_str());

  // Perform post-frame bookkeeping. Unused layers are a no-op.
  uint32_t num_elements = out_layers.size();
  for (size_t i = 0; i < num_elements; ++i) {
    for (size_t j = 0; j < active_layer_count_; ++j) {
      if (layers_[j].GetLayerHandle() == out_layers[i]) {
        layers_[j].Finish(out_fences[i]);
      }
    }
  }
}

void HardwareComposer::SetDisplaySurfaces(
    std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces) {
  ALOGI("HardwareComposer::SetDisplaySurfaces: surface count=%zd",
        surfaces.size());
  const bool display_idle = surfaces.size() == 0;
  {
    std::unique_lock<std::mutex> lock(post_thread_mutex_);
    pending_surfaces_ = std::move(surfaces);
  }

  if (request_display_callback_)
    request_display_callback_(!display_idle);

  // Set idle state based on whether there are any surfaces to handle.
  UpdatePostThreadState(PostThreadState::Idle, display_idle);
}

int HardwareComposer::OnNewGlobalBuffer(DvrGlobalBufferKey key,
                                        IonBuffer& ion_buffer) {
  if (key == DvrGlobalBuffers::kVsyncBuffer) {
    vsync_ring_ = std::make_unique<CPUMappedBroadcastRing<DvrVsyncRing>>(
        &ion_buffer, CPUUsageMode::WRITE_OFTEN);

    if (vsync_ring_->IsMapped() == false) {
      return -EPERM;
    }
  }

  if (key == DvrGlobalBuffers::kVrFlingerConfigBufferKey) {
    return MapConfigBuffer(ion_buffer);
  }

  return 0;
}

void HardwareComposer::OnDeletedGlobalBuffer(DvrGlobalBufferKey key) {
  if (key == DvrGlobalBuffers::kVrFlingerConfigBufferKey) {
    ConfigBufferDeleted();
  }
}

int HardwareComposer::MapConfigBuffer(IonBuffer& ion_buffer) {
  std::lock_guard<std::mutex> lock(shared_config_mutex_);
  shared_config_ring_ = DvrConfigRing();

  if (ion_buffer.width() < DvrConfigRing::MemorySize()) {
    ALOGE("HardwareComposer::MapConfigBuffer: invalid buffer size.");
    return -EINVAL;
  }

  void* buffer_base = 0;
  int result = ion_buffer.Lock(ion_buffer.usage(), 0, 0, ion_buffer.width(),
                               ion_buffer.height(), &buffer_base);
  if (result != 0) {
    ALOGE(
        "HardwareComposer::MapConfigBuffer: Failed to map vrflinger config "
        "buffer.");
    return -EPERM;
  }

  shared_config_ring_ = DvrConfigRing::Create(buffer_base, ion_buffer.width());
  ion_buffer.Unlock();

  return 0;
}

void HardwareComposer::ConfigBufferDeleted() {
  std::lock_guard<std::mutex> lock(shared_config_mutex_);
  shared_config_ring_ = DvrConfigRing();
}

void HardwareComposer::UpdateConfigBuffer() {
  std::lock_guard<std::mutex> lock(shared_config_mutex_);
  if (!shared_config_ring_.is_valid())
    return;
  // Copy from latest record in shared_config_ring_ to local copy.
  DvrConfig record;
  if (shared_config_ring_.GetNewest(&shared_config_ring_sequence_, &record)) {
    post_thread_config_ = record;
  }
}

int HardwareComposer::PostThreadPollInterruptible(
    const pdx::LocalHandle& event_fd, int requested_events) {
  pollfd pfd[2] = {
      {
          .fd = event_fd.Get(),
          .events = static_cast<short>(requested_events),
          .revents = 0,
      },
      {
          .fd = post_thread_event_fd_.Get(),
          .events = POLLPRI | POLLIN,
          .revents = 0,
      },
  };
  int ret, error;
  do {
    ret = poll(pfd, 2, -1);
    error = errno;
    ALOGW_IF(ret < 0,
             "HardwareComposer::PostThreadPollInterruptible: Error during "
             "poll(): %s (%d)",
             strerror(error), error);
  } while (ret < 0 && error == EINTR);

  if (ret < 0) {
    return -error;
  } else if (pfd[0].revents != 0) {
    return 0;
  } else if (pfd[1].revents != 0) {
    ALOGI("VrHwcPost thread interrupted");
    return kPostThreadInterrupted;
  } else {
    return 0;
  }
}

// Reads the value of the display driver wait_pingpong state. Returns 0 or 1
// (the value of the state) on success or a negative error otherwise.
// TODO(eieio): This is pretty driver specific, this should be moved to a
// separate class eventually.
int HardwareComposer::ReadWaitPPState() {
  // Gracefully handle when the kernel does not support this feature.
  if (!primary_display_wait_pp_fd_)
    return 0;

  const int wait_pp_fd = primary_display_wait_pp_fd_.Get();
  int ret, error;

  ret = lseek(wait_pp_fd, 0, SEEK_SET);
  if (ret < 0) {
    error = errno;
    ALOGE("HardwareComposer::ReadWaitPPState: Failed to seek wait_pp fd: %s",
          strerror(error));
    return -error;
  }

  char data = -1;
  ret = read(wait_pp_fd, &data, sizeof(data));
  if (ret < 0) {
    error = errno;
    ALOGE("HardwareComposer::ReadWaitPPState: Failed to read wait_pp state: %s",
          strerror(error));
    return -error;
  }

  switch (data) {
    case '0':
      return 0;
    case '1':
      return 1;
    default:
      ALOGE(
          "HardwareComposer::ReadWaitPPState: Unexpected value for wait_pp: %d",
          data);
      return -EINVAL;
  }
}

// Reads the timestamp of the last vsync from the display driver.
// TODO(eieio): This is pretty driver specific, this should be moved to a
// separate class eventually.
int HardwareComposer::ReadVSyncTimestamp(int64_t* timestamp) {
  const int event_fd = primary_display_vsync_event_fd_.Get();
  int ret, error;

  // The driver returns data in the form "VSYNC=<timestamp ns>".
  std::array<char, 32> data;
  data.fill('\0');

  // Seek back to the beginning of the event file.
  ret = lseek(event_fd, 0, SEEK_SET);
  if (ret < 0) {
    error = errno;
    ALOGE(
        "HardwareComposer::ReadVSyncTimestamp: Failed to seek vsync event fd: "
        "%s",
        strerror(error));
    return -error;
  }

  // Read the vsync event timestamp.
  ret = read(event_fd, data.data(), data.size());
  if (ret < 0) {
    error = errno;
    ALOGE_IF(
        error != EAGAIN,
        "HardwareComposer::ReadVSyncTimestamp: Error while reading timestamp: "
        "%s",
        strerror(error));
    return -error;
  }

  ret = sscanf(data.data(), "VSYNC=%" PRIu64,
               reinterpret_cast<uint64_t*>(timestamp));
  if (ret < 0) {
    error = errno;
    ALOGE(
        "HardwareComposer::ReadVSyncTimestamp: Error while parsing timestamp: "
        "%s",
        strerror(error));
    return -error;
  }

  return 0;
}

// Blocks until the next vsync event is signaled by the display driver.
// TODO(eieio): This is pretty driver specific, this should be moved to a
// separate class eventually.
int HardwareComposer::BlockUntilVSync() {
  // Vsync is signaled by POLLPRI on the fb vsync node.
  return PostThreadPollInterruptible(primary_display_vsync_event_fd_, POLLPRI);
}

// Waits for the next vsync and returns the timestamp of the vsync event. If
// vsync already passed since the last call, returns the latest vsync timestamp
// instead of blocking. This method updates the last_vsync_timeout_ in the
// process.
//
// TODO(eieio): This is pretty driver specific, this should be moved to a
// separate class eventually.
int HardwareComposer::WaitForVSync(int64_t* timestamp) {
  int error;

  // Get the current timestamp and decide what to do.
  while (true) {
    int64_t current_vsync_timestamp;
    error = ReadVSyncTimestamp(&current_vsync_timestamp);
    if (error < 0 && error != -EAGAIN)
      return error;

    if (error == -EAGAIN) {
      // Vsync was turned off, wait for the next vsync event.
      error = BlockUntilVSync();
      if (error < 0 || error == kPostThreadInterrupted)
        return error;

      // Try again to get the timestamp for this new vsync interval.
      continue;
    }

    // Check that we advanced to a later vsync interval.
    if (TimestampGT(current_vsync_timestamp, last_vsync_timestamp_)) {
      *timestamp = last_vsync_timestamp_ = current_vsync_timestamp;
      return 0;
    }

    // See how close we are to the next expected vsync. If we're within 1ms,
    // sleep for 1ms and try again.
    const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
    const int64_t threshold_ns = 1000000;  // 1ms

    const int64_t next_vsync_est = last_vsync_timestamp_ + ns_per_frame;
    const int64_t distance_to_vsync_est = next_vsync_est - GetSystemClockNs();

    if (distance_to_vsync_est > threshold_ns) {
      // Wait for vsync event notification.
      error = BlockUntilVSync();
      if (error < 0 || error == kPostThreadInterrupted)
        return error;
    } else {
      // Sleep for a short time (1 millisecond) before retrying.
      error = SleepUntil(GetSystemClockNs() + threshold_ns);
      if (error < 0 || error == kPostThreadInterrupted)
        return error;
    }
  }
}

int HardwareComposer::SleepUntil(int64_t wakeup_timestamp) {
  const int timer_fd = vsync_sleep_timer_fd_.Get();
  const itimerspec wakeup_itimerspec = {
      .it_interval = {.tv_sec = 0, .tv_nsec = 0},
      .it_value = NsToTimespec(wakeup_timestamp),
  };
  int ret =
      timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &wakeup_itimerspec, nullptr);
  int error = errno;
  if (ret < 0) {
    ALOGE("HardwareComposer::SleepUntil: Failed to set timerfd: %s",
          strerror(error));
    return -error;
  }

  return PostThreadPollInterruptible(vsync_sleep_timer_fd_, POLLIN);
}

void HardwareComposer::PostThread() {
  // NOLINTNEXTLINE(runtime/int)
  prctl(PR_SET_NAME, reinterpret_cast<unsigned long>("VrHwcPost"), 0, 0, 0);

  // Set the scheduler to SCHED_FIFO with high priority. If this fails here
  // there may have been a startup timing issue between this thread and
  // performanced. Try again later when this thread becomes active.
  bool thread_policy_setup =
      SetThreadPolicy("graphics:high", "/system/performance");

#if ENABLE_BACKLIGHT_BRIGHTNESS
  // TODO(hendrikw): This isn't required at the moment. It's possible that there
  //                 is another method to access this when needed.
  // Open the backlight brightness control sysfs node.
  backlight_brightness_fd_ = LocalHandle(kBacklightBrightnessSysFile, O_RDWR);
  ALOGW_IF(!backlight_brightness_fd_,
           "HardwareComposer: Failed to open backlight brightness control: %s",
           strerror(errno));
#endif  // ENABLE_BACKLIGHT_BRIGHTNESS

  // Open the vsync event node for the primary display.
  // TODO(eieio): Move this into a platform-specific class.
  primary_display_vsync_event_fd_ =
      LocalHandle(kPrimaryDisplayVSyncEventFile, O_RDONLY);
  ALOGE_IF(!primary_display_vsync_event_fd_,
           "HardwareComposer: Failed to open vsync event node for primary "
           "display: %s",
           strerror(errno));

  // Open the wait pingpong status node for the primary display.
  // TODO(eieio): Move this into a platform-specific class.
  primary_display_wait_pp_fd_ =
      LocalHandle(kPrimaryDisplayWaitPPEventFile, O_RDONLY);
  ALOGW_IF(
      !primary_display_wait_pp_fd_,
      "HardwareComposer: Failed to open wait_pp node for primary display: %s",
      strerror(errno));

  // Create a timerfd based on CLOCK_MONOTINIC.
  vsync_sleep_timer_fd_.Reset(timerfd_create(CLOCK_MONOTONIC, 0));
  LOG_ALWAYS_FATAL_IF(
      !vsync_sleep_timer_fd_,
      "HardwareComposer: Failed to create vsync sleep timerfd: %s",
      strerror(errno));

  const int64_t ns_per_frame = display_metrics_.vsync_period_ns;
  const int64_t photon_offset_ns = GetPosePredictionTimeOffset(ns_per_frame);

  // TODO(jbates) Query vblank time from device, when such an API is available.
  // This value (6.3%) was measured on A00 in low persistence mode.
  int64_t vblank_ns = ns_per_frame * 63 / 1000;
  int64_t right_eye_photon_offset_ns = (ns_per_frame - vblank_ns) / 2;

  // Check property for overriding right eye offset value.
  right_eye_photon_offset_ns =
      property_get_int64(kRightEyeOffsetProperty, right_eye_photon_offset_ns);

  bool was_running = false;

  while (1) {
    ATRACE_NAME("HardwareComposer::PostThread");

    // Check for updated config once per vsync.
    UpdateConfigBuffer();

    while (post_thread_quiescent_) {
      std::unique_lock<std::mutex> lock(post_thread_mutex_);
      ALOGI("HardwareComposer::PostThread: Entering quiescent state.");

      // Tear down resources if necessary.
      if (was_running)
        OnPostThreadPaused();

      was_running = false;
      post_thread_resumed_ = false;
      post_thread_ready_.notify_all();

      if (post_thread_state_ & PostThreadState::Quit) {
        ALOGI("HardwareComposer::PostThread: Quitting.");
        return;
      }

      post_thread_wait_.wait(lock, [this] { return !post_thread_quiescent_; });

      post_thread_resumed_ = true;
      post_thread_ready_.notify_all();

      ALOGI("HardwareComposer::PostThread: Exiting quiescent state.");
    }

    if (!was_running) {
      // Setup resources.
      OnPostThreadResumed();
      was_running = true;

      // Try to setup the scheduler policy if it failed during startup. Only
      // attempt to do this on transitions from inactive to active to avoid
      // spamming the system with RPCs and log messages.
      if (!thread_policy_setup) {
        thread_policy_setup =
            SetThreadPolicy("graphics:high", "/system/performance");
      }
    }

    int64_t vsync_timestamp = 0;
    {
      std::array<char, 128> buf;
      snprintf(buf.data(), buf.size(), "wait_vsync|vsync=%d|",
               vsync_count_ + 1);
      ATRACE_NAME(buf.data());

      const int error = WaitForVSync(&vsync_timestamp);
      ALOGE_IF(
          error < 0,
          "HardwareComposer::PostThread: Failed to wait for vsync event: %s",
          strerror(-error));
      // Don't bother processing this frame if a pause was requested
      if (error == kPostThreadInterrupted)
        continue;
    }

    ++vsync_count_;

    const bool layer_config_changed = UpdateLayerConfig();

    // Publish the vsync event.
    if (vsync_ring_) {
      DvrVsync vsync;
      vsync.vsync_count = vsync_count_;
      vsync.vsync_timestamp_ns = vsync_timestamp;
      vsync.vsync_left_eye_offset_ns = photon_offset_ns;
      vsync.vsync_right_eye_offset_ns = right_eye_photon_offset_ns;
      vsync.vsync_period_ns = ns_per_frame;

      vsync_ring_->Publish(vsync);
    }

    // Signal all of the vsync clients. Because absolute time is used for the
    // wakeup time below, this can take a little time if necessary.
    if (vsync_callback_)
      vsync_callback_(HWC_DISPLAY_PRIMARY, vsync_timestamp,
                      /*frame_time_estimate*/ 0, vsync_count_);

    {
      // Sleep until shortly before vsync.
      ATRACE_NAME("sleep");

      const int64_t display_time_est_ns = vsync_timestamp + ns_per_frame;
      const int64_t now_ns = GetSystemClockNs();
      const int64_t sleep_time_ns = display_time_est_ns - now_ns -
                                    post_thread_config_.frame_post_offset_ns;
      const int64_t wakeup_time_ns =
          display_time_est_ns - post_thread_config_.frame_post_offset_ns;

      ATRACE_INT64("sleep_time_ns", sleep_time_ns);
      if (sleep_time_ns > 0) {
        int error = SleepUntil(wakeup_time_ns);
        ALOGE_IF(error < 0, "HardwareComposer::PostThread: Failed to sleep: %s",
                 strerror(-error));
        if (error == kPostThreadInterrupted) {
          if (layer_config_changed) {
            // If the layer config changed we need to validateDisplay() even if
            // we're going to drop the frame, to flush the Composer object's
            // internal command buffer and apply our layer changes.
            Validate(HWC_DISPLAY_PRIMARY);
          }
          continue;
        }
      }
    }

    PostLayers();
  }
}

// Checks for changes in the surface stack and updates the layer config to
// accomodate the new stack.
bool HardwareComposer::UpdateLayerConfig() {
  std::vector<std::shared_ptr<DirectDisplaySurface>> surfaces;
  {
    std::unique_lock<std::mutex> lock(post_thread_mutex_);
    if (pending_surfaces_.empty())
      return false;

    surfaces = std::move(pending_surfaces_);
  }

  ATRACE_NAME("UpdateLayerConfig_HwLayers");

  display_surfaces_.clear();

  Layer* target_layer;
  size_t layer_index;
  for (layer_index = 0;
       layer_index < std::min(surfaces.size(), kMaxHardwareLayers);
       layer_index++) {
    // The bottom layer is opaque, other layers blend.
    HWC::BlendMode blending =
        layer_index == 0 ? HWC::BlendMode::None : HWC::BlendMode::Coverage;
    layers_[layer_index].Setup(surfaces[layer_index], blending,
                               display_transform_, HWC::Composition::Device,
                               layer_index);
    display_surfaces_.push_back(surfaces[layer_index]);
  }

  // Clear unused layers.
  for (size_t i = layer_index; i < kMaxHardwareLayers; i++)
    layers_[i].Reset();

  active_layer_count_ = layer_index;
  ALOGD_IF(TRACE, "HardwareComposer::UpdateLayerConfig: %zd active layers",
           active_layer_count_);

  // Any surfaces left over could not be assigned a hardware layer and will
  // not be displayed.
  ALOGW_IF(surfaces.size() != display_surfaces_.size(),
           "HardwareComposer::UpdateLayerConfig: More surfaces than layers: "
           "pending_surfaces=%zu display_surfaces=%zu",
           surfaces.size(), display_surfaces_.size());

  return true;
}

void HardwareComposer::SetVSyncCallback(VSyncCallback callback) {
  vsync_callback_ = callback;
}

void HardwareComposer::HwcRefresh(hwc2_callback_data_t /*data*/,
                                  hwc2_display_t /*display*/) {
  // TODO(eieio): implement invalidate callbacks.
}

void HardwareComposer::HwcVSync(hwc2_callback_data_t /*data*/,
                                hwc2_display_t /*display*/,
                                int64_t /*timestamp*/) {
  ATRACE_NAME(__PRETTY_FUNCTION__);
  // Intentionally empty. HWC may require a callback to be set to enable vsync
  // signals. We bypass this callback thread by monitoring the vsync event
  // directly, but signals still need to be enabled.
}

void HardwareComposer::HwcHotplug(hwc2_callback_data_t /*callbackData*/,
                                  hwc2_display_t /*display*/,
                                  hwc2_connection_t /*connected*/) {
  // TODO(eieio): implement display hotplug callbacks.
}

void HardwareComposer::OnHardwareComposerRefresh() {
  // TODO(steventhomas): Handle refresh.
}

void HardwareComposer::SetBacklightBrightness(int brightness) {
  if (backlight_brightness_fd_) {
    std::array<char, 32> text;
    const int length = snprintf(text.data(), text.size(), "%d", brightness);
    write(backlight_brightness_fd_.Get(), text.data(), length);
  }
}

void Layer::InitializeGlobals(Hwc2::Composer* hwc2_hidl,
                              const HWCDisplayMetrics* metrics) {
  hwc2_hidl_ = hwc2_hidl;
  display_metrics_ = metrics;
}

void Layer::Reset() {
  if (hwc2_hidl_ != nullptr && hardware_composer_layer_) {
    hwc2_hidl_->destroyLayer(HWC_DISPLAY_PRIMARY, hardware_composer_layer_);
    hardware_composer_layer_ = 0;
  }

  z_order_ = 0;
  blending_ = HWC::BlendMode::None;
  transform_ = HWC::Transform::None;
  composition_type_ = HWC::Composition::Invalid;
  target_composition_type_ = composition_type_;
  source_ = EmptyVariant{};
  acquire_fence_.Close();
  surface_rect_functions_applied_ = false;
}

void Layer::Setup(const std::shared_ptr<DirectDisplaySurface>& surface,
                  HWC::BlendMode blending, HWC::Transform transform,
                  HWC::Composition composition_type, size_t z_order) {
  Reset();
  z_order_ = z_order;
  blending_ = blending;
  transform_ = transform;
  composition_type_ = HWC::Composition::Invalid;
  target_composition_type_ = composition_type;
  source_ = SourceSurface{surface};
  CommonLayerSetup();
}

void Layer::Setup(const std::shared_ptr<IonBuffer>& buffer,
                  HWC::BlendMode blending, HWC::Transform transform,
                  HWC::Composition composition_type, size_t z_order) {
  Reset();
  z_order_ = z_order;
  blending_ = blending;
  transform_ = transform;
  composition_type_ = HWC::Composition::Invalid;
  target_composition_type_ = composition_type;
  source_ = SourceBuffer{buffer};
  CommonLayerSetup();
}

void Layer::UpdateBuffer(const std::shared_ptr<IonBuffer>& buffer) {
  if (source_.is<SourceBuffer>())
    std::get<SourceBuffer>(source_) = {buffer};
}

void Layer::SetBlending(HWC::BlendMode blending) { blending_ = blending; }
void Layer::SetZOrder(size_t z_order) { z_order_ = z_order; }

IonBuffer* Layer::GetBuffer() {
  struct Visitor {
    IonBuffer* operator()(SourceSurface& source) { return source.GetBuffer(); }
    IonBuffer* operator()(SourceBuffer& source) { return source.GetBuffer(); }
    IonBuffer* operator()(EmptyVariant) { return nullptr; }
  };
  return source_.Visit(Visitor{});
}

void Layer::UpdateLayerSettings() {
  if (!IsLayerSetup()) {
    ALOGE(
        "HardwareComposer::Layer::UpdateLayerSettings: Attempt to update "
        "unused Layer!");
    return;
  }

  HWC::Error error;
  hwc2_display_t display = HWC_DISPLAY_PRIMARY;

  error = hwc2_hidl_->setLayerCompositionType(
      display, hardware_composer_layer_,
      composition_type_.cast<Hwc2::IComposerClient::Composition>());
  ALOGE_IF(
      error != HWC::Error::None,
      "Layer::UpdateLayerSettings: Error setting layer composition type: %s",
      error.to_string().c_str());

  error = hwc2_hidl_->setLayerBlendMode(
      display, hardware_composer_layer_,
      blending_.cast<Hwc2::IComposerClient::BlendMode>());
  ALOGE_IF(error != HWC::Error::None,
           "Layer::UpdateLayerSettings: Error setting layer blend mode: %s",
           error.to_string().c_str());

  // TODO(eieio): Use surface attributes or some other mechanism to control
  // the layer display frame.
  error = hwc2_hidl_->setLayerDisplayFrame(
      display, hardware_composer_layer_,
      {0, 0, display_metrics_->width, display_metrics_->height});
  ALOGE_IF(error != HWC::Error::None,
           "Layer::UpdateLayerSettings: Error setting layer display frame: %s",
           error.to_string().c_str());

  error = hwc2_hidl_->setLayerVisibleRegion(
      display, hardware_composer_layer_,
      {{0, 0, display_metrics_->width, display_metrics_->height}});
  ALOGE_IF(error != HWC::Error::None,
           "Layer::UpdateLayerSettings: Error setting layer visible region: %s",
           error.to_string().c_str());

  error =
      hwc2_hidl_->setLayerPlaneAlpha(display, hardware_composer_layer_, 1.0f);
  ALOGE_IF(error != HWC::Error::None,
           "Layer::UpdateLayerSettings: Error setting layer plane alpha: %s",
           error.to_string().c_str());

  error =
      hwc2_hidl_->setLayerZOrder(display, hardware_composer_layer_, z_order_);
  ALOGE_IF(error != HWC::Error::None,
           "Layer::UpdateLayerSettings: Error setting z_ order: %s",
           error.to_string().c_str());
}

void Layer::CommonLayerSetup() {
  HWC::Error error =
      hwc2_hidl_->createLayer(HWC_DISPLAY_PRIMARY, &hardware_composer_layer_);
  ALOGE_IF(
      error != HWC::Error::None,
      "Layer::CommonLayerSetup: Failed to create layer on primary display: %s",
      error.to_string().c_str());
  UpdateLayerSettings();
}

void Layer::Prepare() {
  int right, bottom;
  sp<GraphicBuffer> handle;

  // Acquire the next buffer according to the type of source.
  IfAnyOf<SourceSurface, SourceBuffer>::Call(&source_, [&](auto& source) {
    std::tie(right, bottom, handle, acquire_fence_) = source.Acquire();
  });

  // When a layer is first setup there may be some time before the first buffer
  // arrives. Setup the HWC layer as a solid color to stall for time until the
  // first buffer arrives. Once the first buffer arrives there will always be a
  // buffer for the frame even if it is old.
  if (!handle.get()) {
    if (composition_type_ == HWC::Composition::Invalid) {
      composition_type_ = HWC::Composition::SolidColor;
      hwc2_hidl_->setLayerCompositionType(
          HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
          composition_type_.cast<Hwc2::IComposerClient::Composition>());
      Hwc2::IComposerClient::Color layer_color = {0, 0, 0, 0};
      hwc2_hidl_->setLayerColor(HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
                                layer_color);
    } else {
      // The composition type is already set. Nothing else to do until a
      // buffer arrives.
    }
  } else {
    if (composition_type_ != target_composition_type_) {
      composition_type_ = target_composition_type_;
      hwc2_hidl_->setLayerCompositionType(
          HWC_DISPLAY_PRIMARY, hardware_composer_layer_,
          composition_type_.cast<Hwc2::IComposerClient::Composition>());
    }

    HWC::Error error{HWC::Error::None};
    error = hwc2_hidl_->setLayerBuffer(HWC_DISPLAY_PRIMARY,
                                       hardware_composer_layer_, 0, handle,
                                       acquire_fence_.Get());

    ALOGE_IF(error != HWC::Error::None,
             "Layer::Prepare: Error setting layer buffer: %s",
             error.to_string().c_str());

    if (!surface_rect_functions_applied_) {
      const float float_right = right;
      const float float_bottom = bottom;
      error = hwc2_hidl_->setLayerSourceCrop(HWC_DISPLAY_PRIMARY,
                                             hardware_composer_layer_,
                                             {0, 0, float_right, float_bottom});

      ALOGE_IF(error != HWC::Error::None,
               "Layer::Prepare: Error setting layer source crop: %s",
               error.to_string().c_str());

      surface_rect_functions_applied_ = true;
    }
  }
}

void Layer::Finish(int release_fence_fd) {
  IfAnyOf<SourceSurface, SourceBuffer>::Call(
      &source_, [release_fence_fd](auto& source) {
        source.Finish(LocalHandle(release_fence_fd));
      });
}

void Layer::Drop() { acquire_fence_.Close(); }

}  // namespace dvr
}  // namespace android
