// Copyright 2018 The Fuchsia 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 <dirent.h>
#include <errno.h>
#include <fbl/algorithm.h>
#include <fbl/array.h>
#include <fbl/string.h>
#include <fbl/string_printf.h>
#include <fbl/unique_ptr.h>
#include <fbl/vector.h>
#include <fcntl.h>
#include <fuchsia/hardware/input/c/fidl.h>
#include <gfx/gfx.h>
#include <hid/paradise.h>
#include <hid/usages.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async/cpp/task.h>
#include <lib/fidl/coding.h>
#include <lib/fit/defer.h>
#include <lib/fzl/fdio.h>
#include <limits.h>
#include <math.h>
#include <poll.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <trace-provider/provider.h>
#include <trace/event.h>
#include <unistd.h>
#include <zircon/device/display-controller.h>
#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>
#include <zircon/status.h>

#include <utility>

#include "fuchsia/hardware/display/c/fidl.h"

#define DEV_INPUT "/dev/class/input"
#define NUM_FINGERS 5u
#define STYLUS_PEN 0
#define TOUCH_PEN 1
#define NUM_PENCILS 2
#define NUM_BUFFERS 2u
#define SPRITE_DIM 256u
#define SPRITE_RAD (SPRITE_DIM / 2)
#define SPRITE_FORMAT ZX_PIXEL_FORMAT_ARGB_8888
#define PEN_VELOCITY_MAX 12.5f
// Interpolation factor used to compute responsive velocity. Valid range
// is 0.0 to 1.0, where 1.0 takes only current velocity into account.
#define RESPONSIVE_VELOCITY_FACTOR 0.75
// Interpolation factor used to compute smooth velocity. Valid range
// is 0.0 to 1.0, where 1.0 takes only current velocity into account.
#define SMOOTH_VELOCITY_FACTOR 0.25
// Interpolation factor used to compute pen movement. Valid range
// is 0.0 to 1.0, where 1.0 takes only smooth velocity into account.
#define PEN_MOVEMENT_FACTOR 0.25
#define MAX_BLUR_RADIUS 90.0
#define MIN_MOVEMENT_FOR_CURSOR_MOTION_BLUR 2.0
#define CURSOR_MOVEMENT_PREDICTION_MS (1000.0f / 60.0f)
#define CURSOR_HOTSPOT_X 15
#define CURSOR_HOTSPOT_Y 14
#define ORIGIN_VELOCITY_MAX 10.0f
#define ORIGIN_MOVEMENT_FACTOR 0.9f
// Input prediction models depend on velocity which need to be sampled
// at a fixed interval. For example, the lack of input over the interval
// affects the model. Note: This is currently set to cause an update
// for each frame when VSync is enabled.
#define INPUT_PREDICTION_UPDATE_INTERVAL_MS 16

#define HID_REPORT_TRACE_ID(trace_id, report_id) \
  (((uint64_t)(report_id) << 32) | (trace_id))

enum class VSync {
  ON,
  OFF,
  ADAPTIVE,
};

enum class TouchDevice {
  PARADISE_V2,
  PARADISE_V3,
};

typedef struct point {
  uint32_t x;
  uint32_t y;
} point_t;

typedef struct line {
  point_t p1;
  point_t p2;
} line_t;

typedef struct vector {
  int32_t x;
  int32_t y;
} vector_t;

typedef struct pointf {
  float x;
  float y;
} pointf_t;

typedef struct vectorf {
  float x;
  float y;
} vectorf_t;

typedef struct rect {
  uint32_t x1;
  uint32_t y1;
  uint32_t x2;
  uint32_t y2;
} rect_t;

typedef struct buffer {
  zx_handle_t vmo;
  uintptr_t data;
  uint64_t image_id;
  zx_handle_t wait_event;
  uint64_t wait_event_id;
  rect_t damage;
} buffer_t;

static zx_handle_t dc_handle = ZX_HANDLE_INVALID;
static int32_t txid = 0;

#include "background.inc"
#include "cursor.inc"

static double scale(double z, uint32_t screen_dim, uint32_t rpt_dim) {
  return (z * screen_dim) / rpt_dim;
}

static void vector_interpolate(vectorf_t* result, const vectorf_t* start,
                               const vectorf_t* end, float f) {
  result->x = start->x + (end->x - start->x) * f;
  result->y = start->y + (end->y - start->y) * f;
}

static void copy_rect(uint32_t* dst, const uint32_t* src, uint32_t dst_stride,
                      uint32_t src_stride, uint32_t x1, uint32_t y1,
                      uint32_t x2, uint32_t y2) {
  size_t bytes_per_line = (x2 - x1) * sizeof(uint32_t);
  size_t lines = y2 - y1;

  dst += y1 * dst_stride + x1;
  src += y1 * src_stride + x1;

  while (lines--) {
    memcpy(dst, src, bytes_per_line);
    dst += dst_stride;
    src += src_stride;
  }
}

/* source dimensions must be a power of two. */
static void rotate_rect(uint32_t* dst, const uint32_t* src, uint32_t dst_width,
                        uint32_t dst_height, uint32_t dst_stride,
                        uint32_t src_width, uint32_t src_height,
                        uint32_t src_stride, double dst_cx, double dst_cy,
                        double src_cx, double src_cy, double angle) {
  ZX_ASSERT(fbl::is_pow2(src_width));
  ZX_ASSERT(fbl::is_pow2(src_height));

  double du_y = sin(-angle);
  double dv_y = cos(-angle);
  double du_x = dv_y;
  double dv_x = -du_y;
  double startu = src_cx - (dst_cx * dv_y + dst_cy * du_y);
  double startv = src_cy - (dst_cx * dv_x + dst_cy * du_x);
  double rowu = startu;
  double rowv = startv;
  int width_mask = src_width - 1;
  int height_mask = src_height - 1;

  for (uint32_t y = 0; y < dst_height; y++) {
    uint32_t* d = dst + y * dst_stride;
    double u = rowu;
    double v = rowv;

    for (uint32_t x = 0; x < dst_width; x++) {
      const uint32_t* s = src + ((((int)v) & height_mask) * src_stride) +
                          (((int)u) & width_mask);

      *d++ = *s++;

      u += du_x;
      v += dv_x;
    }

    rowu += du_y;
    rowv += dv_y;
  }
}

static inline uint8_t mul_div_255_round(uint16_t a, uint16_t b) {
  unsigned prod = a * b + 128;
  return (uint8_t)((prod + (prod >> 8)) >> 8);
}

static inline void argb_8888_unpack_mul(uint32_t p, uint8_t* a, uint8_t* r,
                                        uint8_t* g, uint8_t* b) {
  *a = (uint8_t)((p & 0xff000000) >> 24);
  *r = (uint8_t)((p & 0x00ff0000) >> 16);
  *g = (uint8_t)((p & 0x0000ff00) >> 8);
  *b = (uint8_t)(p & 0x000000ff);
  if (*a != 255) {
    *r = mul_div_255_round(*r, *a);
    *g = mul_div_255_round(*g, *a);
    *b = mul_div_255_round(*b, *a);
  }
}

/* width must be a power of two. */
static void blur_rect(uint32_t* dst, const uint32_t* src, uint32_t width,
                      uint32_t height, uint32_t stride, int radius) {
  ZX_ASSERT(fbl::is_pow2(width));
  ZX_ASSERT(radius > 0);

  int width_mask = width - 1;
  int radius0 = -radius;
  int radius1 = radius + 1;
  int size = radius + radius + 1;

  for (uint32_t y = 0; y < height; y++) {
    uint8_t a, r, g, b;
    uint32_t a32 = 0;
    uint32_t r32 = 0;
    uint32_t g32 = 0;
    uint32_t b32 = 0;

    for (int x = radius0; x < radius1; ++x) {
      argb_8888_unpack_mul(src[x & width_mask], &a, &r, &g, &b);
      a32 += a;
      r32 += r;
      g32 += g;
      b32 += b;
    }

    for (int x = 0; x <= width_mask; ++x) {
      dst[x] = a32 ? ((a32 / size) << 24) | (((255 * r32) / a32) << 16) |
                         (((255 * g32) / a32) << 8) | (((255 * b32) / a32))
                   : 0;

      argb_8888_unpack_mul(src[(x + radius0) & width_mask], &a, &r, &g, &b);
      a32 -= a;
      r32 -= r;
      g32 -= g;
      b32 -= b;

      argb_8888_unpack_mul(src[(x + radius1) & width_mask], &a, &r, &g, &b);
      a32 += a;
      r32 += r;
      g32 += g;
      b32 += b;
    }

    src += stride;
    dst += stride;
  }
}

static bool is_rect_empty(const rect_t* rect) {
  return rect->x1 >= rect->x2 && rect->y1 >= rect->y2;
}

static void union_rects(rect_t* dst, const rect_t* a, const rect_t* b) {
  if (is_rect_empty(b)) {
    *dst = *a;
  } else if (is_rect_empty(a)) {
    *dst = *b;
  } else {
    dst->x1 = fbl::min(a->x1, b->x1);
    dst->y1 = fbl::min(a->y1, b->y1);
    dst->x2 = fbl::max(a->x2, b->x2);
    dst->y2 = fbl::max(a->y2, b->y2);
  }
}

static fbl::String rect_as_string(const rect_t* rect) {
  return fbl::StringPrintf("%d,%d %dx%d", rect->x1, rect->y1,
                           rect->x2 - rect->x1, rect->y2 - rect->y1);
}

static void prepare_poll(int touchfd, int touchpadfd, int* startfd, int* endfd,
                         struct pollfd* fds) {
  *startfd = 1;
  *endfd = 1;
  if (touchfd >= 0) {
    fds[0].fd = touchfd;
    fds[0].events = POLLIN;
    fds[0].revents = 0;
    *startfd = 0;
  }
  if (touchpadfd >= 0) {
    fds[1].fd = touchpadfd;
    fds[1].events = POLLIN;
    fds[1].revents = 0;
    *endfd = 2;
  }
}

template <typename T>
void parse_paradise_touch_report(uint8_t* r, uint32_t width, uint32_t height,
                                 pointf_t touch[NUM_FINGERS]) {
  const auto report = reinterpret_cast<T*>(r);

  for (uint8_t c = 0; c < NUM_FINGERS; c++) {
    touch[c].x = NAN;
    touch[c].y = NAN;
    if (paradise_finger_flags_tswitch(report->fingers[c].flags)) {
      touch[c].x = (float)scale(report->fingers[c].x, width, PARADISE_X_MAX);
      touch[c].y = (float)scale(report->fingers[c].y, height, PARADISE_Y_MAX);
    }
  }
}

