Commit 18cef85a authored by gman@google.com's avatar gman@google.com

Splits the command buffers into common commands

and specific commands.

Common are things like Noop, SetToken, Jump, Gosub, return.

Specific are O3D etc...

Review URL: http://codereview.chromium.org/329046

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30365 0039d316-1c4b-4281-b951-d872f2087c98
parent bbe28b10
......@@ -57,6 +57,14 @@
'../../<(glewdir)/lib/glew32.lib',
],
},
'copies': [
{
'destination': '<(PRODUCT_DIR)',
'files': [
"../../<(glewdir)/bin/glew32.dll",
]
},
],
},
],
],
......
......@@ -170,6 +170,19 @@ class CommandBufferHelper {
parse_error::ParseError GetParseError();
// Common Commands
void Noop(uint32 skip_count) {
cmd::Noop& cmd = GetImmediateCmdSpace<cmd::Noop>(
skip_count * sizeof(CommandBufferEntry));
cmd.Init(skip_count);
}
void SetToken(uint32 token) {
cmd::SetToken& cmd = GetCmdSpace<cmd::SetToken>();
cmd.Init(token);
}
private:
// Waits until get changes, updating the value of get_.
void WaitForGetChange();
......
......@@ -57,17 +57,6 @@ class O3DCmdHelper : public CommandBufferHelper {
// ------------------ Individual commands ----------------------
void Noop(uint32 skip_count) {
o3d::Noop& cmd = GetImmediateCmdSpace<o3d::Noop>(
skip_count * sizeof(CommandBufferEntry));
cmd.Init(skip_count);
}
void SetToken(uint32 token) {
o3d::SetToken& cmd = GetCmdSpace<o3d::SetToken>();
cmd.Init(token);
}
void BeginFrame() {
o3d::BeginFrame& cmd = GetCmdSpace<o3d::BeginFrame>();
cmd.Init();
......
......@@ -40,6 +40,7 @@
'sources': [
'common/cross/bitfield_helpers.h',
'common/cross/cmd_buffer_common.h',
'common/cross/cmd_buffer_common.cc',
'common/cross/o3d_cmd_format.h',
'common/cross/o3d_cmd_format.cc',
'common/cross/gapi_interface.h',
......@@ -112,6 +113,8 @@
'command_buffer_common',
],
'sources': [
'service/cross/common_decoder.cc',
'service/cross/common_decoder.h',
'service/cross/cmd_buffer_engine.h',
'service/cross/cmd_parser.cc',
'service/cross/cmd_parser.h',
......
/*
* Copyright 2009, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// This file contains the binary format definition of the command buffer and
// command buffer commands.
#include "command_buffer/common/cross/cmd_buffer_common.h"
namespace o3d {
namespace command_buffer {
namespace cmd {
const char* GetCommandName(CommandId command_id) {
static const char* const names[] = {
#define COMMON_COMMAND_BUFFER_CMD_OP(name) # name,
COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
#undef COMMON_COMMAND_BUFFER_CMD_OP
};
int id = static_cast<int>(command_id);
return (id >= 0 && id < kNumCommands) ? names[id] : "*unknown-command*";
}
} // namespace cmd
} // namespace command_buffer
} // namespace o3d
......@@ -171,7 +171,7 @@ namespace cmd {
OP(SetToken) /* 1 */ \
// Common commands.
enum CommonCommandId {
enum CommandId {
#define COMMON_COMMAND_BUFFER_CMD_OP(name) k ## name,
COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
......@@ -179,11 +179,66 @@ enum CommonCommandId {
#undef COMMON_COMMAND_BUFFER_CMD_OP
kNumCommands,
kLastCommonId = 1023, // reserver 1024 spaces for common commands
kLastCommonId = 1023, // reserve 1024 spaces for common commands.
};
COMPILE_ASSERT(kNumCommands - 1 <= kLastCommonId, Too_many_common_commands);
const char* GetCommandName(CommandId id);
struct Noop {
typedef Noop ValueType;
static const CommandId kCmdId = kNoop;
static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
void SetHeader(uint32 skip_count) {
header.Init(kCmdId, skip_count + 1);
}
void Init(uint32 skip_count) {
SetHeader(skip_count);
}
static void* Set(void* cmd, uint32 skip_count) {
static_cast<ValueType*>(cmd)->Init(skip_count);
return NextImmediateCmdAddress<ValueType>(
cmd, skip_count * sizeof(CommandBufferEntry)); // NOLINT
}
CommandHeader header;
};
COMPILE_ASSERT(sizeof(Noop) == 4, Sizeof_Noop_is_not_4);
COMPILE_ASSERT(offsetof(Noop, header) == 0, Offsetof_Noop_header_not_0);
struct SetToken {
typedef SetToken ValueType;
static const CommandId kCmdId = kSetToken;
static const cmd::ArgFlags kArgFlags = cmd::kFixed;
void SetHeader() {
header.SetCmd<ValueType>();
}
void Init(uint32 _token) {
SetHeader();
token = _token;
}
static void* Set(void* cmd, uint32 token) {
static_cast<ValueType*>(cmd)->Init(token);
return NextCmdAddress<ValueType>(cmd);
}
CommandHeader header;
uint32 token;
};
COMPILE_ASSERT(sizeof(SetToken) == 8, Sizeof_SetToken_is_not_8);
COMPILE_ASSERT(offsetof(SetToken, header) == 0,
Offsetof_SetToken_header_not_0);
COMPILE_ASSERT(offsetof(SetToken, token) == 4,
Offsetof_SetToken_token_not_4);
} // namespace cmd
O3D_POP_STRUCTURE_PACKING;
......
......@@ -39,19 +39,18 @@ namespace o3d {
namespace command_buffer {
namespace o3d {
const char* GetCommandName(CommandId id) {
const char* GetCommandName(CommandId command_id) {
static const char* const names[] = {
#define O3D_COMMAND_BUFFER_CMD_OP(name) # name,
O3D_COMMAND_BUFFER_CMDS(O3D_COMMAND_BUFFER_CMD_OP)
#undef O3D_COMMAND_BUFFER_CMD_OP
};
return (static_cast<int>(id) >= 0 && static_cast<int>(id) < kNumCommands) ?
names[id] : "*unknown-command*";
int id = static_cast<int>(command_id);
return (id > kStartPoint && id < kNumCommands) ?
names[id - kStartPoint - 1] : "*unknown-command*";
}
} // namespace cmd
......
......@@ -74,75 +74,73 @@ namespace o3d {
//
// NOTE: THE ORDER OF THESE MUST NOT CHANGE (their id is derived by order)
#define O3D_COMMAND_BUFFER_CMDS(OP) \
OP(Noop) /* 1024 */ \
OP(SetToken) /* 1025 */ \
OP(BeginFrame) /* 1026 */ \
OP(EndFrame) /* 1027 */ \
OP(Clear) /* 1028 */ \
OP(CreateVertexBuffer) /* 1029 */ \
OP(DestroyVertexBuffer) /* 1030 */ \
OP(SetVertexBufferData) /* 1031 */ \
OP(SetVertexBufferDataImmediate) /* 1032 */ \
OP(GetVertexBufferData) /* 1033 */ \
OP(CreateIndexBuffer) /* 1034 */ \
OP(DestroyIndexBuffer) /* 1035 */ \
OP(SetIndexBufferData) /* 1036 */ \
OP(SetIndexBufferDataImmediate) /* 1037 */ \
OP(GetIndexBufferData) /* 1038 */ \
OP(CreateVertexStruct) /* 1039 */ \
OP(DestroyVertexStruct) /* 1040 */ \
OP(SetVertexInput) /* 1041 */ \
OP(SetVertexStruct) /* 1042 */ \
OP(Draw) /* 1043 */ \
OP(DrawIndexed) /* 1044 */ \
OP(CreateEffect) /* 1045 */ \
OP(CreateEffectImmediate) /* 1046 */ \
OP(DestroyEffect) /* 1047 */ \
OP(SetEffect) /* 1048 */ \
OP(GetParamCount) /* 1049 */ \
OP(CreateParam) /* 1050 */ \
OP(CreateParamByName) /* 1051 */ \
OP(CreateParamByNameImmediate) /* 1052 */ \
OP(DestroyParam) /* 1053 */ \
OP(SetParamData) /* 1054 */ \
OP(SetParamDataImmediate) /* 1055 */ \
OP(GetParamDesc) /* 1056 */ \
OP(GetStreamCount) /* 1057 */ \
OP(GetStreamDesc) /* 1058 */ \
OP(DestroyTexture) /* 1059 */ \
OP(CreateTexture2d) /* 1060 */ \
OP(CreateTexture3d) /* 1061 */ \
OP(CreateTextureCube) /* 1062 */ \
OP(SetTextureData) /* 1063 */ \
OP(SetTextureDataImmediate) /* 1064 */ \
OP(GetTextureData) /* 1065 */ \
OP(CreateSampler) /* 1066 */ \
OP(DestroySampler) /* 1067 */ \
OP(SetSamplerStates) /* 1068 */ \
OP(SetSamplerBorderColor) /* 1069 */ \
OP(SetSamplerTexture) /* 1070 */ \
OP(SetViewport) /* 1071 */ \
OP(SetScissor) /* 1072 */ \
OP(SetPointLineRaster) /* 1073 */ \
OP(SetPolygonRaster) /* 1074 */ \
OP(SetPolygonOffset) /* 1075 */ \
OP(SetAlphaTest) /* 1076 */ \
OP(SetDepthTest) /* 1077 */ \
OP(SetStencilTest) /* 1078 */ \
OP(SetBlending) /* 1079 */ \
OP(SetBlendingColor) /* 1080 */ \
OP(SetColorWrite) /* 1081 */ \
OP(CreateRenderSurface) /* 1082 */ \
OP(DestroyRenderSurface) /* 1083 */ \
OP(CreateDepthSurface) /* 1084 */ \
OP(DestroyDepthSurface) /* 1085 */ \
OP(SetRenderSurface) /* 1086 */ \
OP(SetBackSurfaces) /* 1087 */ \
OP(BeginFrame) /* 1024 */ \
OP(EndFrame) /* 1025 */ \
OP(Clear) /* 1026 */ \
OP(CreateVertexBuffer) /* 1027 */ \
OP(DestroyVertexBuffer) /* 1028 */ \
OP(SetVertexBufferData) /* 1029 */ \
OP(SetVertexBufferDataImmediate) /* 1030 */ \
OP(GetVertexBufferData) /* 1031 */ \
OP(CreateIndexBuffer) /* 1032 */ \
OP(DestroyIndexBuffer) /* 1033 */ \
OP(SetIndexBufferData) /* 1034 */ \
OP(SetIndexBufferDataImmediate) /* 1035 */ \
OP(GetIndexBufferData) /* 1036 */ \
OP(CreateVertexStruct) /* 1037 */ \
OP(DestroyVertexStruct) /* 1038 */ \
OP(SetVertexInput) /* 1039 */ \
OP(SetVertexStruct) /* 1040 */ \
OP(Draw) /* 1041 */ \
OP(DrawIndexed) /* 1042 */ \
OP(CreateEffect) /* 1043 */ \
OP(CreateEffectImmediate) /* 1044 */ \
OP(DestroyEffect) /* 1045 */ \
OP(SetEffect) /* 1046 */ \
OP(GetParamCount) /* 1047 */ \
OP(CreateParam) /* 1048 */ \
OP(CreateParamByName) /* 1049 */ \
OP(CreateParamByNameImmediate) /* 1050 */ \
OP(DestroyParam) /* 1051 */ \
OP(SetParamData) /* 1052 */ \
OP(SetParamDataImmediate) /* 1053 */ \
OP(GetParamDesc) /* 1054 */ \
OP(GetStreamCount) /* 1055 */ \
OP(GetStreamDesc) /* 1056 */ \
OP(DestroyTexture) /* 1057 */ \
OP(CreateTexture2d) /* 1058 */ \
OP(CreateTexture3d) /* 1059 */ \
OP(CreateTextureCube) /* 1060 */ \
OP(SetTextureData) /* 1061 */ \
OP(SetTextureDataImmediate) /* 1062 */ \
OP(GetTextureData) /* 1063 */ \
OP(CreateSampler) /* 1064 */ \
OP(DestroySampler) /* 1065 */ \
OP(SetSamplerStates) /* 1066 */ \
OP(SetSamplerBorderColor) /* 1067 */ \
OP(SetSamplerTexture) /* 1068 */ \
OP(SetViewport) /* 1069 */ \
OP(SetScissor) /* 1070 */ \
OP(SetPointLineRaster) /* 1071 */ \
OP(SetPolygonRaster) /* 1072 */ \
OP(SetPolygonOffset) /* 1073 */ \
OP(SetAlphaTest) /* 1074 */ \
OP(SetDepthTest) /* 1075 */ \
OP(SetStencilTest) /* 1076 */ \
OP(SetBlending) /* 1077 */ \
OP(SetBlendingColor) /* 1078 */ \
OP(SetColorWrite) /* 1079 */ \
OP(CreateRenderSurface) /* 1080 */ \
OP(DestroyRenderSurface) /* 1081 */ \
OP(CreateDepthSurface) /* 1082 */ \
OP(DestroyDepthSurface) /* 1083 */ \
OP(SetRenderSurface) /* 1084 */ \
OP(SetBackSurfaces) /* 1085 */ \
// GAPI commands.
enum CommandId {
// kStartPoint = cmd::kLastCommonId, // All O3D commands start after this.
kStartPoint = cmd::kLastCommonId, // All O3D commands start after this.
#define O3D_COMMAND_BUFFER_CMD_OP(name) k ## name,
O3D_COMMAND_BUFFER_CMDS(O3D_COMMAND_BUFFER_CMD_OP)
......@@ -247,59 +245,6 @@ const char* GetCommandName(CommandId id);
// structures.
O3D_PUSH_STRUCTURE_PACKING_1;
struct Noop {
typedef Noop ValueType;
static const CommandId kCmdId = kNoop;
static const cmd::ArgFlags kArgFlags = cmd::kAtLeastN;
void SetHeader(uint32 skip_count) {
header.Init(kCmdId, skip_count + 1);
}
void Init(uint32 skip_count) {
SetHeader(skip_count);
}
static void* Set(void* cmd, uint32 skip_count) {
static_cast<ValueType*>(cmd)->Init(skip_count);
return NextImmediateCmdAddress<ValueType>(
cmd, skip_count * sizeof(CommandBufferEntry)); // NOLINT
}
CommandHeader header;
};
COMPILE_ASSERT(sizeof(Noop) == 4, Sizeof_Noop_is_not_4);
COMPILE_ASSERT(offsetof(Noop, header) == 0, Offsetof_Noop_header_not_0);
struct SetToken {
typedef SetToken ValueType;
static const CommandId kCmdId = kSetToken;
static const cmd::ArgFlags kArgFlags = cmd::kFixed;
void SetHeader() {
header.SetCmd<ValueType>();
}
void Init(uint32 _token) {
SetHeader();
token = _token;
}
static void* Set(void* cmd, uint32 token) {
static_cast<ValueType*>(cmd)->Init(token);
return NextCmdAddress<ValueType>(cmd);
}
CommandHeader header;
uint32 token;
};
COMPILE_ASSERT(sizeof(SetToken) == 8, Sizeof_SetToken_is_not_8);
COMPILE_ASSERT(offsetof(SetToken, header) == 0,
Offsetof_SetToken_header_not_0);
COMPILE_ASSERT(offsetof(SetToken, token) == 4,
Offsetof_SetToken_token_not_4);
struct BeginFrame {
typedef BeginFrame ValueType;
static const CommandId kCmdId = kBeginFrame;
......
......@@ -87,14 +87,18 @@ parse_error::ParseError CommandParser::ProcessCommand() {
// It seems like we need an official way to turn on a debug mode and
// get these errors.
if (result != parse_error::kParseNoError) {
DLOG(INFO)
<< "Error: " << result << " for Command "
<< o3d::GetCommandName(static_cast<o3d::CommandId>(header.command));
ReportError(header.command, result);
}
get_ = (get + header.size) % entry_count_;
return result;
}
void CommandParser::ReportError(unsigned int command_id,
parse_error::ParseError result) {
DLOG(INFO) << "Error: " << result << " for Command "
<< handler_->GetCommandName(command_id);
}
// Processes all the commands, while the buffer is not empty. Stop if an error
// is encountered.
parse_error::ParseError CommandParser::ProcessAllCommands() {
......
......@@ -77,6 +77,9 @@ class CommandParser {
// Processes all commands until get == put.
parse_error::ParseError ProcessAllCommands();
// Reports an error.
void ReportError(unsigned int command_id, parse_error::ParseError result);
private:
CommandBufferOffset get_;
CommandBufferOffset put_;
......@@ -104,6 +107,9 @@ class AsyncAPIInterface {
unsigned int command,
unsigned int arg_count,
const void* cmd_data) = 0;
// Returns a name for a command. Useful for logging / debuging.
virtual const char* GetCommandName(unsigned int command_id) const = 0;
};
} // namespace command_buffer
......
/*
* Copyright 2009, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "command_buffer/service/cross/common_decoder.h"
#include "command_buffer/service/cross/cmd_buffer_engine.h"
namespace o3d {
namespace command_buffer {
void* CommonDecoder::GetAddressAndCheckSize(unsigned int shm_id,
unsigned int offset,
unsigned int size) {
void* shm_addr = engine_->GetSharedMemoryAddress(shm_id);
if (!shm_addr) return NULL;
size_t shm_size = engine_->GetSharedMemorySize(shm_id);
unsigned int end = offset + size;
if (end > shm_size || end < offset) {
return NULL;
}
return static_cast<int8 *>(shm_addr) + offset;
}
const char* CommonDecoder::GetCommonCommandName(
cmd::CommandId command_id) const {
return cmd::GetCommandName(command_id);
}
namespace {
// A struct to hold info about each command.
struct CommandInfo {
int arg_flags; // How to handle the arguments for this command
int 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, \
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.
// 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.
parse_error::ParseError 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];
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)) {
switch (command) {
#define COMMON_COMMAND_BUFFER_CMD_OP(name) \
case cmd::name::kCmdId: \
return Handle ## name( \
arg_count, \
*static_cast<const cmd::name*>(cmd_data)); \
COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
#undef COMMON_COMMAND_BUFFER_CMD_OP
}
} else {
return parse_error::kParseInvalidArguments;
}
}
return DoCommonCommand(command, arg_count, cmd_data);
return parse_error::kParseUnknownCommand;
}
parse_error::ParseError CommonDecoder::HandleNoop(
uint32 arg_count,
const cmd::Noop& args) {
return parse_error::kParseNoError;
}
parse_error::ParseError CommonDecoder::HandleSetToken(
uint32 arg_count,
const cmd::SetToken& args) {
engine_->set_token(args.token);
return parse_error::kParseNoError;
}
} // namespace command_buffer
} // namespace o3d
/*
* Copyright 2009, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef O3D_COMMAND_BUFFER_SERVICE_CROSS_COMMON_DECODER_H_
#define O3D_COMMAND_BUFFER_SERVICE_CROSS_COMMON_DECODER_H_
#include "core/cross/types.h"
#include "command_buffer/service/cross/cmd_parser.h"
namespace o3d {
namespace command_buffer {
class CommandBufferEngine;
// This class is a helper base class for implementing the common parts of the
// o3d/gl2 command buffer decoder.
class CommonDecoder : public AsyncAPIInterface {
public:
typedef parse_error::ParseError ParseError;
CommonDecoder() : engine_(NULL) {
}
virtual ~CommonDecoder() {
}
// Sets the engine, to get shared memory buffers from, and to set the token
// to.
void set_engine(CommandBufferEngine* engine) {
engine_ = engine;
}
protected:
// Executes a common command.
// Parameters:
// command: the command index.
// arg_count: the number of CommandBufferEntry arguments.
// cmd_data: the command data.
// Returns:
// parse_error::NO_ERROR if no error was found, one of
// parse_error::ParseError otherwise.
parse_error::ParseError DoCommonCommand(
unsigned int command,
unsigned int arg_count,
const void* cmd_data);
// Gets the address of shared memory data, given a shared memory ID and an
// offset. Also checks that the size is consistent with the shared memory
// size.
// Parameters:
// shm_id: the id of the shared memory buffer.
// offset: the offset of the data in the shared memory buffer.
// size: the size of the data.
// Returns:
// NULL if shm_id isn't a valid shared memory buffer ID or if the size
// check fails. Return a pointer to the data otherwise.
void* GetAddressAndCheckSize(unsigned int shm_id,
unsigned int offset,
unsigned int size);
// Gets an name for a common command.
const char* GetCommonCommandName(cmd::CommandId command_id) const;
private:
// Generate a member function prototype for each command in an automated and
// typesafe way.
#define COMMON_COMMAND_BUFFER_CMD_OP(name) \
parse_error::ParseError Handle ## name( \
unsigned int arg_count, \
const cmd::name& args); \
COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
#undef COMMON_COMMAND_BUFFER_CMD_OP
CommandBufferEngine* engine_;
};
} // namespace command_buffer
} // namespace o3d
#endif // O3D_COMMAND_BUFFER_SERVICE_CROSS_COMMON_DECODER_H_
......@@ -36,7 +36,6 @@
#include "base/cross/bits.h"
#include "command_buffer/common/cross/gapi_interface.h"
#include "command_buffer/service/cross/gapi_decoder.h"
#include "command_buffer/service/cross/cmd_buffer_engine.h"
namespace o3d {
namespace command_buffer {
......@@ -78,8 +77,7 @@ const CommandInfo g_command_info[] = {
} // anonymous namespace.
// Decode command with its arguments, and call the corresponding GAPIInterface
// method.
// 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.
......@@ -87,9 +85,10 @@ parse_error::ParseError GAPIDecoder::DoCommand(
unsigned int command,
unsigned int arg_count,
const void* cmd_data) {
if (command < arraysize(g_command_info)) {
const CommandInfo& info = g_command_info[command];
unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
unsigned int command_index = command - kStartPoint - 1;
if (command_index < arraysize(g_command_info)) {
const CommandInfo& info = g_command_info[command_index];
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)) {
switch (command) {
......@@ -107,30 +106,16 @@ parse_error::ParseError GAPIDecoder::DoCommand(
return parse_error::kParseInvalidArguments;
}
}
return DoCommonCommand(command, arg_count, cmd_data);
return parse_error::kParseUnknownCommand;
}
void *GAPIDecoder::GetAddressAndCheckSize(unsigned int shm_id,
unsigned int offset,
unsigned int size) {
void * shm_addr = engine_->GetSharedMemoryAddress(shm_id);
if (!shm_addr) return NULL;
size_t shm_size = engine_->GetSharedMemorySize(shm_id);
if (offset + size > shm_size) return NULL;
return static_cast<char *>(shm_addr) + offset;
}
parse_error::ParseError GAPIDecoder::HandleNoop(
uint32 arg_count,
const Noop& args) {
return parse_error::kParseNoError;
}
parse_error::ParseError GAPIDecoder::HandleSetToken(
uint32 arg_count,
const SetToken& args) {
engine_->set_token(args.token);
return parse_error::kParseNoError;
// Overridden from AsyncAPIInterface.
const char* GAPIDecoder::GetCommandName(unsigned int command_id) const {
if (command_id > kStartPoint && command_id < kNumCommands) {
return o3d::GetCommandName(static_cast<CommandId>(command_id));
}
return GetCommonCommandName(static_cast<cmd::CommandId>(command_id));
}
parse_error::ParseError GAPIDecoder::HandleBeginFrame(
......
......@@ -36,25 +36,22 @@
#define O3D_COMMAND_BUFFER_SERVICE_CROSS_GAPI_DECODER_H_
#include "core/cross/types.h"
#include "command_buffer/service/cross/cmd_parser.h"
#include "command_buffer/service/cross/common_decoder.h"
#include "command_buffer/common/cross/o3d_cmd_format.h"
namespace o3d {
namespace command_buffer {
class CommandBufferEngine;
namespace o3d {
class GAPIInterface;
// This class implements the AsyncAPIInterface interface, decoding GAPI
// commands and sending them to a GAPI interface.
class GAPIDecoder : public AsyncAPIInterface {
class GAPIDecoder : public CommonDecoder {
public:
typedef parse_error::ParseError ParseError;
explicit GAPIDecoder(GAPIInterface *gapi) : gapi_(gapi), engine_(NULL) {}
explicit GAPIDecoder(GAPIInterface *gapi) : gapi_(gapi) {}
virtual ~GAPIDecoder() {}
// Overridden from AsyncAPIInterface.
......@@ -62,24 +59,10 @@ class GAPIDecoder : public AsyncAPIInterface {
unsigned int arg_count,
const void* args);
// Sets the engine, to get shared memory buffers from, and to set the token
// to.
void set_engine(CommandBufferEngine *engine) { engine_ = engine; }
private:
// Gets the address of shared memory data, given a shared memory ID and an
// offset. Also checks that the size is consistent with the shared memory
// size.
// Parameters:
// shm_id: the id of the shared memory buffer.
// offset: the offset of the data in the shared memory buffer.
// size: the size of the data.
// Returns:
// NULL if shm_id isn't a valid shared memory buffer ID or if the size
// check fails. Return a pointer to the data otherwise.
void *GetAddressAndCheckSize(unsigned int shm_id,
unsigned int offset,
unsigned int size);
// Overridden from AsyncAPIInterface.
virtual const char* GetCommandName(unsigned int command_id) const;
private:
// Generate a member function prototype for each command in an automated and
// typesafe way.
#define O3D_COMMAND_BUFFER_CMD_OP(name) \
......@@ -92,7 +75,6 @@ class GAPIDecoder : public AsyncAPIInterface {
#undef O3D_COMMAND_BUFFER_CMD_OP
GAPIInterface *gapi_;
CommandBufferEngine *engine_;
};
} // namespace o3d
......
......@@ -44,11 +44,16 @@ namespace command_buffer {
namespace o3d {
GAPIGL::GAPIGL()
: cg_context_(NULL),
#ifdef OS_LINUX
: window_(NULL),
window_(NULL),
#endif
: anti_aliased_(false),
cg_context_(NULL),
#ifdef OS_WIN
hwnd_(NULL),
device_context_(NULL),
gl_context_(NULL),
#endif
anti_aliased_(false),
current_vertex_struct_(kInvalidResource),
validate_streams_(true),
max_vertices_(0),
......@@ -328,7 +333,6 @@ bool GAPIGL::InitGlew() {
// present.
if (!GLEW_VERSION_2_0) {
DLOG(ERROR) << "GL drivers do not have OpenGL 2.0 functionality.";
return false;
}
bool extensions_found = true;
......
......@@ -427,6 +427,8 @@ class GAPIGL : public GAPIInterface {
// programs, and updates parameters if needed.
bool ValidateEffect();
CGcontext cg_context_;
#if defined(OS_LINUX)
XWindowWrapper *window_;
#elif defined(OS_WIN)
......@@ -436,8 +438,6 @@ class GAPIGL : public GAPIInterface {
HGLRC gl_context_;
#endif
CGcontext cg_context_;
bool anti_aliased_;
ResourceId current_vertex_struct_;
bool validate_streams_;
......
......@@ -82,6 +82,10 @@ class AsyncAPIMock : public AsyncAPIInterface {
unsigned int arg_count,
const void* cmd_data));
const char* GetCommandName(unsigned int command_id) const {
return "";
};
// Sets the engine, to forward SetToken commands to it.
void set_engine(CommandBufferEngine *engine) { engine_ = engine; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment