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

Side by Side Diff: content/renderer/render_thread_impl.cc

Issue 1211153002: Expose a SequencedTaskRunner that runs tasks on raster threads. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address reveman's nits. Created 5 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
« no previous file with comments | « content/renderer/render_thread_impl.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 "content/renderer/render_thread_impl.h" 5 #include "content/renderer/render_thread_impl.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <limits> 8 #include <limits>
9 #include <map> 9 #include <map>
10 #include <vector> 10 #include <vector>
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 } 259 }
260 260
261 private: 261 private:
262 const std::string scheme_; 262 const std::string scheme_;
263 const std::string host_; 263 const std::string host_;
264 const double zoom_level_; 264 const double zoom_level_;
265 265
266 DISALLOW_COPY_AND_ASSIGN(RenderViewZoomer); 266 DISALLOW_COPY_AND_ASSIGN(RenderViewZoomer);
267 }; 267 };
268 268
269 class CompositorRasterThread : public base::SimpleThread {
270 public:
271 CompositorRasterThread(cc::TaskGraphRunner* task_graph_runner,
272 const std::string& name_prefix,
273 base::SimpleThread::Options options)
274 : base::SimpleThread(name_prefix, options),
275 task_graph_runner_(task_graph_runner) {}
276
277 // Overridden from base::SimpleThread:
278 void Run() override { task_graph_runner_->Run(); }
279
280 private:
281 cc::TaskGraphRunner* task_graph_runner_;
282
283 DISALLOW_COPY_AND_ASSIGN(CompositorRasterThread);
284 };
285
286 std::string HostToCustomHistogramSuffix(const std::string& host) { 269 std::string HostToCustomHistogramSuffix(const std::string& host) {
287 if (host == "mail.google.com") 270 if (host == "mail.google.com")
288 return ".gmail"; 271 return ".gmail";
289 if (host == "docs.google.com" || host == "drive.google.com") 272 if (host == "docs.google.com" || host == "drive.google.com")
290 return ".docs"; 273 return ".docs";
291 if (host == "plus.google.com") 274 if (host == "plus.google.com")
292 return ".plus"; 275 return ".plus";
293 if (host == "inbox.google.com") 276 if (host == "inbox.google.com")
294 return ".inbox"; 277 return ".inbox";
295 return std::string(); 278 return std::string();
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 attributes.shareResources = true; 372 attributes.shareResources = true;
390 attributes.depth = false; 373 attributes.depth = false;
391 attributes.stencil = false; 374 attributes.stencil = false;
392 attributes.antialias = false; 375 attributes.antialias = false;
393 attributes.noAutomaticFlushes = true; 376 attributes.noAutomaticFlushes = true;
394 return attributes; 377 return attributes;
395 } 378 }
396 379
397 } // namespace 380 } // namespace
398 381
382 class RasterWorkerPool : public base::SequencedTaskRunner,
383 public base::DelegateSimpleThread::Delegate {
384 public:
385 RasterWorkerPool()
386 : namespace_token_(task_graph_runner_.GetNamespaceToken()) {}
387
388 void Start(int num_threads,
389 const base::SimpleThread::Options& thread_options) {
390 DCHECK(threads_.empty());
391 while (threads_.size() < static_cast<size_t>(num_threads)) {
392 scoped_ptr<base::DelegateSimpleThread> thread(
393 new base::DelegateSimpleThread(
394 this, base::StringPrintf(
395 "CompositorTileWorker%u",
396 static_cast<unsigned>(threads_.size() + 1)).c_str(),
397 thread_options));
398 thread->Start();
399 threads_.push_back(thread.Pass());
400 }
401 }
402
403 void Shutdown() {
404 // Shutdown raster threads.
405 task_graph_runner_.Shutdown();
406 while (!threads_.empty()) {
407 threads_.back()->Join();
408 threads_.pop_back();
409 }
410 }
411
412 // Overridden from base::TaskRunner:
413 bool PostDelayedTask(const tracked_objects::Location& from_here,
414 const base::Closure& task,
415 base::TimeDelta delay) override {
416 return PostNonNestableDelayedTask(from_here, task, delay);
417 }
418
419 bool RunsTasksOnCurrentThread() const override { return true; }
420
421 // Overridden from base::SequencedTaskRunner:
422 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here,
423 const base::Closure& task,
424 base::TimeDelta delay) override {
425 base::AutoLock lock(lock_);
426 DCHECK(!threads_.empty());
427
428 // Remove completed tasks.
429 DCHECK(completed_tasks_.empty());
430 task_graph_runner_.CollectCompletedTasks(namespace_token_,
431 &completed_tasks_);
432 DCHECK_LE(completed_tasks_.size(), tasks_.size());
433 DCHECK(std::equal(completed_tasks_.begin(), completed_tasks_.end(),
434 tasks_.begin()));
435 tasks_.erase(tasks_.begin(), tasks_.begin() + completed_tasks_.size());
436 completed_tasks_.clear();
437
438 tasks_.push_back(make_scoped_refptr(new ClosureTask(task)));
439
440 graph_.Reset();
441 for (const auto& task : tasks_) {
442 cc::TaskGraph::Node node(task.get(), 0, graph_.nodes.size());
443 if (graph_.nodes.size()) {
444 graph_.edges.push_back(
445 cc::TaskGraph::Edge(graph_.nodes.back().task, node.task));
446 }
447 graph_.nodes.push_back(node);
448 }
449
450 task_graph_runner_.ScheduleTasks(namespace_token_, &graph_);
451 return true;
452 }
453
454 // Overridden from base::DelegateSimpleThread::Delegate:
455 void Run() override { task_graph_runner_.Run(); }
456
457 cc::TaskGraphRunner* GetTaskGraphRunner() { return &task_graph_runner_; }
458
459 protected:
460 ~RasterWorkerPool() override {}
461
462 private:
463 // Simple Task for the TaskGraphRunner that wraps a closure.
464 class ClosureTask : public cc::Task {
465 public:
466 ClosureTask(const base::Closure& closure) : closure_(closure) {}
467
468 // Overridden from cc::Task:
469 void RunOnWorkerThread() override {
470 closure_.Run();
471 closure_.Reset();
472 };
473
474 protected:
475 ~ClosureTask() override {}
476
477 private:
478 base::Closure closure_;
479
480 DISALLOW_COPY_AND_ASSIGN(ClosureTask);
481 };
482
483 // The actual threads where work is done.
484 ScopedVector<base::DelegateSimpleThread> threads_;
485 cc::TaskGraphRunner task_graph_runner_;
486
487 // Namespace where the SequencedTaskRunner tasks run.
488 const cc::NamespaceToken namespace_token_;
489
490 // Lock to exclusively access all the following members that are used to
491 // implement the SequencedTaskRunner interface.
492 base::Lock lock_;
493 // List of tasks currently queued up for execution.
494 ClosureTask::Vector tasks_;
495 // Cached vector to avoid allocation when getting the list of complete tasks.
496 ClosureTask::Vector completed_tasks_;
497 // Graph object used for scheduling tasks.
498 cc::TaskGraph graph_;
499 };
500
399 // For measuring memory usage after each task. Behind a command line flag. 501 // For measuring memory usage after each task. Behind a command line flag.
400 class MemoryObserver : public base::MessageLoop::TaskObserver { 502 class MemoryObserver : public base::MessageLoop::TaskObserver {
401 public: 503 public:
402 MemoryObserver() {} 504 MemoryObserver() {}
403 ~MemoryObserver() override {} 505 ~MemoryObserver() override {}
404 506
405 void WillProcessTask(const base::PendingTask& pending_task) override {} 507 void WillProcessTask(const base::PendingTask& pending_task) override {}
406 508
407 void DidProcessTask(const base::PendingTask& pending_task) override { 509 void DidProcessTask(const base::PendingTask& pending_task) override {
408 LOCAL_HISTOGRAM_MEMORY_KB("Memory.RendererUsed", GetMemoryUsageKB()); 510 LOCAL_HISTOGRAM_MEMORY_KB("Memory.RendererUsed", GetMemoryUsageKB());
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
456 } 558 }
457 559
458 RenderThreadImpl* RenderThreadImpl::current() { 560 RenderThreadImpl* RenderThreadImpl::current() {
459 return lazy_tls.Pointer()->Get(); 561 return lazy_tls.Pointer()->Get();
460 } 562 }
461 563
462 RenderThreadImpl::RenderThreadImpl(const InProcessChildThreadParams& params) 564 RenderThreadImpl::RenderThreadImpl(const InProcessChildThreadParams& params)
463 : ChildThreadImpl(Options::Builder() 565 : ChildThreadImpl(Options::Builder()
464 .InBrowserProcess(params) 566 .InBrowserProcess(params)
465 .UseMojoChannel(ShouldUseMojoChannel()) 567 .UseMojoChannel(ShouldUseMojoChannel())
466 .Build()) { 568 .Build()),
569 raster_worker_pool_(new RasterWorkerPool()) {
467 Init(); 570 Init();
468 } 571 }
469 572
470 // When we run plugins in process, we actually run them on the render thread, 573 // When we run plugins in process, we actually run them on the render thread,
471 // which means that we need to make the render thread pump UI events. 574 // which means that we need to make the render thread pump UI events.
472 RenderThreadImpl::RenderThreadImpl( 575 RenderThreadImpl::RenderThreadImpl(
473 scoped_ptr<base::MessageLoop> main_message_loop) 576 scoped_ptr<base::MessageLoop> main_message_loop)
474 : ChildThreadImpl(Options::Builder() 577 : ChildThreadImpl(Options::Builder()
475 .UseMojoChannel(ShouldUseMojoChannel()) 578 .UseMojoChannel(ShouldUseMojoChannel())
476 .Build()), 579 .Build()),
477 main_message_loop_(main_message_loop.Pass()) { 580 main_message_loop_(main_message_loop.Pass()),
581 raster_worker_pool_(new RasterWorkerPool()) {
478 Init(); 582 Init();
479 } 583 }
480 584
481 void RenderThreadImpl::Init() { 585 void RenderThreadImpl::Init() {
482 TRACE_EVENT_BEGIN_ETW("RenderThreadImpl::Init", 0, ""); 586 TRACE_EVENT_BEGIN_ETW("RenderThreadImpl::Init", 0, "");
483 587
484 base::trace_event::TraceLog::GetInstance()->SetThreadSortIndex( 588 base::trace_event::TraceLog::GetInstance()->SetThreadSortIndex(
485 base::PlatformThread::CurrentId(), 589 base::PlatformThread::CurrentId(),
486 kTraceEventRendererMainThreadSortIndex); 590 kTraceEventRendererMainThreadSortIndex);
487 591
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
640 is_distance_field_text_enabled_ = false; 744 is_distance_field_text_enabled_ = false;
641 } 745 }
642 746
643 // Note that under Linux, the media library will normally already have 747 // Note that under Linux, the media library will normally already have
644 // been initialized by the Zygote before this instance became a Renderer. 748 // been initialized by the Zygote before this instance became a Renderer.
645 media::InitializeMediaLibrary(); 749 media::InitializeMediaLibrary();
646 750
647 memory_pressure_listener_.reset(new base::MemoryPressureListener( 751 memory_pressure_listener_.reset(new base::MemoryPressureListener(
648 base::Bind(&RenderThreadImpl::OnMemoryPressure, base::Unretained(this)))); 752 base::Bind(&RenderThreadImpl::OnMemoryPressure, base::Unretained(this))));
649 753
650 compositor_task_graph_runner_.reset(new cc::TaskGraphRunner);
651
652 is_gather_pixel_refs_enabled_ = false; 754 is_gather_pixel_refs_enabled_ = false;
653 755
654 int num_raster_threads = 0; 756 int num_raster_threads = 0;
655 std::string string_value = 757 std::string string_value =
656 command_line.GetSwitchValueASCII(switches::kNumRasterThreads); 758 command_line.GetSwitchValueASCII(switches::kNumRasterThreads);
657 bool parsed_num_raster_threads = 759 bool parsed_num_raster_threads =
658 base::StringToInt(string_value, &num_raster_threads); 760 base::StringToInt(string_value, &num_raster_threads);
659 DCHECK(parsed_num_raster_threads) << string_value; 761 DCHECK(parsed_num_raster_threads) << string_value;
660 DCHECK_GT(num_raster_threads, 0); 762 DCHECK_GT(num_raster_threads, 0);
661 763
662 // Note: Currently, gathering of pixel refs when using a single 764 // Note: Currently, gathering of pixel refs when using a single
663 // raster thread doesn't provide any benefit. This might change 765 // raster thread doesn't provide any benefit. This might change
664 // in the future but we avoid it for now to reduce the cost of 766 // in the future but we avoid it for now to reduce the cost of
665 // Picture::Create. 767 // Picture::Create.
666 is_gather_pixel_refs_enabled_ = num_raster_threads > 1; 768 is_gather_pixel_refs_enabled_ = num_raster_threads > 1;
667 769
668 base::SimpleThread::Options thread_options; 770 base::SimpleThread::Options thread_options;
669 #if defined(OS_ANDROID) || defined(OS_LINUX) 771 #if defined(OS_ANDROID) || defined(OS_LINUX)
670 if (!command_line.HasSwitch( 772 if (!command_line.HasSwitch(
671 switches::kUseNormalPriorityForTileTaskWorkerThreads)) { 773 switches::kUseNormalPriorityForTileTaskWorkerThreads)) {
672 thread_options.set_priority(base::ThreadPriority::BACKGROUND); 774 thread_options.set_priority(base::ThreadPriority::BACKGROUND);
673 } 775 }
674 #endif 776 #endif
675 while (compositor_raster_threads_.size() < 777
676 static_cast<size_t>(num_raster_threads)) { 778 raster_worker_pool_->Start(num_raster_threads, thread_options);
677 scoped_ptr<CompositorRasterThread> raster_thread(new CompositorRasterThread(
678 compositor_task_graph_runner_.get(),
679 base::StringPrintf("CompositorTileWorker%u",
680 static_cast<unsigned>(
681 compositor_raster_threads_.size() + 1)).c_str(),
682 thread_options));
683 raster_thread->Start();
684 compositor_raster_threads_.push_back(raster_thread.Pass());
685 }
686 779
687 // TODO(boliu): In single process, browser main loop should set up the 780 // TODO(boliu): In single process, browser main loop should set up the
688 // discardable memory manager, and should skip this if kSingleProcess. 781 // discardable memory manager, and should skip this if kSingleProcess.
689 // See crbug.com/503724. 782 // See crbug.com/503724.
690 base::DiscardableMemoryAllocator::SetInstance( 783 base::DiscardableMemoryAllocator::SetInstance(
691 ChildThreadImpl::discardable_shared_memory_manager()); 784 ChildThreadImpl::discardable_shared_memory_manager());
692 785
693 service_registry()->AddService<RenderFrameSetup>( 786 service_registry()->AddService<RenderFrameSetup>(
694 base::Bind(CreateRenderFrameSetup)); 787 base::Bind(CreateRenderFrameSetup));
695 788
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
754 } 847 }
755 848
756 media_thread_.reset(); 849 media_thread_.reset();
757 850
758 // AudioMessageFilter may be accessed on |media_thread_|, so shutdown after. 851 // AudioMessageFilter may be accessed on |media_thread_|, so shutdown after.
759 RemoveFilter(audio_message_filter_.get()); 852 RemoveFilter(audio_message_filter_.get());
760 audio_message_filter_ = NULL; 853 audio_message_filter_ = NULL;
761 854
762 compositor_thread_.reset(); 855 compositor_thread_.reset();
763 856
764 // Shutdown raster threads. 857 raster_worker_pool_->Shutdown();
765 compositor_task_graph_runner_->Shutdown();
766 while (!compositor_raster_threads_.empty()) {
767 compositor_raster_threads_.back()->Join();
768 compositor_raster_threads_.pop_back();
769 }
770 compositor_task_graph_runner_.reset();
771 858
772 main_input_callback_.Cancel(); 859 main_input_callback_.Cancel();
773 input_handler_manager_.reset(); 860 input_handler_manager_.reset();
774 if (input_event_filter_.get()) { 861 if (input_event_filter_.get()) {
775 RemoveFilter(input_event_filter_.get()); 862 RemoveFilter(input_event_filter_.get());
776 input_event_filter_ = NULL; 863 input_event_filter_ = NULL;
777 } 864 }
778 865
779 // RemoveEmbeddedWorkerRoute may be called while deleting 866 // RemoveEmbeddedWorkerRoute may be called while deleting
780 // EmbeddedWorkerDispatcher. So it must be deleted before deleting 867 // EmbeddedWorkerDispatcher. So it must be deleted before deleting
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 if (SynchronousCompositorFactory* factory = 1540 if (SynchronousCompositorFactory* factory =
1454 SynchronousCompositorFactory::GetInstance()) { 1541 SynchronousCompositorFactory::GetInstance()) {
1455 return factory->CreateExternalBeginFrameSource(routing_id); 1542 return factory->CreateExternalBeginFrameSource(routing_id);
1456 } 1543 }
1457 #endif 1544 #endif
1458 return make_scoped_ptr(new CompositorExternalBeginFrameSource( 1545 return make_scoped_ptr(new CompositorExternalBeginFrameSource(
1459 compositor_message_filter_.get(), sync_message_filter(), routing_id)); 1546 compositor_message_filter_.get(), sync_message_filter(), routing_id));
1460 } 1547 }
1461 1548
1462 cc::TaskGraphRunner* RenderThreadImpl::GetTaskGraphRunner() { 1549 cc::TaskGraphRunner* RenderThreadImpl::GetTaskGraphRunner() {
1463 return compositor_task_graph_runner_.get(); 1550 return raster_worker_pool_->GetTaskGraphRunner();
1464 } 1551 }
1465 1552
1466 bool RenderThreadImpl::IsGatherPixelRefsEnabled() { 1553 bool RenderThreadImpl::IsGatherPixelRefsEnabled() {
1467 return is_gather_pixel_refs_enabled_; 1554 return is_gather_pixel_refs_enabled_;
1468 } 1555 }
1469 1556
1470 bool RenderThreadImpl::IsMainThread() { 1557 bool RenderThreadImpl::IsMainThread() {
1471 return !!current(); 1558 return !!current();
1472 } 1559 }
1473 1560
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 media_thread_->Start(); 1877 media_thread_->Start();
1791 1878
1792 #if defined(OS_ANDROID) 1879 #if defined(OS_ANDROID)
1793 renderer_demuxer_ = new RendererDemuxerAndroid(); 1880 renderer_demuxer_ = new RendererDemuxerAndroid();
1794 AddFilter(renderer_demuxer_.get()); 1881 AddFilter(renderer_demuxer_.get());
1795 #endif 1882 #endif
1796 } 1883 }
1797 return media_thread_->task_runner(); 1884 return media_thread_->task_runner();
1798 } 1885 }
1799 1886
1887 base::SequencedTaskRunner* RenderThreadImpl::GetWorkerSequencedTaskRunner() {
1888 return raster_worker_pool_.get();
1889 }
1890
1800 void RenderThreadImpl::SampleGamepads(blink::WebGamepads* data) { 1891 void RenderThreadImpl::SampleGamepads(blink::WebGamepads* data) {
1801 blink_platform_impl_->sampleGamepads(*data); 1892 blink_platform_impl_->sampleGamepads(*data);
1802 } 1893 }
1803 1894
1804 bool RenderThreadImpl::RendererIsHidden() const { 1895 bool RenderThreadImpl::RendererIsHidden() const {
1805 return widget_count_ > 0 && hidden_widget_count_ == widget_count_; 1896 return widget_count_ > 0 && hidden_widget_count_ == widget_count_;
1806 } 1897 }
1807 1898
1808 void RenderThreadImpl::WidgetCreated() { 1899 void RenderThreadImpl::WidgetCreated() {
1809 bool renderer_was_hidden = RendererIsHidden(); 1900 bool renderer_was_hidden = RendererIsHidden();
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
1880 } 1971 }
1881 1972
1882 void RenderThreadImpl::PendingRenderFrameConnect::OnConnectionError() { 1973 void RenderThreadImpl::PendingRenderFrameConnect::OnConnectionError() {
1883 size_t erased = 1974 size_t erased =
1884 RenderThreadImpl::current()->pending_render_frame_connects_.erase( 1975 RenderThreadImpl::current()->pending_render_frame_connects_.erase(
1885 routing_id_); 1976 routing_id_);
1886 DCHECK_EQ(1u, erased); 1977 DCHECK_EQ(1u, erased);
1887 } 1978 }
1888 1979
1889 } // namespace content 1980 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/render_thread_impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698