void parse_paradise_touchpad_report(uint8_t* r, uint32_t width, uint32_t height,
                                    pointf_t touch[NUM_FINGERS],
                                    uint8_t* button) {
  const auto report = reinterpret_cast<paradise_touchpad_t*>(r);

  for (uint8_t c = 0; c < NUM_FINGERS; c++) {
    touch[c].x = NAN;
    touch[c].y = NAN;
    if (report->fingers[c].tip_switch) {
      touch[c].x = (float)scale(report->fingers[c].x, width, PARADISE_X_MAX);
      touch[c].y = (float)scale(report->fingers[c].y, height, PARADISE_Y_MAX);
    }
  }
  *button = report->button;
}

void parse_paradise_stylus_report(uint8_t* r, uint32_t width, uint32_t height,
                                  pointf_t* pen) {
  const auto report = reinterpret_cast<paradise_stylus_t*>(r);

  if (paradise_stylus_status_tswitch(report->status)) {
    pen->x = (float)scale(report->x, width, PARADISE_STYLUS_X_MAX);
    pen->y = (float)scale(report->y, height, PARADISE_STYLUS_Y_MAX);
  } else {
    pen->x = NAN;
    pen->y = NAN;
  }
}

static zx_status_t compute_linear_image_stride(uint32_t width,
                                               zx_pixel_format_t format,
                                               uint32_t* stride_out) {
  zx_status_t status;

  fuchsia_hardware_display_ControllerComputeLinearImageStrideRequest stride_msg;
  stride_msg.hdr.ordinal =
      fuchsia_hardware_display_ControllerComputeLinearImageStrideOrdinal;
  stride_msg.hdr.txid = txid++;
  stride_msg.width = width;
  stride_msg.pixel_format = format;

  fuchsia_hardware_display_ControllerComputeLinearImageStrideResponse
      stride_rsp;
  zx_channel_call_args_t stride_call = {};
  stride_call.wr_bytes = &stride_msg;
  stride_call.rd_bytes = &stride_rsp;
  stride_call.wr_num_bytes = sizeof(stride_msg);
  stride_call.rd_num_bytes = sizeof(stride_rsp);
  uint32_t actual_bytes, actual_handles;
  if ((status = zx_channel_call(dc_handle, 0, ZX_TIME_INFINITE, &stride_call,
                                &actual_bytes, &actual_handles)) != ZX_OK) {
    return status;
  }

  *stride_out = stride_rsp.stride;
  return ZX_OK;
}

static zx_status_t import_image(zx_handle_t handle, uint32_t width,
                                uint32_t height, zx_pixel_format_t format,
                                uint64_t* id_out) {
  zx_status_t status;
  zx_handle_t dup;
  status = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &dup);
  ZX_ASSERT(status == ZX_OK);

  fuchsia_hardware_display_ControllerImportVmoImageRequest import_msg = {};
  import_msg.hdr.ordinal =
      fuchsia_hardware_display_ControllerImportVmoImageOrdinal;
  import_msg.hdr.txid = txid++;
  import_msg.image_config.height = height;
  import_msg.image_config.width = width;
  import_msg.image_config.pixel_format = format;
  import_msg.image_config.type = IMAGE_TYPE_SIMPLE;
  import_msg.vmo = FIDL_HANDLE_PRESENT;
  import_msg.offset = 0;

  fuchsia_hardware_display_ControllerImportVmoImageResponse import_rsp;
  zx_channel_call_args_t import_call = {};
  import_call.wr_bytes = &import_msg;
  import_call.wr_handles = &dup;
  import_call.rd_bytes = &import_rsp;
  import_call.wr_num_bytes = sizeof(import_msg);
  import_call.wr_num_handles = 1;
  import_call.rd_num_bytes = sizeof(import_rsp);
  uint32_t actual_bytes, actual_handles;
  if ((status = zx_channel_call(dc_handle, 0, ZX_TIME_INFINITE, &import_call,
                                &actual_bytes, &actual_handles)) != ZX_OK) {
    return status;
  }

  if (import_rsp.res != ZX_OK) {
    return import_rsp.res;
  }

  *id_out = import_rsp.image_id;
  return ZX_OK;
}

static void release_image(uint64_t image_id) {
  fuchsia_hardware_display_ControllerReleaseEventRequest release_img_msg;
  release_img_msg.hdr.ordinal =
      fuchsia_hardware_display_ControllerReleaseEventOrdinal;
  release_img_msg.hdr.txid = txid++;
  release_img_msg.id = image_id;
  zx_channel_write(dc_handle, 0, &release_img_msg, sizeof(release_img_msg),
                   NULL, 0);
}

static zx_status_t import_event(zx_handle_t handle, uint64_t id) {
  zx_status_t status;
  zx_handle_t dup;
  status = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &dup);
  ZX_ASSERT(status == ZX_OK);

  fuchsia_hardware_display_ControllerImportEventRequest import_evt_msg;
  import_evt_msg.hdr.ordinal =
      fuchsia_hardware_display_ControllerImportEventOrdinal;
  import_evt_msg.hdr.txid = txid++;
  import_evt_msg.id = id;
  import_evt_msg.event = FIDL_HANDLE_PRESENT;
  return zx_channel_write(dc_handle, 0, &import_evt_msg, sizeof(import_evt_msg),
                          &dup, 1);
}

static void release_event(uint64_t id) {
  fuchsia_hardware_display_ControllerReleaseEventRequest release_evt_msg;
  release_evt_msg.hdr.ordinal =
      fuchsia_hardware_display_ControllerReleaseEventOrdinal;
  release_evt_msg.hdr.txid = txid++;
  release_evt_msg.id = id;
  zx_channel_write(dc_handle, 0, &release_evt_msg, sizeof(release_evt_msg),
                   NULL, 0);
}

static zx_status_t create_layer(uint64_t* layer_id_out) {
  zx_status_t status;

  fuchsia_hardware_display_ControllerCreateLayerRequest create_layer_msg;
  create_layer_msg.hdr.ordinal =
      fuchsia_hardware_display_ControllerCreateLayerOrdinal;

  fuchsia_hardware_display_ControllerCreateLayerResponse create_layer_rsp;
  zx_channel_call_args_t call_args = {};
  call_args.wr_bytes = &create_layer_msg;
  call_args.rd_bytes = &create_layer_rsp;
  call_args.wr_num_bytes = sizeof(create_layer_msg);
  call_args.rd_num_bytes = sizeof(create_layer_rsp);
  uint32_t actual_bytes, actual_handles;
  if ((status = zx_channel_call(dc_handle, 0, ZX_TIME_INFINITE, &call_args,
                                &actual_bytes, &actual_handles)) != ZX_OK) {
    return status;
  }
  if (create_layer_rsp.res != ZX_OK) {
    return create_layer_rsp.res;
  }

  *layer_id_out = create_layer_rsp.layer_id;
  return ZX_OK;
}

static zx_status_t set_display_layers(uint64_t display_id, uint64_t layer_id,
                                      uint64_t sprite_layer_id) {
  uint8_t fidl_bytes
      [sizeof(fuchsia_hardware_display_ControllerSetDisplayLayersRequest) +
       FIDL_ALIGN(sizeof(uint64_t) * 2)];
  fuchsia_hardware_display_ControllerSetDisplayLayersRequest*
      display_layers_msg =
          (fuchsia_hardware_display_ControllerSetDisplayLayersRequest*)
              fidl_bytes;
  display_layers_msg->hdr.ordinal =
      fuchsia_hardware_display_ControllerSetDisplayLayersOrdinal;
  display_layers_msg->display_id = display_id;
  display_layers_msg->layer_ids.count = 2;
  display_layers_msg->layer_ids.data = (void*)FIDL_ALLOC_PRESENT;
  uint64_t* layer_list = (uint64_t*)(display_layers_msg + 1);
  layer_list[0] = layer_id;
  layer_list[1] = sprite_layer_id;
  return zx_channel_write(dc_handle, 0, fidl_bytes, sizeof(fidl_bytes), NULL,
                          0);
}

static zx_status_t set_layer_config(uint64_t layer_id, uint32_t width,
                                    uint32_t height, zx_pixel_format_t format) {
  fuchsia_hardware_display_ControllerSetLayerPrimaryConfigRequest
      layer_cfg_msg = {};
  layer_cfg_msg.hdr.ordinal =
      fuchsia_hardware_display_ControllerSetLayerPrimaryConfigOrdinal;
  layer_cfg_msg.layer_id = layer_id;
  layer_cfg_msg.image_config.width = width;
  layer_cfg_msg.image_config.height = height;
  layer_cfg_msg.image_config.pixel_format = format;
  layer_cfg_msg.image_config.type = IMAGE_TYPE_SIMPLE;
  return zx_channel_write(dc_handle, 0, &layer_cfg_msg, sizeof(layer_cfg_msg),
                          NULL, 0);
}

static zx_status_t set_layer_alpha(uint64_t layer_id, bool alpha) {
  fuchsia_hardware_display_ControllerSetLayerPrimaryAlphaRequest alpha_msg;
  alpha_msg.hdr.ordinal =
      fuchsia_hardware_display_ControllerSetLayerPrimaryAlphaOrdinal;
  alpha_msg.layer_id = layer_id;
  alpha_msg.mode = alpha ? fuchsia_hardware_display_AlphaMode_HW_MULTIPLY
                         : fuchsia_hardware_display_AlphaMode_DISABLE;
  alpha_msg.val = 1.0;
  return zx_channel_write(dc_handle, 0, &alpha_msg, sizeof(alpha_msg), NULL, 0);
}

static zx_status_t set_layer_position(uint64_t layer_id, uint32_t src_x,
                                      uint32_t src_y, uint32_t dest_x,
                                      uint32_t dest_y, uint32_t width,
                                      uint32_t height) {
  fuchsia_hardware_display_ControllerSetLayerPrimaryPositionRequest pos_msg;
  pos_msg.hdr.ordinal =
      fuchsia_hardware_display_ControllerSetLayerPrimaryPositionOrdinal;
  pos_msg.layer_id = layer_id;
  pos_msg.transform = fuchsia_hardware_display_Transform_IDENTITY;
  pos_msg.src_frame.width = width;
  pos_msg.src_frame.height = height;
  pos_msg.src_frame.x_pos = src_x;
  pos_msg.src_frame.y_pos = src_y;
  pos_msg.dest_frame.width = width;
  pos_msg.dest_frame.height = height;
  pos_msg.dest_frame.x_pos = dest_x;
  pos_msg.dest_frame.y_pos = dest_y;
  return zx_channel_write(dc_handle, 0, &pos_msg, sizeof(pos_msg), NULL, 0);
}

