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

#include "src/ui/lib/escher/shape/mesh_spec.h"

#include "src/lib/fxl/logging.h"
#include "src/ui/lib/escher/geometry/types.h"
#include "src/ui/lib/escher/util/bit_ops.h"
#include "src/ui/lib/escher/util/hasher.h"

namespace escher {

// If these assertions fail, code throughout this file will need to be updated
// to match the new invariants.
static_assert(sizeof(MeshAttributes) == sizeof(uint32_t), "sizeof mismatch");
static_assert(VulkanLimits::kNumVertexBuffers >= 2, "too few vertex buffers");

uint32_t GetMeshAttributeSize(MeshAttribute attr) {
  switch (attr) {
    case MeshAttribute::kPosition2D:
      return sizeof(vec2);
    case MeshAttribute::kPosition3D:
      return sizeof(vec3);
    case MeshAttribute::kPositionOffset:
      return sizeof(vec2);
    case MeshAttribute::kUV:
      return sizeof(vec2);
    case MeshAttribute::kPerimeterPos:
      return sizeof(float);
    case MeshAttribute::kBlendWeight1:
      return sizeof(float);
    case MeshAttribute::kStride:
      FXL_CHECK(false);
      return 0;
  }
}

uint32_t MeshSpec::attribute_count(uint32_t vertex_buffer_index) const {
  FXL_DCHECK(vertex_buffer_index < VulkanLimits::kNumVertexBuffers);
  return CountOnes(uint32_t(attributes[vertex_buffer_index]));
}

uint32_t MeshSpec::total_attribute_count() const { return CountOnes(uint32_t(all_attributes())); }

uint32_t MeshSpec::attribute_offset(uint32_t vertex_buffer_index, MeshAttribute flag) const {
  FXL_DCHECK(vertex_buffer_index < VulkanLimits::kNumVertexBuffers);
  return GetMeshAttributeOffset(attributes[vertex_buffer_index], flag);
}

uint32_t GetMeshAttributeOffset(const MeshAttributes& attrs, MeshAttribute attr) {
  FXL_DCHECK(attrs & attr || attr == MeshAttribute::kStride);
  uint32_t offset = 0;

  if (attr == MeshAttribute::kPosition2D) {
    return offset;
  } else if (attrs & MeshAttribute::kPosition2D) {
    offset += sizeof(vec2);
  }

  if (attr == MeshAttribute::kPosition3D) {
    return offset;
  } else if (attrs & MeshAttribute::kPosition3D) {
    offset += sizeof(vec3);
  }

  if (attr == MeshAttribute::kPositionOffset) {
    return offset;
  } else if (attrs & MeshAttribute::kPositionOffset) {
    offset += sizeof(vec2);
  }

  if (attr == MeshAttribute::kUV) {
    return offset;
  } else if (attrs & MeshAttribute::kUV) {
    offset += sizeof(vec2);
  }

  if (attr == MeshAttribute::kPerimeterPos) {
    return offset;
  } else if (attrs & MeshAttribute::kPerimeterPos) {
    offset += sizeof(float);
  }

  if (attr == MeshAttribute::kBlendWeight1) {
    return offset;
  } else if (attrs & MeshAttribute::kBlendWeight1) {
    offset += sizeof(float);
  }

  FXL_DCHECK(attr == MeshAttribute::kStride);
  return offset;
}

bool MeshSpec::has_attribute(uint32_t vertex_buffer_index, MeshAttribute attr) const {
  FXL_DCHECK(vertex_buffer_index < VulkanLimits::kNumVertexBuffers);
  return bool(attributes[vertex_buffer_index] & attr);
}

bool MeshSpec::has_attributes(uint32_t vertex_buffer_index, MeshAttributes attrs) const {
  FXL_DCHECK(vertex_buffer_index < VulkanLimits::kNumVertexBuffers);
  return (attributes[vertex_buffer_index] & attrs) == attrs;
}

MeshAttributes MeshSpec::all_attributes() const {
  MeshAttributes all(attributes[0]);
  for (uint32_t i = 1; i < VulkanLimits::kNumVertexBuffers; ++i) {
    FXL_DCHECK((all & attributes[i]) == MeshAttributes());
    all |= attributes[i];
  }
  return all;
}

uint32_t MeshSpec::vertex_buffer_count() const {
  uint32_t count = 0;
  for (auto& attrs : attributes) {
    count += uint32_t(attrs) ? 1 : 0;
  }
  return count;
}

bool MeshSpec::IsValid() const {
  MeshAttributes all_attrs = all_attributes();
  auto position_attrs = MeshAttribute::kPosition2D | MeshAttribute::kPosition3D;
  if (!(all_attrs & position_attrs)) {
    // Mesh must have a position attribute, either 2D or 3D.
    return false;
  } else if ((all_attrs & position_attrs) == position_attrs) {
    return false;
  } else {
    // Position attribute must always be in the first vertex buffer.
    return bool(attributes[0] & position_attrs);
  }
}

bool MeshSpec::IsValidOneBufferMesh() const {
  if (!IsValid()) {
    return false;
  } else if (attribute_count(0) != total_attribute_count()) {
    // Only the first vertex buffer is allowed to have any attributes.
    return false;
  } else if (has_attribute(0, MeshAttribute::kPosition3D) &&
             (has_attribute(0, MeshAttribute::kPositionOffset) ||
              has_attribute(0, MeshAttribute::kPerimeterPos))) {
    // Position-offset and perimeter attributes are only allowed for 2D meshes.
    // The latter inherently only makes sense for 2D, whereas the former could
    // be modified to support both 2D and 3D variants.
    return false;
  }
  return true;
}

std::size_t MeshSpec::HashMapHasher::operator()(const MeshSpec& spec) const {
  Hasher h;
  for (auto& attr : spec.attributes) {
    h.u32(uint32_t(attr));
  }
  return h.value().val;
}

}  // namespace escher
