Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: gpu/command_buffer/service/common_decoder.cc

Issue 855033002: command_buffer: Table based command dispatch for Common commands (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gpu/command_buffer/service/common_decoder.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "gpu/command_buffer/service/common_decoder.h" 5 #include "gpu/command_buffer/service/common_decoder.h"
6 #include "gpu/command_buffer/service/cmd_buffer_engine.h" 6 #include "gpu/command_buffer/service/cmd_buffer_engine.h"
7 7
8 namespace gpu { 8 namespace gpu {
9 9
10 const CommonDecoder::CommandInfo CommonDecoder::command_info[] = {
11 #define COMMON_COMMAND_BUFFER_CMD_OP(name) \
12 { \
13 &CommonDecoder::Handle##name, cmd::name::kArgFlags, \
14 cmd::name::cmd_flags, \
15 sizeof(cmd::name) / sizeof(CommandBufferEntry) - 1, \
16 } \
17 , /* NOLINT */
18 COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
19 #undef COMMON_COMMAND_BUFFER_CMD_OP
20 };
21
22
10 CommonDecoder::Bucket::Bucket() : size_(0) {} 23 CommonDecoder::Bucket::Bucket() : size_(0) {}
11 24
12 CommonDecoder::Bucket::~Bucket() {} 25 CommonDecoder::Bucket::~Bucket() {}
13 26
14 void* CommonDecoder::Bucket::GetData(size_t offset, size_t size) const { 27 void* CommonDecoder::Bucket::GetData(size_t offset, size_t size) const {
15 if (OffsetSizeValid(offset, size)) { 28 if (OffsetSizeValid(offset, size)) {
16 return data_.get() + offset; 29 return data_.get() + offset;
17 } 30 }
18 return NULL; 31 return NULL;
19 } 32 }
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 const void* AddressAfterStruct(const T& pod) { 114 const void* AddressAfterStruct(const T& pod) {
102 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod); 115 return reinterpret_cast<const uint8*>(&pod) + sizeof(pod);
103 } 116 }
104 117
105 // Returns the address of the frst byte after the struct. 118 // Returns the address of the frst byte after the struct.
106 template <typename RETURN_TYPE, typename COMMAND_TYPE> 119 template <typename RETURN_TYPE, typename COMMAND_TYPE>
107 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod) { 120 RETURN_TYPE GetImmediateDataAs(const COMMAND_TYPE& pod) {
108 return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod))); 121 return static_cast<RETURN_TYPE>(const_cast<void*>(AddressAfterStruct(pod)));
109 } 122 }
110 123
111 // TODO(vmiura): Looks like this g_command_info is duplicated in
112 // common_decoder.cc
113 // and gles2_cmd_decoder.cc. Fix it!
114
115 // A struct to hold info about each command.
116 struct CommandInfo {
117 uint8 arg_flags; // How to handle the arguments for this command
118 uint8 cmd_flags; // How to handle this command
119 uint16 arg_count; // How many arguments are expected for this command.
120 };
121
122 // A table of CommandInfo for all the commands.
123 const CommandInfo g_command_info[] = {
124 #define COMMON_COMMAND_BUFFER_CMD_OP(name) { \
125 cmd::name::kArgFlags, \
126 cmd::name::cmd_flags, \
127 sizeof(cmd::name) / sizeof(CommandBufferEntry) - 1, }, /* NOLINT */
128
129 COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
130
131 #undef COMMON_COMMAND_BUFFER_CMD_OP
132 };
133
134 } // anonymous namespace. 124 } // anonymous namespace.
135 125
136 // Decode command with its arguments, and call the corresponding method. 126 // Decode command with its arguments, and call the corresponding method.
137 // Note: args is a pointer to the command buffer. As such, it could be changed 127 // Note: args is a pointer to the command buffer. As such, it could be changed
138 // by a (malicious) client at any time, so if validation has to happen, it 128 // by a (malicious) client at any time, so if validation has to happen, it
139 // should operate on a copy of them. 129 // should operate on a copy of them.
140 error::Error CommonDecoder::DoCommonCommand( 130 error::Error CommonDecoder::DoCommonCommand(
141 unsigned int command, 131 unsigned int command,
142 unsigned int arg_count, 132 unsigned int arg_count,
143 const void* cmd_data) { 133 const void* cmd_data) {
144 if (command < arraysize(g_command_info)) { 134 if (command < arraysize(command_info)) {
145 const CommandInfo& info = g_command_info[command]; 135 const CommandInfo& info = command_info[command];
146 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count); 136 unsigned int info_arg_count = static_cast<unsigned int>(info.arg_count);
147 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) || 137 if ((info.arg_flags == cmd::kFixed && arg_count == info_arg_count) ||
148 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) { 138 (info.arg_flags == cmd::kAtLeastN && arg_count >= info_arg_count)) {
149 uint32 immediate_data_size = 139 uint32 immediate_data_size =
150 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT 140 (arg_count - info_arg_count) * sizeof(CommandBufferEntry); // NOLINT
151 switch (command) { 141 return (this->*info.cmd_handler)(immediate_data_size, cmd_data);
152 #define COMMON_COMMAND_BUFFER_CMD_OP(name) \
153 case cmd::name::kCmdId: \
154 return Handle ## name( \
155 immediate_data_size, \
156 *static_cast<const cmd::name*>(cmd_data)); \
157
158 COMMON_COMMAND_BUFFER_CMDS(COMMON_COMMAND_BUFFER_CMD_OP)
159
160 #undef COMMON_COMMAND_BUFFER_CMD_OP
161 }
162 } else { 142 } else {
163 return error::kInvalidArguments; 143 return error::kInvalidArguments;
164 } 144 }
165 } 145 }
166 return error::kUnknownCommand; 146 return error::kUnknownCommand;
167 } 147 }
168 148
169 error::Error CommonDecoder::HandleNoop( 149 error::Error CommonDecoder::HandleNoop(
170 uint32 immediate_data_size, 150 uint32 immediate_data_size,
171 const cmd::Noop& args) { 151 const void* cmd_data) {
172 return error::kNoError; 152 return error::kNoError;
173 } 153 }
174 154
175 error::Error CommonDecoder::HandleSetToken( 155 error::Error CommonDecoder::HandleSetToken(
176 uint32 immediate_data_size, 156 uint32 immediate_data_size,
177 const cmd::SetToken& args) { 157 const void* cmd_data) {
158 const cmd::SetToken& args = *static_cast<const cmd::SetToken*>(cmd_data);
178 engine_->set_token(args.token); 159 engine_->set_token(args.token);
179 return error::kNoError; 160 return error::kNoError;
180 } 161 }
181 162
182 error::Error CommonDecoder::HandleSetBucketSize( 163 error::Error CommonDecoder::HandleSetBucketSize(
183 uint32 immediate_data_size, 164 uint32 immediate_data_size,
184 const cmd::SetBucketSize& args) { 165 const void* cmd_data) {
166 const cmd::SetBucketSize& args =
167 *static_cast<const cmd::SetBucketSize*>(cmd_data);
185 uint32 bucket_id = args.bucket_id; 168 uint32 bucket_id = args.bucket_id;
186 uint32 size = args.size; 169 uint32 size = args.size;
187 170
188 Bucket* bucket = CreateBucket(bucket_id); 171 Bucket* bucket = CreateBucket(bucket_id);
189 bucket->SetSize(size); 172 bucket->SetSize(size);
190 return error::kNoError; 173 return error::kNoError;
191 } 174 }
192 175
193 error::Error CommonDecoder::HandleSetBucketData( 176 error::Error CommonDecoder::HandleSetBucketData(
194 uint32 immediate_data_size, 177 uint32 immediate_data_size,
195 const cmd::SetBucketData& args) { 178 const void* cmd_data) {
179 const cmd::SetBucketData& args =
180 *static_cast<const cmd::SetBucketData*>(cmd_data);
196 uint32 bucket_id = args.bucket_id; 181 uint32 bucket_id = args.bucket_id;
197 uint32 offset = args.offset; 182 uint32 offset = args.offset;
198 uint32 size = args.size; 183 uint32 size = args.size;
199 const void* data = GetSharedMemoryAs<const void*>( 184 const void* data = GetSharedMemoryAs<const void*>(
200 args.shared_memory_id, args.shared_memory_offset, size); 185 args.shared_memory_id, args.shared_memory_offset, size);
201 if (!data) { 186 if (!data) {
202 return error::kInvalidArguments; 187 return error::kInvalidArguments;
203 } 188 }
204 Bucket* bucket = GetBucket(bucket_id); 189 Bucket* bucket = GetBucket(bucket_id);
205 if (!bucket) { 190 if (!bucket) {
206 return error::kInvalidArguments; 191 return error::kInvalidArguments;
207 } 192 }
208 if (!bucket->SetData(data, offset, size)) { 193 if (!bucket->SetData(data, offset, size)) {
209 return error::kInvalidArguments; 194 return error::kInvalidArguments;
210 } 195 }
211 196
212 return error::kNoError; 197 return error::kNoError;
213 } 198 }
214 199
215 error::Error CommonDecoder::HandleSetBucketDataImmediate( 200 error::Error CommonDecoder::HandleSetBucketDataImmediate(
216 uint32 immediate_data_size, 201 uint32 immediate_data_size,
217 const cmd::SetBucketDataImmediate& args) { 202 const void* cmd_data) {
203 const cmd::SetBucketDataImmediate& args =
204 *static_cast<const cmd::SetBucketDataImmediate*>(cmd_data);
218 const void* data = GetImmediateDataAs<const void*>(args); 205 const void* data = GetImmediateDataAs<const void*>(args);
219 uint32 bucket_id = args.bucket_id; 206 uint32 bucket_id = args.bucket_id;
220 uint32 offset = args.offset; 207 uint32 offset = args.offset;
221 uint32 size = args.size; 208 uint32 size = args.size;
222 if (size > immediate_data_size) { 209 if (size > immediate_data_size) {
223 return error::kInvalidArguments; 210 return error::kInvalidArguments;
224 } 211 }
225 Bucket* bucket = GetBucket(bucket_id); 212 Bucket* bucket = GetBucket(bucket_id);
226 if (!bucket) { 213 if (!bucket) {
227 return error::kInvalidArguments; 214 return error::kInvalidArguments;
228 } 215 }
229 if (!bucket->SetData(data, offset, size)) { 216 if (!bucket->SetData(data, offset, size)) {
230 return error::kInvalidArguments; 217 return error::kInvalidArguments;
231 } 218 }
232 return error::kNoError; 219 return error::kNoError;
233 } 220 }
234 221
235 error::Error CommonDecoder::HandleGetBucketStart( 222 error::Error CommonDecoder::HandleGetBucketStart(
236 uint32 immediate_data_size, 223 uint32 immediate_data_size,
237 const cmd::GetBucketStart& args) { 224 const void* cmd_data) {
225 const cmd::GetBucketStart& args =
226 *static_cast<const cmd::GetBucketStart*>(cmd_data);
238 uint32 bucket_id = args.bucket_id; 227 uint32 bucket_id = args.bucket_id;
239 uint32* result = GetSharedMemoryAs<uint32*>( 228 uint32* result = GetSharedMemoryAs<uint32*>(
240 args.result_memory_id, args.result_memory_offset, sizeof(*result)); 229 args.result_memory_id, args.result_memory_offset, sizeof(*result));
241 int32 data_memory_id = args.data_memory_id; 230 int32 data_memory_id = args.data_memory_id;
242 uint32 data_memory_offset = args.data_memory_offset; 231 uint32 data_memory_offset = args.data_memory_offset;
243 uint32 data_memory_size = args.data_memory_size; 232 uint32 data_memory_size = args.data_memory_size;
244 uint8* data = NULL; 233 uint8* data = NULL;
245 if (data_memory_size != 0 || data_memory_id != 0 || data_memory_offset != 0) { 234 if (data_memory_size != 0 || data_memory_id != 0 || data_memory_offset != 0) {
246 data = GetSharedMemoryAs<uint8*>( 235 data = GetSharedMemoryAs<uint8*>(
247 args.data_memory_id, args.data_memory_offset, args.data_memory_size); 236 args.data_memory_id, args.data_memory_offset, args.data_memory_size);
(...skipping 16 matching lines...) Expand all
264 *result = bucket_size; 253 *result = bucket_size;
265 if (data) { 254 if (data) {
266 uint32 size = std::min(data_memory_size, bucket_size); 255 uint32 size = std::min(data_memory_size, bucket_size);
267 memcpy(data, bucket->GetData(0, size), size); 256 memcpy(data, bucket->GetData(0, size), size);
268 } 257 }
269 return error::kNoError; 258 return error::kNoError;
270 } 259 }
271 260
272 error::Error CommonDecoder::HandleGetBucketData( 261 error::Error CommonDecoder::HandleGetBucketData(
273 uint32 immediate_data_size, 262 uint32 immediate_data_size,
274 const cmd::GetBucketData& args) { 263 const void* cmd_data) {
264 const cmd::GetBucketData& args =
265 *static_cast<const cmd::GetBucketData*>(cmd_data);
275 uint32 bucket_id = args.bucket_id; 266 uint32 bucket_id = args.bucket_id;
276 uint32 offset = args.offset; 267 uint32 offset = args.offset;
277 uint32 size = args.size; 268 uint32 size = args.size;
278 void* data = GetSharedMemoryAs<void*>( 269 void* data = GetSharedMemoryAs<void*>(
279 args.shared_memory_id, args.shared_memory_offset, size); 270 args.shared_memory_id, args.shared_memory_offset, size);
280 if (!data) { 271 if (!data) {
281 return error::kInvalidArguments; 272 return error::kInvalidArguments;
282 } 273 }
283 Bucket* bucket = GetBucket(bucket_id); 274 Bucket* bucket = GetBucket(bucket_id);
284 if (!bucket) { 275 if (!bucket) {
285 return error::kInvalidArguments; 276 return error::kInvalidArguments;
286 } 277 }
287 const void* src = bucket->GetData(offset, size); 278 const void* src = bucket->GetData(offset, size);
288 if (!src) { 279 if (!src) {
289 return error::kInvalidArguments; 280 return error::kInvalidArguments;
290 } 281 }
291 memcpy(data, src, size); 282 memcpy(data, src, size);
292 return error::kNoError; 283 return error::kNoError;
293 } 284 }
294 285
295 } // namespace gpu 286 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/common_decoder.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698