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

#ifndef SRC_LIB_UI_SCENIC_CPP_HOST_MEMORY_H_
#define SRC_LIB_UI_SCENIC_CPP_HOST_MEMORY_H_

#include <lib/ui/scenic/cpp/resources.h>
#include <lib/zx/vmo.h>

#include <memory>
#include <utility>
#include <vector>

using scenic::Image;
using scenic::Memory;
using scenic::Session;

namespace scenic_util {

// Provides access to data stored in a host-accessible shared memory region.
// The memory is unmapped once all references to this object have been released.
class HostData : public std::enable_shared_from_this<HostData> {
 public:
  // Maps a range of an existing VMO into memory.
  HostData(const zx::vmo& vmo, off_t offset, size_t size);
  ~HostData();

  HostData(const HostData&) = delete;
  HostData& operator=(const HostData&) = delete;

  // Gets the size of the data in bytes.
  size_t size() const { return size_; }

  // Gets a pointer to the data.
  void* ptr() const { return ptr_; }

 private:
  size_t const size_;
  void* ptr_;
};

// Represents a host-accessible shared memory backed memory resource in a
// session.  The memory is mapped read/write into this process and transferred
// read-only to the scene manager.  The shared memory region is retained until
// this object is destroyed.
// TODO(https://fxbug.dev/42097607): Don't inherit from Memory, so that Memory can have a public
// move constructor.
// TODO(https://fxbug.dev/42081257): The memory is currently not transferred read-only, as we may
// choose to map it as device-local memory on UMA platforms, and Vulkan requires
// a read/write vmo in order to successfully import the memory.
class HostMemory final : public Memory {
 public:
  HostMemory(Session* session, size_t size);
  HostMemory(HostMemory&& moved);
  ~HostMemory();

  HostMemory(const HostMemory&) = delete;
  HostMemory& operator=(const HostMemory&) = delete;

  // Gets a reference to the underlying shared memory region.
  const std::shared_ptr<HostData>& data() const { return data_; }

  // Gets the size of the data in bytes.
  size_t data_size() const { return data_->size(); }

  // Gets a pointer to the data.
  void* data_ptr() const { return data_->ptr(); }

 private:
  explicit HostMemory(Session* session, std::pair<zx::vmo, std::shared_ptr<HostData>> init);

  std::shared_ptr<HostData> data_;
};

// Represents an image resource backed by host-accessible shared memory bound to
// a session.  The shared memory region is retained until this object is
// destroyed.
// TODO(https://fxbug.dev/42097607): Don't inherit from Image, so that Image can have a public move
// constructor.
class HostImage final : public Image {
 public:
  HostImage(const HostMemory& memory, off_t memory_offset, fuchsia::images::ImageInfo info);
  HostImage(Session* session, uint32_t memory_id, off_t memory_offset,
            std::shared_ptr<HostData> data, fuchsia::images::ImageInfo info);
  HostImage(HostImage&& moved);
  ~HostImage();

  HostImage(const HostImage&) = delete;
  HostImage& operator=(const HostImage&) = delete;

  // Gets a reference to the underlying shared memory region.
  const std::shared_ptr<HostData>& data() const { return data_; }

  // Gets a pointer to the image data.
  void* image_ptr() const { return static_cast<uint8_t*>(data_->ptr()) + memory_offset(); }

 private:
  std::shared_ptr<HostData> data_;
};

// Represents a pool of image resources backed by host-accessible shared memory
// bound to a session.  All images in the pool must have the same layout.
class HostImagePool {
 public:
  // Creates a pool which can supply up to |num_images| images on demand.
  explicit HostImagePool(Session* session, uint32_t num_images);
  ~HostImagePool();

  HostImagePool(const HostImagePool&) = delete;
  HostImagePool& operator=(const HostImagePool&) = delete;

  // The number of images which this pool can manage.
  uint32_t num_images() const { return static_cast<uint32_t>(image_ptrs_.size()); }

  // Gets information about the images in the pool, or nullptr if the
  // pool is not configured.
  const fuchsia::images::ImageInfo* image_info() const { return &image_info_; }

  // Sets the image information for images in the pool.
  // Previously created images are released but their memory may be reused.
  // If |image_info| is nullptr, the pool reverts to an non-configured state;
  // all images are released but the memory is retained for recycling.
  // Returns true if the configuration changed.
  bool Configure(const fuchsia::images::ImageInfo* image_info);

  // Gets the image with the specified index.
  // The |index| must be between 0 and |num_images() - 1|.
  // The returned pointer is valid until the image is discarded or the
  // pool is reconfigured.  Returns nullptr if the pool is not configured.
  const HostImage* GetImage(uint32_t index);

  // Discards the image with the specified index but recycles its memory.
  // The |index| must be between 0 and |num_images() - 1|.
  void DiscardImage(uint32_t index);

 private:
  Session* const session_;

  bool configured_ = false;
  fuchsia::images::ImageInfo image_info_;
  std::vector<std::unique_ptr<HostImage>> image_ptrs_;
  std::vector<std::unique_ptr<HostMemory>> memory_ptrs_;
};

}  // namespace scenic_util

#endif  // SRC_LIB_UI_SCENIC_CPP_HOST_MEMORY_H_
