// Copyright 2018 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/renderer/uniform_block_allocator.h"

#include "src/ui/lib/escher/impl/uniform_buffer_pool.h"
#include "src/ui/lib/escher/util/align.h"
#include "src/ui/lib/escher/vk/buffer.h"

namespace escher {

UniformBlockAllocator::UniformBlockAllocator(impl::UniformBufferPoolWeakPtr pool)
    : pool_(std::move(pool)), buffer_size_(pool_->buffer_size()) {
  Reset();
}

UniformAllocation UniformBlockAllocator::Allocate(size_t size, size_t alignment) {
  write_index_ = AlignedToNext(write_index_, alignment);
  if (write_index_ + size > buffer_size_) {
    buffers_.push_back(pool_->Allocate());
    FXL_DCHECK(buffers_.back()->host_ptr());
    write_index_ = 0;
  }
  auto& buf = buffers_.back();
  UniformAllocation allocation = {.buffer = buf.get(),
                                  .offset = write_index_,
                                  .size = size,
                                  .host_ptr = buf->host_ptr() + write_index_};
  write_index_ += size;
  return allocation;
}

void UniformBlockAllocator::Reset() {
  // This guarantees that the next allocation attempt will obtain a new
  // suballocation buffer.
  write_index_ = buffer_size_;

  // Clear the current contents of the buffer, and reserve enough space to hold
  // about a megabyte's worth of Buffers.
  constexpr size_t kBufferVectCapacity = 16;
  buffers_.clear();
  buffers_.reserve(kBufferVectCapacity);
}

std::vector<BufferPtr> UniformBlockAllocator::TakeBuffers() {
  std::vector<BufferPtr> retval(std::move(buffers_));
  Reset();
  return retval;
}

}  // namespace escher
