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

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

Issue 7253052: Execute all GL commands up to the put offset reported by a flush. (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
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 { 13 namespace {
14 const int kCommandsPerFlushCheck = 100; 14 const int kCommandsPerFlushCheck = 100;
15 const double kFlushDelay = 1.0 / (5.0 * 60.0); 15 const double kFlushDelay = 1.0 / (5.0 * 60.0);
16 } 16 }
17 17
18 CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer) 18 CommandBufferHelper::CommandBufferHelper(CommandBuffer* command_buffer)
19 : command_buffer_(command_buffer), 19 : command_buffer_(command_buffer),
20 entries_(NULL), 20 entries_(NULL),
21 total_entry_count_(0), 21 total_entry_count_(0),
22 usable_entry_count_(0), 22 usable_entry_count_(0),
23 token_(0), 23 token_(0),
24 last_token_read_(-1),
25 get_(0),
26 put_(0), 24 put_(0),
27 last_put_sent_(0), 25 last_put_sent_(0),
28 commands_issued_(0), 26 commands_issued_(0),
29 last_flush_time_(0) { 27 last_flush_time_(0) {
30 } 28 }
31 29
32 bool CommandBufferHelper::Initialize(int32 ring_buffer_size) { 30 bool CommandBufferHelper::Initialize(int32 ring_buffer_size) {
33 ring_buffer_ = command_buffer_->GetRingBuffer(); 31 ring_buffer_ = command_buffer_->GetRingBuffer();
34 if (!ring_buffer_.ptr) 32 if (!ring_buffer_.ptr)
35 return false; 33 return false;
36 34
37 CommandBuffer::State state = command_buffer_->GetState(); 35 CommandBuffer::State state = command_buffer_->GetState();
38 entries_ = static_cast<CommandBufferEntry*>(ring_buffer_.ptr); 36 entries_ = static_cast<CommandBufferEntry*>(ring_buffer_.ptr);
39 int32 num_ring_buffer_entries = ring_buffer_size / sizeof(CommandBufferEntry); 37 int32 num_ring_buffer_entries = ring_buffer_size / sizeof(CommandBufferEntry);
40 if (num_ring_buffer_entries > state.num_entries) { 38 if (num_ring_buffer_entries > state.num_entries) {
41 return false; 39 return false;
42 } 40 }
43 41
44 const int32 kJumpEntries = 42 const int32 kJumpEntries =
45 sizeof(cmd::Jump) / sizeof(*entries_); // NOLINT 43 sizeof(cmd::Jump) / sizeof(*entries_); // NOLINT
46 44
47 total_entry_count_ = num_ring_buffer_entries; 45 total_entry_count_ = num_ring_buffer_entries;
48 usable_entry_count_ = total_entry_count_ - kJumpEntries; 46 usable_entry_count_ = total_entry_count_ - kJumpEntries;
49 put_ = state.put_offset; 47 put_ = state.put_offset;
50 SynchronizeState(state);
51 return true; 48 return true;
52 } 49 }
53 50
54 CommandBufferHelper::~CommandBufferHelper() { 51 CommandBufferHelper::~CommandBufferHelper() {
55 } 52 }
56 53
57 bool CommandBufferHelper::FlushSync() { 54 bool CommandBufferHelper::FlushSync() {
58 time(&last_flush_time_); 55 time(&last_flush_time_);
59 last_put_sent_ = put_; 56 last_put_sent_ = put_;
60 CommandBuffer::State state = command_buffer_->FlushSync(put_, get_); 57 CommandBuffer::State state = command_buffer_->FlushSync(put_, get_offset());
61 SynchronizeState(state);
62 return state.error == error::kNoError; 58 return state.error == error::kNoError;
63 } 59 }
64 60
65 void CommandBufferHelper::Flush() { 61 void CommandBufferHelper::Flush() {
66 time(&last_flush_time_); 62 time(&last_flush_time_);
67 last_put_sent_ = put_; 63 last_put_sent_ = put_;
68 command_buffer_->Flush(put_); 64 command_buffer_->Flush(put_);
69 } 65 }
70 66
71 // Calls Flush() and then waits until the buffer is empty. Break early if the 67 // Calls Flush() and then waits until the buffer is empty. Break early if the
72 // error is set. 68 // error is set.
73 bool CommandBufferHelper::Finish() { 69 bool CommandBufferHelper::Finish() {
74 TRACE_EVENT0("gpu", "CommandBufferHelper::Finish"); 70 TRACE_EVENT0("gpu", "CommandBufferHelper::Finish");
75 do { 71 do {
76 // Do not loop forever if the flush fails, meaning the command buffer reader 72 // Do not loop forever if the flush fails, meaning the command buffer reader
77 // has shutdown. 73 // has shutdown.
78 if (!FlushSync()) 74 if (!FlushSync())
79 return false; 75 return false;
80 } while (put_ != get_); 76 } while (put_ != get_offset());
81 77
82 return true; 78 return true;
83 } 79 }
84 80
85 // Inserts a new token into the command stream. It uses an increasing value 81 // Inserts a new token into the command stream. It uses an increasing value
86 // scheme so that we don't lose tokens (a token has passed if the current token 82 // scheme so that we don't lose tokens (a token has passed if the current token
87 // value is higher than that token). Calls Finish() if the token value wraps, 83 // value is higher than that token). Calls Finish() if the token value wraps,
88 // which will be rare. 84 // which will be rare.
89 int32 CommandBufferHelper::InsertToken() { 85 int32 CommandBufferHelper::InsertToken() {
90 // Increment token as 31-bit integer. Negative values are used to signal an 86 // Increment token as 31-bit integer. Negative values are used to signal an
91 // error. 87 // error.
92 token_ = (token_ + 1) & 0x7FFFFFFF; 88 token_ = (token_ + 1) & 0x7FFFFFFF;
93 cmd::SetToken& cmd = GetCmdSpace<cmd::SetToken>(); 89 cmd::SetToken& cmd = GetCmdSpace<cmd::SetToken>();
94 cmd.Init(token_); 90 cmd.Init(token_);
95 if (token_ == 0) { 91 if (token_ == 0) {
96 TRACE_EVENT0("gpu", "CommandBufferHelper::InsertToken(wrapped)"); 92 TRACE_EVENT0("gpu", "CommandBufferHelper::InsertToken(wrapped)");
97 // we wrapped 93 // we wrapped
98 Finish(); 94 Finish();
99 GPU_DCHECK_EQ(token_, last_token_read_); 95 GPU_DCHECK_EQ(token_, last_token_read());
100 } 96 }
101 return token_; 97 return token_;
102 } 98 }
103 99
104 // Waits until the current token value is greater or equal to the value passed 100 // Waits until the current token value is greater or equal to the value passed
105 // in argument. 101 // in argument.
106 void CommandBufferHelper::WaitForToken(int32 token) { 102 void CommandBufferHelper::WaitForToken(int32 token) {
107 TRACE_EVENT_IF_LONGER_THAN0(50, "gpu", "CommandBufferHelper::WaitForToken"); 103 TRACE_EVENT_IF_LONGER_THAN0(50, "gpu", "CommandBufferHelper::WaitForToken");
108 // Return immediately if corresponding InsertToken failed. 104 // Return immediately if corresponding InsertToken failed.
109 if (token < 0) 105 if (token < 0)
110 return; 106 return;
111 if (token > token_) return; // we wrapped 107 if (token > token_) return; // we wrapped
112 while (last_token_read_ < token) { 108 while (last_token_read() < token) {
113 if (get_ == put_) { 109 if (get_offset() == put_) {
114 GPU_LOG(FATAL) << "Empty command buffer while waiting on a token."; 110 GPU_LOG(FATAL) << "Empty command buffer while waiting on a token.";
115 return; 111 return;
116 } 112 }
117 // Do not loop forever if the flush fails, meaning the command buffer reader 113 // Do not loop forever if the flush fails, meaning the command buffer reader
118 // has shutdown. 114 // has shutdown.
119 if (!FlushSync()) 115 if (!FlushSync())
120 return; 116 return;
121 } 117 }
122 } 118 }
123 119
124 void CommandBufferHelper::YieldScheduler() {
125 cmd::YieldScheduler& cmd = GetCmdSpace<cmd::YieldScheduler>();
126 cmd.Init();
127 }
128
129 // Waits for available entries, basically waiting until get >= put + count + 1. 120 // Waits for available entries, basically waiting until get >= put + count + 1.
130 // It actually waits for contiguous entries, so it may need to wrap the buffer 121 // It actually waits for contiguous entries, so it may need to wrap the buffer
131 // around, adding a jump. Thus this function may change the value of put_. The 122 // around, adding a jump. Thus this function may change the value of put_. The
132 // function will return early if an error occurs, in which case the available 123 // function will return early if an error occurs, in which case the available
133 // space may not be available. 124 // space may not be available.
134 void CommandBufferHelper::WaitForAvailableEntries(int32 count) { 125 void CommandBufferHelper::WaitForAvailableEntries(int32 count) {
135 GPU_DCHECK(count < usable_entry_count_); 126 GPU_DCHECK(count < usable_entry_count_);
136 if (put_ + count > usable_entry_count_) { 127 if (put_ + count > usable_entry_count_) {
137 // There's not enough room between the current put and the end of the 128 // There's not enough room between the current put and the end of the
138 // buffer, so we need to wrap. We will add a jump back to the start, but we 129 // buffer, so we need to wrap. We will add a jump back to the start, but we
139 // need to make sure get wraps first, actually that get is 1 or more (since 130 // need to make sure get wraps first, actually that get is 1 or more (since
140 // put will wrap to 0 after we add the jump). 131 // put will wrap to 0 after we add the jump).
141 GPU_DCHECK_LE(1, put_); 132 GPU_DCHECK_LE(1, put_);
142 if (get_ > put_ || get_ == 0) { 133 if (get_offset() > put_ || get_offset() == 0) {
143 TRACE_EVENT0("gpu", "CommandBufferHelper::WaitForAvailableEntries"); 134 TRACE_EVENT0("gpu", "CommandBufferHelper::WaitForAvailableEntries");
144 while (get_ > put_ || get_ == 0) { 135 while (get_offset() > put_ || get_offset() == 0) {
145 // Do not loop forever if the flush fails, meaning the command buffer 136 // Do not loop forever if the flush fails, meaning the command buffer
146 // reader has shutdown. 137 // reader has shutdown.
147 if (!FlushSync()) 138 if (!FlushSync())
148 return; 139 return;
149 } 140 }
150 } 141 }
151 // Insert a jump back to the beginning. 142 // Insert a jump back to the beginning.
152 cmd::Jump::Set(&entries_[put_], 0); 143 cmd::Jump::Set(&entries_[put_], 0);
153 put_ = 0; 144 put_ = 0;
154 } 145 }
(...skipping 23 matching lines...) Expand all
178 GPU_DCHECK_LE(put_, usable_entry_count_); 169 GPU_DCHECK_LE(put_, usable_entry_count_);
179 if (put_ == usable_entry_count_) { 170 if (put_ == usable_entry_count_) {
180 cmd::Jump::Set(&entries_[put_], 0); 171 cmd::Jump::Set(&entries_[put_], 0);
181 put_ = 0; 172 put_ = 0;
182 } 173 }
183 return space; 174 return space;
184 } 175 }
185 176
186 error::Error CommandBufferHelper::GetError() { 177 error::Error CommandBufferHelper::GetError() {
187 CommandBuffer::State state = command_buffer_->GetState(); 178 CommandBuffer::State state = command_buffer_->GetState();
188 SynchronizeState(state);
189 return static_cast<error::Error>(state.error); 179 return static_cast<error::Error>(state.error);
190 } 180 }
191 181
192 void CommandBufferHelper::SynchronizeState(const CommandBuffer::State& state) {
193 get_ = state.get_offset;
194 last_token_read_ = state.token;
195 }
196
197 } // namespace gpu 182 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/client/cmd_buffer_helper.h ('k') | gpu/command_buffer/client/cmd_buffer_helper_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698