// Copyright 2019 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 "display.h"

#include <fuchsia/hardware/goldfish/llcpp/fidl.h>
#include <fuchsia/sysmem/c/fidl.h>
#include <lib/async/cpp/task.h>
#include <lib/async/cpp/time.h>
#include <lib/async/cpp/wait.h>
#include <lib/ddk/debug.h>
#include <lib/ddk/trace/event.h>
#include <lib/zircon-internal/align.h>
#include <zircon/pixelformat.h>
#include <zircon/threads.h>

#include <memory>
#include <sstream>
#include <vector>

#include <fbl/auto_lock.h>

#include "src/graphics/display/drivers/goldfish-display/goldfish-display-bind.h"

namespace goldfish {
namespace {

const char* kTag = "goldfish-display";

const char* kPipeName = "pipe:opengles";

constexpr uint64_t kPrimaryDisplayId = 1;

constexpr uint32_t kClientFlags = 0;

constexpr zx_pixel_format_t kPixelFormats[] = {
    ZX_PIXEL_FORMAT_RGB_x888,
    ZX_PIXEL_FORMAT_ARGB_8888,
    ZX_PIXEL_FORMAT_BGR_888x,
    ZX_PIXEL_FORMAT_ABGR_8888,
};

constexpr uint32_t FB_WIDTH = 1;
constexpr uint32_t FB_HEIGHT = 2;
constexpr uint32_t FB_FPS = 5;

constexpr uint32_t GL_RGBA = 0x1908;
constexpr uint32_t GL_BGRA_EXT = 0x80E1;
constexpr uint32_t GL_UNSIGNED_BYTE = 0x1401;

struct GetFbParamCmd {
  uint32_t op;
  uint32_t size;
  uint32_t param;
};
constexpr uint32_t kOP_rcGetFbParam = 10007;
constexpr uint32_t kSize_rcGetFbParam = 12;

struct CreateColorBufferCmd {
  uint32_t op;
  uint32_t size;
  uint32_t width;
  uint32_t height;
  uint32_t internalformat;
};
constexpr uint32_t kOP_rcCreateColorBuffer = 10012;
constexpr uint32_t kSize_rcCreateColorBuffer = 20;

struct OpenColorBufferCmd {
  uint32_t op;
  uint32_t size;
  uint32_t id;
};
constexpr uint32_t kOP_rcOpenColorBuffer = 10013;
constexpr uint32_t kSize_rcOpenColorBuffer = 12;

struct CloseColorBufferCmd {
  uint32_t op;
  uint32_t size;
  uint32_t id;
};
constexpr uint32_t kOP_rcCloseColorBuffer = 10014;
constexpr uint32_t kSize_rcCloseColorBuffer = 12;

struct SetColorBufferVulkanModeCmd {
  uint32_t op;
  uint32_t size;
  uint32_t id;
  uint32_t mode;
};
constexpr uint32_t kOP_rcSetColorBufferVulkanMode = 10045;
constexpr uint32_t kSize_rcSetColorBufferVulkanMode = 16;

struct UpdateColorBufferCmd {
  uint32_t op;
  uint32_t size;
  uint32_t id;
  uint32_t x;
  uint32_t y;
  uint32_t width;
  uint32_t height;
  uint32_t format;
  uint32_t type;
  uint32_t size_pixels;
};
constexpr uint32_t kOP_rcUpdateColorBuffer = 10024;
constexpr uint32_t kSize_rcUpdateColorBuffer = 40;

struct FbPostCmd {
  uint32_t op;
  uint32_t size;
  uint32_t id;
};
constexpr uint32_t kOP_rcFbPost = 10018;
constexpr uint32_t kSize_rcFbPost = 12;

struct CreateDisplayCmd {
  uint32_t op;
  uint32_t size;
  uint32_t size_display_id;
};
constexpr uint32_t kOP_rcCreateDisplay = 10038;
constexpr uint32_t kSize_rcCreateDisplay = 12;

struct DestroyDisplayCmd {
  uint32_t op;
  uint32_t size;
  uint32_t display_id;
};
constexpr uint32_t kOP_rcDestroyDisplay = 10039;
constexpr uint32_t kSize_rcDestroyDisplay = 12;

struct SetDisplayColorBufferCmd {
  uint32_t op;
  uint32_t size;
  uint32_t display_id;
  uint32_t id;
};
constexpr uint32_t kOP_rcSetDisplayColorBuffer = 10040;
constexpr uint32_t kSize_rcSetDisplayColorBuffer = 16;

struct SetDisplayPoseCmd {
  uint32_t op;
  uint32_t size;
  uint32_t display_id;
  int32_t x;
  int32_t y;
  uint32_t w;
  uint32_t h;
};
constexpr uint32_t kOP_rcSetDisplayPose = 10044;
constexpr uint32_t kSize_rcSetDisplayPose = 28;

}  // namespace

// static
zx_status_t Display::Create(void* ctx, zx_device_t* device) {
  auto display = std::make_unique<Display>(device);

  zx_status_t status = display->Bind();
  if (status == ZX_OK) {
    // devmgr now owns device.
    __UNUSED auto* dev = display.release();
  }
  return status;
}

Display::Display(zx_device_t* parent)
    : DisplayType(parent), loop_(&kAsyncLoopConfigNeverAttachToThread) {
  if (parent) {
    control_ = parent;
    pipe_ = parent;
  }
}

Display::~Display() {
  loop_.Shutdown();

  for (auto& it : devices_) {
    TeardownDisplay(it.first);
  }

  if (id_) {
    fbl::AutoLock lock(&lock_);
    if (cmd_buffer_.is_valid()) {
      auto buffer = static_cast<pipe_cmd_buffer_t*>(cmd_buffer_.virt());
      buffer->id = id_;
      buffer->cmd = PIPE_CMD_CODE_CLOSE;
      buffer->status = PIPE_ERROR_INVAL;

      pipe_.Exec(id_);
      ZX_DEBUG_ASSERT(!buffer->status);
    }
    pipe_.Destroy(id_);
  }
}

zx_status_t Display::Bind() {
  fbl::AutoLock lock(&lock_);

  if (!control_.is_valid()) {
    zxlogf(ERROR, "%s: no control protocol", kTag);
    return ZX_ERR_NOT_SUPPORTED;
  }

  if (!pipe_.is_valid()) {
    zxlogf(ERROR, "%s: no pipe protocol", kTag);
    return ZX_ERR_NOT_SUPPORTED;
  }

  zx_status_t status = pipe_.GetBti(&bti_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: GetBti failed: %d", kTag, status);
    return status;
  }

  status = io_buffer_.Init(bti_.get(), PAGE_SIZE, IO_BUFFER_RW | IO_BUFFER_CONTIG);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: io_buffer_init failed: %d", kTag, status);
    return status;
  }

