// Copyright 2016 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.

// Implementation of a client that produces output in the form of RGBA
// buffers when receiving pointer/touch events. RGB contains the lower
// 24 bits of the event timestamp and A is 0xff.

#include <linux-dmabuf-unstable-v1-client-protocol.h>
#include <presentation-time-client-protocol.h>
#include <wayland-client-core.h>
#include <wayland-client-protocol.h>

#include <cmath>
#include <iostream>
#include <string>
#include <vector>

#include "base/at_exit.h"
#include "base/command_line.h"
#include "base/containers/circular_deque.h"
#include "base/logging.h"
#include "base/memory/shared_memory.h"
#include "base/message_loop/message_loop.h"
#include "base/scoped_generic.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "components/exo/wayland/clients/client_base.h"
#include "components/exo/wayland/clients/client_helper.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "ui/gl/gl_bindings.h"

namespace exo {
namespace wayland {
namespace clients {
namespace {

// Rotation speed (degrees/second).
const double kRotationSpeed = 360.0;

// Benchmark warmup frames before starting measurement.
const int kBenchmarkWarmupFrames = 10;

struct EventTimes {
  std::vector<base::TimeTicks> motion_timestamps;
  base::TimeTicks pointer_timestamp;
  base::TimeTicks touch_timestamp;
};

void PointerEnter(void* data,
                  wl_pointer* pointer,
                  uint32_t serial,
                  wl_surface* surface,
                  wl_fixed_t x,
                  wl_fixed_t y) {}

void PointerLeave(void* data,
                  wl_pointer* pointer,
                  uint32_t serial,
                  wl_surface* surface) {}

void PointerMotion(void* data,
                   wl_pointer* pointer,
                   uint32_t time,
                   wl_fixed_t x,
                   wl_fixed_t y) {
  EventTimes* event_times = static_cast<EventTimes*>(data);

  event_times->motion_timestamps.push_back(event_times->pointer_timestamp);
}

void PointerButton(void* data,
                   wl_pointer* pointer,
                   uint32_t serial,
                   uint32_t time,
                   uint32_t button,
                   uint32_t state) {}

void PointerAxis(void* data,
                 wl_pointer* pointer,
                 uint32_t time,
                 uint32_t axis,
                 wl_fixed_t value) {}

void PointerAxisSource(void* data, wl_pointer* pointer, uint32_t axis_source) {}

void PointerAxisStop(void* data,
                     wl_pointer* pointer,
                     uint32_t time,
                     uint32_t axis) {}

void PointerDiscrete(void* data,
                     wl_pointer* pointer,
                     uint32_t axis,
                     int32_t discrete) {}

void PointerFrame(void* data, wl_pointer* pointer) {}

void TouchDown(void* data,
               wl_touch* touch,
               uint32_t serial,
               uint32_t time,
               wl_surface* surface,
               int32_t id,
               wl_fixed_t x,
               wl_fixed_t y) {}

void TouchUp(void* data,
             wl_touch* touch,
             uint32_t serial,
             uint32_t time,
             int32_t id) {}

void TouchMotion(void* data,
                 wl_touch* touch,
                 uint32_t time,
                 int32_t id,
                 wl_fixed_t x,
                 wl_fixed_t y) {
  EventTimes* event_times = static_cast<EventTimes*>(data);

  event_times->motion_timestamps.push_back(event_times->touch_timestamp);
}

void TouchFrame(void* data, wl_touch* touch) {}

void TouchCancel(void* data, wl_touch* touch) {}

struct Schedule {
  uint32_t time = 0;
  bool callback_pending = false;
};

void FrameCallback(void* data, wl_callback* callback, uint32_t time) {
  Schedule* schedule = static_cast<Schedule*>(data);

  static uint32_t initial_time = time;
  schedule->time = time - initial_time;
  schedule->callback_pending = false;
}

struct Frame {
  ClientBase::Buffer* buffer = nullptr;
  base::TimeDelta wall_time;
  base::TimeDelta cpu_time;
  std::vector<base::TimeTicks> event_times;
  std::unique_ptr<struct wp_presentation_feedback> feedback;
};

struct Presentation {
  base::circular_deque<std::unique_ptr<Frame>> scheduled_frames;
  base::TimeDelta wall_time;
  base::TimeDelta cpu_time;
  base::TimeDelta latency_time;
  uint32_t num_frames_presented = 0;
  uint32_t num_events_presented = 0;
};

void FeedbackSyncOutput(void* data,
                        struct wp_presentation_feedback* presentation_feedback,
                        wl_output* output) {}

void FeedbackPresented(void* data,
                       struct wp_presentation_feedback* presentation_feedback,
                       uint32_t tv_sec_hi,
                       uint32_t tv_sec_lo,
                       uint32_t tv_nsec,
                       uint32_t refresh,
                       uint32_t seq_hi,
                       uint32_t seq_lo,
                       uint32_t flags) {
  Presentation* presentation = static_cast<Presentation*>(data);
  DCHECK_GT(presentation->scheduled_frames.size(), 0u);
  std::unique_ptr<Frame> frame =
      std::move(presentation->scheduled_frames.front());
  presentation->scheduled_frames.pop_front();

  presentation->wall_time += frame->wall_time;
  presentation->cpu_time += frame->cpu_time;
  ++presentation->num_frames_presented;

  int64_t seconds = (static_cast<int64_t>(tv_sec_hi) << 32) + tv_sec_lo;
  int64_t microseconds = seconds * base::Time::kMicrosecondsPerSecond +
                         tv_nsec / base::Time::kNanosecondsPerMicrosecond;
  base::TimeTicks presentation_time =
      base::TimeTicks::FromInternalValue(microseconds);
  for (const auto& event_time : frame->event_times) {
    presentation->latency_time += presentation_time - event_time;
    ++presentation->num_events_presented;
  }
}

void FeedbackDiscarded(void* data,
                       struct wp_presentation_feedback* presentation_feedback) {
  Presentation* presentation = static_cast<Presentation*>(data);
  DCHECK_GT(presentation->scheduled_frames.size(), 0u);
  auto it =
      std::find_if(presentation->scheduled_frames.begin(),
                   presentation->scheduled_frames.end(),
                   [presentation_feedback](std::unique_ptr<Frame>& frame) {
                     return frame->feedback.get() == presentation_feedback;
                   });
  DCHECK(it != presentation->scheduled_frames.end());
  presentation->scheduled_frames.erase(it);
  LOG(WARNING) << "Frame discarded";
}

void InputTimestamp(void* data,
                    struct zwp_input_timestamps_v1* zwp_input_timestamps_v1,
                    uint32_t tv_sec_hi,
                    uint32_t tv_sec_lo,
                    uint32_t tv_nsec) {
  auto* timestamp = static_cast<base::TimeTicks*>(data);
  int64_t seconds = (static_cast<int64_t>(tv_sec_hi) << 32) + tv_sec_lo;
  int64_t microseconds = seconds * base::Time::kMicrosecondsPerSecond +
                         tv_nsec / base::Time::kNanosecondsPerMicrosecond;

  *timestamp =
      base::TimeTicks() + base::TimeDelta::FromMicroseconds(microseconds);
}

}  // namespace

////////////////////////////////////////////////////////////////////////////////
// RectsClient:

class RectsClient : public ClientBase {
 public:
  RectsClient() {}

