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

#include "media/fuchsia/common/vmo_buffer.h"

#include <zircon/rights.h>
#include <algorithm>

#include "base/bits.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/memory/page_size.h"

namespace media {

// static
fuchsia::sysmem::BufferCollectionConstraints
VmoBuffer::GetRecommendedConstraints(size_t min_buffer_count,
                                     absl::optional<size_t> min_buffer_size,
                                     bool writable) {
  fuchsia::sysmem::BufferCollectionConstraints buffer_constraints;

  buffer_constraints.usage.cpu = fuchsia::sysmem::cpuUsageRead;
  if (writable)
    buffer_constraints.usage.cpu |= fuchsia::sysmem::cpuUsageWrite;

  buffer_constraints.min_buffer_count = min_buffer_count;

  if (min_buffer_size) {
    buffer_constraints.has_buffer_memory_constraints = true;
    buffer_constraints.buffer_memory_constraints.min_size_bytes =
        min_buffer_size.value();
    buffer_constraints.buffer_memory_constraints.ram_domain_supported = true;
    buffer_constraints.buffer_memory_constraints.cpu_domain_supported = true;
  }

  return buffer_constraints;
}

// static
std::vector<VmoBuffer> VmoBuffer::CreateBuffersFromSysmemCollection(
    fuchsia::sysmem::BufferCollectionInfo_2* info,
    bool writable) {
  std::vector<VmoBuffer> buffers;
  buffers.resize(info->buffer_count);

  fuchsia::sysmem::BufferMemorySettings& settings =
      info->settings.buffer_settings;
  for (size_t i = 0; i < info->buffer_count; ++i) {
    fuchsia::sysmem::VmoBuffer& buffer = info->buffers[i];
    if (!buffers[i].Initialize(std::move(buffer.vmo), writable,
                               buffer.vmo_usable_start, settings.size_bytes,
                               settings.coherency_domain)) {
      return {};
    }
  }

  return buffers;
}

VmoBuffer::VmoBuffer() = default;

VmoBuffer::~VmoBuffer() {
  if (!base_address_) {
    return;
  }

  zx_status_t status = zx::vmar::root_self()->unmap(
      reinterpret_cast<uintptr_t>(base_address_), mapped_size());
  ZX_DCHECK(status == ZX_OK, status) << "zx_vmar_unmap";
}

VmoBuffer::VmoBuffer(VmoBuffer&&) = default;
VmoBuffer& VmoBuffer::operator=(VmoBuffer&&) = default;

bool VmoBuffer::Initialize(zx::vmo vmo,
                           bool writable,
                           size_t offset,
                           size_t size,
                           fuchsia::sysmem::CoherencyDomain coherency_domain) {
  DCHECK(!base_address_);
  DCHECK(vmo);

  writable_ = writable;
  offset_ = offset;
  size_ = size;
  coherency_domain_ = coherency_domain;

  zx_vm_option_t options = ZX_VM_PERM_READ;
  if (writable)
    options |= ZX_VM_PERM_WRITE;

  uintptr_t addr;
  zx_status_t status =
      zx::vmar::root_self()->map(options, /*vmar_offset=*/0, vmo,
                                 /*vmo_offset=*/0, mapped_size(), &addr);
  if (status != ZX_OK) {
    ZX_DLOG(ERROR, status) << "zx_vmar_map";
    return false;
  }

  vmo_ = std::move(vmo);
  base_address_ = reinterpret_cast<uint8_t*>(addr);

  return true;
}

size_t VmoBuffer::Read(size_t offset, base::span<uint8_t> data) {
  if (offset >= size_)
    return 0U;
  size_t bytes_to_fill = std::min(size_ - offset, data.size());
  FlushCache(offset, bytes_to_fill, /*invalidate=*/true);
  memcpy(data.data(), base_address_ + offset_ + offset, bytes_to_fill);
  return bytes_to_fill;
}

size_t VmoBuffer::Write(base::span<const uint8_t> data) {
  DCHECK(writable_);

  size_t bytes_to_fill = std::min(size_, data.size());
  memcpy(base_address_ + offset_, data.data(), bytes_to_fill);

  FlushCache(0, bytes_to_fill, /*invalidate=*/false);

  return bytes_to_fill;
}

base::span<const uint8_t> VmoBuffer::GetMemory() {
  FlushCache(0, size_, /*invalidate=*/true);
  return base::make_span(base_address_ + offset_, size_);
}

base::span<uint8_t> VmoBuffer::GetWritableMemory() {
  DCHECK(writable_);
  return base::make_span(base_address_ + offset_, size_);
}

void VmoBuffer::FlushCache(size_t flush_offset,
                           size_t flush_size,
                           bool invalidate) {
  DCHECK_LE(flush_size, size_ - flush_offset);

  if (coherency_domain_ != fuchsia::sysmem::CoherencyDomain::RAM)
    return;

  uint8_t* address = base_address_ + offset_ + flush_offset;
  uint32_t options = ZX_CACHE_FLUSH_DATA;
  if (invalidate)
    options |= ZX_CACHE_FLUSH_INVALIDATE;
  zx_status_t status = zx_cache_flush(address, flush_size, options);
  ZX_DCHECK(status == ZX_OK, status) << "zx_cache_flush";
}

size_t VmoBuffer::mapped_size() {
  return base::bits::AlignUp(offset_ + size_, base::GetPageSize());
}

zx::vmo VmoBuffer::Duplicate(bool writable) {
  zx_rights_t rights = ZX_RIGHT_DUPLICATE | ZX_RIGHT_TRANSFER | ZX_RIGHT_READ |
                       ZX_RIGHT_MAP | ZX_RIGHT_GET_PROPERTY;
  if (writable)
    rights |= ZX_RIGHT_WRITE;

  zx::vmo vmo;
  zx_status_t status = vmo_.duplicate(rights, &vmo);
  ZX_CHECK(status == ZX_OK, status) << "zx_handle_duplicate";

  return vmo;
}

}  // namespace media