  status = zx::event::create(0u, &pipe_event_);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: zx_event_create failed: %d", kTag, status);
    return status;
  }

  zx::event pipe_event_dup;
  status = pipe_event_.duplicate(ZX_RIGHT_SAME_RIGHTS, &pipe_event_dup);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: zx_handle_duplicate failed: %d", kTag, status);
    return status;
  }

  zx::vmo vmo;
  status = pipe_.Create(&id_, &vmo);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: Create failed: %d", kTag, status);
    return status;
  }
  status = pipe_.SetEvent(id_, std::move(pipe_event_dup));
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: SetEvent failed: %d", kTag, status);
    return status;
  }

  status = cmd_buffer_.InitVmo(bti_.get(), vmo.get(), 0, IO_BUFFER_RW);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: io_buffer_init_vmo failed: %d", kTag, status);
    return status;
  }

  auto buffer = static_cast<pipe_cmd_buffer_t*>(cmd_buffer_.virt());
  buffer->id = id_;
  buffer->cmd = PIPE_CMD_CODE_OPEN;
  buffer->status = PIPE_ERROR_INVAL;

  pipe_.Open(id_);
  if (buffer->status) {
    zxlogf(ERROR, "%s: Open failed: %d", kTag, buffer->status);
    cmd_buffer_.release();
    return ZX_ERR_INTERNAL;
  }

  size_t length = strlen(kPipeName) + 1;
  memcpy(io_buffer_.virt(), kPipeName, length);
  status = WriteLocked(static_cast<uint32_t>(length));
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: Pipe name write failed: %d", kTag, status);
    return status;
  }

  memcpy(io_buffer_.virt(), &kClientFlags, sizeof(kClientFlags));
  status = WriteLocked(sizeof(kClientFlags));
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: Client flags write failed: %d", kTag, status);
    return status;
  }

  uint64_t next_display_id = kPrimaryDisplayId;

  // Parse optional display params. This is comma seperated list of
  // display devices. The format is:
  //
  // widthxheight[-xpos+ypos][@refresh][%scale]
  char* flag = getenv("driver.goldfish.displays");
  if (flag) {
    std::stringstream devices_stream(flag);
    std::string device_string;
    while (std::getline(devices_stream, device_string, ',')) {
      Device device;
      char delim = 0;
      std::stringstream device_stream(device_string);
      do {
        switch (delim) {
          case 0:
            device_stream >> device.width;
            break;
          case 'x':
            device_stream >> device.height;
            break;
          case '-':
            device_stream >> device.x;
            break;
          case '+':
            device_stream >> device.y;
            break;
          case '@':
            device_stream >> device.refresh_rate_hz;
            break;
          case '%':
            device_stream >> device.scale;
            break;
        }
      } while (device_stream >> delim);

      if (!device.width || !device.height) {
        zxlogf(ERROR, "%s: skip device=%s, missing size", kTag, device_string.c_str());
        continue;
      }
      if (!device.refresh_rate_hz) {
        zxlogf(ERROR, "%s: skip device=%s, refresh rate is zero", kTag, device_string.c_str());
        continue;
      }
      if (device.scale < 0.1f || device.scale > 100.f) {
        zxlogf(ERROR, "%s: skip device=%s, scale is not in range 0.1-100", kTag,
               device_string.c_str());
        continue;
      }

      devices_[next_display_id++] = device;
    }
  }

  // Create primary device if needed.
  if (devices_.empty()) {
    Device device;
    device.width = static_cast<uint32_t>(GetFbParamLocked(FB_WIDTH, 1024));
    device.height = static_cast<uint32_t>(GetFbParamLocked(FB_HEIGHT, 768));
    device.refresh_rate_hz = static_cast<uint32_t>(GetFbParamLocked(FB_FPS, 60));
    devices_[kPrimaryDisplayId] = device;
  }

  // Set up display and set up flush task for each device.
  for (auto& it : devices_) {
    zx_status_t status = SetupDisplayLocked(it.first);
    ZX_DEBUG_ASSERT(status == ZX_OK);

    async::PostTask(loop_.dispatcher(), [this, display_id = it.first] {
      FlushDisplay(loop_.dispatcher(), display_id);
    });
  }

  // Start async event thread.
  loop_.StartThread("goldfish_display_event_thread");

  return DdkAdd("goldfish-display");
}

