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

Side by Side Diff: gpu/command_buffer/client/cmd_buffer_helper.cc

Issue 7313032: Cooperatively round robin GPU command buffers. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 5 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 | Annotate | Revision Log
« no previous file with comments | « gpu/command_buffer/client/cmd_buffer_helper.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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 #include "../common/trace_event.h" 9 #include "../common/trace_event.h"
10 10
11 namespace gpu { 11 namespace gpu {
12 12
13 namespace {
14 const int kCommandsPerFlushCheck = 100;
15 const double kFlushDelay = 1.0 / (5.0 * 60.0);
16 }
17
13 CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer) 18 CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer)
14 : command_buffer_(command_buffer), 19 : command_buffer_(command_buffer),
15 entries_(NULL), 20 entries_(NULL),
16 total_entry_count_(0), 21 total_entry_count_(0),
17 usable_entry_count_(0), 22 usable_entry_count_(0),
18 token_(0), 23 token_(0),
19 last_token_read_(-1), 24 last_token_read_(-1),
20 get_(0), 25 get_(0),
21 put_(0), 26 put_(0),
22 last_put_sent_(0) { 27 last_put_sent_(0),
28 commands_issued_(0),
29 last_flush_time_(0) {
23 } 30 }
24 31
25 bool CommandBufferHelper::Initialize(int32 ring_buffer_size) { 32 bool CommandBufferHelper::Initialize(int32 ring_buffer_size) {
26 ring_buffer_ = command_buffer_->GetRingBuffer(); 33 ring_buffer_ = command_buffer_->GetRingBuffer();
27 if (!ring_buffer_.ptr) 34 if (!ring_buffer_.ptr)
28 return false; 35 return false;
29 36
30 CommandBuffer::State state = command_buffer_->GetState(); 37 CommandBuffer::State state = command_buffer_->GetState();
31 entries_ = static_cast<CommandBufferEntry*>(ring_buffer_.ptr); 38 entries_ = static_cast<CommandBufferEntry*>(ring_buffer_.ptr);
32 int32 num_ring_buffer_entries = ring_buffer_size / sizeof(CommandBufferEntry); 39 int32 num_ring_buffer_entries = ring_buffer_size / sizeof(CommandBufferEntry);
33 if (num_ring_buffer_entries > state.num_entries) { 40 if (num_ring_buffer_entries > state.num_entries) {
34 return false; 41 return false;
35 } 42 }
36 43
37 const int32 kJumpEntries = 44 const int32 kJumpEntries =
38 sizeof(cmd::Jump) / sizeof(*entries_); // NOLINT 45 sizeof(cmd::Jump) / sizeof(*entries_); // NOLINT
39 46
40 total_entry_count_ = num_ring_buffer_entries; 47 total_entry_count_ = num_ring_buffer_entries;
41 usable_entry_count_ = total_entry_count_ - kJumpEntries; 48 usable_entry_count_ = total_entry_count_ - kJumpEntries;
42 put_ = state.put_offset; 49 put_ = state.put_offset;
43 SynchronizeState(state); 50 SynchronizeState(state);
44 return true; 51 return true;
45 } 52 }
46 53
47 CommandBufferHelper::~CommandBufferHelper() { 54 CommandBufferHelper::~CommandBufferHelper() {
48 } 55 }
49 56
50 bool CommandBufferHelper::FlushSync() { 57 bool CommandBufferHelper::FlushSync() {
58 time(&last_flush_time_);
51 last_put_sent_ = put_; 59 last_put_sent_ = put_;
52 CommandBuffer::State state = command_buffer_->FlushSync(put_, get_); 60 CommandBuffer::State state = command_buffer_->FlushSync(put_, get_);
53 SynchronizeState(state); 61 SynchronizeState(state);
54 return state.error == error::kNoError; 62 return state.error == error::kNoError;
55 } 63 }
56 64
57 void CommandBufferHelper::Flush() { 65 void CommandBufferHelper::Flush() {
66 time(&last_flush_time_);
58 last_put_sent_ = put_; 67 last_put_sent_ = put_;
59 command_buffer_->Flush(put_); 68 command_buffer_->Flush(put_);
60 } 69 }
61 70
62 // Calls Flush() and then waits until the buffer is empty. Break early if the 71 // Calls Flush() and then waits until the buffer is empty. Break early if the
63 // error is set. 72 // error is set.
64 bool CommandBufferHelper::Finish() { 73 bool CommandBufferHelper::Finish() {
65 TRACE_EVENT0("gpu", "CommandBufferHelper::Finish"); 74 TRACE_EVENT0("gpu", "CommandBufferHelper::Finish");
66 do { 75 do {
67 // Do not loop forever if the flush fails, meaning the command buffer reader 76 // Do not loop forever if the flush fails, meaning the command buffer reader
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
145 } 154 }
146 if (AvailableEntries() < count) { 155 if (AvailableEntries() < count) {
147 TRACE_EVENT0("gpu", "CommandBufferHelper::WaitForAvailableEntries1"); 156 TRACE_EVENT0("gpu", "CommandBufferHelper::WaitForAvailableEntries1");
148 while (AvailableEntries() < count) { 157 while (AvailableEntries() < count) {
149 // Do not loop forever if the flush fails, meaning the command buffer 158 // Do not loop forever if the flush fails, meaning the command buffer
150 // reader has shutdown. 159 // reader has shutdown.
151 if (!FlushSync()) 160 if (!FlushSync())
152 return; 161 return;
153 } 162 }
154 } 163 }
155 // Force a flush if the buffer is getting half full, or even earlier if the 164 // Allow this command buffer to be pre-empted by another if a "reasonable"
156 // reader is known to be idle. 165 // amount of work has been done.
157 int32 pending = 166 if (commands_issued_ % kCommandsPerFlushCheck == 0) {
158 (put_ + usable_entry_count_ - last_put_sent_) % usable_entry_count_; 167 clock_t current_time = time(NULL);
159 int32 limit = usable_entry_count_ / ((get_ == last_put_sent_) ? 16 : 2); 168 if (difftime(current_time, last_flush_time_) > kFlushDelay)
160 if (pending > limit) { 169 Flush();
161 Flush();
162 } 170 }
163 } 171 }
164 172
165 CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) { 173 CommandBufferEntry* CommandBufferHelper::GetSpace(uint32 entries) {
174 ++commands_issued_;
166 WaitForAvailableEntries(entries); 175 WaitForAvailableEntries(entries);
167 CommandBufferEntry* space = &entries_[put_]; 176 CommandBufferEntry* space = &entries_[put_];
168 put_ += entries; 177 put_ += entries;
169 GPU_DCHECK_LE(put_, usable_entry_count_); 178 GPU_DCHECK_LE(put_, usable_entry_count_);
170 if (put_ == usable_entry_count_) { 179 if (put_ == usable_entry_count_) {
171 cmd::Jump::Set(&entries_[put_], 0); 180 cmd::Jump::Set(&entries_[put_], 0);
172 put_ = 0; 181 put_ = 0;
173 } 182 }
174 return space; 183 return space;
175 } 184 }
176 185
177 error::Error CommandBufferHelper::GetError() { 186 error::Error CommandBufferHelper::GetError() {
178 CommandBuffer::State state = command_buffer_->GetState(); 187 CommandBuffer::State state = command_buffer_->GetState();
179 SynchronizeState(state); 188 SynchronizeState(state);
180 return static_cast<error::Error>(state.error); 189 return static_cast<error::Error>(state.error);
181 } 190 }
182 191
183 void CommandBufferHelper::SynchronizeState(const CommandBuffer::State& state) { 192 void CommandBufferHelper::SynchronizeState(const CommandBuffer::State& state) {
184 get_ = state.get_offset; 193 get_ = state.get_offset;
185 last_token_read_ = state.token; 194 last_token_read_ = state.token;
186 } 195 }
187 196
188 } // namespace gpu 197 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/client/cmd_buffer_helper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698