// Copyright 2018 The Chromium OS 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 "sommelier.h"

#include <assert.h>
#include <stdlib.h>
#include <unistd.h>
#include <wayland-client.h>

#include "drm-server-protocol.h"
#include "linux-dmabuf-unstable-v1-client-protocol.h"

struct sl_host_shm_pool {
  struct sl_shm* shm;
  struct wl_resource* resource;
  struct wl_shm_pool* proxy;
  int fd;
};

struct sl_host_shm {
  struct sl_shm* shm;
  struct wl_resource* resource;
  struct wl_shm* shm_proxy;
  struct zwp_linux_dmabuf_v1* linux_dmabuf_proxy;
};

size_t sl_shm_bpp_for_shm_format(uint32_t format) {
  switch (format) {
    case WL_SHM_FORMAT_NV12:
      return 1;
    case WL_SHM_FORMAT_RGB565:
      return 2;
    case WL_SHM_FORMAT_ARGB8888:
    case WL_SHM_FORMAT_ABGR8888:
    case WL_SHM_FORMAT_XRGB8888:
    case WL_SHM_FORMAT_XBGR8888:
      return 4;
  }
  assert(0);
  return 0;
}

size_t sl_shm_num_planes_for_shm_format(uint32_t format) {
  switch (format) {
    case WL_SHM_FORMAT_NV12:
      return 2;
    case WL_SHM_FORMAT_RGB565:
    case WL_SHM_FORMAT_ARGB8888:
    case WL_SHM_FORMAT_ABGR8888:
    case WL_SHM_FORMAT_XRGB8888:
    case WL_SHM_FORMAT_XBGR8888:
      return 1;
  }
  assert(0);
  return 0;
}

static size_t sl_y_subsampling_for_shm_format_plane(uint32_t format,
                                                    size_t plane) {
  switch (format) {
    case WL_SHM_FORMAT_NV12: {
      const size_t subsampling[] = {1, 2};

      assert(plane < ARRAY_SIZE(subsampling));
      return subsampling[plane];
    }
    case WL_SHM_FORMAT_RGB565:
    case WL_SHM_FORMAT_ARGB8888:
    case WL_SHM_FORMAT_ABGR8888:
    case WL_SHM_FORMAT_XRGB8888:
    case WL_SHM_FORMAT_XBGR8888:
      return 1;
  }
  assert(0);
  return 0;
}

static int sl_offset_for_shm_format_plane(uint32_t format,
                                          size_t height,
                                          size_t stride,
                                          size_t plane) {
  switch (format) {
    case WL_SHM_FORMAT_NV12: {
      const size_t offset[] = {0, 1};

      assert(plane < ARRAY_SIZE(offset));
      return offset[plane] * height * stride;
    }
    case WL_SHM_FORMAT_RGB565:
    case WL_SHM_FORMAT_ARGB8888:
    case WL_SHM_FORMAT_ABGR8888:
    case WL_SHM_FORMAT_XRGB8888:
    case WL_SHM_FORMAT_XBGR8888:
      return 0;
  }
  assert(0);
  return 0;
}

static size_t sl_size_for_shm_format_plane(uint32_t format,
                                           size_t height,
                                           size_t stride,
                                           size_t plane) {
  return height / sl_y_subsampling_for_shm_format_plane(format, plane) * stride;
}

static size_t sl_size_for_shm_format(uint32_t format,
                                     size_t height,
                                     size_t stride) {
  size_t i, num_planes = sl_shm_num_planes_for_shm_format(format);
  size_t total_size = 0;

  for (i = 0; i < num_planes; ++i) {
    size_t size = sl_size_for_shm_format_plane(format, height, stride, i);
    size_t offset = sl_offset_for_shm_format_plane(format, height, stride, i);
    total_size = MAX(total_size, size + offset);
  }

  return total_size;
}