void Display::DdkUnbind(ddk::UnbindTxn txn) { txn.Reply(); }

void Display::DdkRelease() { delete this; }

void Display::DisplayControllerImplSetDisplayControllerInterface(
    const display_controller_interface_protocol_t* interface) {
  std::vector<added_display_args_t> args;
  for (auto& it : devices_) {
    added_display_args_t display = {
        .display_id = it.first,
        .edid_present = false,
        .panel =
            {
                .params =
                    {
                        .width = it.second.width,
                        .height = it.second.height,
                        .refresh_rate_e2 = it.second.refresh_rate_hz * 100,
                    },
            },
        .pixel_format_list = kPixelFormats,
        .pixel_format_count = sizeof(kPixelFormats) / sizeof(kPixelFormats[0]),
        .cursor_info_list = nullptr,
        .cursor_info_count = 0,
    };
    args.push_back(display);
  }

  {
    fbl::AutoLock lock(&flush_lock_);
    dc_intf_ = ddk::DisplayControllerInterfaceProtocolClient(interface);
    dc_intf_.OnDisplaysChanged(args.data(), args.size(), nullptr, 0, nullptr, 0, nullptr);
  }
}

zx_status_t Display::ImportVmoImage(image_t* image, zx::vmo vmo, size_t offset) {
  auto color_buffer = std::make_unique<ColorBuffer>();

  // Linear images must be pinned.
  unsigned pixel_size = ZX_PIXEL_FORMAT_BYTES(image->pixel_format);
  color_buffer->size = ZX_ROUNDUP(image->width * image->height * pixel_size, PAGE_SIZE);
  zx_status_t status = bti_.pin(ZX_BTI_PERM_READ | ZX_BTI_CONTIGUOUS, vmo, offset,
                                color_buffer->size, &color_buffer->paddr, 1, &color_buffer->pmt);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: failed to pin VMO: %d", kTag, status);
    return status;
  }

  uint32_t format = (image->pixel_format == ZX_PIXEL_FORMAT_RGB_x888 ||
                     image->pixel_format == ZX_PIXEL_FORMAT_ARGB_8888)
                        ? GL_BGRA_EXT
                        : GL_RGBA;

  color_buffer->vmo = std::move(vmo);
  color_buffer->width = image->width;
  color_buffer->height = image->height;
  color_buffer->format = format;

  {
    fbl::AutoLock lock(&lock_);
    status = CreateColorBufferLocked(image->width, image->height, format, &color_buffer->id);
    if (status != ZX_OK) {
      zxlogf(ERROR, "%s: failed to create color buffer", kTag);
      return status;
    }
  }

  image->handle = reinterpret_cast<uint64_t>(color_buffer.release());
  return ZX_OK;
}

zx_status_t Display::DisplayControllerImplImportImage(image_t* image, zx_unowned_handle_t handle,
                                                      uint32_t index) {
  zx_status_t status, status2;
  fuchsia_sysmem_BufferCollectionInfo_2 collection_info;
  status =
      fuchsia_sysmem_BufferCollectionWaitForBuffersAllocated(handle, &status2, &collection_info);
  if (status != ZX_OK) {
    return status;
  }
  if (status2 != ZX_OK) {
    return status2;
  }

  zx::vmo vmo;
  if (index < collection_info.buffer_count) {
    vmo = zx::vmo(collection_info.buffers[index].vmo);
    collection_info.buffers[index].vmo = ZX_HANDLE_INVALID;
  }
  for (uint32_t i = 0; i < collection_info.buffer_count; ++i) {
    zx_handle_close(collection_info.buffers[i].vmo);
  }

  if (!vmo.is_valid()) {
    zxlogf(ERROR, "%s: invalid index", kTag);
    return ZX_ERR_OUT_OF_RANGE;
  }

  uint64_t offset = collection_info.buffers[index].vmo_usable_start;

  if (collection_info.settings.buffer_settings.heap !=
      fuchsia_sysmem_HeapType_GOLDFISH_DEVICE_LOCAL) {
    return ImportVmoImage(image, std::move(vmo), offset);
  }

  if (!collection_info.settings.has_image_format_constraints || offset) {
    zxlogf(ERROR, "%s: invalid image format or offset", kTag);
    return ZX_ERR_OUT_OF_RANGE;
  }

  auto color_buffer = std::make_unique<ColorBuffer>();
  color_buffer->vmo = std::move(vmo);
  image->handle = reinterpret_cast<uint64_t>(color_buffer.release());
  return ZX_OK;
}

void Display::DisplayControllerImplReleaseImage(image_t* image) {
  auto color_buffer = reinterpret_cast<ColorBuffer*>(image->handle);

  // Color buffer is owned by image in the linear case.
  if (image->type == IMAGE_TYPE_SIMPLE) {
    fbl::AutoLock lock(&lock_);
    CloseColorBufferLocked(color_buffer->id);
  }

  async::PostTask(loop_.dispatcher(), [this, color_buffer] {
    const auto color_buffer_maps = {&current_cb_, &pending_cb_};
    for (const auto map : color_buffer_maps) {
      for (const auto& kv : *map) {
        if (kv.second == color_buffer) {
          map->at(kv.first) = nullptr;
        }
      }
    }
    delete color_buffer;
  });
}

