// Copyright 2016 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 "src/ui/lib/escher/impl/model_data.h"

#include "src/ui/lib/escher/escher.h"
#include "src/ui/lib/escher/impl/command_buffer.h"
#include "src/ui/lib/escher/impl/mesh_shader_binding.h"
#include "src/ui/lib/escher/impl/vulkan_utils.h"
#include "src/ui/lib/escher/vk/gpu_allocator.h"

namespace escher {
namespace impl {

// DescriptorSetPools allocate new sets as necessary, so these are no big
// deal.
constexpr uint32_t kInitialPerModelDescriptorSetCount = 50;
constexpr uint32_t kInitialPerObjectDescriptorSetCount = 200;

ModelData::ModelData(EscherWeakPtr escher, GpuAllocator* allocator)
    : device_(escher->vulkan_context().device),
      // This is a 1-deep pool because it was this way before UniformBufferPool
      // started to defer making buffers available for a number of frames.  The
      // reason why this works (i.e. why the data in the buffer doesn't get
      // stomped by the next frame while it is still being rendered) is because
      // ModelDisplayListBuilder adds all resources to the ModelDisplayList,
      // so they aren't returned to the pool until the frame is finished
      // rendering.
      //
      // Furthermore, if this is deeper that 1, the buffers would never be
      // recycled because nobody calls BeginFrame() on this pool.  In the future
      // we'll likely move to an Escher-wide UniformBufferPool.
      uniform_buffer_pool_(escher, 1, allocator) {}

ModelData::~ModelData() {}

const MeshShaderBinding& ModelData::GetMeshShaderBinding(MeshSpec spec) {
  auto ptr = mesh_shader_binding_cache_[spec].get();
  if (ptr) {
    return *ptr;
  }
  FXL_DCHECK(spec.IsValidOneBufferMesh());

  std::vector<vk::VertexInputAttributeDescription> attributes;

  vk::DeviceSize stride = 0;
  if (spec.has_attribute(0, MeshAttribute::kPosition2D)) {
    vk::VertexInputAttributeDescription attribute;
    attribute.location = kPositionAttributeLocation;
    attribute.binding = 0;
    attribute.format = vk::Format::eR32G32Sfloat;
    attribute.offset = stride;

    stride += sizeof(vec2);
    attributes.push_back(attribute);
  }
  if (spec.has_attribute(0, MeshAttribute::kPosition3D)) {
    vk::VertexInputAttributeDescription attribute;
    attribute.location = kPositionAttributeLocation;
    attribute.binding = 0;
    attribute.format = vk::Format::eR32G32B32Sfloat;
    attribute.offset = stride;

    stride += sizeof(vec3);
    attributes.push_back(attribute);
  }
  if (spec.has_attribute(0, MeshAttribute::kPositionOffset)) {
    vk::VertexInputAttributeDescription attribute;
    attribute.location = kPositionOffsetAttributeLocation;
    attribute.binding = 0;
    attribute.format = vk::Format::eR32G32Sfloat;
    attribute.offset = stride;

    stride += sizeof(vec2);
    attributes.push_back(attribute);
  }
  if (spec.has_attribute(0, MeshAttribute::kUV)) {
    vk::VertexInputAttributeDescription attribute;
    attribute.location = kUVAttributeLocation;
    attribute.binding = 0;
    attribute.format = vk::Format::eR32G32Sfloat;
    attribute.offset = stride;

    stride += sizeof(vec2);
    attributes.push_back(attribute);
  }
  if (spec.has_attribute(0, MeshAttribute::kPerimeterPos)) {
    vk::VertexInputAttributeDescription attribute;
    attribute.location = kPerimeterPosAttributeLocation;
    attribute.binding = 0;
    attribute.format = vk::Format::eR32Sfloat;
    attribute.offset = stride;

    stride += sizeof(float);
    attributes.push_back(attribute);
  }

  vk::VertexInputBindingDescription binding;
  binding.binding = 0;
  binding.stride = stride;
  binding.inputRate = vk::VertexInputRate::eVertex;

  auto msb = std::make_unique<MeshShaderBinding>(std::move(binding), std::move(attributes));
  ptr = msb.get();
  mesh_shader_binding_cache_[spec] = std::move(msb);
  return *ptr;
}

}  // namespace impl
}  // namespace escher
