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 {
|
||||
|
||||
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() {}
|
||||
@@ -108,29 +121,6 @@ RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& 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.
|
||||
|
||||
// Decode command with its arguments, and call the corresponding method.
|
||||
@@ -141,24 +131,14 @@ error::Error CommonDecoder::DoCommonCommand(
|
||||
unsigned int command,
|
||||
unsigned int arg_count,
|
||||
const void* cmd_data) {
|
||||
if (command < arraysize(g_command_info)) {
|
||||
const CommandInfo& info = g_command_info[command];
|
||||
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 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( \
|
||||
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
|
||||
}
|
||||
return (this->*info.cmd_handler)(immediate_data_size, cmd_data);
|
||||
} else {
|
||||
return error::kInvalidArguments;
|
||||
}
|
||||
@@ -168,20 +148,23 @@ error::Error CommonDecoder::DoCommonCommand(
|
||||
|
||||
error::Error CommonDecoder::HandleNoop(
|
||||
uint32 immediate_data_size,
|
||||
const cmd::Noop& args) {
|
||||
const void* cmd_data) {
|
||||
return error::kNoError;
|
||||
}
|
||||
|
||||
error::Error CommonDecoder::HandleSetToken(
|
||||
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);
|
||||
return error::kNoError;
|
||||
}
|
||||
|
||||
error::Error CommonDecoder::HandleSetBucketSize(
|
||||
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 size = args.size;
|
||||
|
||||
@@ -192,7 +175,9 @@ error::Error CommonDecoder::HandleSetBucketSize(
|
||||
|
||||
error::Error CommonDecoder::HandleSetBucketData(
|
||||
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 offset = args.offset;
|
||||
uint32 size = args.size;
|
||||
@@ -214,7 +199,9 @@ error::Error CommonDecoder::HandleSetBucketData(
|
||||
|
||||
error::Error CommonDecoder::HandleSetBucketDataImmediate(
|
||||
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);
|
||||
uint32 bucket_id = args.bucket_id;
|
||||
uint32 offset = args.offset;
|
||||
@@ -234,7 +221,9 @@ error::Error CommonDecoder::HandleSetBucketDataImmediate(
|
||||
|
||||
error::Error CommonDecoder::HandleGetBucketStart(
|
||||
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* result = GetSharedMemoryAs<uint32*>(
|
||||
args.result_memory_id, args.result_memory_offset, sizeof(*result));
|
||||
@@ -271,7 +260,9 @@ error::Error CommonDecoder::HandleGetBucketStart(
|
||||
|
||||
error::Error CommonDecoder::HandleGetBucketData(
|
||||
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 offset = args.offset;
|
||||
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
|
||||
// typesafe way.
|
||||
#define COMMON_COMMAND_BUFFER_CMD_OP(name) \
|
||||
error::Error Handle##name( \
|
||||
uint32 immediate_data_size, \
|
||||
const cmd::name& args); \
|
||||
error::Error Handle##name(uint32 immediate_data_size, const void* data);
|
||||
|
||||
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;
|
||||
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
|
||||
|
Reference in New Issue
Block a user