uint32_t Display::DisplayControllerImplCheckConfiguration(const display_config_t** display_configs,
                                                          size_t display_count,
                                                          uint32_t** layer_cfg_results,
                                                          size_t* layer_cfg_result_count) {
  if (display_count == 0) {
    return CONFIG_DISPLAY_OK;
  }
  for (unsigned i = 0; i < display_count; i++) {
    const size_t layer_count = display_configs[i]->layer_count;
    if (layer_count > 0) {
      ZX_DEBUG_ASSERT(devices_.find(display_configs[i]->display_id) != devices_.end());
      const Device& device = devices_[display_configs[i]->display_id];

      if (display_configs[i]->cc_flags != 0) {
        // Color Correction is not supported, but we will pretend we do.
        // TODO(fxbug.dev/36184): Returning error will cause blank screen if scenic requests
        // color correction. For now, lets pretend we support it, until a proper
        // fix is done (either from scenic or from core display)
        zxlogf(WARNING, "%s: Color Correction not support. No error reported", __func__);
      }

      if (display_configs[i]->layer_list[0]->type != LAYER_TYPE_PRIMARY) {
        // We only support PRIMARY layer. Notify client to convert layer to
        // primary type.
        layer_cfg_results[i][0] |= CLIENT_USE_PRIMARY;
        layer_cfg_result_count[i] = 1;
      } else {
        primary_layer_t* layer = &display_configs[i]->layer_list[0]->cfg.primary;
        // Scaling is allowed if destination frame match display and
        // source frame match image.
        frame_t dest_frame = {
            .x_pos = 0,
            .y_pos = 0,
            .width = device.width,
            .height = device.height,
        };
        frame_t src_frame = {
            .x_pos = 0,
            .y_pos = 0,
            .width = layer->image.width,
            .height = layer->image.height,
        };
        if (memcmp(&layer->dest_frame, &dest_frame, sizeof(frame_t)) != 0) {
          // TODO(fxbug.dev/36222): Need to provide proper flag to indicate driver only
          // accepts full screen dest frame.
          layer_cfg_results[i][0] |= CLIENT_FRAME_SCALE;
        }
        if (memcmp(&layer->src_frame, &src_frame, sizeof(frame_t)) != 0) {
          layer_cfg_results[i][0] |= CLIENT_SRC_FRAME;
        }

        if (layer->alpha_mode != ALPHA_DISABLE) {
          // Alpha is not supported.
          layer_cfg_results[i][0] |= CLIENT_ALPHA;
        }

        if (layer->transform_mode != FRAME_TRANSFORM_IDENTITY) {
          // Transformation is not supported.
          layer_cfg_results[i][0] |= CLIENT_TRANSFORM;
        }

        // Check if any changes to the base layer were required.
        if (layer_cfg_results[i][0] != 0) {
          layer_cfg_result_count[i] = 1;
        }
      }
      // If there is more than one layer, the rest need to be merged into the base layer.
      if (layer_count > 1) {
        layer_cfg_results[i][0] |= CLIENT_MERGE_BASE;
        for (unsigned j = 1; j < layer_count; j++) {
          layer_cfg_results[i][j] |= CLIENT_MERGE_SRC;
        }
        layer_cfg_result_count[i] = layer_count;
      }
    }
  }
  return CONFIG_DISPLAY_OK;
}

zx_status_t Display::PresentColorBuffer(uint32_t display_id, ColorBuffer* color_buffer) {
  if (!color_buffer) {
    return ZX_HANDLE_INVALID;
  }
  if (color_buffer->sync_event.is_valid()) {
    return ZX_ERR_SHOULD_WAIT;
  }

  zx::eventpair event_display, event_sync_device;
  zx_status_t status = zx::eventpair::create(0u, &event_display, &event_sync_device);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: zx_eventpair_create failed: %d", kTag, status);
    return status;
  }
  color_buffer->sync_event = std::move(event_display);

  // Set up async wait.
  color_buffer->async_wait =
      std::make_unique<async::WaitOnce>(color_buffer->sync_event.get(), ZX_EVENTPAIR_SIGNALED, 0u);
  color_buffer->async_wait->Begin(
      loop_.dispatcher(),
      [this, color_buffer, display_id](async_dispatcher_t* dispatcher, async::WaitOnce* wait,
                                       zx_status_t status, const zx_packet_signal_t* signal) {
        TRACE_DURATION("gfx", "Display::SyncEventHandler", "color_buffer", color_buffer->id);
        if (status == ZX_ERR_CANCELED) {
          zxlogf(INFO, "Wait cancelled.\n");
          return;
        }
        ZX_DEBUG_ASSERT_MSG(status == ZX_OK, "Invalid wait status: %d\n", status);

        color_buffer->async_wait.reset();
        color_buffer->sync_event.reset();
        current_cb_[display_id] = color_buffer;
      });

  // Update host-writeable display buffers before presenting.
  if (color_buffer->paddr) {
    fbl::AutoLock lock(&lock_);
    uint32_t result;
    zx_status_t status = UpdateColorBufferLocked(color_buffer->id, color_buffer->paddr,
                                                 color_buffer->width, color_buffer->height,
                                                 color_buffer->format, color_buffer->size, &result);
    if (status != ZX_OK || result) {
      zxlogf(ERROR, "%s : color buffer update failed: %d:%u", kTag, status, result);
      return status;
    }
  }

  // Present the buffer.
  {
    fbl::AutoLock lock(&lock_);

    uint32_t host_display_id = devices_[display_id].host_display_id;
    if (host_display_id) {
      // Set color buffer for secondary displays.
      uint32_t result;
      status = SetDisplayColorBufferLocked(host_display_id, color_buffer->id, &result);
      if (status != ZX_OK || result) {
        zxlogf(ERROR, "%s: failed to set display color buffer", kTag);
        return status;
      }
    } else {
      status = FbPostLocked(color_buffer->id);
      if (status != ZX_OK) {
        zxlogf(ERROR, "%s: FbPost failed: %d", kTag, status);
        return status;
      }
    }

    status = control_.CreateSyncFence(std::move(event_sync_device));
    if (status != ZX_OK) {
      zxlogf(ERROR, "%s: CreateSyncFence failed: %d", kTag, status);
      return status;
    }
  }

  return ZX_OK;
}

