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

Side by Side Diff: gpu/command_buffer/service/gpu_scheduler.cc

Issue 1348363003: content/gpu: Simplify stub scheduling. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@gpu_channel_stream
Patch Set: fix android compile error sigh Created 5 years, 3 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
« no previous file with comments | « gpu/command_buffer/service/gpu_scheduler.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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "gpu/command_buffer/service/gpu_scheduler.h" 5 #include "gpu/command_buffer/service/gpu_scheduler.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
11 #include "base/time/time.h" 11 #include "base/time/time.h"
12 #include "base/trace_event/trace_event.h" 12 #include "base/trace_event/trace_event.h"
13 #include "gpu/command_buffer/service/logger.h" 13 #include "gpu/command_buffer/service/logger.h"
14 #include "ui/gl/gl_bindings.h" 14 #include "ui/gl/gl_bindings.h"
15 #include "ui/gl/gl_fence.h" 15 #include "ui/gl/gl_fence.h"
16 #include "ui/gl/gl_switches.h" 16 #include "ui/gl/gl_switches.h"
17 17
18 #if defined(OS_WIN)
19 #include "base/win/windows_version.h"
20 #endif
21
22 using ::base::SharedMemory; 18 using ::base::SharedMemory;
23 19
24 namespace gpu { 20 namespace gpu {
25 21
26 #if defined(OS_WIN) 22 #if defined(OS_WIN)
27 const int64 kRescheduleTimeOutDelay = 1000; 23 const int64 kRescheduleTimeOutDelay = 1000;
28 #endif 24 #endif
29 25
30 GpuScheduler::GpuScheduler(CommandBufferServiceBase* command_buffer, 26 GpuScheduler::GpuScheduler(CommandBufferServiceBase* command_buffer,
31 AsyncAPIInterface* handler, 27 AsyncAPIInterface* handler,
32 gles2::GLES2Decoder* decoder) 28 gles2::GLES2Decoder* decoder)
33 : command_buffer_(command_buffer), 29 : command_buffer_(command_buffer),
34 handler_(handler), 30 handler_(handler),
35 decoder_(decoder), 31 decoder_(decoder),
36 unscheduled_count_(0), 32 scheduled_(true),
37 rescheduled_count_(0), 33 was_preempted_(false) {}
38 was_preempted_(false),
39 reschedule_task_factory_(this) {}
40 34
41 GpuScheduler::~GpuScheduler() { 35 GpuScheduler::~GpuScheduler() {}
42 }
43 36
44 void GpuScheduler::PutChanged() { 37 void GpuScheduler::PutChanged() {
45 TRACE_EVENT1( 38 TRACE_EVENT1(
46 "gpu", "GpuScheduler:PutChanged", 39 "gpu", "GpuScheduler:PutChanged",
47 "decoder", decoder_ ? decoder_->GetLogger()->GetLogPrefix() : "None"); 40 "decoder", decoder_ ? decoder_->GetLogger()->GetLogPrefix() : "None");
48 41
49 CommandBuffer::State state = command_buffer_->GetLastState(); 42 CommandBuffer::State state = command_buffer_->GetLastState();
50 43
51 // If there is no parser, exit. 44 // If there is no parser, exit.
52 if (!parser_.get()) { 45 if (!parser_.get()) {
53 DCHECK_EQ(state.get_offset, command_buffer_->GetPutOffset()); 46 DCHECK_EQ(state.get_offset, command_buffer_->GetPutOffset());
54 return; 47 return;
55 } 48 }
56 49
57 parser_->set_put(command_buffer_->GetPutOffset()); 50 parser_->set_put(command_buffer_->GetPutOffset());
58 if (state.error != error::kNoError) 51 if (state.error != error::kNoError)
59 return; 52 return;
60 53
61 // One of the unschedule fence tasks might have unscheduled us.
62 if (!IsScheduled())
63 return;
64
65 base::TimeTicks begin_time(base::TimeTicks::Now()); 54 base::TimeTicks begin_time(base::TimeTicks::Now());
66 error::Error error = error::kNoError; 55 error::Error error = error::kNoError;
67 if (decoder_) 56 if (decoder_)
68 decoder_->BeginDecoding(); 57 decoder_->BeginDecoding();
69 while (!parser_->IsEmpty()) { 58 while (!parser_->IsEmpty()) {
70 if (IsPreempted()) 59 if (IsPreempted())
71 break; 60 break;
72 61
73 DCHECK(IsScheduled()); 62 DCHECK(scheduled());
74 63
75 error = parser_->ProcessCommands(CommandParser::kParseCommandsSlice); 64 error = parser_->ProcessCommands(CommandParser::kParseCommandsSlice);
76 65
77 if (error == error::kDeferCommandUntilLater) { 66 if (error == error::kDeferCommandUntilLater) {
78 DCHECK_GT(unscheduled_count_, 0); 67 DCHECK(!scheduled());
79 break; 68 break;
80 } 69 }
81 70
82 // TODO(piman): various classes duplicate various pieces of state, leading 71 // TODO(piman): various classes duplicate various pieces of state, leading
83 // to needlessly complex update logic. It should be possible to simply 72 // to needlessly complex update logic. It should be possible to simply
84 // share the state across all of them. 73 // share the state across all of them.
85 command_buffer_->SetGetOffset(static_cast<int32>(parser_->get())); 74 command_buffer_->SetGetOffset(static_cast<int32>(parser_->get()));
86 75
87 if (error::IsError(error)) { 76 if (error::IsError(error)) {
88 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); 77 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
89 command_buffer_->SetParseError(error); 78 command_buffer_->SetParseError(error);
90 break; 79 break;
91 } 80 }
92 81
93 if (!command_processed_callback_.is_null()) 82 if (!command_processed_callback_.is_null())
94 command_processed_callback_.Run(); 83 command_processed_callback_.Run();
95 84
96 if (unscheduled_count_ > 0) 85 if (!scheduled())
97 break; 86 break;
98 } 87 }
99 88
100 if (decoder_) { 89 if (decoder_) {
101 if (!error::IsError(error) && decoder_->WasContextLost()) { 90 if (!error::IsError(error) && decoder_->WasContextLost()) {
102 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); 91 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
103 command_buffer_->SetParseError(error::kLostContext); 92 command_buffer_->SetParseError(error::kLostContext);
104 } 93 }
105 decoder_->EndDecoding(); 94 decoder_->EndDecoding();
106 decoder_->AddProcessingCommandsTime(base::TimeTicks::Now() - begin_time); 95 decoder_->AddProcessingCommandsTime(base::TimeTicks::Now() - begin_time);
107 } 96 }
108 } 97 }
109 98
110 void GpuScheduler::SetScheduled(bool scheduled) { 99 void GpuScheduler::SetScheduled(bool scheduled) {
111 TRACE_EVENT2("gpu", "GpuScheduler:SetScheduled", "this", this, 100 TRACE_EVENT2("gpu", "GpuScheduler:SetScheduled", "this", this, "scheduled",
112 "new unscheduled_count_", 101 scheduled);
113 unscheduled_count_ + (scheduled? -1 : 1)); 102 if (scheduled_ == scheduled)
114 if (scheduled) { 103 return;
115 // If the scheduler was rescheduled after a timeout, ignore the subsequent 104 scheduled_ = scheduled;
116 // calls to SetScheduled when they eventually arrive until they are all 105 if (!scheduling_changed_callback_.is_null())
117 // accounted for. 106 scheduling_changed_callback_.Run(scheduled);
118 if (rescheduled_count_ > 0) {
119 --rescheduled_count_;
120 return;
121 } else {
122 --unscheduled_count_;
123 }
124
125 DCHECK_GE(unscheduled_count_, 0);
126
127 if (unscheduled_count_ == 0) {
128 TRACE_EVENT_ASYNC_END1("gpu", "ProcessingSwap", this,
129 "GpuScheduler", this);
130 // When the scheduler transitions from the unscheduled to the scheduled
131 // state, cancel the task that would reschedule it after a timeout.
132 reschedule_task_factory_.InvalidateWeakPtrs();
133
134 if (!scheduling_changed_callback_.is_null())
135 scheduling_changed_callback_.Run(true);
136 }
137 } else {
138 ++unscheduled_count_;
139 if (unscheduled_count_ == 1) {
140 TRACE_EVENT_ASYNC_BEGIN1("gpu", "ProcessingSwap", this,
141 "GpuScheduler", this);
142 #if defined(OS_WIN)
143 if (base::win::GetVersion() < base::win::VERSION_VISTA) {
144 // When the scheduler transitions from scheduled to unscheduled, post a
145 // delayed task that it will force it back into a scheduled state after
146 // a timeout. This should only be necessary on pre-Vista.
147 base::MessageLoop::current()->PostDelayedTask(
148 FROM_HERE,
149 base::Bind(&GpuScheduler::RescheduleTimeOut,
150 reschedule_task_factory_.GetWeakPtr()),
151 base::TimeDelta::FromMilliseconds(kRescheduleTimeOutDelay));
152 }
153 #endif
154 if (!scheduling_changed_callback_.is_null())
155 scheduling_changed_callback_.Run(false);
156 }
157 }
158 }
159
160 bool GpuScheduler::IsScheduled() {
161 return unscheduled_count_ == 0;
162 } 107 }
163 108
164 bool GpuScheduler::HasPendingQueries() const { 109 bool GpuScheduler::HasPendingQueries() const {
165 return (decoder_ && decoder_->HasPendingQueries()); 110 return (decoder_ && decoder_->HasPendingQueries());
166 } 111 }
167 112
168 void GpuScheduler::ProcessPendingQueries() { 113 void GpuScheduler::ProcessPendingQueries() {
169 if (!decoder_) 114 if (!decoder_)
170 return; 115 return;
171 decoder_->ProcessPendingQueries(false); 116 decoder_->ProcessPendingQueries(false);
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
237 bool GpuScheduler::HasMoreIdleWork() const { 182 bool GpuScheduler::HasMoreIdleWork() const {
238 return (decoder_ && decoder_->HasMoreIdleWork()); 183 return (decoder_ && decoder_->HasMoreIdleWork());
239 } 184 }
240 185
241 void GpuScheduler::PerformIdleWork() { 186 void GpuScheduler::PerformIdleWork() {
242 if (!decoder_) 187 if (!decoder_)
243 return; 188 return;
244 decoder_->PerformIdleWork(); 189 decoder_->PerformIdleWork();
245 } 190 }
246 191
247 void GpuScheduler::RescheduleTimeOut() {
248 int new_count = unscheduled_count_ + rescheduled_count_;
249
250 rescheduled_count_ = 0;
251
252 while (unscheduled_count_)
253 SetScheduled(true);
254
255 rescheduled_count_ = new_count;
256 }
257
258 } // namespace gpu 192 } // namespace gpu
OLDNEW
« no previous file with comments | « gpu/command_buffer/service/gpu_scheduler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698