| Index: gpu/command_buffer/service/common_decoder.cc
|
| ===================================================================
|
| --- gpu/command_buffer/service/common_decoder.cc (revision 34064)
|
| +++ gpu/command_buffer/service/common_decoder.cc (working copy)
|
| @@ -35,6 +35,30 @@
|
|
|
| namespace command_buffer {
|
|
|
| +const 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[size] : NULL);
|
| + size_ = size;
|
| + memset(data_.get(), 0, size);
|
| + }
|
| +}
|
| +
|
| +bool CommonDecoder::Bucket::SetData(
|
| + const void* src, size_t offset, size_t size) {
|
| + if (OffsetSizeValid(offset, size)) {
|
| + memcpy(data_.get() + offset, src, size);
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| void* CommonDecoder::GetAddressAndCheckSize(unsigned int shm_id,
|
| unsigned int offset,
|
| unsigned int size) {
|
| @@ -53,8 +77,25 @@
|
| return cmd::GetCommandName(command_id);
|
| }
|
|
|
| +CommonDecoder::Bucket* CommonDecoder::GetBucket(uint32 bucket_id) const {
|
| + BucketMap::const_iterator iter(buckets_.find(bucket_id));
|
| + return iter != buckets_.end() ? &(*iter->second) : NULL;
|
| +}
|
| +
|
| namespace {
|
|
|
| +// Returns the address of the first byte after a struct.
|
| +template <typename T>
|
| +const void* AddressAfterStruct(const T& pod) {
|
| + return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
|
| +}
|
| +
|
| +// Returns the address of the frst byte after the struct.
|
| +template <typename RETURN_TYPE, typename COMMAND_TYPE>
|
| +RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod) {
|
| + return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod)));
|
| +}
|
| +
|
| // A struct to hold info about each command.
|
| struct CommandInfo {
|
| int arg_flags; // How to handle the arguments for this command
|
| @@ -87,11 +128,13 @@
|
| 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 immediate_data_size =
|
| + (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
|
| switch (command) {
|
| #define COMMON_COMMAND_BUFFER_CMD_OP(name) \
|
| case cmd::name::kCmdId: \
|
| return Handle ## name( \
|
| - arg_count, \
|
| + immediate_data_size, \
|
| *static_cast<const cmd::name*>(cmd_data)); \
|
|
|
| COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
|
| @@ -107,85 +150,148 @@
|
| }
|
|
|
| parse_error::ParseError CommonDecoder::HandleNoop(
|
| - uint32 arg_count,
|
| + uint32 immediate_data_size,
|
| const cmd::Noop& args) {
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError CommonDecoder::HandleSetToken(
|
| - uint32 arg_count,
|
| + uint32 immediate_data_size,
|
| const cmd::SetToken& args) {
|
| engine_->set_token(args.token);
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError CommonDecoder::HandleJump(
|
| - uint32 arg_count,
|
| + uint32 immediate_data_size,
|
| const cmd::Jump& args) {
|
| DCHECK(false); // TODO(gman): Implement.
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError CommonDecoder::HandleJumpRelative(
|
| - uint32 arg_count,
|
| + uint32 immediate_data_size,
|
| const cmd::JumpRelative& args) {
|
| DCHECK(false); // TODO(gman): Implement.
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError CommonDecoder::HandleCall(
|
| - uint32 arg_count,
|
| + uint32 immediate_data_size,
|
| const cmd::Call& args) {
|
| DCHECK(false); // TODO(gman): Implement.
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError CommonDecoder::HandleCallRelative(
|
| - uint32 arg_count,
|
| + uint32 immediate_data_size,
|
| const cmd::CallRelative& args) {
|
| DCHECK(false); // TODO(gman): Implement.
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError CommonDecoder::HandleReturn(
|
| - uint32 arg_count,
|
| + uint32 immediate_data_size,
|
| const cmd::Return& args) {
|
| DCHECK(false); // TODO(gman): Implement.
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError CommonDecoder::HandleSetBucketSize(
|
| - uint32 arg_count,
|
| + uint32 immediate_data_size,
|
| const cmd::SetBucketSize& args) {
|
| - DCHECK(false); // TODO(gman): Implement.
|
| + uint32 bucket_id = args.bucket_id;
|
| + uint32 size = args.size;
|
| +
|
| + Bucket* bucket = GetBucket(bucket_id);
|
| + if (!bucket) {
|
| + bucket = new Bucket();
|
| + buckets_[bucket_id] = linked_ptr<Bucket>(bucket);
|
| + }
|
| +
|
| + bucket->SetSize(size);
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError CommonDecoder::HandleSetBucketData(
|
| - uint32 arg_count,
|
| + uint32 immediate_data_size,
|
| const cmd::SetBucketData& args) {
|
| - DCHECK(false); // TODO(gman): Implement.
|
| + uint32 bucket_id = args.bucket_id;
|
| + uint32 offset = args.offset;
|
| + uint32 size = args.size;
|
| + const void* data = GetSharedMemoryAs<const void*>(
|
| + args.shared_memory_id, args.shared_memory_offset, size);
|
| + if (!data) {
|
| + return parse_error::kParseInvalidArguments;
|
| + }
|
| + Bucket* bucket = GetBucket(bucket_id);
|
| + if (!bucket) {
|
| + return parse_error::kParseInvalidArguments;
|
| + }
|
| + if (!bucket->SetData(data, offset, size)) {
|
| + return parse_error::kParseInvalidArguments;
|
| + }
|
| +
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| parse_error::ParseError CommonDecoder::HandleSetBucketDataImmediate(
|
| - uint32 arg_count,
|
| + uint32 immediate_data_size,
|
| const cmd::SetBucketDataImmediate& args) {
|
| - DCHECK(false); // TODO(gman): Implement.
|
| + const void* data = GetImmediateDataAs<const void*>(args);
|
| + uint32 bucket_id = args.bucket_id;
|
| + uint32 offset = args.offset;
|
| + uint32 size = args.size;
|
| + if (size > immediate_data_size) {
|
| + return parse_error::kParseInvalidArguments;
|
| + }
|
| + Bucket* bucket = GetBucket(bucket_id);
|
| + if (!bucket) {
|
| + return parse_error::kParseInvalidArguments;
|
| + }
|
| + if (!bucket->SetData(data, offset, size)) {
|
| + return parse_error::kParseInvalidArguments;
|
| + }
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| -parse_error::ParseError CommonDecoder::HandleGetResultSize(
|
| - uint32 arg_count,
|
| - const cmd::GetResultSize& args) {
|
| - DCHECK(false); // TODO(gman): Implement.
|
| +parse_error::ParseError CommonDecoder::HandleGetBucketSize(
|
| + uint32 immediate_data_size,
|
| + const cmd::GetBucketSize& args) {
|
| + uint32 bucket_id = args.bucket_id;
|
| + uint32* data = GetSharedMemoryAs<uint32*>(
|
| + args.shared_memory_id, args.shared_memory_offset, sizeof(*data));
|
| + if (!data) {
|
| + return parse_error::kParseInvalidArguments;
|
| + }
|
| + Bucket* bucket = GetBucket(bucket_id);
|
| + if (!bucket) {
|
| + return parse_error::kParseInvalidArguments;
|
| + }
|
| + *data = bucket->size();
|
| return parse_error::kParseNoError;
|
| }
|
|
|
| -parse_error::ParseError CommonDecoder::HandleGetResultData(
|
| - uint32 arg_count,
|
| - const cmd::GetResultData& args) {
|
| - DCHECK(false); // TODO(gman): Implement.
|
| +parse_error::ParseError CommonDecoder::HandleGetBucketData(
|
| + uint32 immediate_data_size,
|
| + const cmd::GetBucketData& args) {
|
| + uint32 bucket_id = args.bucket_id;
|
| + uint32 offset = args.offset;
|
| + uint32 size = args.size;
|
| + void* data = GetSharedMemoryAs<void*>(
|
| + args.shared_memory_id, args.shared_memory_offset, size);
|
| + if (!data) {
|
| + return parse_error::kParseInvalidArguments;
|
| + }
|
| + Bucket* bucket = GetBucket(bucket_id);
|
| + if (!bucket) {
|
| + return parse_error::kParseInvalidArguments;
|
| + }
|
| + const void* src = bucket->GetData(offset, size);
|
| + if (!src) {
|
| + return parse_error::kParseInvalidArguments;
|
| + }
|
| + memcpy(data, src, size);
|
| return parse_error::kParseNoError;
|
| }
|
|
|
|
|