void Display::DisplayControllerImplApplyConfiguration(const display_config_t** display_configs,
                                                      size_t display_count) {
  for (auto it : devices_) {
    uint64_t handle = 0;
    for (unsigned i = 0; i < display_count; i++) {
      if (display_configs[i]->display_id == it.first) {
        if (display_configs[i]->layer_count) {
          handle = display_configs[i]->layer_list[0]->cfg.primary.image.handle;
        }
        break;
      }
    }
    auto color_buffer = reinterpret_cast<ColorBuffer*>(handle);
    if (color_buffer && !color_buffer->id) {
      zx::vmo vmo;

      zx_status_t status = color_buffer->vmo.duplicate(ZX_RIGHT_SAME_RIGHTS, &vmo);
      if (status != ZX_OK) {
        zxlogf(ERROR, "%s: failed to duplicate vmo: %d", kTag, status);
      } else {
        fbl::AutoLock lock(&lock_);

        status = control_.GetColorBuffer(std::move(vmo), &color_buffer->id);
        if (status != ZX_OK) {
          zxlogf(ERROR, "%s: failed to get color buffer: %d", kTag, status);
        }

        // Color buffers are in vulkan-only mode by default as that avoids
        // unnecessary copies on the host in some cases. The color buffer
        // needs to be moved out of vulkan-only mode before being used for
        // presentation.
        if (color_buffer->id) {
          uint32_t result = 0;
          status = SetColorBufferVulkanModeLocked(color_buffer->id, 0, &result);
          if (status != ZX_OK || result) {
            zxlogf(ERROR, "%s: failed to set vulkan mode: %d %d", kTag, status, result);
          }
        }
      }
    }

    if (color_buffer) {
      async::PostTask(loop_.dispatcher(), [this, color_buffer, display_id = it.first] {
        pending_cb_[display_id] = color_buffer;
      });
    }
  }
}

zx_status_t Display::DisplayControllerImplGetSysmemConnection(zx::channel connection) {
  fbl::AutoLock lock(&lock_);

  zx_status_t status = pipe_.ConnectSysmem(std::move(connection));
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: failed to connect to sysmem: %d", kTag, status);
    return status;
  }
  return ZX_OK;
}

zx_status_t Display::DisplayControllerImplSetBufferCollectionConstraints(const image_t* config,
                                                                         uint32_t collection) {
  fuchsia_sysmem_BufferCollectionConstraints constraints = {};
  constraints.usage.display = fuchsia_sysmem_displayUsageLayer;
  constraints.has_buffer_memory_constraints = true;
  fuchsia_sysmem_BufferMemoryConstraints& buffer_constraints =
      constraints.buffer_memory_constraints;
  buffer_constraints.min_size_bytes = 0;
  buffer_constraints.max_size_bytes = 0xffffffff;
  buffer_constraints.physically_contiguous_required = true;
  buffer_constraints.secure_required = false;
  buffer_constraints.ram_domain_supported = true;
  buffer_constraints.cpu_domain_supported = true;
  buffer_constraints.inaccessible_domain_supported = true;
  buffer_constraints.heap_permitted_count = 2;
  buffer_constraints.heap_permitted[0] = fuchsia_sysmem_HeapType_SYSTEM_RAM;
  buffer_constraints.heap_permitted[1] = fuchsia_sysmem_HeapType_GOLDFISH_DEVICE_LOCAL;
  constraints.image_format_constraints_count = 4;
  for (uint32_t i = 0; i < constraints.image_format_constraints_count; i++) {
    fuchsia_sysmem_ImageFormatConstraints& image_constraints =
        constraints.image_format_constraints[i];
    image_constraints.pixel_format.type =
        i & 0b01 ? fuchsia_sysmem_PixelFormatType_R8G8B8A8 : fuchsia_sysmem_PixelFormatType_BGRA32;
    image_constraints.pixel_format.has_format_modifier = true;
    image_constraints.pixel_format.format_modifier.value =
        i & 0b10 ? fuchsia_sysmem_FORMAT_MODIFIER_LINEAR
                 : fuchsia_sysmem_FORMAT_MODIFIER_GOOGLE_GOLDFISH_OPTIMAL;
    image_constraints.color_spaces_count = 1;
    image_constraints.color_space[0].type = fuchsia_sysmem_ColorSpaceType_SRGB;
    image_constraints.min_coded_width = 0;
    image_constraints.max_coded_width = 0xffffffff;
    image_constraints.min_coded_height = 0;
    image_constraints.max_coded_height = 0xffffffff;
    image_constraints.min_bytes_per_row = 0;
    image_constraints.max_bytes_per_row = 0xffffffff;
    image_constraints.max_coded_width_times_coded_height = 0xffffffff;
    image_constraints.layers = 1;
    image_constraints.coded_width_divisor = 1;
    image_constraints.coded_height_divisor = 1;
    image_constraints.bytes_per_row_divisor = 1;
    image_constraints.start_offset_divisor = 1;
    image_constraints.display_width_divisor = 1;
    image_constraints.display_height_divisor = 1;
  }

  zx_status_t status =
      fuchsia_sysmem_BufferCollectionSetConstraints(collection, true, &constraints);
  if (status != ZX_OK) {
    zxlogf(ERROR, "%s: failed to set constraints", kTag);
    return status;
  }
  return ZX_OK;
}