static zx_status_t set_layer_image(uint64_t layer_id, uint64_t image_id,
                                   uint64_t wait_event_id) {
  fuchsia_hardware_display_ControllerSetLayerImageRequest set_msg;
  set_msg.hdr.ordinal = fuchsia_hardware_display_ControllerSetLayerImageOrdinal;
  set_msg.hdr.txid = txid++;
  set_msg.layer_id = layer_id;
  set_msg.image_id = image_id;
  set_msg.wait_event_id = wait_event_id;
  set_msg.signal_event_id = INVALID_ID;
  return zx_channel_write(dc_handle, 0, &set_msg, sizeof(set_msg), NULL, 0);
}

static zx_status_t check_config() {
  fuchsia_hardware_display_ControllerCheckConfigRequest check_msg;
  uint8_t check_resp_bytes[ZX_CHANNEL_MAX_MSG_BYTES];
  check_msg.discard = false;
  check_msg.hdr.ordinal = fuchsia_hardware_display_ControllerCheckConfigOrdinal;
  zx_channel_call_args_t check_call = {};
  check_call.wr_bytes = &check_msg;
  check_call.rd_bytes = check_resp_bytes;
  check_call.wr_num_bytes = sizeof(check_msg);
  check_call.rd_num_bytes = sizeof(check_resp_bytes);
  uint32_t actual_bytes, actual_handles;
  zx_status_t status;
  if ((status = zx_channel_call(dc_handle, 0, ZX_TIME_INFINITE, &check_call,
                                &actual_bytes, &actual_handles)) != ZX_OK) {
    return status;
  }

  const char* err_msg;
  if ((status = fidl_decode(
           &fuchsia_hardware_display_ControllerCheckConfigResponseTable,
           check_resp_bytes, actual_bytes, NULL, 0, &err_msg)) != ZX_OK) {
    return ZX_ERR_STOP;
  }

  fuchsia_hardware_display_ControllerCheckConfigResponse* check_rsp =
      (fuchsia_hardware_display_ControllerCheckConfigResponse*)check_resp_bytes;
  if (check_rsp->res != fuchsia_hardware_display_ConfigResult_OK) {
    fprintf(stderr, "config not valid (%d)\n", check_rsp->res);
    auto* arr = static_cast<fuchsia_hardware_display_ClientCompositionOp*>(
        check_rsp->ops.data);
    for (unsigned i = 0; i < check_rsp->ops.count; i++) {
      fprintf(stderr, "client composition op (display %ld, layer %ld): %d\n",
              arr[i].display_id, arr[i].layer_id, arr[i].opcode);
    }
    return ZX_ERR_STOP;
  }
  return ZX_OK;
}

static zx_status_t apply_config() {
  fuchsia_hardware_display_ControllerApplyConfigRequest apply_msg;
  apply_msg.hdr.txid = txid++;
  apply_msg.hdr.ordinal = fuchsia_hardware_display_ControllerApplyConfigOrdinal;
  return zx_channel_write(dc_handle, 0, &apply_msg, sizeof(apply_msg), NULL, 0);
}

static zx_status_t alloc_image_buffer(uint32_t size, zx_handle_t* vmo_out) {
  fuchsia_hardware_display_ControllerAllocateVmoRequest alloc_msg;
  alloc_msg.hdr.ordinal = fuchsia_hardware_display_ControllerAllocateVmoOrdinal;
  alloc_msg.hdr.txid = txid++;
  alloc_msg.size = size;

  fuchsia_hardware_display_ControllerAllocateVmoResponse alloc_rsp;
  zx_channel_call_args_t call_args = {};
  call_args.wr_bytes = &alloc_msg;
  call_args.rd_bytes = &alloc_rsp;
  call_args.rd_handles = vmo_out;
  call_args.wr_num_bytes = sizeof(alloc_msg);
  call_args.rd_num_bytes = sizeof(alloc_rsp);
  call_args.rd_num_handles = 1;
  uint32_t actual_bytes, actual_handles;
  zx_status_t status;
  if ((status = zx_channel_call(dc_handle, 0, ZX_TIME_INFINITE, &call_args,
                                &actual_bytes, &actual_handles)) != ZX_OK) {
    if (alloc_rsp.res != ZX_OK) {
      status = alloc_rsp.res;
    }
    return status;
  }
  return ZX_OK;
}

zx_status_t enable_vsync(bool enable) {
  fuchsia_hardware_display_ControllerEnableVsyncRequest enable_vsync;
  enable_vsync.hdr.ordinal =
      fuchsia_hardware_display_ControllerEnableVsyncOrdinal;
  enable_vsync.enable = enable;
  return zx_channel_write(dc_handle, 0, &enable_vsync, sizeof(enable_vsync),
                          NULL, 0);
}

zx_status_t wait_for_vsync(zx_time_t* timestamp, uint64_t image_ids[2]) {
  zx_status_t status;
  zx_handle_t observed;
  uint32_t signals = ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED;
  if ((status = zx_object_wait_one(dc_handle, signals, ZX_TIME_INFINITE,
                                   &observed)) != ZX_OK) {
    return status;
  }
  if (observed & ZX_CHANNEL_PEER_CLOSED) {
    return ZX_ERR_PEER_CLOSED;
  }

  uint8_t bytes[ZX_CHANNEL_MAX_MSG_BYTES];
  uint32_t actual_bytes, actual_handles;
  if ((status =
           zx_channel_read(dc_handle, 0, bytes, NULL, ZX_CHANNEL_MAX_MSG_BYTES,
                           0, &actual_bytes, &actual_handles)) != ZX_OK) {
    return ZX_ERR_STOP;
  }

  if (actual_bytes < sizeof(fidl_message_header_t)) {
    return ZX_ERR_INTERNAL;
  }

  fidl_message_header_t* header = (fidl_message_header_t*)bytes;

  switch (header->ordinal) {
    case fuchsia_hardware_display_ControllerDisplaysChangedOrdinal:
      return ZX_ERR_STOP;
    case fuchsia_hardware_display_ControllerClientOwnershipChangeOrdinal:
      return ZX_ERR_NEXT;
    case fuchsia_hardware_display_ControllerVsyncOrdinal:
      break;
    default:
      return ZX_ERR_STOP;
  }

  const char* err_msg;
  if ((status = fidl_decode(&fuchsia_hardware_display_ControllerVsyncEventTable,
                            bytes, actual_bytes, NULL, 0, &err_msg)) != ZX_OK) {
    return ZX_ERR_STOP;
  }

  fuchsia_hardware_display_ControllerVsyncEvent* vsync =
      (fuchsia_hardware_display_ControllerVsyncEvent*)bytes;
  *timestamp = vsync->timestamp;
  image_ids[0] =
      vsync->images.count > 0 ? ((uint64_t*)vsync->images.data)[0] : INVALID_ID;
  image_ids[1] =
      vsync->images.count > 1 ? ((uint64_t*)vsync->images.data)[1] : INVALID_ID;
  return ZX_OK;
}

static void print_usage(FILE* stream) {
  fprintf(stream,
          "usage: gfxlatency [options]\n\n"
          "options:\n"
          "  -h, --help\t\t\tPrint this help\n"
          "  --vsync=on|off|adaptive\tVSync mode (default=adaptive)\n"
          "  --offset=MS\t\t\tVSync offset (default=15)\n"
          "  --pen-prediction=MS\t\tPen prediction (default=15)\n"
          "  --scroll-prediction=MS\tScroll prediction (default=15)\n"
          "  --prediction-color=COLOR\tPrediction color (default=0x7f000000)\n"
          "  --slow-down-scale-factor=NUM\tUpdate each line multiple times "
          "(default=1)\n");
}

class BufferArray {
 public:
  BufferArray(uint32_t buffer_size, size_t count, uint32_t width,
              uint32_t height, zx_pixel_format_t format)
      : size_(buffer_size), array_(new buffer_t[NUM_BUFFERS], count) {
    for (auto& buffer : array_) {
      zx_status_t status = alloc_image_buffer(size_, &buffer.vmo);
      ZX_ASSERT(status == ZX_OK);

      zx_vmo_set_cache_policy(buffer.vmo, ZX_CACHE_POLICY_WRITE_COMBINING);

      status =
          import_image(buffer.vmo, width, height, format, &buffer.image_id);
      ZX_ASSERT(status == ZX_OK);

      status =
          zx_vmar_map(zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE,
                      0, buffer.vmo, 0, size_, &buffer.data);
      ZX_ASSERT(status == ZX_OK);
    }
  }

  ~BufferArray() {
    for (auto& buffer : array_) {
      release_image(buffer.image_id);
      if (buffer.wait_event_id != INVALID_ID) {
        release_event(buffer.wait_event_id);
      }
      if (buffer.wait_event != ZX_HANDLE_INVALID) {
        zx_handle_close(buffer.wait_event);
      }
      zx_vmar_unmap(zx_vmar_root_self(), buffer.data, size_);
      zx_handle_close(buffer.vmo);
    }
  }

  size_t size() const { return array_.size(); }

  buffer_t& operator[](size_t i) const { return array_[i]; }

  buffer_t* begin() const { return array_.begin(); }

  buffer_t* end() const { return array_.end(); }

 private:
  uint32_t size_;
  fbl::Array<buffer_t> array_;
};