  // Initialize and run client main loop.
  int Run(const ClientBase::InitParams& params,
          size_t max_frames_pending,
          size_t num_rects,
          size_t num_benchmark_runs,
          base::TimeDelta benchmark_interval,
          bool show_fps_counter);

 private:
  DISALLOW_COPY_AND_ASSIGN(RectsClient);
};

int RectsClient::Run(const ClientBase::InitParams& params,
                     size_t max_frames_pending,
                     size_t num_rects,
                     size_t num_benchmark_runs,
                     base::TimeDelta benchmark_interval,
                     bool show_fps_counter) {
  if (!ClientBase::Init(params))
    return 1;

  EventTimes event_times;

  std::unique_ptr<wl_pointer> pointer(
      static_cast<wl_pointer*>(wl_seat_get_pointer(globals_.seat.get())));
  if (!pointer) {
    LOG(ERROR) << "Can't get pointer";
    return 1;
  }

  wl_pointer_listener pointer_listener = {
      PointerEnter,      PointerLeave,    PointerMotion,
      PointerButton,     PointerAxis,     PointerFrame,
      PointerAxisSource, PointerAxisStop, PointerDiscrete};
  wl_pointer_add_listener(pointer.get(), &pointer_listener, &event_times);

  std::unique_ptr<wl_touch> touch(
      static_cast<wl_touch*>(wl_seat_get_touch(globals_.seat.get())));
  if (!touch) {
    LOG(ERROR) << "Can't get touch";
    return 1;
  }
  wl_touch_listener touch_listener = {TouchDown, TouchUp, TouchMotion,
                                      TouchFrame, TouchCancel};
  wl_touch_add_listener(touch.get(), &touch_listener, &event_times);

  zwp_input_timestamps_v1_listener input_timestamps_listener = {InputTimestamp};

  std::unique_ptr<zwp_input_timestamps_v1> pointer_timestamps(
      zwp_input_timestamps_manager_v1_get_pointer_timestamps(
          globals_.input_timestamps_manager.get(), pointer.get()));
  if (!pointer_timestamps) {
    LOG(ERROR) << "Can't get pointer timestamps";
    return 1;
  }
  zwp_input_timestamps_v1_add_listener(pointer_timestamps.get(),
                                       &input_timestamps_listener,
                                       &event_times.pointer_timestamp);

  std::unique_ptr<zwp_input_timestamps_v1> touch_timestamps(
      zwp_input_timestamps_manager_v1_get_touch_timestamps(
          globals_.input_timestamps_manager.get(), touch.get()));
  if (!touch_timestamps) {
    LOG(ERROR) << "Can't get touch timestamps";
    return 1;
  }
  zwp_input_timestamps_v1_add_listener(touch_timestamps.get(),
                                       &input_timestamps_listener,
                                       &event_times.touch_timestamp);

  Schedule schedule;
  std::unique_ptr<wl_callback> frame_callback;
  wl_callback_listener frame_listener = {FrameCallback};

  Presentation presentation;
  base::circular_deque<std::unique_ptr<Frame>> pending_frames;

  size_t num_benchmark_runs_left = num_benchmark_runs;
  base::TimeTicks benchmark_start_time;
  std::string fps_counter_text("??");

  wp_presentation_feedback_listener feedback_listener = {
      FeedbackSyncOutput, FeedbackPresented, FeedbackDiscarded};

  SkPaint text_paint;
  text_paint.setTextSize(32.0f);
  text_paint.setColor(SK_ColorWHITE);
  text_paint.setStyle(SkPaint::kFill_Style);

  int dispatch_status = 0;
  do {
    bool enqueue_frame = schedule.callback_pending
                             ? pending_frames.size() < max_frames_pending
                             : pending_frames.empty();
    if (enqueue_frame) {
      Buffer* buffer = DequeueBuffer();
      if (!buffer) {
        LOG(ERROR) << "Can't find free buffer";
        return 1;
      }

      auto frame = std::make_unique<Frame>();
      frame->buffer = buffer;

      base::TimeTicks wall_time_start;
      base::ThreadTicks cpu_time_start;
      if (num_benchmark_runs || show_fps_counter) {
        wall_time_start = base::TimeTicks::Now();
        if (presentation.num_frames_presented <= kBenchmarkWarmupFrames)
          benchmark_start_time = wall_time_start;

        base::TimeDelta benchmark_time = wall_time_start - benchmark_start_time;
        if (benchmark_time > benchmark_interval) {
          uint32_t benchmark_frames =
              presentation.num_frames_presented - kBenchmarkWarmupFrames;
          if (num_benchmark_runs_left) {
            // Print benchmark statistics for the frames presented and exit.
            std::cout << benchmark_frames << '\t'
                      << benchmark_time.InMilliseconds() << '\t'
                      << presentation.wall_time.InMilliseconds() << '\t'
                      << presentation.cpu_time.InMilliseconds() << '\t'
                      << presentation.num_events_presented << '\t'
                      << presentation.latency_time.InMilliseconds() << '\t'
                      << std::endl;
            if (!--num_benchmark_runs_left)
              return 0;
          }

          // Set FPS counter text in case it's being shown.
          fps_counter_text = base::UintToString(
              std::round(benchmark_frames / benchmark_interval.InSecondsF()));

          benchmark_start_time = wall_time_start;
          presentation.wall_time = base::TimeDelta();
          presentation.cpu_time = base::TimeDelta();
          presentation.latency_time = base::TimeDelta();
          presentation.num_frames_presented = kBenchmarkWarmupFrames;
          presentation.num_events_presented = 0;
        }

        cpu_time_start = base::ThreadTicks::Now();
      }

      SkCanvas* canvas = buffer->sk_surface->getCanvas();
      if (event_times.motion_timestamps.empty()) {
        canvas->clear(transparent_background_ ? SK_ColorTRANSPARENT
                                              : SK_ColorBLACK);
      } else {
        // Split buffer into one horizontal rectangle for each event received
        // since last frame. Latest event at the top.
        int y = 0;
        // Note: Rounding up to ensure we cover the whole canvas.
        int h = (size_.height() + (event_times.motion_timestamps.size() / 2)) /
                event_times.motion_timestamps.size();
        while (!event_times.motion_timestamps.empty()) {
          SkIRect rect = SkIRect::MakeXYWH(0, y, size_.width(), h);
          SkPaint paint;
          base::TimeDelta event_time =
              event_times.motion_timestamps.back() - base::TimeTicks();
          int64_t event_time_msec = event_time.InMilliseconds();
          paint.setColor(SkColorSetRGB((event_time_msec & 0x0000ff) >> 0,
                                       (event_time_msec & 0x00ff00) >> 8,
                                       (event_time_msec & 0xff0000) >> 16));
          canvas->drawIRect(rect, paint);
          std::string text = base::NumberToString(event_time.InMicroseconds());
          canvas->drawText(text.c_str(), text.length(), 8, y + 32, text_paint);
          frame->event_times.push_back(event_times.motion_timestamps.back());
          event_times.motion_timestamps.pop_back();
          y += h;
        }
      }

      // Draw rotating rects.
      SkScalar half_width = SkScalarHalf(size_.width());
      SkScalar half_height = SkScalarHalf(size_.height());
      SkIRect rect = SkIRect::MakeXYWH(-SkScalarHalf(half_width),
                                       -SkScalarHalf(half_height), half_width,
                                       half_height);
      SkScalar rotation = schedule.time * kRotationSpeed / 1000;
      canvas->save();
      canvas->translate(half_width, half_height);
      for (size_t i = 0; i < num_rects; ++i) {
        const SkColor kColors[] = {SK_ColorBLUE, SK_ColorGREEN,
                                   SK_ColorRED,  SK_ColorYELLOW,
                                   SK_ColorCYAN, SK_ColorMAGENTA};
        SkPaint paint;
        paint.setColor(SkColorSetA(kColors[i % base::size(kColors)], 0xA0));
        canvas->rotate(rotation / num_rects);
        canvas->drawIRect(rect, paint);
      }
      canvas->restore();

      // Draw FPS counter.
      if (show_fps_counter) {
        canvas->drawText(fps_counter_text.c_str(), fps_counter_text.length(),
                         size_.width() - 48, 32, text_paint);
      }
      GrContext* gr_context = gr_context_.get();
      if (gr_context) {
        gr_context->flush();

#if defined(USE_GBM)
        if (egl_sync_type_) {
          buffer->egl_sync.reset(new ScopedEglSync(eglCreateSyncKHR(
              eglGetCurrentDisplay(), egl_sync_type_, nullptr)));
          DCHECK(buffer->egl_sync->is_valid());
        }
#endif

        glFlush();
      }

      if (num_benchmark_runs) {
        frame->wall_time = base::TimeTicks::Now() - wall_time_start;
        frame->cpu_time = base::ThreadTicks::Now() - cpu_time_start;
      }
      pending_frames.push_back(std::move(frame));
      continue;
    }

    if (!schedule.callback_pending) {
      DCHECK_GT(pending_frames.size(), 0u);
      std::unique_ptr<Frame> frame = std::move(pending_frames.front());
      pending_frames.pop_front();

      wl_surface* surface = surface_.get();
      wl_surface_set_buffer_scale(surface, scale_);
      wl_surface_set_buffer_transform(surface_.get(), transform_);
      wl_surface_damage(surface_.get(), 0, 0, surface_size_.width(),
                        surface_size_.height());
      wl_surface_attach(surface, frame->buffer->buffer.get(), 0, 0);

#if defined(USE_GBM)
      if (frame->buffer->egl_sync) {
        eglClientWaitSyncKHR(eglGetCurrentDisplay(),
                             frame->buffer->egl_sync->get(),
                             EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR);
      }
#endif

      frame_callback.reset(wl_surface_frame(surface));
      wl_callback_add_listener(frame_callback.get(), &frame_listener,
                               &schedule);
      schedule.callback_pending = true;

      frame->feedback.reset(
          wp_presentation_feedback(globals_.presentation.get(), surface));
      wp_presentation_feedback_add_listener(frame->feedback.get(),
                                            &feedback_listener, &presentation);
      presentation.scheduled_frames.push_back(std::move(frame));

      wl_surface_commit(surface);
      wl_display_flush(display_.get());
      continue;
    }

    dispatch_status = wl_display_dispatch(display_.get());
  } while (dispatch_status != -1);
  return 0;
}
}  // namespace clients
}  // namespace wayland
}  // namespace exo