zx_status_t Display::DisplayControllerImplGetSingleBufferFramebuffer(zx::vmo* out_vmo,
                                                                     uint32_t* out_stride) {
  return ZX_ERR_NOT_SUPPORTED;
}

zx_status_t Display::WriteLocked(uint32_t cmd_size) {
  TRACE_DURATION("gfx", "Display::Write", "cmd_size", cmd_size);

  auto buffer = static_cast<pipe_cmd_buffer_t*>(cmd_buffer_.virt());
  uint32_t remaining = cmd_size;
  while (remaining) {
    buffer->id = id_;
    buffer->cmd = PIPE_CMD_CODE_WRITE;
    buffer->status = PIPE_ERROR_INVAL;
    buffer->rw_params.ptrs[0] = io_buffer_.phys() + cmd_size - remaining;
    buffer->rw_params.sizes[0] = remaining;
    buffer->rw_params.buffers_count = 1;
    buffer->rw_params.consumed_size = 0;
    pipe_.Exec(id_);

    if (buffer->rw_params.consumed_size) {
      remaining -= buffer->rw_params.consumed_size;
      continue;
    }

    // Early out if error is not because of back-pressure.
    if (buffer->status != PIPE_ERROR_AGAIN) {
      zxlogf(ERROR, "%s: write to pipe buffer failed: %d", kTag, buffer->status);
      return ZX_ERR_INTERNAL;
    }

    buffer->id = id_;
    buffer->cmd = PIPE_CMD_CODE_WAKE_ON_WRITE;
    buffer->status = PIPE_ERROR_INVAL;
    pipe_.Exec(id_);

    // Wait for pipe to become writable.
    zx_status_t status = pipe_event_.wait_one(fuchsia_hardware_goldfish::wire::SIGNAL_HANGUP |
                                                  fuchsia_hardware_goldfish::wire::SIGNAL_WRITABLE,
                                              zx::time::infinite(), nullptr);
    if (status != ZX_OK) {
      if (status != ZX_ERR_CANCELED) {
        zxlogf(ERROR, "%s: zx_object_wait_one failed: %d", kTag, status);
      }
      return status;
    }
  }
  return ZX_OK;
}

zx_status_t Display::ReadResultLocked(uint32_t* result, uint32_t count) {
  TRACE_DURATION("gfx", "Display::ReadResult");

  size_t length = sizeof(*result) * count;
  size_t remaining = length;
  while (remaining) {
    auto buffer = static_cast<pipe_cmd_buffer_t*>(cmd_buffer_.virt());
    buffer->id = id_;
    buffer->cmd = PIPE_CMD_CODE_READ;
    buffer->status = PIPE_ERROR_INVAL;
    buffer->rw_params.ptrs[0] = io_buffer_.phys();
    buffer->rw_params.sizes[0] = static_cast<uint32_t>(remaining);
    buffer->rw_params.buffers_count = 1;
    buffer->rw_params.consumed_size = 0;
    pipe_.Exec(id_);

    // Positive consumed size always indicate a successful transfer.
    if (buffer->rw_params.consumed_size) {
      memcpy(reinterpret_cast<char*>(result) + (length - remaining), io_buffer_.virt(),
             buffer->rw_params.consumed_size);
      remaining -= buffer->rw_params.consumed_size;
      continue;
    }

    // Early out if error is not because of back-pressure.
    if (buffer->status != PIPE_ERROR_AGAIN) {
      zxlogf(ERROR, "%s: reading result failed: %d", kTag, buffer->status);
      return ZX_ERR_INTERNAL;
    }

    buffer->id = id_;
    buffer->cmd = PIPE_CMD_CODE_WAKE_ON_READ;
    buffer->status = PIPE_ERROR_INVAL;
    pipe_.Exec(id_);
    ZX_DEBUG_ASSERT(!buffer->status);

    // Wait for pipe to become readable.
    zx_status_t status = pipe_event_.wait_one(fuchsia_hardware_goldfish::wire::SIGNAL_HANGUP |
                                                  fuchsia_hardware_goldfish::wire::SIGNAL_READABLE,
                                              zx::time::infinite(), nullptr);
    if (status != ZX_OK) {
      if (status != ZX_ERR_CANCELED) {
        zxlogf(ERROR, "%s: zx_object_wait_one failed: %d", kTag, status);
      }
      return status;
    }
  }

  return ZX_OK;
}

zx_status_t Display::ExecuteCommandLocked(uint32_t cmd_size, uint32_t* result) {
  TRACE_DURATION("gfx", "Display::ExecuteCommand", "cmd_size", cmd_size);

  zx_status_t status = WriteLocked(cmd_size);
  if (status != ZX_OK) {
    return status;
  }
  return ReadResultLocked(result, 1);
}

