// Copyright (c) 2011 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 "gpu/command_buffer/client/mapped_memory.h"

#include <algorithm>
#include <functional>

#include "base/debug/trace_event.h"
#include "base/logging.h"
#include "gpu/command_buffer/client/cmd_buffer_helper.h"

namespace gpu {

MemoryChunk::MemoryChunk(int32 shm_id,
                         scoped_refptr<gpu::Buffer> shm,
                         CommandBufferHelper* helper,
                         const base::Closure& poll_callback)
    : shm_id_(shm_id),
      shm_(shm),
      allocator_(shm->size(), helper, poll_callback, shm->memory()) {}

MemoryChunk::~MemoryChunk() {}

MappedMemoryManager::MappedMemoryManager(CommandBufferHelper* helper,
                                         const base::Closure& poll_callback,
                                         size_t unused_memory_reclaim_limit)
    : chunk_size_multiple_(1),
      helper_(helper),
      poll_callback_(poll_callback),
      allocated_memory_(0),
      max_free_bytes_(unused_memory_reclaim_limit) {
}

MappedMemoryManager::~MappedMemoryManager() {
  CommandBuffer* cmd_buf = helper_->command_buffer();
  for (MemoryChunkVector::iterator iter = chunks_.begin();
       iter != chunks_.end(); ++iter) {
    MemoryChunk* chunk = *iter;
    cmd_buf->DestroyTransferBuffer(chunk->shm_id());
  }
}

void* MappedMemoryManager::Alloc(
    unsigned int size, int32* shm_id, unsigned int* shm_offset) {
  DCHECK(shm_id);
  DCHECK(shm_offset);
  if (size <= allocated_memory_) {
    size_t total_bytes_in_use = 0;
    // See if any of the chunks can satisfy this request.
    for (size_t ii = 0; ii < chunks_.size(); ++ii) {
      MemoryChunk* chunk = chunks_[ii];
      chunk->FreeUnused();
      total_bytes_in_use += chunk->bytes_in_use();
      if (chunk->GetLargestFreeSizeWithoutWaiting() >= size) {
        void* mem = chunk->Alloc(size);
        DCHECK(mem);
        *shm_id = chunk->shm_id();
        *shm_offset = chunk->GetOffset(mem);
        return mem;
      }
    }

    // If there is a memory limit being enforced and total free
    // memory (allocated_memory_ - total_bytes_in_use) is larger than
    // the limit try waiting.
    if (max_free_bytes_ != kNoLimit &&
        (allocated_memory_ - total_bytes_in_use) >= max_free_bytes_) {
      TRACE_EVENT0("gpu", "MappedMemoryManager::Alloc::wait");
      for (size_t ii = 0; ii < chunks_.size(); ++ii) {
        MemoryChunk* chunk = chunks_[ii];
        if (chunk->GetLargestFreeSizeWithWaiting() >= size) {
          void* mem = chunk->Alloc(size);
          DCHECK(mem);
          *shm_id = chunk->shm_id();
          *shm_offset = chunk->GetOffset(mem);
          return mem;
        }
      }
    }
  }

  // Make a new chunk to satisfy the request.
  CommandBuffer* cmd_buf = helper_->command_buffer();
  unsigned int chunk_size =
      ((size + chunk_size_multiple_ - 1) / chunk_size_multiple_) *
      chunk_size_multiple_;
  int32 id = -1;
  scoped_refptr<gpu::Buffer> shm =
      cmd_buf->CreateTransferBuffer(chunk_size, &id);
  if (id  < 0)
    return NULL;
  DCHECK(shm.get());
  MemoryChunk* mc = new MemoryChunk(id, shm, helper_, poll_callback_);
  allocated_memory_ += mc->GetSize();
  chunks_.push_back(mc);
  void* mem = mc->Alloc(size);
  DCHECK(mem);
  *shm_id = mc->shm_id();
  *shm_offset = mc->GetOffset(mem);
  return mem;
}

void MappedMemoryManager::Free(void* pointer) {
  for (size_t ii = 0; ii < chunks_.size(); ++ii) {
    MemoryChunk* chunk = chunks_[ii];
    if (chunk->IsInChunk(pointer)) {
      chunk->Free(pointer);
      return;
    }
  }
  NOTREACHED();
}

void MappedMemoryManager::FreePendingToken(void* pointer, int32 token) {
  for (size_t ii = 0; ii < chunks_.size(); ++ii) {
    MemoryChunk* chunk = chunks_[ii];
    if (chunk->IsInChunk(pointer)) {
      chunk->FreePendingToken(pointer, token);
      return;
    }
  }
  NOTREACHED();
}

void MappedMemoryManager::FreeUnused() {
  CommandBuffer* cmd_buf = helper_->command_buffer();
  MemoryChunkVector::iterator iter = chunks_.begin();
  while (iter != chunks_.end()) {
    MemoryChunk* chunk = *iter;
    chunk->FreeUnused();
    if (!chunk->InUse()) {
      cmd_buf->DestroyTransferBuffer(chunk->shm_id());
      allocated_memory_ -= chunk->GetSize();
      iter = chunks_.erase(iter);
    } else {
      ++iter;
    }
  }
}

}  // namespace gpu
