command_buffer: Table based command dispatch for Common commands
Change command dispatch from "switch" based to table based as done with GLES2 Commands. This will probably show marginal performance enhancement but will also raise code consistency. BUG=394570 Review URL: https://codereview.chromium.org/855033002 Cr-Commit-Position: refs/heads/master@{#312780}
This commit is contained in:

committed by
Commit bot

parent
150b0c13ed
commit
9249663e86
gpu/command_buffer/service
@@ -7,6 +7,19 @@
|
|||||||
|
|
||||||
namespace gpu {
|
namespace gpu {
|
||||||
|
|
||||||
|
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() : size_(0) {}
|
||||||
|
|
||||||
CommonDecoder::Bucket::~Bucket() {}
|
CommonDecoder::Bucket::~Bucket() {}
|
||||||
@@ -108,29 +121,6 @@ RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod) {
|
|||||||
return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod)));
|
return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(vmiura): Looks like this g_command_info is duplicated in
|
|
||||||
// common_decoder.cc
|
|
||||||
// and gles2_cmd_decoder.cc. Fix it!
|
|
||||||
|
|
||||||
// A struct to hold info about each command.
|
|
||||||
struct CommandInfo {
|
|
||||||
uint8 arg_flags; // How to handle the arguments for this command
|
|
||||||
uint8 cmd_flags; // How to handle this command
|
|
||||||
uint16 arg_count; // How many arguments are expected for this command.
|
|
||||||
};
|
|
||||||
|
|
||||||
// A table of CommandInfo for all the commands.
|
|
||||||
const CommandInfo g_command_info[] = {
|
|
||||||
#define COMMON_COMMAND_BUFFER_CMD_OP(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
|
|
||||||
};
|
|
||||||
|
|
||||||
} // anonymous namespace.
|
} // anonymous namespace.
|
||||||
|
|
||||||
// Decode command with its arguments, and call the corresponding method.
|
// Decode command with its arguments, and call the corresponding method.
|
||||||
@@ -141,24 +131,14 @@ error::Error CommonDecoder::DoCommonCommand(
|
|||||||
unsigned int command,
|
unsigned int command,
|
||||||
unsigned int arg_count,
|
unsigned int arg_count,
|
||||||
const void* cmd_data) {
|
const void* cmd_data) {
|
||||||
if (command < arraysize(g_command_info)) {
|
if (command < arraysize(command_info)) {
|
||||||
const CommandInfo& info = g_command_info[command];
|
const CommandInfo& info = command_info[command];
|
||||||
unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
|
unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
|
||||||
if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
|
if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
|
||||||
(info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
|
(info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
|
||||||
uint32 immediate_data_size =
|
uint32 immediate_data_size =
|
||||||
(arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
|
(arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
|
||||||
switch (command) {
|
return (this->*info.cmd_handler)(immediate_data_size, cmd_data);
|
||||||
#define COMMON_COMMAND_BUFFER_CMD_OP(name) \
|
|
||||||
case cmd::name::kCmdId: \
|
|
||||||
return Handle ## name( \
|
|
||||||
immediate_data_size, \
|
|
||||||
*static_cast<const cmd::name*>(cmd_data)); \
|
|
||||||
|
|
||||||
COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
|
|
||||||
|
|
||||||
#undef COMMON_COMMAND_BUFFER_CMD_OP
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return error::kInvalidArguments;
|
return error::kInvalidArguments;
|
||||||
}
|
}
|
||||||
@@ -168,20 +148,23 @@ error::Error CommonDecoder::DoCommonCommand(
|
|||||||
|
|
||||||
error::Error CommonDecoder::HandleNoop(
|
error::Error CommonDecoder::HandleNoop(
|
||||||
uint32 immediate_data_size,
|
uint32 immediate_data_size,
|
||||||
const cmd::Noop& args) {
|
const void* cmd_data) {
|
||||||
return error::kNoError;
|
return error::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
error::Error CommonDecoder::HandleSetToken(
|
error::Error CommonDecoder::HandleSetToken(
|
||||||
uint32 immediate_data_size,
|
uint32 immediate_data_size,
|
||||||
const cmd::SetToken& args) {
|
const void* cmd_data) {
|
||||||
|
const cmd::SetToken& args = *static_cast<const cmd::SetToken*>(cmd_data);
|
||||||
engine_->set_token(args.token);
|
engine_->set_token(args.token);
|
||||||
return error::kNoError;
|
return error::kNoError;
|
||||||
}
|
}
|
||||||
|
|
||||||
error::Error CommonDecoder::HandleSetBucketSize(
|
error::Error CommonDecoder::HandleSetBucketSize(
|
||||||
uint32 immediate_data_size,
|
uint32 immediate_data_size,
|
||||||
const cmd::SetBucketSize& args) {
|
const void* cmd_data) {
|
||||||
|
const cmd::SetBucketSize& args =
|
||||||
|
*static_cast<const cmd::SetBucketSize*>(cmd_data);
|
||||||
uint32 bucket_id = args.bucket_id;
|
uint32 bucket_id = args.bucket_id;
|
||||||
uint32 size = args.size;
|
uint32 size = args.size;
|
||||||
|
|
||||||
@@ -192,7 +175,9 @@ error::Error CommonDecoder::HandleSetBucketSize(
|
|||||||
|
|
||||||
error::Error CommonDecoder::HandleSetBucketData(
|
error::Error CommonDecoder::HandleSetBucketData(
|
||||||
uint32 immediate_data_size,
|
uint32 immediate_data_size,
|
||||||
const cmd::SetBucketData& args) {
|
const void* cmd_data) {
|
||||||
|
const cmd::SetBucketData& args =
|
||||||
|
*static_cast<const cmd::SetBucketData*>(cmd_data);
|
||||||
uint32 bucket_id = args.bucket_id;
|
uint32 bucket_id = args.bucket_id;
|
||||||
uint32 offset = args.offset;
|
uint32 offset = args.offset;
|
||||||
uint32 size = args.size;
|
uint32 size = args.size;
|
||||||
@@ -214,7 +199,9 @@ error::Error CommonDecoder::HandleSetBucketData(
|
|||||||
|
|
||||||
error::Error CommonDecoder::HandleSetBucketDataImmediate(
|
error::Error CommonDecoder::HandleSetBucketDataImmediate(
|
||||||
uint32 immediate_data_size,
|
uint32 immediate_data_size,
|
||||||
const cmd::SetBucketDataImmediate& args) {
|
const void* cmd_data) {
|
||||||
|
const cmd::SetBucketDataImmediate& args =
|
||||||
|
*static_cast<const cmd::SetBucketDataImmediate*>(cmd_data);
|
||||||
const void* data = GetImmediateDataAs<const void*>(args);
|
const void* data = GetImmediateDataAs<const void*>(args);
|
||||||
uint32 bucket_id = args.bucket_id;
|
uint32 bucket_id = args.bucket_id;
|
||||||
uint32 offset = args.offset;
|
uint32 offset = args.offset;
|
||||||
@@ -234,7 +221,9 @@ error::Error CommonDecoder::HandleSetBucketDataImmediate(
|
|||||||
|
|
||||||
error::Error CommonDecoder::HandleGetBucketStart(
|
error::Error CommonDecoder::HandleGetBucketStart(
|
||||||
uint32 immediate_data_size,
|
uint32 immediate_data_size,
|
||||||
const cmd::GetBucketStart& args) {
|
const void* cmd_data) {
|
||||||
|
const cmd::GetBucketStart& args =
|
||||||
|
*static_cast<const cmd::GetBucketStart*>(cmd_data);
|
||||||
uint32 bucket_id = args.bucket_id;
|
uint32 bucket_id = args.bucket_id;
|
||||||
uint32* result = GetSharedMemoryAs<uint32*>(
|
uint32* result = GetSharedMemoryAs<uint32*>(
|
||||||
args.result_memory_id, args.result_memory_offset, sizeof(*result));
|
args.result_memory_id, args.result_memory_offset, sizeof(*result));
|
||||||
@@ -271,7 +260,9 @@ error::Error CommonDecoder::HandleGetBucketStart(
|
|||||||
|
|
||||||
error::Error CommonDecoder::HandleGetBucketData(
|
error::Error CommonDecoder::HandleGetBucketData(
|
||||||
uint32 immediate_data_size,
|
uint32 immediate_data_size,
|
||||||
const cmd::GetBucketData& args) {
|
const void* cmd_data) {
|
||||||
|
const cmd::GetBucketData& args =
|
||||||
|
*static_cast<const cmd::GetBucketData*>(cmd_data);
|
||||||
uint32 bucket_id = args.bucket_id;
|
uint32 bucket_id = args.bucket_id;
|
||||||
uint32 offset = args.offset;
|
uint32 offset = args.offset;
|
||||||
uint32 size = args.size;
|
uint32 size = args.size;
|
||||||
|
@@ -155,9 +155,7 @@ class GPU_EXPORT CommonDecoder : NON_EXPORTED_BASE(public AsyncAPIInterface) {
|
|||||||
// Generate a member function prototype for each command in an automated and
|
// Generate a member function prototype for each command in an automated and
|
||||||
// typesafe way.
|
// typesafe way.
|
||||||
#define COMMON_COMMAND_BUFFER_CMD_OP(name) \
|
#define COMMON_COMMAND_BUFFER_CMD_OP(name) \
|
||||||
error::Error Handle##name( \
|
error::Error Handle##name(uint32 immediate_data_size, const void* data);
|
||||||
uint32 immediate_data_size, \
|
|
||||||
const cmd::name& args); \
|
|
||||||
|
|
||||||
COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
|
COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
|
||||||
|
|
||||||
@@ -167,6 +165,22 @@ class GPU_EXPORT CommonDecoder : NON_EXPORTED_BASE(public AsyncAPIInterface) {
|
|||||||
|
|
||||||
typedef std::map<uint32, linked_ptr<Bucket> > BucketMap;
|
typedef std::map<uint32, linked_ptr<Bucket> > BucketMap;
|
||||||
BucketMap buckets_;
|
BucketMap buckets_;
|
||||||
|
|
||||||
|
typedef Error (CommonDecoder::*CmdHandler)(
|
||||||
|
uint32 immediate_data_size,
|
||||||
|
const void* data);
|
||||||
|
|
||||||
|
// A struct to hold info about each command.
|
||||||
|
struct CommandInfo {
|
||||||
|
CmdHandler cmd_handler;
|
||||||
|
uint8 arg_flags; // How to handle the arguments for this command
|
||||||
|
uint8 cmd_flags; // How to handle this command
|
||||||
|
uint16 arg_count; // How many arguments are expected for this command.
|
||||||
|
};
|
||||||
|
|
||||||
|
// A table of CommandInfo for all the commands.
|
||||||
|
static const CommandInfo command_info[];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace gpu
|
} // namespace gpu
|
||||||
|
Reference in New Issue
Block a user