int32_t Display::GetFbParamLocked(uint32_t param, int32_t default_value) {
  TRACE_DURATION("gfx", "Display::GetFbParam", "param", param);

  auto cmd = static_cast<GetFbParamCmd*>(io_buffer_.virt());
  cmd->op = kOP_rcGetFbParam;
  cmd->size = kSize_rcGetFbParam;
  cmd->param = param;

  uint32_t result;
  zx_status_t status = ExecuteCommandLocked(kSize_rcGetFbParam, &result);
  return status == ZX_OK ? result : default_value;
}

zx_status_t Display::CreateColorBufferLocked(uint32_t width, uint32_t height, uint32_t format,
                                             uint32_t* id) {
  TRACE_DURATION("gfx", "Display::CreateColorBuffer", "width", width, "height", height, "format",
                 format);

  auto cmd = static_cast<CreateColorBufferCmd*>(io_buffer_.virt());
  cmd->op = kOP_rcCreateColorBuffer;
  cmd->size = kSize_rcCreateColorBuffer;
  cmd->width = width;
  cmd->height = height;
  cmd->internalformat = format;

  return ExecuteCommandLocked(kSize_rcCreateColorBuffer, id);
}

zx_status_t Display::OpenColorBufferLocked(uint32_t id) {
  TRACE_DURATION("gfx", "Display::OpenColorBuffer", "id", id);

  auto cmd = static_cast<OpenColorBufferCmd*>(io_buffer_.virt());
  cmd->op = kOP_rcOpenColorBuffer;
  cmd->size = kSize_rcOpenColorBuffer;
  cmd->id = id;

  return WriteLocked(kSize_rcOpenColorBuffer);
}

zx_status_t Display::CloseColorBufferLocked(uint32_t id) {
  TRACE_DURATION("gfx", "Display::CloseColorBuffer", "id", id);

  auto cmd = static_cast<CloseColorBufferCmd*>(io_buffer_.virt());
  cmd->op = kOP_rcCloseColorBuffer;
  cmd->size = kSize_rcCloseColorBuffer;
  cmd->id = id;

  return WriteLocked(kSize_rcCloseColorBuffer);
}

zx_status_t Display::SetColorBufferVulkanModeLocked(uint32_t id, uint32_t mode, uint32_t* result) {
  TRACE_DURATION("gfx", "Display::SetColorBufferVulkanMode", "id", id, "mode", mode);

  auto cmd = static_cast<SetColorBufferVulkanModeCmd*>(io_buffer_.virt());
  cmd->op = kOP_rcSetColorBufferVulkanMode;
  cmd->size = kSize_rcSetColorBufferVulkanMode;
  cmd->id = id;
  cmd->mode = mode;

  return ExecuteCommandLocked(kSize_rcSetColorBufferVulkanMode, result);
}

zx_status_t Display::UpdateColorBufferLocked(uint32_t id, zx_paddr_t paddr, uint32_t width,
                                             uint32_t height, uint32_t format, size_t size,
                                             uint32_t* result) {
  TRACE_DURATION("gfx", "Display::UpdateColorBuffer", "size", size);

  auto cmd = static_cast<UpdateColorBufferCmd*>(io_buffer_.virt());
  cmd->op = kOP_rcUpdateColorBuffer;
  cmd->size = kSize_rcUpdateColorBuffer + static_cast<uint32_t>(size);
  cmd->id = id;
  cmd->x = 0;
  cmd->y = 0;
  cmd->width = width;
  cmd->height = height;
  cmd->format = format;
  cmd->type = GL_UNSIGNED_BYTE;
  cmd->size_pixels = static_cast<uint32_t>(size);

  auto buffer = static_cast<pipe_cmd_buffer_t*>(cmd_buffer_.virt());
  buffer->id = id_;
  buffer->cmd = PIPE_CMD_CODE_WRITE;
  buffer->status = PIPE_ERROR_INVAL;
  buffer->rw_params.ptrs[0] = io_buffer_.phys();
  buffer->rw_params.ptrs[1] = paddr;
  buffer->rw_params.sizes[0] = kSize_rcUpdateColorBuffer;
  buffer->rw_params.sizes[1] = static_cast<uint32_t>(size);
  buffer->rw_params.buffers_count = 2;
  buffer->rw_params.consumed_size = 0;

  pipe_.Exec(id_);
  ZX_DEBUG_ASSERT(buffer->rw_params.consumed_size ==
                  static_cast<int32_t>(kSize_rcUpdateColorBuffer + size));

  return ReadResultLocked(result, 1);
}

zx_status_t Display::FbPostLocked(uint32_t id) {
  TRACE_DURATION("gfx", "Display::FbPost", "id", id);

  auto cmd = static_cast<FbPostCmd*>(io_buffer_.virt());
  cmd->op = kOP_rcFbPost;
  cmd->size = kSize_rcFbPost;
  cmd->id = id;

  return WriteLocked(kSize_rcFbPost);
}

zx_status_t Display::CreateDisplayLocked(uint32_t* result) {
  TRACE_DURATION("gfx", "Display::CreateDisplay");

  auto cmd = static_cast<CreateDisplayCmd*>(io_buffer_.virt());
  cmd->op = kOP_rcCreateDisplay;
  cmd->size = kSize_rcCreateDisplay;
  cmd->size_display_id = sizeof(uint32_t);

  zx_status_t status = WriteLocked(kSize_rcCreateDisplay);
  if (status != ZX_OK) {
    return status;
  }
  return ReadResultLocked(result, 2);
}