static void sl_host_shm_pool_create_host_buffer(struct wl_client* client,
                                                struct wl_resource* resource,
                                                uint32_t id,
                                                int32_t offset,
                                                int32_t width,
                                                int32_t height,
                                                int32_t stride,
                                                uint32_t format) {
  struct sl_host_shm_pool* host = wl_resource_get_user_data(resource);

  if (host->shm->ctx->shm_driver == SHM_DRIVER_NOOP) {
    assert(host->proxy);
    sl_create_host_buffer(client, id,
                          wl_shm_pool_create_buffer(host->proxy, offset, width,
                                                    height, stride, format),
                          width, height);
  } else {
    struct sl_host_buffer* host_buffer =
        sl_create_host_buffer(client, id, NULL, width, height);

    host_buffer->shm_format = format;
    host_buffer->shm_mmap = sl_mmap_create(
        host->fd, sl_size_for_shm_format(format, height, stride),
        sl_shm_bpp_for_shm_format(format),
        sl_shm_num_planes_for_shm_format(format), offset, stride,
        offset + sl_offset_for_shm_format_plane(format, height, stride, 1),
        stride, sl_y_subsampling_for_shm_format_plane(format, 0),
        sl_y_subsampling_for_shm_format_plane(format, 1));
    // In the case of mmaps created from the client buffer, we want to be able
    // to close the FD when the client releases the shm pool (i.e. when it's
    // done transferring) as opposed to when the pool is freed (i.e. when we're
    // done drawing).
    // We do this by removing the handle to the FD after it has been mmapped,
    // which prevents a double-close.
    host_buffer->shm_mmap->fd = -1;
    host_buffer->shm_mmap->buffer_resource = host_buffer->resource;
  }
}

static void sl_host_shm_pool_destroy(struct wl_client* client,
                                     struct wl_resource* resource) {
  wl_resource_destroy(resource);
}

static void sl_host_shm_pool_resize(struct wl_client* client,
                                    struct wl_resource* resource,
                                    int32_t size) {
  struct sl_host_shm_pool* host = wl_resource_get_user_data(resource);

  if (host->proxy)
    wl_shm_pool_resize(host->proxy, size);
}

static const struct wl_shm_pool_interface sl_shm_pool_implementation = {
    sl_host_shm_pool_create_host_buffer, sl_host_shm_pool_destroy,
    sl_host_shm_pool_resize};

static void sl_destroy_host_shm_pool(struct wl_resource* resource) {
  struct sl_host_shm_pool* host = wl_resource_get_user_data(resource);

  if (host->fd >= 0)
    close(host->fd);
  if (host->proxy)
    wl_shm_pool_destroy(host->proxy);
  wl_resource_set_user_data(resource, NULL);
  free(host);
}

static void sl_shm_create_host_pool(struct wl_client* client,
                                    struct wl_resource* resource,
                                    uint32_t id,
                                    int fd,
                                    int32_t size) {
  struct sl_host_shm* host = wl_resource_get_user_data(resource);
  struct sl_host_shm_pool* host_shm_pool;

  host_shm_pool = malloc(sizeof(*host_shm_pool));
  assert(host_shm_pool);

  host_shm_pool->shm = host->shm;
  host_shm_pool->fd = -1;
  host_shm_pool->proxy = NULL;
  host_shm_pool->resource =
      wl_resource_create(client, &wl_shm_pool_interface, 1, id);
  wl_resource_set_implementation(host_shm_pool->resource,
                                 &sl_shm_pool_implementation, host_shm_pool,
                                 sl_destroy_host_shm_pool);

  switch (host->shm->ctx->shm_driver) {
    case SHM_DRIVER_NOOP:
      host_shm_pool->proxy = wl_shm_create_pool(host->shm_proxy, fd, size);
      wl_shm_pool_set_user_data(host_shm_pool->proxy, host_shm_pool);
      close(fd);
      break;
    case SHM_DRIVER_DMABUF:
    case SHM_DRIVER_VIRTWL:
    case SHM_DRIVER_VIRTWL_DMABUF:
      host_shm_pool->fd = fd;
      break;
  }
}

static const struct wl_shm_interface sl_shm_implementation = {
    sl_shm_create_host_pool};

static void sl_shm_format(void* data, struct wl_shm* shm, uint32_t format) {
  struct sl_host_shm* host = wl_shm_get_user_data(shm);

  switch (format) {
    case WL_SHM_FORMAT_RGB565:
    case WL_SHM_FORMAT_ARGB8888:
    case WL_SHM_FORMAT_ABGR8888:
    case WL_SHM_FORMAT_XRGB8888:
    case WL_SHM_FORMAT_XBGR8888:
      wl_shm_send_format(host->resource, format);
      break;
    default:
      break;
  }
}