namespace switches {

// Specifies the maximum number of pending frames.
const char kMaxFramesPending[] = "max-frames-pending";

// Specifies the number of rotating rects to draw.
const char kNumRects[] = "num-rects";

// Enables benchmark mode and specifies the number of benchmark runs to
// perform before client will exit. Client will print the results to
// standard output as a tab seperated list.
//
//  The output format is:
//   "frames wall-time-ms cpu-time-ms"
const char kBenchmark[] = "benchmark";

// Specifies the number of milliseconds to use as benchmark interval.
const char kBenchmarkInterval[] = "benchmark-interval";

// Specifies if FPS counter should be shown.
const char kShowFpsCounter[] = "show-fps-counter";

}  // namespace switches

int main(int argc, char* argv[]) {
  base::AtExitManager exit_manager;
  base::CommandLine::Init(argc, argv);
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();

  exo::wayland::clients::ClientBase::InitParams params;
  params.num_buffers = 8;  // Allow up to 8 buffers by default.
  if (!params.FromCommandLine(*command_line))
    return 1;

  size_t max_frames_pending = 0;
  if (command_line->HasSwitch(switches::kMaxFramesPending) &&
      (!base::StringToSizeT(
          command_line->GetSwitchValueASCII(switches::kMaxFramesPending),
          &max_frames_pending))) {
    LOG(ERROR) << "Invalid value for " << switches::kMaxFramesPending;
    return 1;
  }

  size_t num_rects = 1;
  if (command_line->HasSwitch(switches::kNumRects) &&
      !base::StringToSizeT(
          command_line->GetSwitchValueASCII(switches::kNumRects), &num_rects)) {
    LOG(ERROR) << "Invalid value for " << switches::kNumRects;
    return 1;
  }

  size_t num_benchmark_runs = 0;
  if (command_line->HasSwitch(switches::kBenchmark) &&
      (!base::StringToSizeT(
          command_line->GetSwitchValueASCII(switches::kBenchmark),
          &num_benchmark_runs))) {
    LOG(ERROR) << "Invalid value for " << switches::kBenchmark;
    return 1;
  }

  size_t benchmark_interval_ms = 5000;  // 5 seconds.
  if (command_line->HasSwitch(switches::kBenchmarkInterval) &&
      (!base::StringToSizeT(
          command_line->GetSwitchValueASCII(switches::kBenchmarkInterval),
          &benchmark_interval_ms))) {
    LOG(ERROR) << "Invalid value for " << switches::kBenchmarkInterval;
    return 1;
  }

  base::MessageLoopForUI message_loop;
  exo::wayland::clients::RectsClient client;
  return client.Run(params, max_frames_pending, num_rects, num_benchmark_runs,
                    base::TimeDelta::FromMilliseconds(benchmark_interval_ms),
                    command_line->HasSwitch(switches::kShowFpsCounter));
}