int main(int argc, char* argv[]) {
  async::Loop loop(&kAsyncLoopConfigNoAttachToThread);
  trace::TraceProvider provider(loop.dispatcher());

  VSync vsync = VSync::ADAPTIVE;
  zx_time_t vsync_offset = ZX_MSEC(15);
  int slow_down_scale_factor = 1;
  uint32_t pen_prediction_ms = 15;
  uint32_t scroll_prediction_ms = 15;
  uint32_t prediction_color = 0x7f000000;

  for (int i = 1; i < argc; ++i) {
    const char* arg = argv[i];
    if (strstr(arg, "--vsync") == arg) {
      const char* s = strchr(arg, '=');
      ++s;
      if (!strcmp(s, "on")) {
        vsync = VSync::ON;
      } else if (!strcmp(s, "off")) {
        vsync = VSync::OFF;
      } else if (!strcmp(s, "adaptive")) {
        vsync = VSync::ADAPTIVE;
      } else {
        fprintf(stderr, "invalid vsync mode: %s\n", s);
        print_usage(stderr);
        return -1;
      }
    } else if (strstr(arg, "--offset") == arg) {
      const char* s = strchr(arg, '=');
      ++s;
      vsync_offset = ZX_MSEC(atoi(s));
    } else if (strstr(arg, "--pen-prediction") == arg) {
      const char* s = strchr(arg, '=');
      ++s;
      pen_prediction_ms = atoi(s);
    } else if (strstr(arg, "--prediction-color") == arg) {
      const char* s = strchr(arg, '=');
      ++s;
      prediction_color = (uint32_t)strtol(s, NULL, 16);
    } else if (strstr(arg, "--scroll-prediction") == arg) {
      const char* s = strchr(arg, '=');
      ++s;
      scroll_prediction_ms = atoi(s);
    } else if (strstr(arg, "--slow-down-scale-factor") == arg) {
      const char* s = strchr(arg, '=');
      ++s;
      slow_down_scale_factor = fbl::max(1, atoi(s));
    } else if (strstr(arg, "-h") == arg) {
      print_usage(stdout);
      return 0;
    } else {
      fprintf(stderr, "invalid argument: %s\n", arg);
      print_usage(stderr);
      return -1;
    }
  }

  fbl::unique_fd fd(open("/dev/class/display-controller/000", O_RDWR));
  if (!fd) {
    fprintf(stderr, "failed to open display controller\n");
    return -1;
  }

  zx::channel device_server, device_client;
  zx_status_t status = zx::channel::create(0, &device_server, &device_client);
  if (status != ZX_OK) {
    fprintf(stderr, "failed to create device channel %d (%s)\n", status, zx_status_get_string(status));
    return -1;
  }
  zx::channel dc_server, dc_client;
  status = zx::channel::create(0, &dc_server, &dc_client);
  if (status != ZX_OK) {
    fprintf(stderr, "failed to create controller channel %d (%s)\n", status, zx_status_get_string(status));
    return -1;
  }

  fzl::FdioCaller caller(std::move(fd));
  zx_status_t fidl_status = fuchsia_hardware_display_ProviderOpenController(
      caller.borrow_channel(), device_server.release(), dc_server.release(), &status);
  if (fidl_status != ZX_OK) {
    fprintf(stderr, "failed to call service handle %d (%s)\n", fidl_status, zx_status_get_string(fidl_status));
    return -1;
  }
  if (status != ZX_OK) {
    fprintf(stderr, "failed to open controller %d (%s)\n", status, zx_status_get_string(status));
    return -1;
  }
  dc_handle = dc_client.release();

  uint8_t bytes[ZX_CHANNEL_MAX_MSG_BYTES];
  uint32_t actual_bytes, actual_handles;
  bool has_display = false;
  while (!has_display) {
    zx_handle_t observed;
    uint32_t signals = ZX_CHANNEL_READABLE | ZX_CHANNEL_PEER_CLOSED;
    if ((status = zx_object_wait_one(dc_handle, signals, ZX_TIME_INFINITE,
                                     &observed)) != ZX_OK) {
      fprintf(stderr, "failed waiting for display\n");
      return -1;
    }
    if (observed & ZX_CHANNEL_PEER_CLOSED) {
      fprintf(stderr, "display controller connection closed\n");
      return -1;
    }

    if ((status = zx_channel_read(dc_handle, 0, bytes, NULL,
                                  ZX_CHANNEL_MAX_MSG_BYTES, 0, &actual_bytes,
                                  &actual_handles)) != ZX_OK ||
        actual_bytes < sizeof(fidl_message_header_t)) {
      fprintf(stderr, "reading display addded callback failed\n");
      return -1;
    }

    fidl_message_header_t* hdr = (fidl_message_header_t*)bytes;
    if (hdr->ordinal !=
        fuchsia_hardware_display_ControllerDisplaysChangedOrdinal) {
      continue;
    }
    const char* err_msg;
    if ((status = fidl_decode(
             &fuchsia_hardware_display_ControllerDisplaysChangedEventTable,
             bytes, actual_bytes, NULL, 0, &err_msg)) != ZX_OK) {
      fprintf(stderr, "%s\n", err_msg);
      return -1;
    }
    has_display = true;
  }

  // We're guaranteed that added contains at least one display, since we
  // haven't been notified of any displays to remove.
  fuchsia_hardware_display_ControllerDisplaysChangedEvent* changes =
      (fuchsia_hardware_display_ControllerDisplaysChangedEvent*)bytes;
  fuchsia_hardware_display_Info* display =
      (fuchsia_hardware_display_Info*)changes->added.data;
  fuchsia_hardware_display_Mode* mode =
      (fuchsia_hardware_display_Mode*)display->modes.data;

  uint32_t width = mode->horizontal_resolution;
  uint32_t height = mode->vertical_resolution;
  zx_pixel_format_t format = ((int32_t*)(display->pixel_format.data))[0];

  uint32_t stride;
  if (compute_linear_image_stride(width, format, &stride) != ZX_OK) {
    fprintf(stderr, "failed to get linear stride\n");
    return -1;
  }

  uint64_t layer_id;
  if (create_layer(&layer_id) != ZX_OK) {
    fprintf(stderr, "failed to create layer\n");
    return -1;
  }

  uint32_t sprite_stride;
  if (compute_linear_image_stride(SPRITE_DIM, SPRITE_FORMAT, &sprite_stride) !=
      ZX_OK) {
    fprintf(stderr, "failed to get linear stride\n");
    return -1;
  }

  uint64_t sprite_layer_id;
  if (create_layer(&sprite_layer_id) != ZX_OK) {
    fprintf(stderr, "failed to create sprite layer\n");
    return -1;
  }

  if (set_display_layers(display->id, layer_id, sprite_layer_id) != ZX_OK) {
    fprintf(stderr, "failed to set display layers\n");
    return -1;
  }

  if ((status = set_layer_config(layer_id, width, height, format)) != ZX_OK) {
    fprintf(stderr, "failed to set layer config\n");
    return -1;
  }

  if ((status = set_layer_config(sprite_layer_id, SPRITE_DIM, SPRITE_DIM,
                                 format)) != ZX_OK) {
    fprintf(stderr, "failed to set sprite layer config\n");
    return -1;
  }

  uint32_t buffer_size = ZX_PIXEL_FORMAT_BYTES(format) * height * stride;
  uint32_t canvas_width = width * 2;
  uint32_t canvas_height = height * 2;
  fbl::unique_ptr<uint8_t[]> surface_data(
      new uint8_t[ZX_PIXEL_FORMAT_BYTES(format) * canvas_width *
                  canvas_height]);
  gfx_surface* surface =
      gfx_create_surface((void*)surface_data.get(), canvas_width, canvas_height,
                         canvas_width, format, 0);
  auto cleanup_surface =
      fit::defer([surface]() { gfx_surface_destroy(surface); });
  ZX_ASSERT(surface);
  {
    TRACE_DURATION("app", "Initialize Canvas");

    // Initialize using background image if format allows.
    if (ZX_PIXEL_FORMAT_BYTES(format) == 4) {
      copy_rect((uint32_t*)surface->ptr,
                (const uint32_t*)background_image.pixel_data, canvas_width,
                background_image.width, 0, 0, background_image.width,
                background_image.height);
      for (uint32_t y = 0; y < canvas_height; y += background_image.height) {
        for (uint32_t x = 0; x < canvas_width; x += background_image.width) {
          gfx_copyrect(surface, 0, 0, background_image.width,
                       background_image.height, x, y);
        }
      }
    } else {
      gfx_clear(surface, 0xffffffff);
    }
  }

  fbl::unique_ptr<uint8_t[]> sprite_surface_data(
      new uint8_t[ZX_PIXEL_FORMAT_BYTES(SPRITE_FORMAT) * SPRITE_DIM *
                  SPRITE_DIM]);
  gfx_surface* sprite_surface =
      gfx_create_surface((void*)sprite_surface_data.get(), SPRITE_DIM,
                         SPRITE_DIM, SPRITE_DIM, SPRITE_FORMAT, 0);
  ZX_ASSERT(sprite_surface);
  auto cleanup_sprite_surface =
      fit::defer([sprite_surface]() { gfx_surface_destroy(sprite_surface); });
  gfx_clear(sprite_surface, 0);

  // Scratch buffer for sprite updates. 2 times the size of the sprite.
  fbl::unique_ptr<uint8_t[]> sprite_scratch(
      new uint8_t[ZX_PIXEL_FORMAT_BYTES(SPRITE_FORMAT) * SPRITE_DIM *
                  SPRITE_DIM * 2]);
  memset(sprite_scratch.get(), 0,
         ZX_PIXEL_FORMAT_BYTES(SPRITE_FORMAT) * SPRITE_DIM * SPRITE_DIM * 2);

  pointf_t pen[NUM_PENCILS] = {{.x = NAN, .y = NAN}, {.x = NAN, .y = NAN}};
  point_t sprite_location = {.x = width / 2, .y = height / 2};
  vector_t sprite_hotspot = {.x = SPRITE_RAD, .y = SPRITE_RAD};
  pointf_t cursor = {.x = (float)sprite_location.x,
                     .y = (float)sprite_location.y};
  pointf_t touch[NUM_FINGERS] = {{.x = NAN, .y = NAN},
                                 {.x = NAN, .y = NAN},
                                 {.x = NAN, .y = NAN},
                                 {.x = NAN, .y = NAN},
                                 {.x = NAN, .y = NAN}};
  point_t origin = {.x = canvas_width / 2 - width / 2,
                    .y = canvas_height / 2 - height / 2};
  point_t predicted_origin = origin;
  vectorf_t origin_delta = {.x = 0, .y = 0};

  uint64_t next_event_id = INVALID_ID + 1;

  BufferArray buffers(buffer_size, vsync == VSync::OFF ? 1 : NUM_BUFFERS, width,
                      height, format);
  for (auto& buffer : buffers) {
    status = zx_event_create(0, &buffer.wait_event);
    ZX_ASSERT(status == ZX_OK);
    buffer.wait_event_id = INVALID_ID;
    if (vsync == VSync::ON) {
      buffer.wait_event_id = next_event_id++;
      status = import_event(buffer.wait_event, buffer.wait_event_id);
      ZX_ASSERT(status == ZX_OK);
    }
    zx_object_signal(buffer.wait_event, 0, ZX_EVENT_SIGNALED);

    copy_rect(
        (uint32_t*)buffer.data,
        (const uint32_t*)surface->ptr + origin.y * canvas_width + origin.x,
        stride, canvas_width, 0, 0, width, height);
    memset(&buffer.damage, 0, sizeof(buffer.damage));
  }

  uint32_t sprite_size =
      ZX_PIXEL_FORMAT_BYTES(format) * SPRITE_DIM * sprite_stride;
  BufferArray sprites(sprite_size, vsync == VSync::OFF ? 1 : NUM_BUFFERS,
                      SPRITE_DIM, SPRITE_DIM, SPRITE_FORMAT);
  for (auto& sprite : sprites) {
    status = zx_event_create(0, &sprite.wait_event);
    ZX_ASSERT(status == ZX_OK);
    sprite.wait_event_id = INVALID_ID;
    if (vsync == VSync::ON) {
      sprite.wait_event_id = next_event_id++;
      status = import_event(sprite.wait_event, sprite.wait_event_id);
      ZX_ASSERT(status == ZX_OK);
    }
    zx_object_signal(sprite.wait_event, 0, ZX_EVENT_SIGNALED);

    memset((void*)sprite.data, 0, sprite_size);
    memset(&sprite.damage, 0, sizeof(sprite.damage));
  }

  // Enable vsync if needed.
  if (vsync != VSync::OFF) {
    if ((status = enable_vsync(true)) != ZX_OK) {
      fprintf(stderr, "failed to enable vsync\n");
      return -1;
    }
    TRACE_ASYNC_BEGIN("app", "Buffer Scheduled", (uintptr_t)&buffers[0],
                      "image", buffers[0].image_id);
    TRACE_ASYNC_BEGIN("app", "Sprite Scheduled", (uintptr_t)&sprites[0],
                      "image", sprites[0].image_id);
  }

  // Set initial image for root layer.
  if ((status = set_layer_image(layer_id, buffers[0].image_id, INVALID_ID)) !=
      ZX_OK) {
    fprintf(stderr, "failed to set layer image\n");
    return -1;
  }
  // Set initial image and position for sprite layer.
  if ((status = set_layer_image(sprite_layer_id, sprites[0].image_id,
                                INVALID_ID)) != ZX_OK) {
    fprintf(stderr, "failed to set sprite layer image\n");
    return -1;
  }
  if ((status = set_layer_position(
           sprite_layer_id, 0, 0, sprite_location.x - sprite_hotspot.x,
           sprite_location.y - sprite_hotspot.y, SPRITE_DIM, SPRITE_DIM)) !=
      ZX_OK) {
    fprintf(stderr, "failed to set sprite layer position\n");
    return -1;
  }
  if ((status = set_layer_alpha(sprite_layer_id, true)) != ZX_OK) {
    fprintf(stderr, "failed to set sprite layer alpha\n");
    return -1;
  }

  // Check initial layer config. We assume that movement to the sprite layer
  // doesn't require another check.
  if ((status = check_config()) != ZX_OK) {
    fprintf(stderr, "layer config failed\n");
    return -1;
  }

  // Present initial buffers.
  if ((status = apply_config()) != ZX_OK) {
    fprintf(stderr, "failed to present layers\n");
    return -1;
  }

  DIR* dir = opendir(DEV_INPUT);
  if (!dir) {
    fprintf(stderr, "failed to open %s: %d\n", DEV_INPUT, errno);
    return -1;
  }

  TouchDevice touch_device;
  int touchfd = -1;
  uint32_t touchtraceid = 0;
  int touchpadfd = -1;
  uint32_t touchpadtraceid = 0;
  struct dirent* de;
  while ((de = readdir(dir))) {
    char devname[128];

    if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
      continue;

    snprintf(devname, sizeof(devname), "%s/%s", DEV_INPUT, de->d_name);
    int fd = open(devname, O_RDONLY);
    if (fd < 0) {
      fprintf(stderr, "failed to open %s: %d\n", devname, errno);
      continue;
    }

    fzl::FdioCaller caller{fbl::unique_fd(fd)};

    uint16_t rpt_desc_len;
    status = fuchsia_hardware_input_DeviceGetReportDescSize(
        caller.borrow_channel(), &rpt_desc_len);
    if (status != ZX_OK) {
      fprintf(stderr, "failed to get report descriptor length for %s: %d\n",
              devname, status);
      continue;
    }

    uint8_t rpt_desc[rpt_desc_len];
    size_t actual_rpt_desc_len;
    status = fuchsia_hardware_input_DeviceGetReportDesc(
        caller.borrow_channel(), rpt_desc, sizeof(rpt_desc),
        &actual_rpt_desc_len);
    if (status != ZX_OK) {
      fprintf(stderr, "failed to get report descriptor for %s: %d\n", devname,
              status);
      continue;
    }

    // Use lower 32 bits of channel koid as trace ID.
    zx_info_handle_basic_t info;
    zx_object_get_info(caller.borrow_channel(), ZX_INFO_HANDLE_BASIC, &info,
                       sizeof(info), nullptr, nullptr);
    uint32_t traceid = info.koid & 0xffffffff;

    status = fuchsia_hardware_input_DeviceSetTraceId(caller.borrow_channel(),
                                                     traceid);
    if (status != ZX_OK) {
      fprintf(stderr, "failed to set trace ID for %s: %d\n", devname, status);
      continue;
    }

    if (is_paradise_touch_v2_report_desc(rpt_desc, actual_rpt_desc_len)) {
      touch_device = TouchDevice::PARADISE_V2;
      touchfd = caller.release().release();
      touchtraceid = traceid;
      continue;
    }

    if (is_paradise_touch_v3_report_desc(rpt_desc, actual_rpt_desc_len)) {
      touch_device = TouchDevice::PARADISE_V3;
      touchfd = caller.release().release();
      touchtraceid = traceid;
      continue;
    }

    if (is_paradise_touchpad_v2_report_desc(rpt_desc, actual_rpt_desc_len)) {
      touchpadfd = caller.release().release();
      touchpadtraceid = traceid;
      continue;
    }
  }
  closedir(dir);

  if (touchfd < 0 && touchpadfd < 0) {
    fprintf(stderr, "could not find a touch device\n");
    return -1;
  }

  uint16_t max_touch_rpt_sz = 0;
  uint16_t max_touchpad_rpt_sz = 0;
  if (touchfd >= 0) {
    fzl::FdioCaller caller{fbl::unique_fd(touchfd)};
    status = fuchsia_hardware_input_DeviceGetMaxInputReportSize(
        caller.borrow_channel(), &max_touch_rpt_sz);
    touchfd = caller.release().release();
    ZX_ASSERT(status == ZX_OK);
  }
  if (touchpadfd >= 0) {
    fzl::FdioCaller caller{fbl::unique_fd(touchpadfd)};
    status = fuchsia_hardware_input_DeviceGetMaxInputReportSize(
        caller.borrow_channel(), &max_touchpad_rpt_sz);
    touchpadfd = caller.release().release();
    ZX_ASSERT(status == ZX_OK);
  }

  async::Loop update_loop(&kAsyncLoopConfigNoAttachToThread);
  update_loop.StartThread();
  async::Loop sprite_update_loop(&kAsyncLoopConfigNoAttachToThread);
  sprite_update_loop.StartThread();

  size_t buffer_frame = 0;
  size_t sprite_frame = 0;
  bool buffer_frame_scheduled = vsync != VSync::OFF;
  bool sprite_frame_scheduled = vsync != VSync::OFF;
  bool buffer_update_pending = false;
  bool sprite_update_pending = false;
  bool show_cursor = false;
  fbl::Vector<pointf_t> points[NUM_PENCILS];
  fbl::Vector<line_t> lines;

  // Input prediction state.
  zx_time_t last_input_prediction_update = zx_clock_get_monotonic();
  pointf_t touch0[NUM_FINGERS];
  memcpy(touch0, touch, sizeof(touch));
  pointf_t pen0[NUM_PENCILS];
  memcpy(pen0, pen, sizeof(pen));
  pointf_t origin0 = {.x = (float)origin.x, .y = (float)origin.y};
  pointf_t cursor0 = cursor;
  double cursor_blur_radius = 0;
  double cursor_movement_angle = 0;
  vector_t cursor_blur_offset = {.x = 0, .y = 0};
  vectorf_t origin_responsive_velocity = {.x = 0, .y = 0};
  vectorf_t origin_smooth_velocity = {.x = 0, .y = 0};
  vectorf_t predicted_origin_movement = {.x = 0, .y = 0};
  vectorf_t pen_responsive_velocity[NUM_PENCILS] = {
      {.x = 0, .y = 0},
      {.x = 0, .y = 0},
  };
  vectorf_t pen_smooth_velocity[NUM_PENCILS] = {
      {.x = 0, .y = 0},
      {.x = 0, .y = 0},
  };
  vectorf_t predicted_stylus_movement = {.x = 0, .y = 0};
  uint32_t touchreports_read = 0;
  uint32_t touchpadreports_read = 0;

  async::TaskClosure frame_task([&] {
    if (vsync == VSync::OFF) {
      int startfd, endfd;
      struct pollfd fds[2];

      // Wait for input until it is time to update the input prediction
      // model.
      int timeout = fbl::max((int)(ZX_MSEC(last_input_prediction_update) +
                                   INPUT_PREDICTION_UPDATE_INTERVAL_MS -
                                   ZX_MSEC(zx_clock_get_monotonic())),
                             0);
      prepare_poll(touchfd, touchpadfd, &startfd, &endfd, fds);
      poll(&fds[startfd], endfd - startfd, timeout);
    } else {
      zx_time_t vsync_time;
      zx_status_t status;

      // Wait for VSync.
      uint64_t image_ids[2] = {INVALID_ID, INVALID_ID};
      while ((status = wait_for_vsync(&vsync_time, image_ids)) != ZX_OK) {
        if (status == ZX_ERR_STOP) {
          loop.Quit();
          return;
        }
      }

      // Detect when image from current frame is being scanned out.
      auto& buffer = buffers[buffer_frame % buffers.size()];
      if (buffer_frame_scheduled && (image_ids[0] == buffer.image_id ||
                                     image_ids[1] == buffer.image_id)) {
        TRACE_ASYNC_END("app", "Buffer Scheduled", (uintptr_t)&buffer, "image",
                        buffer.image_id);
        if (buffer_frame > 0) {
          auto& last_buffer = buffers[(buffer_frame - 1) % buffers.size()];
          TRACE_ASYNC_END("app", "Buffer Displayed", (uintptr_t)&last_buffer,
                          "image", last_buffer.image_id);
        }
        TRACE_ASYNC_BEGIN("app", "Buffer Displayed", (uintptr_t)&buffer,
                          "image", buffer.image_id);
        buffer_frame_scheduled = false;
      }
      auto& sprite = sprites[sprite_frame % sprites.size()];
      if (sprite_frame_scheduled && (image_ids[0] == sprite.image_id ||
                                     image_ids[1] == sprite.image_id)) {
        TRACE_ASYNC_END("app", "Sprite Scheduled", (uintptr_t)&sprite, "image",
                        sprite.image_id);
        if (sprite_frame > 0) {
          auto& last_sprite = sprites[(sprite_frame - 1) % sprites.size()];
          TRACE_ASYNC_END("app", "Sprite Displayed", (uintptr_t)&last_sprite,
                          "image", last_sprite.image_id);
        }
        TRACE_ASYNC_BEGIN("app", "Sprite Displayed", (uintptr_t)&sprite,
                          "image", sprite.image_id);
        sprite_frame_scheduled = false;
      }

      {
        TRACE_DURATION("app", "Waiting For VSync Offset");

        // Wait until vsync + offset.
        zx_nanosleep(vsync_time + vsync_offset);
      }
    }

    // Save current state.
    point_t old_origin = origin;
    pointf_t old_pen[NUM_PENCILS];
    memcpy(old_pen, pen, sizeof(pen));
    point_t old_sprite_location = sprite_location;
    bool old_show_cursor = show_cursor;
    double old_cursor_blur_radius = cursor_blur_radius;
    vector_t old_cursor_blur_offset = cursor_blur_offset;

    // Process all pending input events.
    int ready = 0;
    while (true) {
      int startfd, endfd;
      struct pollfd fds[2];

      prepare_poll(touchfd, touchpadfd, &startfd, &endfd, fds);
      ready = poll(&fds[startfd], endfd - startfd, 0);
      if (!ready)
        break;

      TRACE_DURATION("app", "Process Input Event");

      if (touchfd >= 0 && fds[0].revents) {
        uint8_t rpt_buf[max_touch_rpt_sz];
        ssize_t bytes = read(touchfd, rpt_buf, max_touch_rpt_sz);
        ZX_ASSERT(bytes > 0);

        TRACE_FLOW_END("input", "hid_report",
                       HID_REPORT_TRACE_ID(touchtraceid, touchreports_read));
        ++touchreports_read;

        uint8_t id = *(uint8_t*)rpt_buf;
        if (id == PARADISE_RPT_ID_TOUCH) {
          if (touch_device == TouchDevice::PARADISE_V2) {
            parse_paradise_touch_report<paradise_touch_v2_t>(rpt_buf, width,
                                                             height, touch);
          } else {
            parse_paradise_touch_report<paradise_touch_t>(rpt_buf, width,
                                                          height, touch);
          }
          for (uint8_t c = 0; c < NUM_FINGERS; c++) {
            if (!isnan(touch[c].x) && !isnan(touch[c].y)) {
              show_cursor = false;
            }
          }
        } else if (id == PARADISE_RPT_ID_STYLUS) {
          parse_paradise_stylus_report(rpt_buf, width, height,
                                       &pen[STYLUS_PEN]);

          if (!isnan(pen[STYLUS_PEN].x) && !isnan(pen[STYLUS_PEN].y)) {
            points[STYLUS_PEN].push_back(pen[STYLUS_PEN]);
            show_cursor = false;
          }
        }
      }

      if (touchpadfd >= 0 && fds[1].revents) {
        uint8_t rpt_buf[max_touchpad_rpt_sz];
        ssize_t bytes = read(touchpadfd, rpt_buf, max_touchpad_rpt_sz);
        ZX_ASSERT(bytes > 0);

        TRACE_FLOW_END(
            "input", "hid_report",
            HID_REPORT_TRACE_ID(touchpadtraceid, touchpadreports_read));
        ++touchpadreports_read;

        uint8_t button = 0;
        parse_paradise_touchpad_report(rpt_buf, width, height, touch, &button);

        uint32_t contact_count = 0;
        for (uint8_t c = 0; c < NUM_FINGERS; c++) {
          if (!isnan(touch[c].x) && !isnan(touch[c].y)) {
            ++contact_count;
          }
        }

        pen[TOUCH_PEN].x = NAN;
        pen[TOUCH_PEN].y = NAN;
        // Show cursor if we only have one contact point.
        if (contact_count == 1 && (!isnan(touch[0].x) && !isnan(touch[0].y))) {
          show_cursor = true;
          if (button) {
            pen[TOUCH_PEN].x = cursor.x;
            pen[TOUCH_PEN].y = cursor.y;
            points[TOUCH_PEN].push_back(pen[TOUCH_PEN]);
          }
        }
      }
    }

    // Calculate origin delta from the average touch delta.
    vectorf_t touch_delta = {.x = 0, .y = 0};
    int32_t contact_count = 0;
    for (uint8_t c = 0; c < NUM_FINGERS; c++) {
      if (isnan(touch0[c].x) || isnan(touch[c].x) || isnan(touch0[c].y) ||
          isnan(touch[c].y)) {
        continue;
      }

      // Ignore cursor.
      if (show_cursor && c == 0) {
        continue;
      }

      touch_delta.x += touch[c].x - touch0[c].x;
      touch_delta.y += touch[c].y - touch0[c].y;
      ++contact_count;
    }
    if (contact_count) {
      origin_delta.x = -touch_delta.x / (float)contact_count;
      origin_delta.y = -touch_delta.y / (float)contact_count;
    }

    // Calculate cursor delta. Cursor should only move when no other
    // touch points are active.
    vectorf_t cursor_delta = {.x = 0, .y = 0};
    if (show_cursor && !contact_count && !isnan(touch0[0].x) &&
        !isnan(touch[0].x) && !isnan(touch0[0].y) && !isnan(touch[0].y)) {
      cursor_delta.x = touch[0].x - touch0[0].x;
      cursor_delta.y = touch[0].y - touch0[0].y;
    }

    // Update input prodiction model if enough time has passed. The input
    // prediction model is effected by velocity. Velocity needs to be
    // sampled at an interval to provide a meaningful value.
    zx_time_t current_time = zx_clock_get_monotonic();
    if (ZX_MSEC(current_time - last_input_prediction_update) >=
        INPUT_PREDICTION_UPDATE_INTERVAL_MS) {
      zx_time_t elapsed = current_time - last_input_prediction_update;
      float elapsed_ms = (float)elapsed / ZX_MSEC(1);
      last_input_prediction_update = current_time;

      TRACE_DURATION("app", "Update Input Prediction", "elapsed", elapsed_ms);

      // Update origin prediction.
      pointf_t new_origin = {
          .x = fbl::clamp(origin0.x + origin_delta.x, 0.0f,
                          (float)(surface->width - width)),
          .y = fbl::clamp(origin0.y + origin_delta.y, 0.0f,
                          (float)(surface->height - height))};
      vectorf_t velocity = {
          .x = fbl::clamp((new_origin.x - origin0.x) / elapsed_ms,
                          -ORIGIN_VELOCITY_MAX, ORIGIN_VELOCITY_MAX),
          .y = fbl::clamp((new_origin.y - origin0.y) / elapsed_ms,
                          -ORIGIN_VELOCITY_MAX, ORIGIN_VELOCITY_MAX)};
      // Slowly reduce velocity when we don't have any active touch
      // points.
      if (!contact_count) {
        velocity.x *= 0.95f;
        velocity.y *= 0.95f;
      }
      vector_interpolate(&origin_responsive_velocity,
                         &origin_responsive_velocity, &velocity,
                         RESPONSIVE_VELOCITY_FACTOR);
      vector_interpolate(&origin_smooth_velocity, &origin_smooth_velocity,
                         &velocity, SMOOTH_VELOCITY_FACTOR);

      origin0 = new_origin;
      // Update origin delta to match current touch points when we have
      // active contact points.
      if (contact_count) {
        origin_delta.x = 0;
        origin_delta.y = 0;
        vector_interpolate(&predicted_origin_movement,
                           &origin_responsive_velocity, &origin_smooth_velocity,
                           ORIGIN_MOVEMENT_FACTOR);
        predicted_origin_movement.x *= (float)scroll_prediction_ms;
        predicted_origin_movement.y *= (float)scroll_prediction_ms;
        TRACE_INSTANT("app", "Scroll Prediction", TRACE_SCOPE_THREAD, "dx",
                      predicted_origin_movement.x, "dy",
                      predicted_origin_movement.y);
      } else {
        // Compute a new delta based on velocity when we don't have
        // any active touch points. This results in some motion
        // being maintained after active touch points are gone.
        vector_interpolate(&origin_delta, &origin_responsive_velocity,
                           &origin_smooth_velocity, ORIGIN_MOVEMENT_FACTOR);
        origin_delta.x *= elapsed_ms;
        origin_delta.y *= elapsed_ms;
        origin_delta.x += predicted_origin_movement.x;
        origin_delta.y += predicted_origin_movement.y;
        predicted_origin_movement.x = 0;
        predicted_origin_movement.y = 0;
      }

      // Update cursor prediction.
      pointf_t new_cursor = {
          .x = fbl::clamp(cursor0.x + cursor_delta.x, 0.0f, (float)(width - 1)),
          .y = fbl::clamp(cursor0.y + cursor_delta.y, 0.0f,
                          (float)(height - 1))};
      vectorf_t pen_velocity = {
          .x = fbl::clamp((new_cursor.x - cursor0.x) / elapsed_ms,
                          -PEN_VELOCITY_MAX, PEN_VELOCITY_MAX),
          .y = fbl::clamp((new_cursor.y - cursor0.y) / elapsed_ms,
                          -PEN_VELOCITY_MAX, PEN_VELOCITY_MAX)};
      vector_interpolate(&pen_responsive_velocity[TOUCH_PEN],
                         &pen_responsive_velocity[TOUCH_PEN], &pen_velocity,
                         RESPONSIVE_VELOCITY_FACTOR);
      vector_interpolate(&pen_smooth_velocity[TOUCH_PEN],
                         &pen_smooth_velocity[TOUCH_PEN], &pen_velocity,
                         SMOOTH_VELOCITY_FACTOR);
      vectorf_t movement;
      vector_interpolate(&movement, &pen_responsive_velocity[TOUCH_PEN],
                         &pen_smooth_velocity[TOUCH_PEN], PEN_MOVEMENT_FACTOR);
      movement.x *= CURSOR_MOVEMENT_PREDICTION_MS;
      movement.y *= CURSOR_MOVEMENT_PREDICTION_MS;
      TRACE_INSTANT("app", "Cursor Prediction", TRACE_SCOPE_THREAD, "dx",
                    movement.x, "dy", movement.y);

      double distance = sqrt(movement.x * movement.x + movement.y * movement.y);
      if (distance >= MIN_MOVEMENT_FOR_CURSOR_MOTION_BLUR) {
        cursor_movement_angle = atan2(movement.y, movement.x);
        cursor_blur_radius = fbl::min(round(distance / 2), MAX_BLUR_RADIUS);
        cursor_blur_offset.x =
            (int32_t)round(movement.x * cursor_blur_radius / distance);
        cursor_blur_offset.y =
            (int32_t)round(movement.y * cursor_blur_radius / distance);
      } else {
        cursor_movement_angle = 0;
        cursor_blur_radius = 0;
        cursor_blur_offset.x = 0;
        cursor_blur_offset.y = 0;
      }

      cursor0 = new_cursor;
      cursor_delta.x = 0;
      cursor_delta.y = 0;

      memcpy(touch0, touch, sizeof(touch));

      // Update pen prediction.
      pen_velocity = {.x = 0, .y = 0};
      if (!isnan(pen0[STYLUS_PEN].x) && !isnan(pen[STYLUS_PEN].x) &&
          !isnan(pen0[STYLUS_PEN].y) && !isnan(pen[STYLUS_PEN].y)) {
        pen_velocity = {
            .x = fbl::clamp(
                (pen[STYLUS_PEN].x - pen0[STYLUS_PEN].x) / elapsed_ms,
                -PEN_VELOCITY_MAX, PEN_VELOCITY_MAX),
            .y = fbl::clamp(
                (pen[STYLUS_PEN].y - pen0[STYLUS_PEN].y) / elapsed_ms,
                -PEN_VELOCITY_MAX, PEN_VELOCITY_MAX)};
      }
      vector_interpolate(&pen_responsive_velocity[STYLUS_PEN],
                         &pen_responsive_velocity[STYLUS_PEN], &pen_velocity,
                         RESPONSIVE_VELOCITY_FACTOR);
      vector_interpolate(&pen_smooth_velocity[STYLUS_PEN],
                         &pen_smooth_velocity[STYLUS_PEN], &pen_velocity,
                         SMOOTH_VELOCITY_FACTOR);
      vector_interpolate(&predicted_stylus_movement,
                         &pen_responsive_velocity[STYLUS_PEN],
                         &pen_smooth_velocity[STYLUS_PEN], PEN_MOVEMENT_FACTOR);
      predicted_stylus_movement.x *= (float)pen_prediction_ms;
      predicted_stylus_movement.y *= (float)pen_prediction_ms;
      TRACE_INSTANT("app", "Pen Prediction", TRACE_SCOPE_THREAD, "dx",
                    predicted_stylus_movement.x, "dy",
                    predicted_stylus_movement.y);

      pen0[STYLUS_PEN] = pen[STYLUS_PEN];
    }

    // Determine new origin. This might add lines if pencils are active.
    origin.x = fbl::clamp((int32_t)round(origin0.x + origin_delta.x), 0,
                          (int32_t)(surface->width - width));
    origin.y = fbl::clamp((int32_t)round(origin0.y + origin_delta.y), 0,
                          (int32_t)(surface->height - height));
    if (origin.x != old_origin.x || origin.y != old_origin.y) {
      rect_t damage = {.x1 = 0, .y1 = 0, .x2 = width, .y2 = height};
      for (auto& buffer : buffers) {
        union_rects(&buffer.damage, &buffer.damage, &damage);
      }

      // Update lines if penciles were active during change to origin.
      for (size_t i = 0; i < NUM_PENCILS; ++i) {
        if (!isnan(pen[i].x) && !isnan(old_pen[i].x) && !isnan(pen[i].y) &&
            !isnan(old_pen[i].y)) {
          lines.push_back({{(uint32_t)round(old_pen[i].x) + old_origin.x,
                            (uint32_t)round(old_pen[i].y) + old_origin.y},
                           {(uint32_t)round(pen[i].x) + origin.x,
                            (uint32_t)round(pen[i].y) + origin.y}});
          points[i].reset();
        }
      }
    }

    // Determine new predicted origin.
    predicted_origin.x = fbl::clamp((int32_t)round(origin0.x + origin_delta.x +
                                                   predicted_origin_movement.x),
                                    0, (int32_t)(surface->width - width));
    predicted_origin.y = fbl::clamp((int32_t)round(origin0.y + origin_delta.y +
                                                   predicted_origin_movement.y),
                                    0, (int32_t)(surface->height - height));
    if (predicted_origin.x != origin.x || predicted_origin.y != origin.y) {
      rect_t damage = {.x1 = 0, .y1 = 0, .x2 = width, .y2 = height};
      for (auto& buffer : buffers) {
        union_rects(&buffer.damage, &buffer.damage, &damage);
      }
    }

    // Full sprite damage if cursor or stylus pen state changed.
    if (old_show_cursor != show_cursor ||
        !isnan(pen[STYLUS_PEN].x) != !isnan(old_pen[STYLUS_PEN].x) ||
        !isnan(pen[STYLUS_PEN].y) != !isnan(old_pen[STYLUS_PEN].y)) {
      rect_t damage = {.x1 = 0, .y1 = 0, .x2 = SPRITE_DIM, .y2 = SPRITE_DIM};
      for (auto& sprite : sprites) {
        union_rects(&sprite.damage, &sprite.damage, &damage);
      }
    }

    // Determine new cursor position.
    if (show_cursor) {
      cursor.x = cursor0.x + cursor_delta.x;
      cursor.y = cursor0.y + cursor_delta.y;

      sprite_location.x =
          (uint32_t)round(cursor.x - (float)cursor_blur_offset.x);
      sprite_location.y =
          (uint32_t)round(cursor.y - (float)cursor_blur_offset.y);
      sprite_hotspot.x = SPRITE_RAD - cursor_image.width / 2 + CURSOR_HOTSPOT_X;
      sprite_hotspot.y =
          SPRITE_RAD - cursor_image.height / 2 + CURSOR_HOTSPOT_Y;

      if (cursor_blur_radius != old_cursor_blur_radius ||
          cursor_blur_offset.x != old_cursor_blur_offset.y ||
          cursor_blur_offset.x != old_cursor_blur_offset.y) {
        // TODO(reveman): Limit damage to area of sprite that changed.
        rect_t damage = {.x1 = 0, .y1 = 0, .x2 = SPRITE_DIM, .y2 = SPRITE_DIM};
        for (auto& sprite : sprites) {
          union_rects(&sprite.damage, &sprite.damage, &damage);
        }
      }
    }

    // Handle stylus prediction.
    if (pen_prediction_ms && !isnan(pen[STYLUS_PEN].x) &&
        !isnan(pen[STYLUS_PEN].y)) {
      sprite_location.x =
          (uint32_t)round(pen[STYLUS_PEN].x + predicted_stylus_movement.x);
      sprite_location.y =
          (uint32_t)round(pen[STYLUS_PEN].y + predicted_stylus_movement.y);
      sprite_hotspot.x = SPRITE_RAD;
      sprite_hotspot.y = SPRITE_RAD;

      // New prediction point.
      point_t pp = {
          (uint32_t)round(pen[STYLUS_PEN].x) + SPRITE_RAD - sprite_location.x,
          (uint32_t)round(pen[STYLUS_PEN].y) + SPRITE_RAD - sprite_location.y};
      rect_t damage = {.x1 = fbl::min(pp.x, SPRITE_RAD),
                       .y1 = fbl::min(pp.y, SPRITE_RAD),
                       .x2 = fbl::max(pp.x, SPRITE_RAD) + 1,
                       .y2 = fbl::max(pp.y, SPRITE_RAD) + 1};

      // Old prediction point.
      if (!isnan(old_pen[STYLUS_PEN].x) && !isnan(old_pen[STYLUS_PEN].y)) {
        point_t pp = {(uint32_t)round(old_pen[STYLUS_PEN].x) + SPRITE_RAD -
                          old_sprite_location.x,
                      (uint32_t)round(old_pen[STYLUS_PEN].y) + SPRITE_RAD -
                          old_sprite_location.y};
        rect_t r = {.x1 = fbl::min(pp.x, SPRITE_RAD),
                    .y1 = fbl::min(pp.y, SPRITE_RAD),
                    .x2 = fbl::max(pp.x, SPRITE_RAD) + 1,
                    .y2 = fbl::max(pp.y, SPRITE_RAD) + 1};
        union_rects(&damage, &damage, &r);
      }
      for (auto& sprite : sprites) {
        union_rects(&sprite.damage, &sprite.damage, &damage);
      }
    }

    // Update lines if we have new points from the pencils.
    for (size_t i = 0; i < NUM_PENCILS; ++i) {
      if (points[i].is_empty())
        continue;

      pointf_t p0 = old_pen[i];

      // Convert point to surface coordinate by adding origin.
      if (!isnan(p0.x))
        p0.x += (float)origin.x;
      if (!isnan(p0.y))
        p0.y += (float)origin.y;

      for (auto& p : points[i]) {
        pointf_t p1 = {.x = p.x + (float)origin.x, .y = p.y + (float)origin.y};

        if (!isnan(p0.x) && !isnan(p0.y)) {
          uint32_t x1 = (uint32_t)round(p0.x);
          uint32_t y1 = (uint32_t)round(p0.y);
          uint32_t x2 = (uint32_t)round(p1.x);
          uint32_t y2 = (uint32_t)round(p1.y);

          lines.push_back({{x1, y1}, {x2, y2}});

          rect_t damage = {.x1 = fbl::min(x1, x2) - origin.x,
                           .y1 = fbl::min(y1, y2) - origin.y,
                           .x2 = fbl::max(x1, x2) - origin.x + 1,
                           .y2 = fbl::max(y1, y2) - origin.y + 1};
          for (auto& buffer : buffers) {
            union_rects(&buffer.damage, &buffer.damage, &damage);
          }
        }
        p0 = p1;
      }

      points[i].reset();
    }

    // Update pending and frame scheduled are the same when VSync is on.
    if (vsync == VSync::ON) {
      buffer_update_pending = buffer_frame_scheduled;
      sprite_update_pending = sprite_frame_scheduled;
    } else {
      // Check if updates have completed. This provides back-pressure when
      // not using VSync.
      if (buffer_update_pending) {
        zx_handle_t observed;
        auto& buffer = buffers[buffer_frame % buffers.size()];
        status = zx_object_wait_one(buffer.wait_event, ZX_EVENT_SIGNALED, 0,
                                    &observed);
        buffer_update_pending = (status == ZX_ERR_TIMED_OUT);
      }
      if (sprite_update_pending) {
        zx_handle_t observed;
        auto& sprite = sprites[sprite_frame % sprites.size()];
        status = zx_object_wait_one(sprite.wait_event, ZX_EVENT_SIGNALED, 0,
                                    &observed);
        sprite_update_pending = (status == ZX_ERR_TIMED_OUT);
      }
    }

    bool update_buffer = false;
    bool update_sprite = false;

    // Delay update if frame is scheduled or update is pending.
    if (!buffer_frame_scheduled && !buffer_update_pending) {
      if ((update_buffer = !is_rect_empty(
               &buffers[buffer_frame % buffers.size()].damage))) {
        auto& buffer = buffers[++buffer_frame % buffers.size()];

        // Reset wait event.
        zx_object_signal(buffer.wait_event, ZX_EVENT_SIGNALED, 0);

        if (vsync != VSync::OFF) {
          // Present buffer. wait_event_id is invalid when using
          // adaptive sync as that allows scanout to start event if we
          // haven't finished producing the new frame.
          status =
              set_layer_image(layer_id, buffer.image_id, buffer.wait_event_id);
          ZX_ASSERT(status == ZX_OK);

          buffer_frame_scheduled = true;
          TRACE_ASYNC_BEGIN("app", "Buffer Scheduled", (uintptr_t)&buffer,
                            "image", buffer.image_id);
        }
      }
    }
    if (!sprite_frame_scheduled && !sprite_update_pending) {
      if ((update_sprite = !is_rect_empty(
               &sprites[sprite_frame % sprites.size()].damage))) {
        auto& sprite = sprites[++sprite_frame % sprites.size()];

        // Reset wait event.
        zx_object_signal(sprite.wait_event, ZX_EVENT_SIGNALED, 0);

        if (vsync != VSync::OFF) {
          // Present sprite. wait_event_id is invalid when using
          // adaptive sync as that allows scanout to start event if we
          // haven't finished producing the new frame.
          status = set_layer_image(sprite_layer_id, sprite.image_id,
                                   sprite.wait_event_id);
          ZX_ASSERT(status == ZX_OK);

          sprite_frame_scheduled = true;
          TRACE_ASYNC_BEGIN("app", "Sprite Scheduled", (uintptr_t)&sprite,
                            "image", sprite.image_id);
        }
      }
    }

    if (update_sprite) {
      auto& sprite = sprites[sprite_frame % sprites.size()];
      rect_t damage = sprite.damage;
      memset(&sprite.damage, 0, sizeof(sprite.damage));
      sprite_update_pending = true;

      // Schedule update on sprite update thread.
      async::PostTask(
          sprite_update_loop.dispatcher(),
          [&sprite_stride, &sprite_surface, &sprite_scratch, &prediction_color,
           &sprites, sprite_frame, damage, sprite_location, pen, show_cursor,
           cursor_blur_radius, cursor_movement_angle] {
            auto& sprite = sprites[sprite_frame % sprites.size()];

            TRACE_DURATION("app", "Update Sprite", "image", sprite.image_id,
                           "damage", rect_as_string(&sprite.damage));

            ZX_ASSERT(!is_rect_empty(&damage));
            ZX_ASSERT(sprite_surface->pixelsize == sizeof(uint32_t));

            if (show_cursor) {
              ZX_ASSERT(cursor_image.width <= SPRITE_DIM);
              ZX_ASSERT(cursor_image.height <= SPRITE_DIM);

              if (cursor_blur_radius > 0.0) {
                uint32_t* sprite_scratch1 = (uint32_t*)sprite_scratch.get();
                uint32_t* sprite_scratch2 =
                    sprite_scratch1 + SPRITE_DIM * sprite_stride;
                uint32_t blur_offset =
                    (SPRITE_RAD - cursor_image.height / 2) * sprite_stride;

                {
                  TRACE_DURATION("app", "Rotate Cursor", "angle",
                                 cursor_movement_angle);
                  rotate_rect(sprite_scratch1 +
                                  (SPRITE_RAD - cursor_image.height / 2) *
                                      sprite_stride +
                                  SPRITE_RAD - cursor_image.width / 2,
                              (const uint32_t*)cursor_image.pixel_data,
                              cursor_image.width, cursor_image.height,
                              sprite_stride, cursor_image.width,
                              cursor_image.height, cursor_image.width,
                              cursor_image.width / 2, cursor_image.height / 2,
                              cursor_image.width / 2, cursor_image.height / 2,
                              cursor_movement_angle);
                }

                {
                  TRACE_DURATION("app", "Blur Cursor", "radius",
                                 cursor_blur_radius);
                  blur_rect(sprite_scratch2 + blur_offset,
                            sprite_scratch1 + blur_offset, SPRITE_DIM,
                            cursor_image.height, sprite_stride,
                            (int)cursor_blur_radius);
                }

                {
                  TRACE_DURATION("app", "Rotate Sprite", "angle",
                                 -cursor_movement_angle);
                  rotate_rect((uint32_t*)sprite.data, sprite_scratch2,
                              SPRITE_DIM, SPRITE_DIM, sprite_stride, SPRITE_DIM,
                              SPRITE_DIM, sprite_stride, SPRITE_RAD, SPRITE_RAD,
                              SPRITE_RAD, SPRITE_RAD, -cursor_movement_angle);
                }
              } else {
                {
                  TRACE_DURATION("app", "Clear Sprite");
                  gfx_fillrect(sprite_surface, 0, 0, SPRITE_DIM, SPRITE_DIM, 0);
                }

                {
                  TRACE_DURATION("app", "Copy Cursor To Sprite");
                  copy_rect(((uint32_t*)sprite_surface->ptr) +
                                (SPRITE_RAD - cursor_image.height / 2) *
                                    sprite_stride +
                                SPRITE_RAD - cursor_image.width / 2,
                            (const uint32_t*)cursor_image.pixel_data,
                            sprite_surface->stride, cursor_image.width, 0, 0,
                            cursor_image.width, cursor_image.height);
                }

                {
                  TRACE_DURATION("app", "Copy Sprite To Buffer");
                  copy_rect((uint32_t*)sprite.data,
                            (const uint32_t*)sprite_surface->ptr, sprite_stride,
                            sprite_surface->stride, 0, 0, SPRITE_DIM,
                            SPRITE_DIM);
                }
              }
            } else {
              uint32_t x1 = damage.x1;
              uint32_t y1 = damage.y1;
              uint32_t x2 = damage.x2;
              uint32_t y2 = damage.y2;

              if (x2 > SPRITE_DIM)
                x2 = SPRITE_DIM;
              if (y2 > SPRITE_DIM)
                y2 = SPRITE_DIM;

              if (x1 < x2 && y1 < y2) {
                {
                  TRACE_DURATION("app", "Clear Sprite");
                  gfx_fillrect(sprite_surface, x1, y1, x2 - x1, y2 - y1, 0);
                }

                if (!isnan(pen[STYLUS_PEN].x) && !isnan(pen[STYLUS_PEN].y)) {
                  TRACE_DURATION(
                      "app", "Draw Stylus Prediction Line", "dx",
                      (uint32_t)round(pen[STYLUS_PEN].x) - sprite_location.x,
                      "dy",
                      (uint32_t)round(pen[STYLUS_PEN].y) - sprite_location.y);
                  gfx_line(sprite_surface,
                           (uint32_t)round(pen[STYLUS_PEN].x) + SPRITE_RAD -
                               sprite_location.x,
                           (uint32_t)round(pen[STYLUS_PEN].y) + SPRITE_RAD -
                               sprite_location.y,
                           SPRITE_RAD, SPRITE_RAD, prediction_color);
                }

                {
                  TRACE_DURATION("app", "Copy Sprite To Buffer");
                  copy_rect((uint32_t*)sprite.data,
                            (const uint32_t*)sprite_surface->ptr, sprite_stride,
                            sprite_surface->stride, x1, y1, x2, y2);
                }
              }
            }

            // Signal wait event to communicate that update has
            // completed.
            zx_object_signal(sprite.wait_event, 0, ZX_EVENT_SIGNALED);
          });
    }

    if (update_buffer) {
      auto& buffer = buffers[buffer_frame % buffers.size()];
      rect_t damage = buffer.damage;
      memset(&buffer.damage, 0, sizeof(buffer.damage));
      buffer_update_pending = true;

      // Schedule each line on update thread.
      for (auto& line : lines) {
        async::PostTask(update_loop.dispatcher(), [&surface, line] {
          TRACE_DURATION("app", "Draw Line");
          gfx_line(surface, line.p1.x, line.p1.y, line.p2.x, line.p2.y,
                   /*color=*/0);
        });
      }
      lines.reset();

      // Schedule buffer update on update thread.
      async::PostTask(
          update_loop.dispatcher(),
          [&stride, &surface, &slow_down_scale_factor, &width, &height,
           &buffers, buffer_frame, damage, predicted_origin] {
            auto& buffer = buffers[buffer_frame % buffers.size()];

            TRACE_DURATION("app", "Update Buffer", "image", buffer.image_id,
                           "damage", rect_as_string(&damage));

            ZX_ASSERT(!is_rect_empty(&damage));

            uint32_t x1 = damage.x1;
            uint32_t y1 = damage.y1;
            uint32_t x2 = damage.x2;
            uint32_t y2 = damage.y2;

            if (x2 > width)
              x2 = width;
            if (y2 > height)
              y2 = height;

            if (x1 < x2 && y1 < y2) {
              uint32_t pixelsize = surface->pixelsize;
              uint32_t lines = y2 - y1;
              uint32_t bytes_per_line = (x2 - x1) * pixelsize;
              uint32_t dst_pitch = stride * pixelsize;
              uint32_t src_pitch = surface->stride * pixelsize;
              uint8_t* dst =
                  ((uint8_t*)buffer.data) + (y1 * stride + x1) * pixelsize;
              const uint8_t* src =
                  ((uint8_t*)surface->ptr) +
                  ((y1 + predicted_origin.y) * surface->stride + x1 +
                   predicted_origin.x) *
                      pixelsize;

              TRACE_DURATION("app", "Copy Contents To Buffer");

              while (lines--) {
                int n = slow_down_scale_factor;
                while (n--)
                  memcpy(dst, src, bytes_per_line);
                dst += dst_pitch;
                src += src_pitch;
              }
            }

            // Signal wait event to communicate that update has
            // completed.
            zx_object_signal(buffer.wait_event, 0, ZX_EVENT_SIGNALED);
          });
    }

    // Set sprite position.
    int32_t sprite_x1 = sprite_location.x - sprite_hotspot.x;
    int32_t sprite_y1 = sprite_location.y - sprite_hotspot.y;
    int32_t sprite_x2 = sprite_x1 + SPRITE_DIM;
    int32_t sprite_y2 = sprite_y1 + SPRITE_DIM;
    int32_t clipped_sprite_x1 = fbl::max(sprite_x1, 0);
    int32_t clipped_sprite_y1 = fbl::max(sprite_y1, 0);
    int32_t clipped_sprite_x2 = fbl::min(sprite_x2, (int32_t)width);
    int32_t clipped_sprite_y2 = fbl::min(sprite_y2, (int32_t)height);
    ZX_ASSERT(sprite_x1 <= clipped_sprite_x1);
    ZX_ASSERT(sprite_y1 <= clipped_sprite_y1);
    status = set_layer_position(sprite_layer_id, clipped_sprite_x1 - sprite_x1,
                                clipped_sprite_y1 - sprite_y1,
                                clipped_sprite_x1, clipped_sprite_y1,
                                clipped_sprite_x2 - clipped_sprite_x1,
                                clipped_sprite_y2 - clipped_sprite_y1);
    ZX_ASSERT(status == ZX_OK);

    status = apply_config();
    ZX_ASSERT(status == ZX_OK);

    frame_task.Post(loop.dispatcher());
  });
  frame_task.Post(loop.dispatcher());

  loop.Run();

  if (touchfd >= 0)
    close(touchfd);
  if (touchpadfd >= 0)
    close(touchpadfd);
  zx_handle_close(dc_handle);
  return 0;
}
