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: | |
382 RasterWorkerPool() : namespace_token_(){}; | |
reveman
2015/06/30 04:47:52
; after function definition?
Daniele Castagna
2015/06/30 15:43:49
Done.
| |
383 | |
384 void Start(int num_raster_threads, | |
385 const base::SimpleThread::Options& thread_options) { | |
reveman
2015/06/30 04:47:51
Can we create whatever is possible in ctor and jus
Daniele Castagna
2015/06/30 15:43:50
Done.
| |
386 DCHECK(!task_graph_runner_); | |
387 task_graph_runner_.reset(new cc::TaskGraphRunner); | |
388 namespace_token_ = task_graph_runner_->GetNamespaceToken(); | |
389 | |
390 while (raster_threads_.size() < static_cast<size_t>(num_raster_threads)) { | |
391 scoped_ptr<RasterThread> raster_thread(new RasterThread( | |
392 task_graph_runner_.get(), | |
393 base::StringPrintf("CompositorTileWorker%u", | |
394 static_cast<unsigned>(raster_threads_.size() + 1)) | |
395 .c_str(), | |
396 thread_options)); | |
397 raster_thread->Start(); | |
398 raster_threads_.push_back(raster_thread.Pass()); | |
399 } | |
400 } | |
401 | |
402 void Shutdown() { | |
403 // Shutdown raster threads. | |
404 task_graph_runner_->Shutdown(); | |
405 while (!raster_threads_.empty()) { | |
406 raster_threads_.back()->Join(); | |
407 raster_threads_.pop_back(); | |
408 } | |
409 } | |
410 | |
411 // Overridden from base::TaskRunner: | |
412 bool PostDelayedTask(const tracked_objects::Location& from_here, | |
413 const base::Closure& task, | |
414 base::TimeDelta delay) override { | |
415 DCHECK(task_graph_runner_); | |
416 return PostNonNestableDelayedTask(from_here, task, delay); | |
417 } | |
418 | |
419 // Overridden from base::TaskRunner: | |
420 bool RunsTasksOnCurrentThread() const override { return true; } | |
421 | |
422 // Overridden from base::SequencedTaskRunner: | |
423 bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, | |
424 const base::Closure& task, | |
425 base::TimeDelta delay) override { | |
426 base::AutoLock lock(lock_); | |
427 DCHECK(task_graph_runner_); | |
428 DCHECK(!raster_threads_.empty()); | |
429 | |
430 // Remove completed tasks. | |
431 DCHECK(completed_tasks_.empty()); | |
432 task_graph_runner_->CollectCompletedTasks(namespace_token_, | |
433 &completed_tasks_); | |
434 DCHECK_LE(completed_tasks_.size(), tasks_.size()); | |
435 DCHECK(std::equal(completed_tasks_.begin(), completed_tasks_.end(), | |
436 tasks_.begin())); | |
437 tasks_.erase(tasks_.begin(), tasks_.begin() + completed_tasks_.size()); | |
438 completed_tasks_.clear(); | |
439 | |
440 tasks_.push_back(make_scoped_refptr(new TaskGraphRunnerClosureTask(task))); | |
441 | |
442 graph_.Reset(); | |
443 for (const auto& task : tasks_) { | |
444 cc::TaskGraph::Node node(task.get(), 0, graph_.nodes.size()); | |
445 if (graph_.nodes.size()) { | |
446 graph_.edges.push_back( | |
447 cc::TaskGraph::Edge(graph_.nodes.back().task, node.task)); | |
448 } | |
449 graph_.nodes.push_back(node); | |
450 } | |
451 | |
452 task_graph_runner_->ScheduleTasks(namespace_token_, &graph_); | |
453 return true; | |
454 } | |
455 | |
456 cc::TaskGraphRunner* GetTaskGraphRunner() { return task_graph_runner_.get(); } | |
457 | |
458 protected: | |
459 ~RasterWorkerPool() override{}; | |
460 | |
461 private: | |
462 // Simple Task for the TaskGraphRunner that wraps a closure. | |
463 class TaskGraphRunnerClosureTask : public cc::Task { | |
reveman
2015/06/30 04:47:52
"ClosureTask" sufficient name?
Daniele Castagna
2015/06/30 15:43:50
Done.
| |
464 public: | |
465 TaskGraphRunnerClosureTask(const base::Closure& closure) | |
466 : closure_(closure) {} | |
467 void RunOnWorkerThread() override { | |
468 closure_.Run(); | |
469 closure_.Reset(); | |
470 }; | |
471 | |
472 protected: | |
473 ~TaskGraphRunnerClosureTask() override {} | |
474 | |
475 private: | |
476 base::Closure closure_; | |
477 | |
478 DISALLOW_COPY_AND_ASSIGN(TaskGraphRunnerClosureTask); | |
479 }; | |
480 | |
481 // Simple thread that calls Run on the TaskGraphRunner. | |
482 class RasterThread : public base::SimpleThread { | |
reveman
2015/06/30 04:47:51
can we use DelegateSimpleThread instead and have R
Daniele Castagna
2015/06/30 15:43:49
Done.
It'd be nicer if DelegateSimpleThread took
| |
483 public: | |
484 RasterThread(cc::TaskGraphRunner* task_graph_runner, | |
485 const std::string& name_prefix, | |
486 base::SimpleThread::Options options) | |
487 : base::SimpleThread(name_prefix, options), | |
488 task_graph_runner_(task_graph_runner) {} | |
489 | |
490 // Overridden from base::SimpleThread: | |
491 void Run() override { task_graph_runner_->Run(); } | |
492 | |
493 private: | |
494 cc::TaskGraphRunner* task_graph_runner_; | |
495 | |
496 DISALLOW_COPY_AND_ASSIGN(RasterThread); | |
497 }; | |
498 | |
499 // The actual threads where work is done. | |
500 ScopedVector<base::SimpleThread> raster_threads_; | |
501 scoped_ptr<cc::TaskGraphRunner> task_graph_runner_; | |
reveman
2015/06/30 04:47:52
Can this just be "cc::TaskGraphRunner task_graph_r
Daniele Castagna
2015/06/30 15:43:50
Done.
| |
502 | |
503 // Lock for the SequencedTaskRunner implementation state. | |
reveman
2015/06/30 04:47:52
what is that state? everything below? please make
Daniele Castagna
2015/06/30 15:43:50
Done.
| |
504 base::Lock lock_; | |
505 // List of tasks currently queued up for execution. | |
506 TaskGraphRunnerClosureTask::Vector tasks_; | |
507 // Cached vector to avoid allocation when getting the list of complete tasks. | |
508 TaskGraphRunnerClosureTask::Vector completed_tasks_; | |
509 // Current graph set for scheduling. | |
reveman
2015/06/30 04:47:52
not really true, is it? this is used to avoid unne
Daniele Castagna
2015/06/30 15:43:49
This is the last graph scheduled with ::ScheduleTa
| |
510 cc::TaskGraph graph_; | |
511 // Namespace where the SequencedTaskRunner tasks run. | |
512 cc::NamespaceToken namespace_token_; | |
513 }; | |
514 | |
397 } // namespace | 515 } // namespace |
398 | 516 |
399 // For measuring memory usage after each task. Behind a command line flag. | 517 // For measuring memory usage after each task. Behind a command line flag. |
400 class MemoryObserver : public base::MessageLoop::TaskObserver { | 518 class MemoryObserver : public base::MessageLoop::TaskObserver { |
401 public: | 519 public: |
402 MemoryObserver() {} | 520 MemoryObserver() {} |
403 ~MemoryObserver() override {} | 521 ~MemoryObserver() override {} |
404 | 522 |
405 void WillProcessTask(const base::PendingTask& pending_task) override {} | 523 void WillProcessTask(const base::PendingTask& pending_task) override {} |
406 | 524 |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
640 is_distance_field_text_enabled_ = false; | 758 is_distance_field_text_enabled_ = false; |
641 } | 759 } |
642 | 760 |
643 // Note that under Linux, the media library will normally already have | 761 // Note that under Linux, the media library will normally already have |
644 // been initialized by the Zygote before this instance became a Renderer. | 762 // been initialized by the Zygote before this instance became a Renderer. |
645 media::InitializeMediaLibrary(); | 763 media::InitializeMediaLibrary(); |
646 | 764 |
647 memory_pressure_listener_.reset(new base::MemoryPressureListener( | 765 memory_pressure_listener_.reset(new base::MemoryPressureListener( |
648 base::Bind(&RenderThreadImpl::OnMemoryPressure, base::Unretained(this)))); | 766 base::Bind(&RenderThreadImpl::OnMemoryPressure, base::Unretained(this)))); |
649 | 767 |
650 compositor_task_graph_runner_.reset(new cc::TaskGraphRunner); | |
651 | |
652 is_gather_pixel_refs_enabled_ = false; | 768 is_gather_pixel_refs_enabled_ = false; |
653 | 769 |
654 int num_raster_threads = 0; | 770 int num_raster_threads = 0; |
655 std::string string_value = | 771 std::string string_value = |
656 command_line.GetSwitchValueASCII(switches::kNumRasterThreads); | 772 command_line.GetSwitchValueASCII(switches::kNumRasterThreads); |
657 bool parsed_num_raster_threads = | 773 bool parsed_num_raster_threads = |
658 base::StringToInt(string_value, &num_raster_threads); | 774 base::StringToInt(string_value, &num_raster_threads); |
659 DCHECK(parsed_num_raster_threads) << string_value; | 775 DCHECK(parsed_num_raster_threads) << string_value; |
660 DCHECK_GT(num_raster_threads, 0); | 776 DCHECK_GT(num_raster_threads, 0); |
661 | 777 |
662 // Note: Currently, gathering of pixel refs when using a single | 778 // Note: Currently, gathering of pixel refs when using a single |
663 // raster thread doesn't provide any benefit. This might change | 779 // 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 | 780 // in the future but we avoid it for now to reduce the cost of |
665 // Picture::Create. | 781 // Picture::Create. |
666 is_gather_pixel_refs_enabled_ = num_raster_threads > 1; | 782 is_gather_pixel_refs_enabled_ = num_raster_threads > 1; |
667 | 783 |
668 base::SimpleThread::Options thread_options; | 784 base::SimpleThread::Options thread_options; |
669 #if defined(OS_ANDROID) || defined(OS_LINUX) | 785 #if defined(OS_ANDROID) || defined(OS_LINUX) |
670 if (!command_line.HasSwitch( | 786 if (!command_line.HasSwitch( |
671 switches::kUseNormalPriorityForTileTaskWorkerThreads)) { | 787 switches::kUseNormalPriorityForTileTaskWorkerThreads)) { |
672 thread_options.set_priority(base::ThreadPriority::BACKGROUND); | 788 thread_options.set_priority(base::ThreadPriority::BACKGROUND); |
673 } | 789 } |
674 #endif | 790 #endif |
675 while (compositor_raster_threads_.size() < | 791 |
676 static_cast<size_t>(num_raster_threads)) { | 792 raster_worker_pool_ = make_scoped_refptr(new RasterWorkerPool()); |
reveman
2015/06/30 04:47:51
move this to ctor?
Daniele Castagna
2015/06/30 15:43:49
Done.
| |
677 scoped_ptr<CompositorRasterThread> raster_thread(new CompositorRasterThread( | 793 raster_worker_pool_->Start(num_raster_threads, thread_options); |
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 | 794 |
687 // TODO(boliu): In single process, browser main loop should set up the | 795 // TODO(boliu): In single process, browser main loop should set up the |
688 // discardable memory manager, and should skip this if kSingleProcess. | 796 // discardable memory manager, and should skip this if kSingleProcess. |
689 // See crbug.com/503724. | 797 // See crbug.com/503724. |
690 base::DiscardableMemoryAllocator::SetInstance( | 798 base::DiscardableMemoryAllocator::SetInstance( |
691 ChildThreadImpl::discardable_shared_memory_manager()); | 799 ChildThreadImpl::discardable_shared_memory_manager()); |
692 | 800 |
693 service_registry()->AddService<RenderFrameSetup>( | 801 service_registry()->AddService<RenderFrameSetup>( |
694 base::Bind(CreateRenderFrameSetup)); | 802 base::Bind(CreateRenderFrameSetup)); |
695 | 803 |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
754 } | 862 } |
755 | 863 |
756 media_thread_.reset(); | 864 media_thread_.reset(); |
757 | 865 |
758 // AudioMessageFilter may be accessed on |media_thread_|, so shutdown after. | 866 // AudioMessageFilter may be accessed on |media_thread_|, so shutdown after. |
759 RemoveFilter(audio_message_filter_.get()); | 867 RemoveFilter(audio_message_filter_.get()); |
760 audio_message_filter_ = NULL; | 868 audio_message_filter_ = NULL; |
761 | 869 |
762 compositor_thread_.reset(); | 870 compositor_thread_.reset(); |
763 | 871 |
764 // Shutdown raster threads. | 872 raster_worker_pool_->Shutdown(); |
765 compositor_task_graph_runner_->Shutdown(); | 873 raster_worker_pool_ = nullptr; |
reveman
2015/06/30 04:47:52
We need Shutdown here but maybe just let the dtor
Daniele Castagna
2015/06/30 15:43:50
Done.
| |
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 | 874 |
772 main_input_callback_.Cancel(); | 875 main_input_callback_.Cancel(); |
773 input_handler_manager_.reset(); | 876 input_handler_manager_.reset(); |
774 if (input_event_filter_.get()) { | 877 if (input_event_filter_.get()) { |
775 RemoveFilter(input_event_filter_.get()); | 878 RemoveFilter(input_event_filter_.get()); |
776 input_event_filter_ = NULL; | 879 input_event_filter_ = NULL; |
777 } | 880 } |
778 | 881 |
779 // RemoveEmbeddedWorkerRoute may be called while deleting | 882 // RemoveEmbeddedWorkerRoute may be called while deleting |
780 // EmbeddedWorkerDispatcher. So it must be deleted before deleting | 883 // 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 = | 1556 if (SynchronousCompositorFactory* factory = |
1454 SynchronousCompositorFactory::GetInstance()) { | 1557 SynchronousCompositorFactory::GetInstance()) { |
1455 return factory->CreateExternalBeginFrameSource(routing_id); | 1558 return factory->CreateExternalBeginFrameSource(routing_id); |
1456 } | 1559 } |
1457 #endif | 1560 #endif |
1458 return make_scoped_ptr(new CompositorExternalBeginFrameSource( | 1561 return make_scoped_ptr(new CompositorExternalBeginFrameSource( |
1459 compositor_message_filter_.get(), sync_message_filter(), routing_id)); | 1562 compositor_message_filter_.get(), sync_message_filter(), routing_id)); |
1460 } | 1563 } |
1461 | 1564 |
1462 cc::TaskGraphRunner* RenderThreadImpl::GetTaskGraphRunner() { | 1565 cc::TaskGraphRunner* RenderThreadImpl::GetTaskGraphRunner() { |
1463 return compositor_task_graph_runner_.get(); | 1566 return raster_worker_pool_->GetTaskGraphRunner(); |
1464 } | 1567 } |
1465 | 1568 |
1466 bool RenderThreadImpl::IsGatherPixelRefsEnabled() { | 1569 bool RenderThreadImpl::IsGatherPixelRefsEnabled() { |
1467 return is_gather_pixel_refs_enabled_; | 1570 return is_gather_pixel_refs_enabled_; |
1468 } | 1571 } |
1469 | 1572 |
1470 bool RenderThreadImpl::IsMainThread() { | 1573 bool RenderThreadImpl::IsMainThread() { |
1471 return !!current(); | 1574 return !!current(); |
1472 } | 1575 } |
1473 | 1576 |
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1790 media_thread_->Start(); | 1893 media_thread_->Start(); |
1791 | 1894 |
1792 #if defined(OS_ANDROID) | 1895 #if defined(OS_ANDROID) |
1793 renderer_demuxer_ = new RendererDemuxerAndroid(); | 1896 renderer_demuxer_ = new RendererDemuxerAndroid(); |
1794 AddFilter(renderer_demuxer_.get()); | 1897 AddFilter(renderer_demuxer_.get()); |
1795 #endif | 1898 #endif |
1796 } | 1899 } |
1797 return media_thread_->task_runner(); | 1900 return media_thread_->task_runner(); |
1798 } | 1901 } |
1799 | 1902 |
1903 scoped_refptr<base::SequencedTaskRunner> | |
1904 RenderThreadImpl::GetWorkerSequencedTaskRunner() { | |
1905 return raster_worker_pool_; | |
1906 } | |
1907 | |
1800 void RenderThreadImpl::SampleGamepads(blink::WebGamepads* data) { | 1908 void RenderThreadImpl::SampleGamepads(blink::WebGamepads* data) { |
1801 blink_platform_impl_->sampleGamepads(*data); | 1909 blink_platform_impl_->sampleGamepads(*data); |
1802 } | 1910 } |
1803 | 1911 |
1804 bool RenderThreadImpl::RendererIsHidden() const { | 1912 bool RenderThreadImpl::RendererIsHidden() const { |
1805 return widget_count_ > 0 && hidden_widget_count_ == widget_count_; | 1913 return widget_count_ > 0 && hidden_widget_count_ == widget_count_; |
1806 } | 1914 } |
1807 | 1915 |
1808 void RenderThreadImpl::WidgetCreated() { | 1916 void RenderThreadImpl::WidgetCreated() { |
1809 bool renderer_was_hidden = RendererIsHidden(); | 1917 bool renderer_was_hidden = RendererIsHidden(); |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1880 } | 1988 } |
1881 | 1989 |
1882 void RenderThreadImpl::PendingRenderFrameConnect::OnConnectionError() { | 1990 void RenderThreadImpl::PendingRenderFrameConnect::OnConnectionError() { |
1883 size_t erased = | 1991 size_t erased = |
1884 RenderThreadImpl::current()->pending_render_frame_connects_.erase( | 1992 RenderThreadImpl::current()->pending_render_frame_connects_.erase( |
1885 routing_id_); | 1993 routing_id_); |
1886 DCHECK_EQ(1u, erased); | 1994 DCHECK_EQ(1u, erased); |
1887 } | 1995 } |
1888 | 1996 |
1889 } // namespace content | 1997 } // namespace content |
OLD | NEW |