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 "../client/cmd_buffer_helper.h" | 7 #include "../client/cmd_buffer_helper.h" |
8 #include "../common/command_buffer.h" | 8 #include "../common/command_buffer.h" |
9 | 9 |
10 namespace gpu { | 10 namespace gpu { |
(...skipping 27 matching lines...) Expand all Loading... | |
38 total_entry_count_ = num_ring_buffer_entries; | 38 total_entry_count_ = num_ring_buffer_entries; |
39 usable_entry_count_ = total_entry_count_ - kJumpEntries; | 39 usable_entry_count_ = total_entry_count_ - kJumpEntries; |
40 put_ = state.put_offset; | 40 put_ = state.put_offset; |
41 SynchronizeState(state); | 41 SynchronizeState(state); |
42 return true; | 42 return true; |
43 } | 43 } |
44 | 44 |
45 CommandBufferHelper::~CommandBufferHelper() { | 45 CommandBufferHelper::~CommandBufferHelper() { |
46 } | 46 } |
47 | 47 |
48 bool CommandBufferHelper::Flush() { | 48 bool CommandBufferHelper::FlushSync() { |
49 CommandBuffer::State state = command_buffer_->Flush(put_); | 49 CommandBuffer::State state = command_buffer_->FlushSync(put_); |
50 SynchronizeState(state); | 50 SynchronizeState(state); |
51 return state.error == error::kNoError; | 51 return state.error == error::kNoError; |
52 } | 52 } |
53 | 53 |
54 void CommandBufferHelper::Flush() { | |
55 command_buffer_->Flush(put_); | |
56 } | |
57 | |
54 // Calls Flush() and then waits until the buffer is empty. Break early if the | 58 // Calls Flush() and then waits until the buffer is empty. Break early if the |
55 // error is set. | 59 // error is set. |
56 bool CommandBufferHelper::Finish() { | 60 bool CommandBufferHelper::Finish() { |
57 do { | 61 do { |
58 // Do not loop forever if the flush fails, meaning the command buffer reader | 62 // Do not loop forever if the flush fails, meaning the command buffer reader |
59 // has shutdown. | 63 // has shutdown. |
60 if (!Flush()) | 64 if (!FlushSync()) |
61 return false; | 65 return false; |
62 } while (put_ != get_); | 66 } while (put_ != get_); |
63 | 67 |
64 return true; | 68 return true; |
65 } | 69 } |
66 | 70 |
67 // Inserts a new token into the command stream. It uses an increasing value | 71 // Inserts a new token into the command stream. It uses an increasing value |
68 // scheme so that we don't lose tokens (a token has passed if the current token | 72 // scheme so that we don't lose tokens (a token has passed if the current token |
69 // value is higher than that token). Calls Finish() if the token value wraps, | 73 // value is higher than that token). Calls Finish() if the token value wraps, |
70 // which will be rare. | 74 // which will be rare. |
(...skipping 20 matching lines...) Expand all Loading... | |
91 if (last_token_read_ >= token) return; // fast path. | 95 if (last_token_read_ >= token) return; // fast path. |
92 if (token > token_) return; // we wrapped | 96 if (token > token_) return; // we wrapped |
93 Flush(); | 97 Flush(); |
94 while (last_token_read_ < token) { | 98 while (last_token_read_ < token) { |
95 if (get_ == put_) { | 99 if (get_ == put_) { |
96 GPU_LOG(FATAL) << "Empty command buffer while waiting on a token."; | 100 GPU_LOG(FATAL) << "Empty command buffer while waiting on a token."; |
97 return; | 101 return; |
98 } | 102 } |
99 // Do not loop forever if the flush fails, meaning the command buffer reader | 103 // Do not loop forever if the flush fails, meaning the command buffer reader |
100 // has shutdown. | 104 // has shutdown. |
101 if (!Flush()) | 105 if (!FlushSync()) |
102 return; | 106 return; |
103 } | 107 } |
104 } | 108 } |
105 | 109 |
106 // Waits for available entries, basically waiting until get >= put + count + 1. | 110 // Waits for available entries, basically waiting until get >= put + count + 1. |
107 // It actually waits for contiguous entries, so it may need to wrap the buffer | 111 // It actually waits for contiguous entries, so it may need to wrap the buffer |
108 // around, adding a jump. Thus this function may change the value of put_. The | 112 // around, adding a jump. Thus this function may change the value of put_. The |
109 // function will return early if an error occurs, in which case the available | 113 // function will return early if an error occurs, in which case the available |
110 // space may not be available. | 114 // space may not be available. |
111 void CommandBufferHelper::WaitForAvailableEntries(int32 count) { | 115 void CommandBufferHelper::WaitForAvailableEntries(int32 count) { |
112 GPU_CHECK(count < usable_entry_count_); | 116 GPU_CHECK(count < usable_entry_count_); |
apatrick
2011/01/14 18:31:34
I was thinking about putting an async flush in her
Antoine Labour
2011/01/14 21:35:33
Done. (added at the end of the function)
| |
113 if (put_ + count > usable_entry_count_) { | 117 if (put_ + count > usable_entry_count_) { |
114 // There's not enough room between the current put and the end of the | 118 // There's not enough room between the current put and the end of the |
115 // buffer, so we need to wrap. We will add a jump back to the start, but we | 119 // buffer, so we need to wrap. We will add a jump back to the start, but we |
116 // need to make sure get wraps first, actually that get is 1 or more (since | 120 // need to make sure get wraps first, actually that get is 1 or more (since |
117 // put will wrap to 0 after we add the jump). | 121 // put will wrap to 0 after we add the jump). |
118 GPU_DCHECK_LE(1, put_); | 122 GPU_DCHECK_LE(1, put_); |
119 Flush(); | 123 Flush(); |
apatrick
2011/01/14 18:31:34
Won't this async flush likely be immediately follo
Antoine Labour
2011/01/14 21:35:33
Done. You're right we don't need to do it, and it
| |
120 while (get_ > put_ || get_ == 0) { | 124 while (get_ > put_ || get_ == 0) { |
121 // Do not loop forever if the flush fails, meaning the command buffer | 125 // Do not loop forever if the flush fails, meaning the command buffer |
122 // reader has shutdown. | 126 // reader has shutdown. |
123 if (!Flush()) | 127 if (!FlushSync()) |
124 return; | 128 return; |
125 } | 129 } |
126 // Insert a jump back to the beginning. | 130 // Insert a jump back to the beginning. |
127 cmd::Jump::Set(&entries_[put_], 0); | 131 cmd::Jump::Set(&entries_[put_], 0); |
128 put_ = 0; | 132 put_ = 0; |
129 } | 133 } |
130 // If we have enough room, return immediatly. | 134 // If we have enough room, return immediatly. |
131 if (count <= AvailableEntries()) return; | 135 if (count <= AvailableEntries()) return; |
132 // Otherwise flush, and wait until we do have enough room. | 136 // Otherwise flush, and wait until we do have enough room. |
133 Flush(); | 137 Flush(); |
apatrick
2011/01/14 18:31:34
Same here. And some other places in this file.
Antoine Labour
2011/01/14 21:35:33
Done.
| |
134 while (AvailableEntries() < count) { | 138 while (AvailableEntries() < count) { |
135 // Do not loop forever if the flush fails, meaning the command buffer reader | 139 // Do not loop forever if the flush fails, meaning the command buffer reader |
136 // has shutdown. | 140 // has shutdown. |
137 if (!Flush()) | 141 if (!FlushSync()) |
138 return; | 142 return; |
139 } | 143 } |
140 } | 144 } |
141 | 145 |
142 CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) { | 146 CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) { |
143 WaitForAvailableEntries(entries); | 147 WaitForAvailableEntries(entries); |
144 CommandBufferEntry* space = &entries_[put_]; | 148 CommandBufferEntry* space = &entries_[put_]; |
145 put_ += entries; | 149 put_ += entries; |
146 GPU_DCHECK_LE(put_, usable_entry_count_); | 150 GPU_DCHECK_LE(put_, usable_entry_count_); |
147 if (put_ == usable_entry_count_) { | 151 if (put_ == usable_entry_count_) { |
148 cmd::Jump::Set(&entries_[put_], 0); | 152 cmd::Jump::Set(&entries_[put_], 0); |
149 put_ = 0; | 153 put_ = 0; |
150 } | 154 } |
151 return space; | 155 return space; |
152 } | 156 } |
153 | 157 |
154 error::Error CommandBufferHelper::GetError() { | 158 error::Error CommandBufferHelper::GetError() { |
155 CommandBuffer::State state = command_buffer_->GetState(); | 159 CommandBuffer::State state = command_buffer_->GetState(); |
156 SynchronizeState(state); | 160 SynchronizeState(state); |
157 return static_cast<error::Error>(state.error); | 161 return static_cast<error::Error>(state.error); |
158 } | 162 } |
159 | 163 |
160 void CommandBufferHelper::SynchronizeState(CommandBuffer::State state) { | 164 void CommandBufferHelper::SynchronizeState(CommandBuffer::State state) { |
161 get_ = state.get_offset; | 165 get_ = state.get_offset; |
162 last_token_read_ = state.token; | 166 last_token_read_ = state.token; |
163 } | 167 } |
164 | 168 |
165 } // namespace gpu | 169 } // namespace gpu |
OLD | NEW |