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

Side by Side Diff: content/common/gpu/gpu_command_buffer_stub.cc

Issue 1315713007: gpu: Reduce GL context switches used to check pending queries. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase 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
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 "base/bind.h" 5 #include "base/bind.h"
6 #include "base/bind_helpers.h" 6 #include "base/bind_helpers.h"
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/hash.h" 8 #include "base/hash.h"
9 #include "base/json/json_writer.h" 9 #include "base/json/json_writer.h"
10 #include "base/memory/shared_memory.h" 10 #include "base/memory/shared_memory.h"
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 gpu_preference_(gpu_preference), 192 gpu_preference_(gpu_preference),
193 use_virtualized_gl_context_(use_virtualized_gl_context), 193 use_virtualized_gl_context_(use_virtualized_gl_context),
194 stream_id_(stream_id), 194 stream_id_(stream_id),
195 route_id_(route_id), 195 route_id_(route_id),
196 surface_id_(surface_id), 196 surface_id_(surface_id),
197 software_(software), 197 software_(software),
198 last_flush_count_(0), 198 last_flush_count_(0),
199 last_memory_allocation_valid_(false), 199 last_memory_allocation_valid_(false),
200 watchdog_(watchdog), 200 watchdog_(watchdog),
201 sync_point_wait_count_(0), 201 sync_point_wait_count_(0),
202 delayed_work_scheduled_(false),
203 previous_processed_num_(0), 202 previous_processed_num_(0),
204 active_url_(active_url), 203 active_url_(active_url),
205 total_gpu_memory_(0) { 204 total_gpu_memory_(0) {
206 active_url_hash_ = base::Hash(active_url.possibly_invalid_spec()); 205 active_url_hash_ = base::Hash(active_url.possibly_invalid_spec());
207 FastSetActiveURL(active_url_, active_url_hash_); 206 FastSetActiveURL(active_url_, active_url_hash_);
208 207
209 gpu::gles2::ContextCreationAttribHelper attrib_parser; 208 gpu::gles2::ContextCreationAttribHelper attrib_parser;
210 attrib_parser.Parse(requested_attribs_); 209 attrib_parser.Parse(requested_attribs_);
211 210
212 if (share_group) { 211 if (share_group) {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 OnSetClientHasMemoryAllocationChangedCallback) 305 OnSetClientHasMemoryAllocationChangedCallback)
307 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateImage, OnCreateImage); 306 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateImage, OnCreateImage);
308 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyImage, OnDestroyImage); 307 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyImage, OnDestroyImage);
309 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture, 308 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateStreamTexture,
310 OnCreateStreamTexture) 309 OnCreateStreamTexture)
311 IPC_MESSAGE_UNHANDLED(handled = false) 310 IPC_MESSAGE_UNHANDLED(handled = false)
312 IPC_END_MESSAGE_MAP() 311 IPC_END_MESSAGE_MAP()
313 312
314 CheckCompleteWaits(); 313 CheckCompleteWaits();
315 314
315 // Ensure that any delayed work that was created will be handled.
316 if (have_context) { 316 if (have_context) {
317 // Ensure that any delayed work that was created will be handled. 317 if (scheduler_)
318 ScheduleDelayedWork(kHandleMoreWorkPeriodMs); 318 scheduler_->ProcessPendingQueries();
319 ScheduleDelayedWork(
320 base::TimeDelta::FromMilliseconds(kHandleMoreWorkPeriodMs));
319 } 321 }
320 322
321 DCHECK(handled); 323 DCHECK(handled);
322 return handled; 324 return handled;
323 } 325 }
324 326
325 bool GpuCommandBufferStub::Send(IPC::Message* message) { 327 bool GpuCommandBufferStub::Send(IPC::Message* message) {
326 return channel_->Send(message); 328 return channel_->Send(message);
327 } 329 }
328 330
329 bool GpuCommandBufferStub::IsScheduled() { 331 bool GpuCommandBufferStub::IsScheduled() {
330 return (!scheduler_.get() || scheduler_->IsScheduled()); 332 return (!scheduler_.get() || scheduler_->IsScheduled());
331 } 333 }
332 334
333 bool GpuCommandBufferStub::HasMoreWork() { 335 void GpuCommandBufferStub::PollWork() {
334 return scheduler_.get() && scheduler_->HasMoreWork(); 336 // Post another delayed task if we have not yet reached the time at which
337 // we should process delayed work.
338 base::TimeTicks current_time = base::TimeTicks::Now();
339 DCHECK(!process_delayed_work_time_.is_null());
340 if (process_delayed_work_time_ > current_time) {
341 task_runner_->PostDelayedTask(
342 FROM_HERE, base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()),
343 process_delayed_work_time_ - current_time);
344 return;
345 }
346 process_delayed_work_time_ = base::TimeTicks();
347
348 PerformWork();
335 } 349 }
336 350
337 void GpuCommandBufferStub::PollWork() { 351 void GpuCommandBufferStub::PerformWork() {
338 TRACE_EVENT0("gpu", "GpuCommandBufferStub::PollWork"); 352 TRACE_EVENT0("gpu", "GpuCommandBufferStub::PerformWork");
339 delayed_work_scheduled_ = false; 353
340 FastSetActiveURL(active_url_, active_url_hash_); 354 FastSetActiveURL(active_url_, active_url_hash_);
341 if (decoder_.get() && !MakeCurrent()) 355 if (decoder_.get() && !MakeCurrent())
342 return; 356 return;
343 357
344 if (scheduler_) { 358 if (scheduler_) {
345 const uint32_t current_unprocessed_num = 359 const uint32_t current_unprocessed_num =
346 channel()->gpu_channel_manager()->UnprocessedOrderNumber(); 360 channel()->gpu_channel_manager()->UnprocessedOrderNumber();
347 // We're idle when no messages were processed or scheduled. 361 // We're idle when no messages were processed or scheduled.
348 bool is_idle = (previous_processed_num_ == current_unprocessed_num); 362 bool is_idle = (previous_processed_num_ == current_unprocessed_num);
349 if (!is_idle && !last_idle_time_.is_null()) { 363 if (!is_idle && !last_idle_time_.is_null()) {
350 base::TimeDelta time_since_idle = 364 base::TimeDelta time_since_idle =
351 base::TimeTicks::Now() - last_idle_time_; 365 base::TimeTicks::Now() - last_idle_time_;
352 base::TimeDelta max_time_since_idle = 366 base::TimeDelta max_time_since_idle =
353 base::TimeDelta::FromMilliseconds(kMaxTimeSinceIdleMs); 367 base::TimeDelta::FromMilliseconds(kMaxTimeSinceIdleMs);
354 368
355 // Force idle when it's been too long since last time we were idle. 369 // Force idle when it's been too long since last time we were idle.
356 if (time_since_idle > max_time_since_idle) 370 if (time_since_idle > max_time_since_idle)
357 is_idle = true; 371 is_idle = true;
358 } 372 }
359 373
360 if (is_idle) { 374 if (is_idle) {
361 last_idle_time_ = base::TimeTicks::Now(); 375 last_idle_time_ = base::TimeTicks::Now();
362 scheduler_->PerformIdleWork(); 376 scheduler_->PerformIdleWork();
363 } 377 }
378
379 scheduler_->ProcessPendingQueries();
364 } 380 }
365 ScheduleDelayedWork(kHandleMoreWorkPeriodBusyMs); 381
382 ScheduleDelayedWork(
383 base::TimeDelta::FromMilliseconds(kHandleMoreWorkPeriodBusyMs));
366 } 384 }
367 385
368 bool GpuCommandBufferStub::HasUnprocessedCommands() { 386 bool GpuCommandBufferStub::HasUnprocessedCommands() {
369 if (command_buffer_) { 387 if (command_buffer_) {
370 gpu::CommandBuffer::State state = command_buffer_->GetLastState(); 388 gpu::CommandBuffer::State state = command_buffer_->GetLastState();
371 return command_buffer_->GetPutOffset() != state.get_offset && 389 return command_buffer_->GetPutOffset() != state.get_offset &&
372 !gpu::error::IsError(state.error); 390 !gpu::error::IsError(state.error);
373 } 391 }
374 return false; 392 return false;
375 } 393 }
376 394
377 void GpuCommandBufferStub::ScheduleDelayedWork(int64 delay) { 395 void GpuCommandBufferStub::ScheduleDelayedWork(base::TimeDelta delay) {
378 if (!HasMoreWork()) { 396 bool has_more_work = scheduler_.get() && (scheduler_->HasPendingQueries() ||
397 scheduler_->HasMoreIdleWork());
398 if (!has_more_work) {
379 last_idle_time_ = base::TimeTicks(); 399 last_idle_time_ = base::TimeTicks();
380 return; 400 return;
381 } 401 }
382 402
383 if (delayed_work_scheduled_) 403 base::TimeTicks current_time = base::TimeTicks::Now();
404 // |process_delayed_work_time_| is set if processing of delayed work is
405 // already scheduled. Just update the time if already scheduled.
406 if (!process_delayed_work_time_.is_null()) {
407 process_delayed_work_time_ = current_time + delay;
384 return; 408 return;
385 delayed_work_scheduled_ = true; 409 }
386 410
387 // Idle when no messages are processed between now and when 411 // Idle when no messages are processed between now and when
388 // PollWork is called. 412 // PollWork is called.
389 previous_processed_num_ = 413 previous_processed_num_ =
390 channel()->gpu_channel_manager()->ProcessedOrderNumber(); 414 channel()->gpu_channel_manager()->ProcessedOrderNumber();
391 if (last_idle_time_.is_null()) 415 if (last_idle_time_.is_null())
392 last_idle_time_ = base::TimeTicks::Now(); 416 last_idle_time_ = current_time;
393 417
394 // IsScheduled() returns true after passing all unschedule fences 418 // IsScheduled() returns true after passing all unschedule fences
395 // and this is when we can start performing idle work. Idle work 419 // and this is when we can start performing idle work. Idle work
396 // is done synchronously so we can set delay to 0 and instead poll 420 // is done synchronously so we can set delay to 0 and instead poll
397 // for more work at the rate idle work is performed. This also ensures 421 // for more work at the rate idle work is performed. This also ensures
398 // that idle work is done as efficiently as possible without any 422 // that idle work is done as efficiently as possible without any
399 // unnecessary delays. 423 // unnecessary delays.
400 if (scheduler_.get() && 424 if (scheduler_.get() &&
401 scheduler_->IsScheduled() && 425 scheduler_->IsScheduled() &&
402 scheduler_->HasMoreIdleWork()) { 426 scheduler_->HasMoreIdleWork()) {
403 delay = 0; 427 delay = base::TimeDelta();
404 } 428 }
405 429
430 process_delayed_work_time_ = current_time + delay;
406 task_runner_->PostDelayedTask( 431 task_runner_->PostDelayedTask(
407 FROM_HERE, base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()), 432 FROM_HERE, base::Bind(&GpuCommandBufferStub::PollWork, AsWeakPtr()),
408 base::TimeDelta::FromMilliseconds(delay)); 433 delay);
409 } 434 }
410 435
411 bool GpuCommandBufferStub::MakeCurrent() { 436 bool GpuCommandBufferStub::MakeCurrent() {
412 if (decoder_->MakeCurrent()) 437 if (decoder_->MakeCurrent())
413 return true; 438 return true;
414 DLOG(ERROR) << "Context lost because MakeCurrent failed."; 439 DLOG(ERROR) << "Context lost because MakeCurrent failed.";
415 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason()); 440 command_buffer_->SetContextLostReason(decoder_->GetContextLostReason());
416 command_buffer_->SetParseError(gpu::error::kLostContext); 441 command_buffer_->SetParseError(gpu::error::kLostContext);
417 CheckContextLost(); 442 CheckContextLost();
418 return false; 443 return false;
(...skipping 759 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 result)); 1203 result));
1179 } 1204 }
1180 1205
1181 void GpuCommandBufferStub::SendUpdateVSyncParameters(base::TimeTicks timebase, 1206 void GpuCommandBufferStub::SendUpdateVSyncParameters(base::TimeTicks timebase,
1182 base::TimeDelta interval) { 1207 base::TimeDelta interval) {
1183 Send(new GpuCommandBufferMsg_UpdateVSyncParameters(route_id_, timebase, 1208 Send(new GpuCommandBufferMsg_UpdateVSyncParameters(route_id_, timebase,
1184 interval)); 1209 interval));
1185 } 1210 }
1186 1211
1187 } // namespace content 1212 } // namespace content
OLDNEW
« no previous file with comments | « content/common/gpu/gpu_command_buffer_stub.h ('k') | gpu/command_buffer/service/gles2_cmd_decoder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698