static const struct wl_shm_listener sl_shm_listener = {sl_shm_format};

static void sl_drm_format(void* data,
                          struct zwp_linux_dmabuf_v1* linux_dmabuf,
                          uint32_t format) {
  struct sl_host_shm* host = zwp_linux_dmabuf_v1_get_user_data(linux_dmabuf);

  // Forward SHM versions of supported formats.
  switch (format) {
    case WL_DRM_FORMAT_NV12:
      wl_shm_send_format(host->resource, WL_SHM_FORMAT_NV12);
      break;
    case WL_DRM_FORMAT_RGB565:
      wl_shm_send_format(host->resource, WL_SHM_FORMAT_RGB565);
      break;
    case WL_DRM_FORMAT_ARGB8888:
      wl_shm_send_format(host->resource, WL_SHM_FORMAT_ARGB8888);
      break;
    case WL_DRM_FORMAT_ABGR8888:
      wl_shm_send_format(host->resource, WL_SHM_FORMAT_ABGR8888);
      break;
    case WL_DRM_FORMAT_XRGB8888:
      wl_shm_send_format(host->resource, WL_SHM_FORMAT_XRGB8888);
      break;
    case WL_DRM_FORMAT_XBGR8888:
      wl_shm_send_format(host->resource, WL_SHM_FORMAT_XBGR8888);
      break;
  }
}

static void sl_drm_modifier(void* data,
                            struct zwp_linux_dmabuf_v1* linux_dmabuf,
                            uint32_t format,
                            uint32_t modifier_hi,
                            uint32_t modifier_lo) {}

static const struct zwp_linux_dmabuf_v1_listener sl_linux_dmabuf_listener = {
    sl_drm_format, sl_drm_modifier};

static void sl_destroy_host_shm(struct wl_resource* resource) {
  struct sl_host_shm* host = wl_resource_get_user_data(resource);

  if (host->shm_proxy)
    wl_shm_destroy(host->shm_proxy);
  if (host->linux_dmabuf_proxy)
    zwp_linux_dmabuf_v1_destroy(host->linux_dmabuf_proxy);
  wl_resource_set_user_data(resource, NULL);
  free(host);
}

static void sl_bind_host_shm(struct wl_client* client,
                             void* data,
                             uint32_t version,
                             uint32_t id) {
  struct sl_context* ctx = (struct sl_context*)data;
  struct sl_host_shm* host;

  host = malloc(sizeof(*host));
  assert(host);
  host->shm = ctx->shm;
  host->shm_proxy = NULL;
  host->linux_dmabuf_proxy = NULL;
  host->resource = wl_resource_create(client, &wl_shm_interface, 1, id);
  wl_resource_set_implementation(host->resource, &sl_shm_implementation, host,
                                 sl_destroy_host_shm);

  switch (ctx->shm_driver) {
    case SHM_DRIVER_NOOP:
    case SHM_DRIVER_VIRTWL:
      host->shm_proxy = wl_registry_bind(
          wl_display_get_registry(ctx->display), ctx->shm->id,
          &wl_shm_interface, wl_resource_get_version(host->resource));
      wl_shm_set_user_data(host->shm_proxy, host);
      wl_shm_add_listener(host->shm_proxy, &sl_shm_listener, host);
      break;
    case SHM_DRIVER_VIRTWL_DMABUF:
    case SHM_DRIVER_DMABUF:
      assert(ctx->linux_dmabuf);
      host->linux_dmabuf_proxy = wl_registry_bind(
          wl_display_get_registry(ctx->display), ctx->linux_dmabuf->id,
          &zwp_linux_dmabuf_v1_interface,
          wl_resource_get_version(host->resource));
      zwp_linux_dmabuf_v1_set_user_data(host->linux_dmabuf_proxy, host);
      zwp_linux_dmabuf_v1_add_listener(host->linux_dmabuf_proxy,
                                       &sl_linux_dmabuf_listener, host);
      break;
  }
}

struct sl_global* sl_shm_global_create(struct sl_context* ctx) {
  return sl_global_create(ctx, &wl_shm_interface, 1, ctx, sl_bind_host_shm);
}
