// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/ozone/platform/dri/hardware_display_controller.h"

#include <drm.h>
#include <errno.h>
#include <string.h>
#include <xf86drm.h>

#include "base/basictypes.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/size.h"
#include "ui/ozone/platform/dri/crtc_controller.h"
#include "ui/ozone/platform/dri/dri_buffer.h"
#include "ui/ozone/platform/dri/dri_wrapper.h"
#include "ui/ozone/public/native_pixmap.h"

namespace ui {

namespace {

// DRM callback on page flip events. This callback is triggered after the
// page flip has happened and the backbuffer is now the new frontbuffer
// The old frontbuffer is no longer used by the hardware and can be used for
// future draw operations.
//
// |device| will contain a reference to the |ScanoutSurface| object which
// the event belongs to.
//
// TODO(dnicoara) When we have a FD handler for the DRM calls in the message
// loop, we can move this function in the handler.
void HandlePageFlipEvent(int fd,
                         unsigned int frame,
                         unsigned int seconds,
                         unsigned int useconds,
                         void* controller) {
  static_cast<CrtcController*>(controller)
      ->OnPageFlipEvent(frame, seconds, useconds);
}

}  // namespace

HardwareDisplayController::HardwareDisplayController(
    scoped_ptr<CrtcController> controller)
    : is_disabled_(true) {
  crtc_controllers_.push_back(controller.release());
}

HardwareDisplayController::~HardwareDisplayController() {
  // Reset the cursor.
  UnsetCursor();
}

bool HardwareDisplayController::Modeset(const OverlayPlane& primary,
                                        drmModeModeInfo mode) {
  TRACE_EVENT0("dri", "HDC::Modeset");
  DCHECK(primary.buffer.get());
  bool status = true;
  for (size_t i = 0; i < crtc_controllers_.size(); ++i)
    status &= crtc_controllers_[i]->Modeset(primary, mode);

  current_planes_ = std::vector<OverlayPlane>(1, primary);
  pending_planes_.clear();
  is_disabled_ = false;
  mode_ = mode;
  return status;
}

bool HardwareDisplayController::Enable() {
  TRACE_EVENT0("dri", "HDC::Enable");
  DCHECK(!current_planes_.empty());
  OverlayPlane primary = OverlayPlane::GetPrimaryPlane(current_planes_);
  DCHECK(primary.buffer.get());
  bool status = true;
  for (size_t i = 0; i < crtc_controllers_.size(); ++i)
    status &= crtc_controllers_[i]->Modeset(primary, mode_);

  return status;
}

void HardwareDisplayController::Disable() {
  TRACE_EVENT0("dri", "HDC::Disable");
  for (size_t i = 0; i < crtc_controllers_.size(); ++i)
    crtc_controllers_[i]->Disable();

  is_disabled_ = true;
}

void HardwareDisplayController::QueueOverlayPlane(const OverlayPlane& plane) {
  pending_planes_.push_back(plane);
}

bool HardwareDisplayController::SchedulePageFlip() {
  DCHECK(!pending_planes_.empty());

  if (is_disabled_)
    return true;

  bool status = true;
  for (size_t i = 0; i < crtc_controllers_.size(); ++i)
    status &= crtc_controllers_[i]->SchedulePageFlip(pending_planes_);

  return status;
}

void HardwareDisplayController::WaitForPageFlipEvent() {
  TRACE_EVENT0("dri", "HDC::WaitForPageFlipEvent");

  drmEventContext drm_event;
  drm_event.version = DRM_EVENT_CONTEXT_VERSION;
  drm_event.page_flip_handler = HandlePageFlipEvent;
  drm_event.vblank_handler = NULL;

  bool has_pending_page_flips = false;
  // Wait for the page-flips to complete.
  for (size_t i = 0; i < crtc_controllers_.size(); ++i) {
    // In mirror mode the page flip callbacks can happen in different order than
    // scheduled, so we need to make sure that the event for the current CRTC is
    // processed before moving to the next CRTC.
    while (crtc_controllers_[i]->page_flip_pending()) {
      has_pending_page_flips = true;
      crtc_controllers_[i]->drm()->HandleEvent(drm_event);
    }
  }

  // In case there are no pending pageflips do not replace the current planes
  // since they are still being used.
  if (has_pending_page_flips)
    current_planes_.swap(pending_planes_);

  pending_planes_.clear();
}

bool HardwareDisplayController::SetCursor(
    const scoped_refptr<ScanoutBuffer>& buffer) {
  bool status = true;

  if (is_disabled_)
    return true;

  for (size_t i = 0; i < crtc_controllers_.size(); ++i)
    status &= crtc_controllers_[i]->SetCursor(buffer);

  return status;
}

bool HardwareDisplayController::UnsetCursor() {
  bool status = true;
  for (size_t i = 0; i < crtc_controllers_.size(); ++i)
    status &= crtc_controllers_[i]->UnsetCursor();

  return status;
}

bool HardwareDisplayController::MoveCursor(const gfx::Point& location) {
  if (is_disabled_)
    return true;

  bool status = true;
  for (size_t i = 0; i < crtc_controllers_.size(); ++i)
    status &= crtc_controllers_[i]->MoveCursor(location);

  return status;
}

void HardwareDisplayController::AddCrtc(scoped_ptr<CrtcController> controller) {
  crtc_controllers_.push_back(controller.release());
}

scoped_ptr<CrtcController> HardwareDisplayController::RemoveCrtc(
    uint32_t crtc) {
  for (ScopedVector<CrtcController>::iterator it = crtc_controllers_.begin();
       it != crtc_controllers_.end();
       ++it) {
    if ((*it)->crtc() == crtc) {
      scoped_ptr<CrtcController> controller(*it);
      crtc_controllers_.weak_erase(it);
      return controller.Pass();
    }
  }

  return scoped_ptr<CrtcController>();
}

bool HardwareDisplayController::HasCrtc(uint32_t crtc) const {
  for (size_t i = 0; i < crtc_controllers_.size(); ++i)
    if (crtc_controllers_[i]->crtc() == crtc)
      return true;

  return false;
}

bool HardwareDisplayController::IsMirrored() const {
  return crtc_controllers_.size() > 1;
}

bool HardwareDisplayController::IsDisabled() const {
  return is_disabled_;
}

gfx::Size HardwareDisplayController::GetModeSize() const {
  return gfx::Size(mode_.hdisplay, mode_.vdisplay);
}

uint64_t HardwareDisplayController::GetTimeOfLastFlip() const {
  uint64_t time = 0;
  for (size_t i = 0; i < crtc_controllers_.size(); ++i)
    if (time < crtc_controllers_[i]->time_of_last_flip())
      time = crtc_controllers_[i]->time_of_last_flip();

  return time;
}

}  // namespace ui
