| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 // This file contains the implementation of the command buffer helper class. | 5 // This file contains the implementation of the command buffer helper class. |
| 6 | 6 |
| 7 #include "gpu/command_buffer/client/cmd_buffer_helper.h" | 7 #include "gpu/command_buffer/client/cmd_buffer_helper.h" |
| 8 #include "gpu/command_buffer/common/command_buffer.h" | 8 #include "gpu/command_buffer/common/command_buffer.h" |
| 9 | 9 |
| 10 namespace gpu { | 10 namespace gpu { |
| 11 | 11 |
| 12 CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer) | 12 CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer) |
| 13 : command_buffer_(command_buffer), | 13 : command_buffer_(command_buffer), |
| 14 entries_(NULL), | 14 entries_(NULL), |
| 15 entry_count_(0), | 15 entry_count_(0), |
| 16 token_(0), | 16 token_(0), |
| 17 last_token_read_(-1), | 17 last_token_read_(-1), |
| 18 get_(0), | 18 get_(0), |
| 19 put_(0) { | 19 put_(0) { |
| 20 } | 20 } |
| 21 | 21 |
| 22 bool CommandBufferHelper::Initialize() { | 22 bool CommandBufferHelper::Initialize() { |
| 23 ring_buffer_ = command_buffer_->GetRingBuffer(); | 23 ring_buffer_ = command_buffer_->GetRingBuffer(); |
| 24 if (!ring_buffer_.ptr) | 24 if (!ring_buffer_.ptr) |
| 25 return false; | 25 return false; |
| 26 | 26 |
| 27 CommandBuffer::State state = command_buffer_->GetState(); |
| 27 entries_ = static_cast<CommandBufferEntry*>(ring_buffer_.ptr); | 28 entries_ = static_cast<CommandBufferEntry*>(ring_buffer_.ptr); |
| 28 entry_count_ = command_buffer_->GetSize(); | 29 entry_count_ = state.size; |
| 29 get_ = command_buffer_->GetGetOffset(); | 30 put_ = state.put_offset; |
| 30 put_ = command_buffer_->GetPutOffset(); | 31 SynchronizeState(state); |
| 31 last_token_read_ = command_buffer_->GetToken(); | |
| 32 | |
| 33 return true; | 32 return true; |
| 34 } | 33 } |
| 35 | 34 |
| 36 CommandBufferHelper::~CommandBufferHelper() { | 35 CommandBufferHelper::~CommandBufferHelper() { |
| 37 } | 36 } |
| 38 | 37 |
| 39 bool CommandBufferHelper::Flush() { | 38 bool CommandBufferHelper::Flush() { |
| 40 get_ = command_buffer_->SyncOffsets(put_); | 39 CommandBuffer::State state = command_buffer_->Flush(put_); |
| 41 return !command_buffer_->GetErrorStatus(); | 40 SynchronizeState(state); |
| 41 return state.error == parse_error::kParseNoError; |
| 42 } | 42 } |
| 43 | 43 |
| 44 // Calls Flush() and then waits until the buffer is empty. Break early if the | 44 // Calls Flush() and then waits until the buffer is empty. Break early if the |
| 45 // error is set. | 45 // error is set. |
| 46 bool CommandBufferHelper::Finish() { | 46 bool CommandBufferHelper::Finish() { |
| 47 do { | 47 do { |
| 48 // Do not loop forever if the flush fails, meaning the command buffer reader | 48 // Do not loop forever if the flush fails, meaning the command buffer reader |
| 49 // has shutdown). | 49 // has shutdown. |
| 50 if (!Flush()) | 50 if (!Flush()) |
| 51 return false; | 51 return false; |
| 52 } while (put_ != get_); | 52 } while (put_ != get_); |
| 53 | 53 |
| 54 return true; | 54 return true; |
| 55 } | 55 } |
| 56 | 56 |
| 57 // Inserts a new token into the command stream. It uses an increasing value | 57 // Inserts a new token into the command stream. It uses an increasing value |
| 58 // scheme so that we don't lose tokens (a token has passed if the current token | 58 // scheme so that we don't lose tokens (a token has passed if the current token |
| 59 // value is higher than that token). Calls Finish() if the token value wraps, | 59 // value is higher than that token). Calls Finish() if the token value wraps, |
| 60 // which will be rare. | 60 // which will be rare. |
| 61 int32 CommandBufferHelper::InsertToken() { | 61 int32 CommandBufferHelper::InsertToken() { |
| 62 // Increment token as 31-bit integer. Negative values are used to signal an | 62 // Increment token as 31-bit integer. Negative values are used to signal an |
| 63 // error. | 63 // error. |
| 64 token_ = (token_ + 1) & 0x7FFFFFFF; | 64 token_ = (token_ + 1) & 0x7FFFFFFF; |
| 65 CommandBufferEntry args; | 65 CommandBufferEntry args; |
| 66 args.value_uint32 = token_; | 66 args.value_uint32 = token_; |
| 67 const uint32 kSetToken = 1; // TODO(gman): add a common set of commands. | 67 const uint32 kSetToken = 1; // TODO(gman): add a common set of commands. |
| 68 AddCommand(kSetToken, 1, &args); | 68 AddCommand(kSetToken, 1, &args); |
| 69 if (token_ == 0) { | 69 if (token_ == 0) { |
| 70 // we wrapped | 70 // we wrapped |
| 71 Finish(); | 71 Finish(); |
| 72 last_token_read_ = command_buffer_->GetToken(); | |
| 73 DCHECK_EQ(token_, last_token_read_); | 72 DCHECK_EQ(token_, last_token_read_); |
| 74 } | 73 } |
| 75 return token_; | 74 return token_; |
| 76 } | 75 } |
| 77 | 76 |
| 78 // Waits until the current token value is greater or equal to the value passed | 77 // Waits until the current token value is greater or equal to the value passed |
| 79 // in argument. | 78 // in argument. |
| 80 void CommandBufferHelper::WaitForToken(int32 token) { | 79 void CommandBufferHelper::WaitForToken(int32 token) { |
| 81 // Return immediately if corresponding InsertToken failed. | 80 // Return immediately if corresponding InsertToken failed. |
| 82 if (token < 0) | 81 if (token < 0) |
| 83 return; | 82 return; |
| 84 if (last_token_read_ >= token) return; // fast path. | 83 if (last_token_read_ >= token) return; // fast path. |
| 85 if (token > token_) return; // we wrapped | 84 if (token > token_) return; // we wrapped |
| 86 Flush(); | 85 Flush(); |
| 87 last_token_read_ = command_buffer_->GetToken(); | |
| 88 while (last_token_read_ < token) { | 86 while (last_token_read_ < token) { |
| 89 if (get_ == put_) { | 87 if (get_ == put_) { |
| 90 LOG(FATAL) << "Empty command buffer while waiting on a token."; | 88 LOG(FATAL) << "Empty command buffer while waiting on a token."; |
| 91 return; | 89 return; |
| 92 } | 90 } |
| 93 // Do not loop forever if the flush fails, meaning the command buffer reader | 91 // Do not loop forever if the flush fails, meaning the command buffer reader |
| 94 // has shutdown. | 92 // has shutdown. |
| 95 if (!Flush()) | 93 if (!Flush()) |
| 96 return; | 94 return; |
| 97 last_token_read_ = command_buffer_->GetToken(); | |
| 98 } | 95 } |
| 99 } | 96 } |
| 100 | 97 |
| 101 // Waits for available entries, basically waiting until get >= put + count + 1. | 98 // Waits for available entries, basically waiting until get >= put + count + 1. |
| 102 // It actually waits for contiguous entries, so it may need to wrap the buffer | 99 // It actually waits for contiguous entries, so it may need to wrap the buffer |
| 103 // around, adding noops. Thus this function may change the value of put_. | 100 // around, adding noops. Thus this function may change the value of put_. |
| 104 // The function will return early if an error occurs, in which case the | 101 // The function will return early if an error occurs, in which case the |
| 105 // available space may not be available. | 102 // available space may not be available. |
| 106 void CommandBufferHelper::WaitForAvailableEntries(int32 count) { | 103 void CommandBufferHelper::WaitForAvailableEntries(int32 count) { |
| 107 CHECK(count < entry_count_); | 104 CHECK(count < entry_count_); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 } | 139 } |
| 143 } | 140 } |
| 144 | 141 |
| 145 CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) { | 142 CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) { |
| 146 WaitForAvailableEntries(entries); | 143 WaitForAvailableEntries(entries); |
| 147 CommandBufferEntry* space = &entries_[put_]; | 144 CommandBufferEntry* space = &entries_[put_]; |
| 148 put_ += entries; | 145 put_ += entries; |
| 149 return space; | 146 return space; |
| 150 } | 147 } |
| 151 | 148 |
| 152 parse_error::ParseError CommandBufferHelper::GetParseError() { | 149 parse_error::ParseError CommandBufferHelper::GetError() { |
| 153 int32 parse_error = command_buffer_->ResetParseError(); | 150 CommandBuffer::State state = command_buffer_->GetState(); |
| 154 return static_cast<parse_error::ParseError>(parse_error); | 151 SynchronizeState(state); |
| 152 return static_cast<parse_error::ParseError>(state.error); |
| 153 } |
| 154 |
| 155 void CommandBufferHelper::SynchronizeState(CommandBuffer::State state) { |
| 156 get_ = state.get_offset; |
| 157 last_token_read_ = state.token; |
| 155 } | 158 } |
| 156 | 159 |
| 157 } // namespace gpu | 160 } // namespace gpu |
| OLD | NEW |