OLD | NEW |
---|---|
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 Loading... | |
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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
387 blink::WebGraphicsContext3D::Attributes GetOffscreenAttribs() { | 370 blink::WebGraphicsContext3D::Attributes GetOffscreenAttribs() { |
388 blink::WebGraphicsContext3D::Attributes attributes; | 371 blink::WebGraphicsContext3D::Attributes attributes; |
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 |
380 class RasterWorkerPool : public base::SequencedTaskRunner, | |
381 public base::DelegateSimpleThread::Delegate { | |
382 public: | |
383 RasterWorkerPool() | |
384 : namespace_token_(task_graph_runner_.GetNamespaceToken()) {} | |
385 | |
386 void Start(int num_raster_threads, | |
387 const base::SimpleThread::Options& thread_options) { | |
388 DCHECK(raster_threads_.empty()); | |
389 while (raster_threads_.size() < static_cast<size_t>(num_raster_threads)) { | |
390 scoped_ptr<base::DelegateSimpleThread> raster_thread( | |
391 new base::DelegateSimpleThread( | |
392 this, base::StringPrintf("CompositorTileWorker%u", | |
393 static_cast<unsigned>( | |
394 raster_threads_.size() + 1)).c_str(), | |
395 thread_options)); | |
396 raster_thread->Start(); | |
397 raster_threads_.push_back(raster_thread.Pass()); | |
398 } | |
399 } | |
400 | |
401 void Shutdown() { | |
402 // Shutdown raster threads. | |
403 task_graph_runner_.Shutdown(); | |
404 while (!raster_threads_.empty()) { | |
405 raster_threads_.back()->Join(); | |
406 raster_threads_.pop_back(); | |
407 } | |
408 } | |
409 | |
410 // Overridden from base::TaskRunner: | |
411 bool PostDelayedTask(const tracked_objects::Location& from_here, | |
412 const base::Closure& task, | |
413 base::TimeDelta delay) override { | |
414 return PostNonNestableDelayedTask(from_here, task, delay); | |
415 } | |
416 | |
417 // Overridden from base::TaskRunner: | |
reveman
2015/06/30 18:03:52
nit: remove line 417 and 416 so these functions be
Daniele Castagna
2015/06/30 18:55:25
Done.
| |
418 bool RunsTasksOnCurrentThread() const override { return true; } | |
419 | |
420 // Overridden from base::SequencedTaskRunner: | |
421 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, | |
422 const base::Closure& task, | |
423 base::TimeDelta delay) override { | |
424 base::AutoLock lock(lock_); | |
425 DCHECK(!raster_threads_.empty()); | |
426 | |
427 // Remove completed tasks. | |
428 DCHECK(completed_tasks_.empty()); | |
429 task_graph_runner_.CollectCompletedTasks(namespace_token_, | |
430 &completed_tasks_); | |
431 DCHECK_LE(completed_tasks_.size(), tasks_.size()); | |
432 DCHECK(std::equal(completed_tasks_.begin(), completed_tasks_.end(), | |
433 tasks_.begin())); | |
434 tasks_.erase(tasks_.begin(), tasks_.begin() + completed_tasks_.size()); | |
435 completed_tasks_.clear(); | |
436 | |
437 tasks_.push_back(make_scoped_refptr(new ClosureTask(task))); | |
438 | |
439 graph_.Reset(); | |
440 for (const auto& task : tasks_) { | |
441 cc::TaskGraph::Node node(task.get(), 0, graph_.nodes.size()); | |
442 if (graph_.nodes.size()) { | |
443 graph_.edges.push_back( | |
444 cc::TaskGraph::Edge(graph_.nodes.back().task, node.task)); | |
445 } | |
446 graph_.nodes.push_back(node); | |
447 } | |
448 | |
449 task_graph_runner_.ScheduleTasks(namespace_token_, &graph_); | |
450 return true; | |
451 } | |
452 | |
453 // Overridden from base::DelegateSimpleThread::Delegate: | |
454 void Run() override { task_graph_runner_.Run(); } | |
455 | |
456 cc::TaskGraphRunner* GetTaskGraphRunner() { return &task_graph_runner_; } | |
457 | |
458 protected: | |
459 ~RasterWorkerPool() override {} | |
460 | |
461 private: | |
462 // Simple Task for the TaskGraphRunner that wraps a closure. | |
463 class ClosureTask : public cc::Task { | |
464 public: | |
465 ClosureTask(const base::Closure& closure) : closure_(closure) {} | |
466 void RunOnWorkerThread() override { | |
reveman
2015/06/30 18:03:52
nit: blank line after ctor and add: // Overridden
Daniele Castagna
2015/06/30 18:55:24
Done.
| |
467 closure_.Run(); | |
468 closure_.Reset(); | |
469 }; | |
470 | |
471 protected: | |
472 ~ClosureTask() override {} | |
473 | |
474 private: | |
475 base::Closure closure_; | |
476 | |
477 DISALLOW_COPY_AND_ASSIGN(ClosureTask); | |
478 }; | |
479 | |
480 // The actual threads where work is done. | |
481 ScopedVector<base::DelegateSimpleThread> raster_threads_; | |
reveman
2015/06/30 18:03:52
nit: just "threads_" as "raster" is implicit from
Daniele Castagna
2015/06/30 18:55:24
Done.
| |
482 cc::TaskGraphRunner task_graph_runner_; | |
483 | |
484 // Lock to exclusively access all the following members that are used to | |
485 // implement the SequencedTaskRunner interface. | |
486 base::Lock lock_; | |
487 // List of tasks currently queued up for execution. | |
488 ClosureTask::Vector tasks_; | |
489 // Cached vector to avoid allocation when getting the list of complete tasks. | |
490 ClosureTask::Vector completed_tasks_; | |
491 // Graph object used for scheduling tasks. | |
492 cc::TaskGraph graph_; | |
493 // Namespace where the SequencedTaskRunner tasks run. | |
494 cc::NamespaceToken namespace_token_; | |
reveman
2015/06/30 18:03:52
nit: can you move this above the lock_ and make it
Daniele Castagna
2015/06/30 18:55:24
Done.
| |
495 }; | |
496 | |
397 } // namespace | 497 } // namespace |
398 | 498 |
399 // For measuring memory usage after each task. Behind a command line flag. | 499 // For measuring memory usage after each task. Behind a command line flag. |
400 class MemoryObserver : public base::MessageLoop::TaskObserver { | 500 class MemoryObserver : public base::MessageLoop::TaskObserver { |
401 public: | 501 public: |
402 MemoryObserver() {} | 502 MemoryObserver() {} |
403 ~MemoryObserver() override {} | 503 ~MemoryObserver() override {} |
404 | 504 |
405 void WillProcessTask(const base::PendingTask& pending_task) override {} | 505 void WillProcessTask(const base::PendingTask& pending_task) override {} |
406 | 506 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
456 } | 556 } |
457 | 557 |
458 RenderThreadImpl* RenderThreadImpl::current() { | 558 RenderThreadImpl* RenderThreadImpl::current() { |
459 return lazy_tls.Pointer()->Get(); | 559 return lazy_tls.Pointer()->Get(); |
460 } | 560 } |
461 | 561 |
462 RenderThreadImpl::RenderThreadImpl(const InProcessChildThreadParams& params) | 562 RenderThreadImpl::RenderThreadImpl(const InProcessChildThreadParams& params) |
463 : ChildThreadImpl(Options::Builder() | 563 : ChildThreadImpl(Options::Builder() |
464 .InBrowserProcess(params) | 564 .InBrowserProcess(params) |
465 .UseMojoChannel(ShouldUseMojoChannel()) | 565 .UseMojoChannel(ShouldUseMojoChannel()) |
466 .Build()) { | 566 .Build()), |
567 raster_worker_pool_(new RasterWorkerPool()) { | |
467 Init(); | 568 Init(); |
468 } | 569 } |
469 | 570 |
470 // When we run plugins in process, we actually run them on the render thread, | 571 // 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. | 572 // which means that we need to make the render thread pump UI events. |
472 RenderThreadImpl::RenderThreadImpl( | 573 RenderThreadImpl::RenderThreadImpl( |
473 scoped_ptr<base::MessageLoop> main_message_loop) | 574 scoped_ptr<base::MessageLoop> main_message_loop) |
474 : ChildThreadImpl(Options::Builder() | 575 : ChildThreadImpl(Options::Builder() |
475 .UseMojoChannel(ShouldUseMojoChannel()) | 576 .UseMojoChannel(ShouldUseMojoChannel()) |
476 .Build()), | 577 .Build()), |
477 main_message_loop_(main_message_loop.Pass()) { | 578 main_message_loop_(main_message_loop.Pass()), |
579 raster_worker_pool_(new RasterWorkerPool()) { | |
478 Init(); | 580 Init(); |
479 } | 581 } |
480 | 582 |
481 void RenderThreadImpl::Init() { | 583 void RenderThreadImpl::Init() { |
482 TRACE_EVENT_BEGIN_ETW("RenderThreadImpl::Init", 0, ""); | 584 TRACE_EVENT_BEGIN_ETW("RenderThreadImpl::Init", 0, ""); |
483 | 585 |
484 base::trace_event::TraceLog::GetInstance()->SetThreadSortIndex( | 586 base::trace_event::TraceLog::GetInstance()->SetThreadSortIndex( |
485 base::PlatformThread::CurrentId(), | 587 base::PlatformThread::CurrentId(), |
486 kTraceEventRendererMainThreadSortIndex); | 588 kTraceEventRendererMainThreadSortIndex); |
487 | 589 |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
640 is_distance_field_text_enabled_ = false; | 742 is_distance_field_text_enabled_ = false; |
641 } | 743 } |
642 | 744 |
643 // Note that under Linux, the media library will normally already have | 745 // Note that under Linux, the media library will normally already have |
644 // been initialized by the Zygote before this instance became a Renderer. | 746 // been initialized by the Zygote before this instance became a Renderer. |
645 media::InitializeMediaLibrary(); | 747 media::InitializeMediaLibrary(); |
646 | 748 |
647 memory_pressure_listener_.reset(new base::MemoryPressureListener( | 749 memory_pressure_listener_.reset(new base::MemoryPressureListener( |
648 base::Bind(&RenderThreadImpl::OnMemoryPressure, base::Unretained(this)))); | 750 base::Bind(&RenderThreadImpl::OnMemoryPressure, base::Unretained(this)))); |
649 | 751 |
650 compositor_task_graph_runner_.reset(new cc::TaskGraphRunner); | |
651 | |
652 is_gather_pixel_refs_enabled_ = false; | 752 is_gather_pixel_refs_enabled_ = false; |
653 | 753 |
654 int num_raster_threads = 0; | 754 int num_raster_threads = 0; |
655 std::string string_value = | 755 std::string string_value = |
656 command_line.GetSwitchValueASCII(switches::kNumRasterThreads); | 756 command_line.GetSwitchValueASCII(switches::kNumRasterThreads); |
657 bool parsed_num_raster_threads = | 757 bool parsed_num_raster_threads = |
658 base::StringToInt(string_value, &num_raster_threads); | 758 base::StringToInt(string_value, &num_raster_threads); |
659 DCHECK(parsed_num_raster_threads) << string_value; | 759 DCHECK(parsed_num_raster_threads) << string_value; |
660 DCHECK_GT(num_raster_threads, 0); | 760 DCHECK_GT(num_raster_threads, 0); |
661 | 761 |
662 // Note: Currently, gathering of pixel refs when using a single | 762 // Note: Currently, gathering of pixel refs when using a single |
663 // raster thread doesn't provide any benefit. This might change | 763 // 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 | 764 // in the future but we avoid it for now to reduce the cost of |
665 // Picture::Create. | 765 // Picture::Create. |
666 is_gather_pixel_refs_enabled_ = num_raster_threads > 1; | 766 is_gather_pixel_refs_enabled_ = num_raster_threads > 1; |
667 | 767 |
668 base::SimpleThread::Options thread_options; | 768 base::SimpleThread::Options thread_options; |
669 #if defined(OS_ANDROID) || defined(OS_LINUX) | 769 #if defined(OS_ANDROID) || defined(OS_LINUX) |
670 if (!command_line.HasSwitch( | 770 if (!command_line.HasSwitch( |
671 switches::kUseNormalPriorityForTileTaskWorkerThreads)) { | 771 switches::kUseNormalPriorityForTileTaskWorkerThreads)) { |
672 thread_options.set_priority(base::ThreadPriority::BACKGROUND); | 772 thread_options.set_priority(base::ThreadPriority::BACKGROUND); |
673 } | 773 } |
674 #endif | 774 #endif |
675 while (compositor_raster_threads_.size() < | 775 |
676 static_cast<size_t>(num_raster_threads)) { | 776 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 | 777 |
687 // TODO(boliu): In single process, browser main loop should set up the | 778 // TODO(boliu): In single process, browser main loop should set up the |
688 // discardable memory manager, and should skip this if kSingleProcess. | 779 // discardable memory manager, and should skip this if kSingleProcess. |
689 // See crbug.com/503724. | 780 // See crbug.com/503724. |
690 base::DiscardableMemoryAllocator::SetInstance( | 781 base::DiscardableMemoryAllocator::SetInstance( |
691 ChildThreadImpl::discardable_shared_memory_manager()); | 782 ChildThreadImpl::discardable_shared_memory_manager()); |
692 | 783 |
693 service_registry()->AddService<RenderFrameSetup>( | 784 service_registry()->AddService<RenderFrameSetup>( |
694 base::Bind(CreateRenderFrameSetup)); | 785 base::Bind(CreateRenderFrameSetup)); |
695 | 786 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
754 } | 845 } |
755 | 846 |
756 media_thread_.reset(); | 847 media_thread_.reset(); |
757 | 848 |
758 // AudioMessageFilter may be accessed on |media_thread_|, so shutdown after. | 849 // AudioMessageFilter may be accessed on |media_thread_|, so shutdown after. |
759 RemoveFilter(audio_message_filter_.get()); | 850 RemoveFilter(audio_message_filter_.get()); |
760 audio_message_filter_ = NULL; | 851 audio_message_filter_ = NULL; |
761 | 852 |
762 compositor_thread_.reset(); | 853 compositor_thread_.reset(); |
763 | 854 |
764 // Shutdown raster threads. | 855 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 | 856 |
772 main_input_callback_.Cancel(); | 857 main_input_callback_.Cancel(); |
773 input_handler_manager_.reset(); | 858 input_handler_manager_.reset(); |
774 if (input_event_filter_.get()) { | 859 if (input_event_filter_.get()) { |
775 RemoveFilter(input_event_filter_.get()); | 860 RemoveFilter(input_event_filter_.get()); |
776 input_event_filter_ = NULL; | 861 input_event_filter_ = NULL; |
777 } | 862 } |
778 | 863 |
779 // RemoveEmbeddedWorkerRoute may be called while deleting | 864 // RemoveEmbeddedWorkerRoute may be called while deleting |
780 // EmbeddedWorkerDispatcher. So it must be deleted before deleting | 865 // EmbeddedWorkerDispatcher. So it must be deleted before deleting |
(...skipping 672 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1453 if (SynchronousCompositorFactory* factory = | 1538 if (SynchronousCompositorFactory* factory = |
1454 SynchronousCompositorFactory::GetInstance()) { | 1539 SynchronousCompositorFactory::GetInstance()) { |
1455 return factory->CreateExternalBeginFrameSource(routing_id); | 1540 return factory->CreateExternalBeginFrameSource(routing_id); |
1456 } | 1541 } |
1457 #endif | 1542 #endif |
1458 return make_scoped_ptr(new CompositorExternalBeginFrameSource( | 1543 return make_scoped_ptr(new CompositorExternalBeginFrameSource( |
1459 compositor_message_filter_.get(), sync_message_filter(), routing_id)); | 1544 compositor_message_filter_.get(), sync_message_filter(), routing_id)); |
1460 } | 1545 } |
1461 | 1546 |
1462 cc::TaskGraphRunner* RenderThreadImpl::GetTaskGraphRunner() { | 1547 cc::TaskGraphRunner* RenderThreadImpl::GetTaskGraphRunner() { |
1463 return compositor_task_graph_runner_.get(); | 1548 return raster_worker_pool_->GetTaskGraphRunner(); |
1464 } | 1549 } |
1465 | 1550 |
1466 bool RenderThreadImpl::IsGatherPixelRefsEnabled() { | 1551 bool RenderThreadImpl::IsGatherPixelRefsEnabled() { |
1467 return is_gather_pixel_refs_enabled_; | 1552 return is_gather_pixel_refs_enabled_; |
1468 } | 1553 } |
1469 | 1554 |
1470 bool RenderThreadImpl::IsMainThread() { | 1555 bool RenderThreadImpl::IsMainThread() { |
1471 return !!current(); | 1556 return !!current(); |
1472 } | 1557 } |
1473 | 1558 |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1790 media_thread_->Start(); | 1875 media_thread_->Start(); |
1791 | 1876 |
1792 #if defined(OS_ANDROID) | 1877 #if defined(OS_ANDROID) |
1793 renderer_demuxer_ = new RendererDemuxerAndroid(); | 1878 renderer_demuxer_ = new RendererDemuxerAndroid(); |
1794 AddFilter(renderer_demuxer_.get()); | 1879 AddFilter(renderer_demuxer_.get()); |
1795 #endif | 1880 #endif |
1796 } | 1881 } |
1797 return media_thread_->task_runner(); | 1882 return media_thread_->task_runner(); |
1798 } | 1883 } |
1799 | 1884 |
1885 base::SequencedTaskRunner* RenderThreadImpl::GetWorkerSequencedTaskRunner() { | |
1886 return raster_worker_pool_.get(); | |
1887 } | |
1888 | |
1800 void RenderThreadImpl::SampleGamepads(blink::WebGamepads* data) { | 1889 void RenderThreadImpl::SampleGamepads(blink::WebGamepads* data) { |
1801 blink_platform_impl_->sampleGamepads(*data); | 1890 blink_platform_impl_->sampleGamepads(*data); |
1802 } | 1891 } |
1803 | 1892 |
1804 bool RenderThreadImpl::RendererIsHidden() const { | 1893 bool RenderThreadImpl::RendererIsHidden() const { |
1805 return widget_count_ > 0 && hidden_widget_count_ == widget_count_; | 1894 return widget_count_ > 0 && hidden_widget_count_ == widget_count_; |
1806 } | 1895 } |
1807 | 1896 |
1808 void RenderThreadImpl::WidgetCreated() { | 1897 void RenderThreadImpl::WidgetCreated() { |
1809 bool renderer_was_hidden = RendererIsHidden(); | 1898 bool renderer_was_hidden = RendererIsHidden(); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1880 } | 1969 } |
1881 | 1970 |
1882 void RenderThreadImpl::PendingRenderFrameConnect::OnConnectionError() { | 1971 void RenderThreadImpl::PendingRenderFrameConnect::OnConnectionError() { |
1883 size_t erased = | 1972 size_t erased = |
1884 RenderThreadImpl::current()->pending_render_frame_connects_.erase( | 1973 RenderThreadImpl::current()->pending_render_frame_connects_.erase( |
1885 routing_id_); | 1974 routing_id_); |
1886 DCHECK_EQ(1u, erased); | 1975 DCHECK_EQ(1u, erased); |
1887 } | 1976 } |
1888 | 1977 |
1889 } // namespace content | 1978 } // namespace content |
OLD | NEW |