| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2009, Google Inc. | 2 * Copyright 2009, Google Inc. |
| 3 * All rights reserved. | 3 * All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 29 matching lines...) Expand all Loading... |
| 40 | 40 |
| 41 // Creates a RPC implementation using 'this' as the handler, and a RPC server | 41 // Creates a RPC implementation using 'this' as the handler, and a RPC server |
| 42 // for it. | 42 // for it. |
| 43 CommandBufferEngine::CommandBufferEngine(AsyncAPIInterface *handler) | 43 CommandBufferEngine::CommandBufferEngine(AsyncAPIInterface *handler) |
| 44 : buffer_rpc_impl_(), | 44 : buffer_rpc_impl_(), |
| 45 process_interface_(NULL), | 45 process_interface_(NULL), |
| 46 parser_(), | 46 parser_(), |
| 47 handler_(handler), | 47 handler_(handler), |
| 48 client_rpc_(NULL), | 48 client_rpc_(NULL), |
| 49 token_(0), | 49 token_(0), |
| 50 status_(NOT_CONNECTED), | 50 status_(kNotConnected), |
| 51 signal_change_(false), | 51 signal_change_(false), |
| 52 signal_rpc_message_id_(0), | 52 signal_rpc_message_id_(0), |
| 53 parse_error_(PARSE_NO_ERROR) { | 53 parse_error_(kParseNoError) { |
| 54 buffer_rpc_impl_.reset(new BufferRPCImpl(this)); | 54 buffer_rpc_impl_.reset(new BufferRPCImpl(this)); |
| 55 } | 55 } |
| 56 | 56 |
| 57 CommandBufferEngine::~CommandBufferEngine() {} | 57 CommandBufferEngine::~CommandBufferEngine() {} |
| 58 | 58 |
| 59 // Inits the connection. Registers the client RPC service. | 59 // Inits the connection. Registers the client RPC service. |
| 60 void CommandBufferEngine::InitConnection() { | 60 void CommandBufferEngine::InitConnection() { |
| 61 status_ = NO_BUFFER; | 61 status_ = kNoBuffer; |
| 62 } | 62 } |
| 63 | 63 |
| 64 // Closes the connection. Executes all remaining commands. | 64 // Closes the connection. Executes all remaining commands. |
| 65 void CommandBufferEngine::CloseConnection() { | 65 void CommandBufferEngine::CloseConnection() { |
| 66 FinishParsing(); | 66 FinishParsing(); |
| 67 status_ = NOT_CONNECTED; | 67 status_ = kNotConnected; |
| 68 parser_.reset(NULL); | 68 parser_.reset(NULL); |
| 69 } | 69 } |
| 70 | 70 |
| 71 // Adds the shared memory buffer somewhere into the list, return the index in | 71 // Adds the shared memory buffer somewhere into the list, return the index in |
| 72 // the list as the handle. Either find a hole in the list, or add it at the | 72 // the list as the handle. Either find a hole in the list, or add it at the |
| 73 // end. We don't want to invalidate exiting indices. | 73 // end. We don't want to invalidate exiting indices. |
| 74 unsigned int CommandBufferEngine::RegisterSharedMemory( | 74 unsigned int CommandBufferEngine::RegisterSharedMemory( |
| 75 RPCShmHandle handle, | 75 RPCShmHandle handle, |
| 76 size_t size) { | 76 size_t size) { |
| 77 void *address = MapShm(handle, size); | 77 void *address = MapShm(handle, size); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 106 void CommandBufferEngine::SetCommandBuffer(unsigned int shm_id, | 106 void CommandBufferEngine::SetCommandBuffer(unsigned int shm_id, |
| 107 ptrdiff_t offset, | 107 ptrdiff_t offset, |
| 108 size_t size, | 108 size_t size, |
| 109 CommandBufferOffset start_get) { | 109 CommandBufferOffset start_get) { |
| 110 if ((shm_id >= shared_memory_buffers_.size()) || | 110 if ((shm_id >= shared_memory_buffers_.size()) || |
| 111 !shared_memory_buffers_[shm_id].size) { | 111 !shared_memory_buffers_[shm_id].size) { |
| 112 LOG(ERROR) << "Trying to set the command buffer from a non-registered " | 112 LOG(ERROR) << "Trying to set the command buffer from a non-registered " |
| 113 << "shared memory"; | 113 << "shared memory"; |
| 114 return; | 114 return; |
| 115 } | 115 } |
| 116 if (status_ == NOT_CONNECTED) return; | 116 if (status_ == kNotConnected) return; |
| 117 FinishParsing(); | 117 FinishParsing(); |
| 118 parser_.reset(new CommandParser(shared_memory_buffers_[shm_id].address, | 118 parser_.reset(new CommandParser(shared_memory_buffers_[shm_id].address, |
| 119 shared_memory_buffers_[shm_id].size, offset, | 119 shared_memory_buffers_[shm_id].size, offset, |
| 120 size, start_get, handler_)); | 120 size, start_get, handler_)); |
| 121 status_ = PARSING; | 121 status_ = kParsing; |
| 122 parse_error_ = PARSE_NO_ERROR; | 122 parse_error_ = kParseNoError; |
| 123 } | 123 } |
| 124 | 124 |
| 125 // Changes the put value. | 125 // Changes the put value. |
| 126 void CommandBufferEngine::Put(CommandBufferOffset offset) { | 126 void CommandBufferEngine::Put(CommandBufferOffset offset) { |
| 127 if (parser_.get()) { | 127 if (parser_.get()) { |
| 128 parser_->set_put(offset); | 128 parser_->set_put(offset); |
| 129 } | 129 } |
| 130 } | 130 } |
| 131 | 131 |
| 132 // Retrieves the get value. This returns -1 if there is no current parser. | 132 // Retrieves the get value. This returns -1 if there is no current parser. |
| 133 CommandBufferOffset CommandBufferEngine::Get() { | 133 CommandBufferOffset CommandBufferEngine::Get() { |
| 134 if (parser_.get()) { | 134 if (parser_.get()) { |
| 135 return parser_->get(); | 135 return parser_->get(); |
| 136 } else { | 136 } else { |
| 137 return -1; | 137 return -1; |
| 138 } | 138 } |
| 139 } | 139 } |
| 140 | 140 |
| 141 // Retrieves the current token value. | 141 // Retrieves the current token value. |
| 142 unsigned int CommandBufferEngine::GetToken() { | 142 unsigned int CommandBufferEngine::GetToken() { |
| 143 return token_; | 143 return token_; |
| 144 } | 144 } |
| 145 | 145 |
| 146 // Executes commands until get is different from the value passed in. It will | 146 // Executes commands until get is different from the value passed in. It will |
| 147 // return immediately if the get value is already different, or if the engine | 147 // return immediately if the get value is already different, or if the engine |
| 148 // is not in the PARSING status, or if the buffer is empty. It will return -1 | 148 // is not in the kParsing status, or if the buffer is empty. It will return -1 |
| 149 // if there is no current buffer. | 149 // if there is no current buffer. |
| 150 CommandBufferOffset CommandBufferEngine::WaitGetChanges( | 150 CommandBufferOffset CommandBufferEngine::WaitGetChanges( |
| 151 CommandBufferOffset current_value) { | 151 CommandBufferOffset current_value) { |
| 152 if (parser_.get()) { | 152 if (parser_.get()) { |
| 153 while (status_ == PARSING && | 153 while (status_ == kParsing && |
| 154 parser_->get() == current_value && | 154 parser_->get() == current_value && |
| 155 !parser_->IsEmpty()) { | 155 !parser_->IsEmpty()) { |
| 156 ProcessOneCommand(); | 156 ProcessOneCommand(); |
| 157 } | 157 } |
| 158 return parser_->get(); | 158 return parser_->get(); |
| 159 } else { | 159 } else { |
| 160 return -1; | 160 return -1; |
| 161 } | 161 } |
| 162 } | 162 } |
| 163 | 163 |
| 164 // Signals the client when get gets different from the value passed in. If get | 164 // Signals the client when get gets different from the value passed in. If get |
| 165 // is already different, or if the engine is not in the PARSING status, that | 165 // is already different, or if the engine is not in the kParsing status, that |
| 166 // will happen immediately, otherwise it will happen when commands get | 166 // will happen immediately, otherwise it will happen when commands get |
| 167 // executed, moving the get pointer. | 167 // executed, moving the get pointer. |
| 168 void CommandBufferEngine::SignalGetChanges(CommandBufferOffset current_value, | 168 void CommandBufferEngine::SignalGetChanges(CommandBufferOffset current_value, |
| 169 int rpc_message_id) { | 169 int rpc_message_id) { |
| 170 if (status_ != PARSING || parser_->get() != current_value) { | 170 if (status_ != kParsing || parser_->get() != current_value) { |
| 171 DoSignalChangedGet(rpc_message_id); | 171 DoSignalChangedGet(rpc_message_id); |
| 172 } else { | 172 } else { |
| 173 signal_change_ = true; | 173 signal_change_ = true; |
| 174 signal_rpc_message_id_ = rpc_message_id; | 174 signal_rpc_message_id_ = rpc_message_id; |
| 175 } | 175 } |
| 176 } | 176 } |
| 177 | 177 |
| 178 // Gets the memory address from the list entry. | 178 // Gets the memory address from the list entry. |
| 179 void *CommandBufferEngine::GetSharedMemoryAddress(unsigned int shm_id) { | 179 void *CommandBufferEngine::GetSharedMemoryAddress(unsigned int shm_id) { |
| 180 if ((shm_id >= shared_memory_buffers_.size()) || | 180 if ((shm_id >= shared_memory_buffers_.size()) || |
| (...skipping 12 matching lines...) Expand all Loading... |
| 193 return 0; | 193 return 0; |
| 194 } | 194 } |
| 195 return shared_memory_buffers_[shm_id].size; | 195 return shared_memory_buffers_[shm_id].size; |
| 196 } | 196 } |
| 197 | 197 |
| 198 // Gets the status. | 198 // Gets the status. |
| 199 BufferSyncInterface::ParserStatus CommandBufferEngine::GetStatus() { | 199 BufferSyncInterface::ParserStatus CommandBufferEngine::GetStatus() { |
| 200 return status_; | 200 return status_; |
| 201 } | 201 } |
| 202 | 202 |
| 203 // Gets the current parse error, reset it to PARSE_NO_ERROR. | 203 // Gets the current parse error, reset it to kParseNoError. |
| 204 BufferSyncInterface::ParseError CommandBufferEngine::GetParseError() { | 204 BufferSyncInterface::ParseError CommandBufferEngine::GetParseError() { |
| 205 ParseError error = parse_error_; | 205 ParseError error = parse_error_; |
| 206 parse_error_ = PARSE_NO_ERROR; | 206 parse_error_ = kParseNoError; |
| 207 return error; | 207 return error; |
| 208 } | 208 } |
| 209 | 209 |
| 210 // Finishes parsing, executing all the commands until the buffer is empty, or a | 210 // Finishes parsing, executing all the commands until the buffer is empty, or a |
| 211 // parsing error occurs. | 211 // parsing error occurs. |
| 212 void CommandBufferEngine::FinishParsing() { | 212 void CommandBufferEngine::FinishParsing() { |
| 213 // terminates current parsing, that is, execute all the commands | 213 // terminates current parsing, that is, execute all the commands |
| 214 // NOTE: status_ == PARSING implies parser_ != NULL | 214 // NOTE: status_ == kParsing implies parser_ != NULL |
| 215 while (status_ == PARSING && !parser_->IsEmpty()) { | 215 while (status_ == kParsing && !parser_->IsEmpty()) { |
| 216 ProcessOneCommand(); | 216 ProcessOneCommand(); |
| 217 } | 217 } |
| 218 } | 218 } |
| 219 | 219 |
| 220 // Processes one command from the command buffer. This must only be called when | 220 // Processes one command from the command buffer. This must only be called when |
| 221 // in the PARSING status. | 221 // in the kParsing status. |
| 222 // This will update the status_ and the parse_error_ fields if an error occurs. | 222 // This will update the status_ and the parse_error_ fields if an error occurs. |
| 223 void CommandBufferEngine::ProcessOneCommand() { | 223 void CommandBufferEngine::ProcessOneCommand() { |
| 224 DCHECK_EQ(PARSING, status_); | 224 DCHECK_EQ(kParsing, status_); |
| 225 DCHECK(parser_.get()); | 225 DCHECK(parser_.get()); |
| 226 ParseError result = parser_->ProcessCommand(); | 226 ParseError result = parser_->ProcessCommand(); |
| 227 switch (result) { | 227 switch (result) { |
| 228 case PARSE_NO_ERROR: | 228 case kParseNoError: |
| 229 break; | 229 break; |
| 230 case PARSE_OUT_OF_BOUNDS: | 230 case kParseOutOfBounds: |
| 231 case PARSE_INVALID_SIZE: | 231 case kParseInvalidSize: |
| 232 status_ = PARSE_ERROR; | 232 status_ = kParseError; |
| 233 // Always override the error, to properly signal the stopping condition. | 233 // Always override the error, to properly signal the stopping condition. |
| 234 parse_error_ = result; | 234 parse_error_ = result; |
| 235 break; | 235 break; |
| 236 case PARSE_INVALID_ARGUMENTS: | 236 case kParseInvalidArguments: |
| 237 case PARSE_UNKNOWN_COMMAND: | 237 case kParseUnknownCommand: |
| 238 // Only set the error if it is not set already. | 238 // Only set the error if it is not set already. |
| 239 if (parse_error_ == PARSE_NO_ERROR) { | 239 if (parse_error_ == kParseNoError) { |
| 240 parse_error_ = result; | 240 parse_error_ = result; |
| 241 } | 241 } |
| 242 break; | 242 break; |
| 243 } | 243 } |
| 244 // get has changed, signal the client if needed. | 244 // get has changed, signal the client if needed. |
| 245 if (signal_change_) { | 245 if (signal_change_) { |
| 246 DoSignalChangedGet(signal_rpc_message_id_); | 246 DoSignalChangedGet(signal_rpc_message_id_); |
| 247 signal_change_ = false; | 247 signal_change_ = false; |
| 248 } | 248 } |
| 249 } | 249 } |
| 250 | 250 |
| 251 // Executes the main loop. While there are commands in the buffer, processes | 251 // Executes the main loop. While there are commands in the buffer, processes |
| 252 // them one by one, checking for RPC messages between each of them (executing | 252 // them one by one, checking for RPC messages between each of them (executing |
| 253 // all of them). If the buffer is empty, block until a RPC message comes. | 253 // all of them). If the buffer is empty, block until a RPC message comes. |
| 254 void CommandBufferEngine::DoMainLoop() { | 254 void CommandBufferEngine::DoMainLoop() { |
| 255 while (DoWork()) { } | 255 while (DoWork()) { } |
| 256 // Clean up if needed: execute all pending commands, then close the | 256 // Clean up if needed: execute all pending commands, then close the |
| 257 // connection. | 257 // connection. |
| 258 if (status_ != NOT_CONNECTED) CloseConnection(); | 258 if (status_ != kNotConnected) CloseConnection(); |
| 259 } | 259 } |
| 260 | 260 |
| 261 bool CommandBufferEngine::HasWork() { | 261 bool CommandBufferEngine::HasWork() { |
| 262 return (status_ == PARSING && !parser_->IsEmpty()) || | 262 return (status_ == kParsing && !parser_->IsEmpty()) || |
| 263 process_interface_->HasMessage(); | 263 process_interface_->HasMessage(); |
| 264 } | 264 } |
| 265 | 265 |
| 266 bool CommandBufferEngine::DoWork() { | 266 bool CommandBufferEngine::DoWork() { |
| 267 if (status_ == PARSING && !parser_->IsEmpty()) { | 267 if (status_ == kParsing && !parser_->IsEmpty()) { |
| 268 bool running = true; | 268 bool running = true; |
| 269 // process as many messages as available but do not block. | 269 // process as many messages as available but do not block. |
| 270 while (process_interface_->HasMessage()) { | 270 while (process_interface_->HasMessage()) { |
| 271 running = process_interface_->ProcessMessage(); | 271 running = process_interface_->ProcessMessage(); |
| 272 } | 272 } |
| 273 if (running) ProcessOneCommand(); | 273 if (running) ProcessOneCommand(); |
| 274 return running; | 274 return running; |
| 275 } else { | 275 } else { |
| 276 // call ProcessMessage, always blocking. We have nothing else to do. | 276 // call ProcessMessage, always blocking. We have nothing else to do. |
| 277 return process_interface_->ProcessMessage(); | 277 return process_interface_->ProcessMessage(); |
| 278 } | 278 } |
| 279 } | 279 } |
| 280 | 280 |
| 281 // Signals that get has changed, sending a RPC message back to the client. It | 281 // Signals that get has changed, sending a RPC message back to the client. It |
| 282 // will send -1 if there is no current buffer. | 282 // will send -1 if there is no current buffer. |
| 283 void CommandBufferEngine::DoSignalChangedGet(int rpc_message_id) { | 283 void CommandBufferEngine::DoSignalChangedGet(int rpc_message_id) { |
| 284 DCHECK(client_rpc_); | 284 DCHECK(client_rpc_); |
| 285 CommandBufferOffset get = parser_.get() ? parser_->get() : -1; | 285 CommandBufferOffset get = parser_.get() ? parser_->get() : -1; |
| 286 client_rpc_->SendCall(rpc_message_id, &get, sizeof(get), NULL, 0); | 286 client_rpc_->SendCall(rpc_message_id, &get, sizeof(get), NULL, 0); |
| 287 } | 287 } |
| 288 | 288 |
| 289 } // namespace command_buffer | 289 } // namespace command_buffer |
| 290 } // namespace o3d | 290 } // namespace o3d |
| OLD | NEW |