zx_status_t Display::DestroyDisplayLocked(uint32_t display_id, uint32_t* result) {
  TRACE_DURATION("gfx", "Display::DestroyDisplay", "display_id", display_id);

  auto cmd = static_cast<DestroyDisplayCmd*>(io_buffer_.virt());
  cmd->op = kOP_rcDestroyDisplay;
  cmd->size = kSize_rcDestroyDisplay;
  cmd->display_id = display_id;

  return ExecuteCommandLocked(kSize_rcDestroyDisplay, result);
}

zx_status_t Display::SetDisplayColorBufferLocked(uint32_t display_id, uint32_t id,
                                                 uint32_t* result) {
  TRACE_DURATION("gfx", "Display::SetDisplayColorBuffer", "display_id", display_id, "id", id);

  auto cmd = static_cast<SetDisplayColorBufferCmd*>(io_buffer_.virt());
  cmd->op = kOP_rcSetDisplayColorBuffer;
  cmd->size = kSize_rcSetDisplayColorBuffer;
  cmd->display_id = display_id;
  cmd->id = id;

  return ExecuteCommandLocked(kSize_rcSetDisplayColorBuffer, result);
}

zx_status_t Display::SetDisplayPoseLocked(uint32_t display_id, int32_t x, int32_t y, uint32_t w,
                                          uint32_t h, uint32_t* result) {
  TRACE_DURATION("gfx", "Display::SetDisplayPose", "display_id", display_id);

  auto cmd = static_cast<SetDisplayPoseCmd*>(io_buffer_.virt());
  cmd->op = kOP_rcSetDisplayPose;
  cmd->size = kSize_rcSetDisplayPose;
  cmd->display_id = display_id;
  cmd->x = x;
  cmd->y = y;
  cmd->w = w;
  cmd->h = h;

  return ExecuteCommandLocked(kSize_rcSetDisplayPose, result);
}

zx_status_t Display::SetupDisplayLocked(uint64_t display_id) {
  Device& device = devices_[display_id];

  // Create secondary displays.
  if (display_id != kPrimaryDisplayId) {
    uint32_t result[2] = {0, 1};
    zx_status_t status = CreateDisplayLocked(result);
    if (status != ZX_OK || result[1]) {
      zxlogf(ERROR, "%s: failed to create display: %d %d", kTag, status, result[1]);
      return status != ZX_OK ? status : ZX_ERR_INTERNAL;
    }
    device.host_display_id = result[0];
  }
  uint32_t width = static_cast<uint32_t>(static_cast<float>(device.width) * device.scale);
  uint32_t height = static_cast<uint32_t>(static_cast<float>(device.height) * device.scale);
  uint32_t result = 1;
  zx_status_t status =
      SetDisplayPoseLocked(device.host_display_id, device.x, device.y, width, height, &result);
  if (status != ZX_OK || result) {
    zxlogf(ERROR, "%s: failed to set display pose: %d %d", kTag, status, result);
    return status != ZX_OK ? status : ZX_ERR_INTERNAL;
  }
  device.expected_next_flush = async::Now(loop_.dispatcher());

  return ZX_OK;
}

void Display::TeardownDisplay(uint64_t display_id) {
  Device& device = devices_[display_id];

  if (device.host_display_id) {
    fbl::AutoLock lock(&lock_);
    uint32_t result;
    zx_status_t status = DestroyDisplayLocked(device.host_display_id, &result);
    ZX_DEBUG_ASSERT(status == ZX_OK);
    ZX_DEBUG_ASSERT(!result);
  }
}

void Display::FlushDisplay(async_dispatcher_t* dispatcher, uint64_t display_id) {
  Device& device = devices_[display_id];

  zx::duration period = zx::sec(1) / device.refresh_rate_hz;
  zx::time expected_next_flush = device.expected_next_flush + period;

  ColorBuffer* pending_cb = nullptr;
  if (pending_cb_.find(display_id) != pending_cb_.end()) {
    pending_cb = pending_cb_[display_id];
  }

  if (pending_cb) {
    zx_status_t status = PresentColorBuffer(display_id, pending_cb);
    ZX_DEBUG_ASSERT(status == ZX_OK || status == ZX_ERR_SHOULD_WAIT);
  }

  {
    fbl::AutoLock lock(&flush_lock_);

    if (dc_intf_.is_valid()) {
      ColorBuffer* current_cb = nullptr;
      if (current_cb_.find(display_id) != current_cb_.end()) {
        current_cb = current_cb_[display_id];
      }
      uint64_t handles[] = {reinterpret_cast<uint64_t>(current_cb)};
      zx::time now = async::Now(dispatcher);
      dc_intf_.OnDisplayVsync(display_id, now.get(), handles, current_cb ? 1 : 0);
    }
  }

  // If we've already passed the |expected_next_flush| deadline, skip the
  // Vsync and adjust the deadline to the earliest next available frame.
  zx::time now = async::Now(dispatcher);
  if (now > expected_next_flush) {
    expected_next_flush +=
        period * (((now - expected_next_flush + period).get() - 1L) / period.get());
  }

  device.expected_next_flush = expected_next_flush;
  async::PostTaskForTime(
      dispatcher, [this, dispatcher, display_id] { FlushDisplay(dispatcher, display_id); },
      expected_next_flush);
}

}  // namespace goldfish

static constexpr zx_driver_ops_t goldfish_display_driver_ops = []() -> zx_driver_ops_t {
  zx_driver_ops_t ops = {};
  ops.version = DRIVER_OPS_VERSION;
  ops.bind = goldfish::Display::Create;
  return ops;
}();

ZIRCON_DRIVER(goldfish_display, goldfish_display_driver_ops, "zircon", "0.1");
