// Copyright (c) 2012 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/service/common_decoder.h"

#include <stddef.h>
#include <stdint.h>

#include <algorithm>

#include "base/numerics/safe_math.h"
#include "gpu/command_buffer/service/cmd_buffer_engine.h"

namespace gpu {
namespace {
static const size_t kDefaultMaxBucketSize = 1u << 30;  // 1 GB
}

const CommonDecoder::CommandInfo CommonDecoder::command_info[] = {
#define COMMON_COMMAND_BUFFER_CMD_OP(name)                       \
  {                                                              \
    &CommonDecoder::Handle##name, cmd::name::kArgFlags,          \
        cmd::name::cmd_flags,                                    \
        sizeof(cmd::name) / sizeof(CommandBufferEntry) - 1,      \
  }                                                              \
  ,  /* NOLINT */
  COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
  #undef COMMON_COMMAND_BUFFER_CMD_OP
};


CommonDecoder::Bucket::Bucket() : size_(0) {}

CommonDecoder::Bucket::~Bucket() {}

void* CommonDecoder::Bucket::GetData(size_t offset, size_t size) const {
  if (OffsetSizeValid(offset, size)) {
    return data_.get() + offset;
  }
  return NULL;
}

void CommonDecoder::Bucket::SetSize(size_t size) {
  if (size != size_) {
    data_.reset(size ? new int8_t[size] : NULL);
    size_ = size;
    memset(data_.get(), 0, size);
  }
}

bool CommonDecoder::Bucket::SetData(
    const volatile void* src, size_t offset, size_t size) {
  if (OffsetSizeValid(offset, size)) {
    memcpy(data_.get() + offset, const_cast<const void*>(src), size);
    return true;
  }
  return false;
}

void CommonDecoder::Bucket::SetFromString(const char* str) {
  // Strings are passed NULL terminated to distinguish between empty string
  // and no string.
  if (!str) {
    SetSize(0);
  } else {
    size_t size = strlen(str) + 1;
    SetSize(size);
    SetData(str, 0, size);
  }
}

bool CommonDecoder::Bucket::GetAsString(std::string* str) {
  DCHECK(str);
  if (size_ == 0) {
    return false;
  }
  str->assign(GetDataAs<const char*>(0, size_ - 1), size_ - 1);
  return true;
}

bool CommonDecoder::Bucket::GetAsStrings(
    GLsizei* _count, std::vector<char*>* _string, std::vector<GLint>* _length) {
  const size_t kMinBucketSize = sizeof(GLint);
  // Each string has at least |length| in the header and a NUL character.
  const size_t kMinStringSize = sizeof(GLint) + 1;
  const size_t bucket_size = this->size();
  if (bucket_size < kMinBucketSize) {
    return false;
  }
  char* bucket_data = this->GetDataAs<char*>(0, bucket_size);
  GLint* header = reinterpret_cast<GLint*>(bucket_data);
  GLsizei count = static_cast<GLsizei>(header[0]);
  if (count < 0) {
    return false;
  }
  const size_t max_count = (bucket_size - kMinBucketSize) / kMinStringSize;
  if (max_count < static_cast<size_t>(count)) {
    return false;
  }
  GLint* length = header + 1;
  std::vector<char*> strs(count);
  base::CheckedNumeric<size_t> total_size = sizeof(GLint);
  total_size *= count + 1;  // Header size.
  if (!total_size.IsValid())
    return false;
  for (GLsizei ii = 0; ii < count; ++ii) {
    strs[ii] = bucket_data + total_size.ValueOrDefault(0);
    total_size += length[ii];
    total_size += 1;  // NUL char at the end of each char array.
    if (!total_size.IsValid() || total_size.ValueOrDefault(0) > bucket_size ||
        strs[ii][length[ii]] != 0) {
      return false;
    }
  }
  if (total_size.ValueOrDefault(0) != bucket_size) {
    return false;
  }
  DCHECK(_count && _string && _length);
  *_count = count;
  *_string = strs;
  _length->resize(count);
  for (GLsizei ii = 0; ii < count; ++ii) {
    (*_length)[ii] = length[ii];
  }
  return true;
}

CommonDecoder::CommonDecoder()
    : engine_(NULL), max_bucket_size_(kDefaultMaxBucketSize) {}

CommonDecoder::~CommonDecoder() {}

void* CommonDecoder::GetAddressAndCheckSize(unsigned int shm_id,
                                            unsigned int data_offset,
                                            unsigned int data_size) {
  CHECK(engine_);
  scoped_refptr<gpu::Buffer> buffer = engine_->GetSharedMemoryBuffer(shm_id);
  if (!buffer.get())
    return NULL;
  return buffer->GetDataAddress(data_offset, data_size);
}

void* CommonDecoder::GetAddressAndSize(unsigned int shm_id,
                                       unsigned int data_offset,
                                       unsigned int* data_size) {
  CHECK(engine_);
  scoped_refptr<gpu::Buffer> buffer = engine_->GetSharedMemoryBuffer(shm_id);
  if (!buffer.get())
    return NULL;
  return buffer->GetDataAddressAndSize(data_offset, data_size);
}

unsigned int CommonDecoder::GetSharedMemorySize(unsigned int shm_id,
                                                unsigned int offset) {
  CHECK(engine_);
  scoped_refptr<gpu::Buffer> buffer = engine_->GetSharedMemoryBuffer(shm_id);
  if (!buffer.get())
    return 0;
  return buffer->GetRemainingSize(offset);
}

scoped_refptr<gpu::Buffer> CommonDecoder::GetSharedMemoryBuffer(
    unsigned int shm_id) {
  return engine_->GetSharedMemoryBuffer(shm_id);
}

const char* CommonDecoder::GetCommonCommandName(
    cmd::CommandId command_id) const {
  return cmd::GetCommandName(command_id);
}

CommonDecoder::Bucket* CommonDecoder::GetBucket(uint32_t bucket_id) const {
  BucketMap::const_iterator iter(buckets_.find(bucket_id));
  return iter != buckets_.end() ? &(*iter->second) : NULL;
}

CommonDecoder::Bucket* CommonDecoder::CreateBucket(uint32_t bucket_id) {
  Bucket* bucket = GetBucket(bucket_id);
  if (!bucket) {
    bucket = new Bucket();
    buckets_[bucket_id] = std::unique_ptr<Bucket>(bucket);
  }
  return bucket;
}

namespace {

// Returns the address of the first byte after a struct.
template <typename T>
const volatile void* AddressAfterStruct(const volatile T& pod) {
  return reinterpret_cast<const volatile uint8_t*>(&pod) + sizeof(pod);
}

// Returns the address of the frst byte after the struct.
template <typename RETURN_TYPE, typename COMMAND_TYPE>
RETURN_TYPE GetImmediateDataAs(const volatile COMMAND_TYPE& pod) {
  return static_cast<RETURN_TYPE>(
      const_cast<volatile void*>(AddressAfterStruct(pod)));
}

}  // anonymous namespace.

// Decode command with its arguments, and call the corresponding method.
// Note: args is a pointer to the command buffer. As such, it could be changed
// by a (malicious) client at any time, so if validation has to happen, it
// should operate on a copy of them.
error::Error CommonDecoder::DoCommonCommand(unsigned int command,
                                            unsigned int arg_count,
                                            const volatile void* cmd_data) {
  if (command < arraysize(command_info)) {
    const CommandInfo& info = command_info[command];
    unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
    if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
        (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
      uint32_t immediate_data_size =
          (arg_count - info_arg_count) * sizeof(CommandBufferEntry);  // NOLINT
      return (this->*info.cmd_handler)(immediate_data_size, cmd_data);
    } else {
      return error::kInvalidArguments;
    }
  }
  return error::kUnknownCommand;
}

error::Error CommonDecoder::HandleNoop(uint32_t immediate_data_size,
                                       const volatile void* cmd_data) {
  return error::kNoError;
}

error::Error CommonDecoder::HandleSetToken(uint32_t immediate_data_size,
                                           const volatile void* cmd_data) {
  const volatile cmd::SetToken& args =
      *static_cast<const volatile cmd::SetToken*>(cmd_data);
  engine_->set_token(args.token);
  return error::kNoError;
}

error::Error CommonDecoder::HandleSetBucketSize(uint32_t immediate_data_size,
                                                const volatile void* cmd_data) {
  const volatile cmd::SetBucketSize& args =
      *static_cast<const volatile cmd::SetBucketSize*>(cmd_data);
  uint32_t bucket_id = args.bucket_id;
  uint32_t size = args.size;
  if (size > max_bucket_size_)
    return error::kOutOfBounds;

  Bucket* bucket = CreateBucket(bucket_id);
  bucket->SetSize(size);
  return error::kNoError;
}

error::Error CommonDecoder::HandleSetBucketData(uint32_t immediate_data_size,
                                                const volatile void* cmd_data) {
  const volatile cmd::SetBucketData& args =
      *static_cast<const volatile cmd::SetBucketData*>(cmd_data);
  uint32_t bucket_id = args.bucket_id;
  uint32_t offset = args.offset;
  uint32_t size = args.size;
  const void* data = GetSharedMemoryAs<const void*>(
      args.shared_memory_id, args.shared_memory_offset, size);
  if (!data) {
    return error::kInvalidArguments;
  }
  Bucket* bucket = GetBucket(bucket_id);
  if (!bucket) {
    return error::kInvalidArguments;
  }
  if (!bucket->SetData(data, offset, size)) {
    return error::kInvalidArguments;
  }

  return error::kNoError;
}

error::Error CommonDecoder::HandleSetBucketDataImmediate(
    uint32_t immediate_data_size,
    const volatile void* cmd_data) {
  const volatile cmd::SetBucketDataImmediate& args =
      *static_cast<const volatile cmd::SetBucketDataImmediate*>(cmd_data);
  const volatile void* data = GetImmediateDataAs<const volatile void*>(args);
  uint32_t bucket_id = args.bucket_id;
  uint32_t offset = args.offset;
  uint32_t size = args.size;
  if (size > immediate_data_size) {
    return error::kInvalidArguments;
  }
  Bucket* bucket = GetBucket(bucket_id);
  if (!bucket) {
    return error::kInvalidArguments;
  }
  if (!bucket->SetData(data, offset, size)) {
    return error::kInvalidArguments;
  }
  return error::kNoError;
}

error::Error CommonDecoder::HandleGetBucketStart(
    uint32_t immediate_data_size,
    const volatile void* cmd_data) {
  const volatile cmd::GetBucketStart& args =
      *static_cast<const volatile cmd::GetBucketStart*>(cmd_data);
  uint32_t bucket_id = args.bucket_id;
  uint32_t* result = GetSharedMemoryAs<uint32_t*>(
      args.result_memory_id, args.result_memory_offset, sizeof(*result));
  int32_t data_memory_id = args.data_memory_id;
  uint32_t data_memory_offset = args.data_memory_offset;
  uint32_t data_memory_size = args.data_memory_size;
  uint8_t* data = NULL;
  if (data_memory_size != 0 || data_memory_id != 0 || data_memory_offset != 0) {
    data = GetSharedMemoryAs<uint8_t*>(data_memory_id, data_memory_offset,
                                       data_memory_size);
    if (!data) {
      return error::kInvalidArguments;
    }
  }
  if (!result) {
    return error::kInvalidArguments;
  }
  // Check that the client initialized the result.
  if (*result != 0) {
    return error::kInvalidArguments;
  }
  Bucket* bucket = GetBucket(bucket_id);
  if (!bucket) {
    return error::kInvalidArguments;
  }
  uint32_t bucket_size = bucket->size();
  *result = bucket_size;
  if (data) {
    uint32_t size = std::min(data_memory_size, bucket_size);
    memcpy(data, bucket->GetData(0, size), size);
  }
  return error::kNoError;
}

error::Error CommonDecoder::HandleGetBucketData(uint32_t immediate_data_size,
                                                const volatile void* cmd_data) {
  const volatile cmd::GetBucketData& args =
      *static_cast<const volatile cmd::GetBucketData*>(cmd_data);
  uint32_t bucket_id = args.bucket_id;
  uint32_t offset = args.offset;
  uint32_t size = args.size;
  void* data = GetSharedMemoryAs<void*>(
      args.shared_memory_id, args.shared_memory_offset, size);
  if (!data) {
    return error::kInvalidArguments;
  }
  Bucket* bucket = GetBucket(bucket_id);
  if (!bucket) {
    return error::kInvalidArguments;
  }
  const void* src = bucket->GetData(offset, size);
  if (!src) {
      return error::kInvalidArguments;
  }
  memcpy(data, src, size);
  return error::kNoError;
}

}  // namespace gpu
