Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / content / renderer / render_thread_impl.cc
index ed604a9..6984b13 100644 (file)
 #include "base/lazy_instance.h"
 #include "base/logging.h"
 #include "base/memory/discardable_memory.h"
+#include "base/memory/discardable_memory_emulated.h"
+#include "base/memory/discardable_memory_shmem_allocator.h"
 #include "base/memory/shared_memory.h"
 #include "base/metrics/field_trial.h"
 #include "base/metrics/histogram.h"
 #include "base/metrics/stats_table.h"
 #include "base/path_service.h"
+#include "base/single_thread_task_runner.h"
 #include "base/strings/string16.h"
-#include "base/strings/string_tokenizer.h"
 #include "base/strings/string_number_conversions.h"
+#include "base/strings/string_tokenizer.h"
 #include "base/strings/utf_string_conversions.h"
 #include "base/threading/thread_local.h"
 #include "base/threading/thread_restrictions.h"
 #include "base/values.h"
 #include "cc/base/switches.h"
+#include "cc/blink/web_external_bitmap_impl.h"
+#include "cc/blink/web_layer_impl.h"
 #include "cc/resources/raster_worker_pool.h"
 #include "content/child/appcache/appcache_dispatcher.h"
 #include "content/child/appcache/appcache_frontend_impl.h"
+#include "content/child/child_discardable_shared_memory_manager.h"
+#include "content/child/child_gpu_memory_buffer_manager.h"
 #include "content/child/child_histogram_message_filter.h"
+#include "content/child/content_child_helpers.h"
 #include "content/child/db_message_filter.h"
 #include "content/child/indexed_db/indexed_db_dispatcher.h"
 #include "content/child/indexed_db/indexed_db_message_filter.h"
 #include "content/child/runtime_features.h"
 #include "content/child/thread_safe_sender.h"
 #include "content/child/web_database_observer_impl.h"
+#include "content/child/worker_task_runner.h"
 #include "content/common/child_process_messages.h"
 #include "content/common/content_constants_internal.h"
 #include "content/common/database_messages.h"
 #include "content/common/dom_storage/dom_storage_messages.h"
+#include "content/common/frame_messages.h"
 #include "content/common/gpu/client/context_provider_command_buffer.h"
 #include "content/common/gpu/client/gpu_channel_host.h"
-#include "content/common/gpu/client/gpu_memory_buffer_impl.h"
 #include "content/common/gpu/gpu_messages.h"
 #include "content/common/gpu/gpu_process_launch_causes.h"
+#include "content/common/render_frame_setup.mojom.h"
 #include "content/common/resource_messages.h"
 #include "content/common/view_messages.h"
+#include "content/common/worker_messages.h"
 #include "content/public/common/content_constants.h"
 #include "content/public/common/content_paths.h"
 #include "content/public/common/content_switches.h"
 #include "content/renderer/dom_storage/dom_storage_dispatcher.h"
 #include "content/renderer/dom_storage/webstoragearea_impl.h"
 #include "content/renderer/dom_storage/webstoragenamespace_impl.h"
-#include "content/renderer/gamepad_shared_memory_reader.h"
 #include "content/renderer/gpu/compositor_output_surface.h"
-#include "content/renderer/gpu/gpu_benchmarking_extension.h"
 #include "content/renderer/input/input_event_filter.h"
 #include "content/renderer/input/input_handler_manager.h"
+#include "content/renderer/media/aec_dump_message_filter.h"
 #include "content/renderer/media/audio_input_message_filter.h"
 #include "content/renderer/media/audio_message_filter.h"
 #include "content/renderer/media/audio_renderer_mixer_manager.h"
 #include "content/renderer/media/media_stream_center.h"
-#include "content/renderer/media/media_stream_dependency_factory.h"
 #include "content/renderer/media/midi_message_filter.h"
-#include "content/renderer/media/peer_connection_tracker.h"
+#include "content/renderer/media/renderer_gpu_video_accelerator_factories.h"
 #include "content/renderer/media/video_capture_impl_manager.h"
 #include "content/renderer/media/video_capture_message_filter.h"
-#include "content/renderer/media/webrtc_identity_service.h"
+#include "content/renderer/net_info_helper.h"
 #include "content/renderer/p2p/socket_dispatcher.h"
+#include "content/renderer/render_frame_proxy.h"
 #include "content/renderer/render_process_impl.h"
 #include "content/renderer/render_view_impl.h"
-#include "content/renderer/renderer_webkitplatformsupport_impl.h"
+#include "content/renderer/renderer_blink_platform_impl.h"
+#include "content/renderer/scheduler/renderer_scheduler.h"
 #include "content/renderer/service_worker/embedded_worker_context_message_filter.h"
 #include "content/renderer/service_worker/embedded_worker_dispatcher.h"
-#include "grit/content_resources.h"
+#include "content/renderer/shared_worker/embedded_shared_worker_stub.h"
 #include "ipc/ipc_channel_handle.h"
 #include "ipc/ipc_forwarding_message_filter.h"
 #include "ipc/ipc_platform_file.h"
+#include "ipc/mojo/ipc_channel_mojo.h"
 #include "media/base/audio_hardware_config.h"
 #include "media/base/media.h"
 #include "media/filters/gpu_video_accelerator_factories.h"
+#include "mojo/common/common_type_converters.h"
 #include "net/base/net_errors.h"
 #include "net/base/net_util.h"
+#include "skia/ext/event_tracer_impl.h"
 #include "third_party/WebKit/public/platform/WebString.h"
+#include "third_party/WebKit/public/platform/WebThread.h"
 #include "third_party/WebKit/public/web/WebColorName.h"
 #include "third_party/WebKit/public/web/WebDatabase.h"
 #include "third_party/WebKit/public/web/WebDocument.h"
 #include "ui/base/layout.h"
 #include "ui/base/ui_base_switches.h"
 #include "v8/include/v8.h"
-#include "webkit/child/worker_task_runner.h"
-#include "webkit/renderer/compositor_bindings/web_external_bitmap_impl.h"
 
-#if defined(OS_WIN)
-#include <windows.h>
-#include <objbase.h>
-#else
-// TODO(port)
-#include "base/memory/scoped_handle.h"
-#include "content/child/npapi/np_channel_base.h"
+#if defined(OS_ANDROID)
+#include <cpu-features.h>
+#include "content/renderer/android/synchronous_compositor_factory.h"
+#include "content/renderer/media/android/renderer_demuxer_android.h"
+#endif
+
+#if defined(OS_MACOSX)
+#include "content/renderer/webscrollbarbehavior_impl_mac.h"
 #endif
 
 #if defined(OS_POSIX)
 #include "ipc/ipc_channel_posix.h"
 #endif
 
-#if defined(OS_ANDROID)
-#include <cpu-features.h>
-#include "content/renderer/android/synchronous_compositor_factory.h"
-#include "content/renderer/media/android/renderer_demuxer_android.h"
+#if defined(OS_WIN)
+#include <windows.h>
+#include <objbase.h>
+#else
+// TODO(port)
+#include "content/child/npapi/np_channel_base.h"
 #endif
 
 #if defined(ENABLE_PLUGINS)
 #include "content/renderer/npapi/plugin_channel_host.h"
 #endif
 
+#if defined(ENABLE_WEBRTC)
+#include "content/renderer/media/peer_connection_tracker.h"
+#include "content/renderer/media/rtc_peer_connection_handler.h"
+#include "content/renderer/media/webrtc/peer_connection_dependency_factory.h"
+#include "content/renderer/media/webrtc_identity_service.h"
+#endif
+
 using base::ThreadRestrictions;
 using blink::WebDocument;
 using blink::WebFrame;
@@ -152,11 +175,16 @@ namespace content {
 namespace {
 
 const int64 kInitialIdleHandlerDelayMs = 1000;
-const int64 kShortIdleHandlerDelayMs = 1000;
 const int64 kLongIdleHandlerDelayMs = 30*1000;
-const int kIdleCPUUsageThresholdInPercents = 3;
-const int kMinRasterThreads = 1;
-const int kMaxRasterThreads = 64;
+
+// Maximum allocation size allowed for image scaling filters that
+// require pre-scaling. Skia will fallback to a filter that doesn't
+// require pre-scaling if the default filter would require an
+// allocation that exceeds this limit.
+const size_t kImageCacheSingleAllocationByteLimit = 64 * 1024 * 1024;
+
+const size_t kEmulatedDiscardableMemoryBytesToKeepWhenWidgetsHidden =
+    4 * 1024 * 1024;
 
 // Keep the global RenderThreadImpl in a TLS slot so it is impossible to access
 // incorrectly from the wrong thread.
@@ -172,7 +200,7 @@ class RenderViewZoomer : public RenderViewVisitor {
                                         zoom_level_(zoom_level) {
   }
 
-  virtual bool Visit(RenderView* render_view) OVERRIDE {
+  bool Visit(RenderView* render_view) override {
     WebView* webview = render_view->GetWebView();
     WebDocument document = webview->mainFrame()->document();
 
@@ -183,7 +211,10 @@ class RenderViewZoomer : public RenderViewVisitor {
     GURL url(document.url());
     // Empty scheme works as wildcard that matches any scheme,
     if ((net::GetHostOrSpecFromURL(url) == host_) &&
-        (scheme_.empty() || scheme_ == url.scheme())) {
+        (scheme_.empty() || scheme_ == url.scheme()) &&
+        !static_cast<RenderViewImpl*>(render_view)
+             ->uses_temporary_zoom_level()) {
+      webview->hidePopups();
       webview->setZoomLevel(zoom_level_);
     }
     return true;
@@ -234,7 +265,7 @@ scoped_ptr<base::SharedMemory> AllocateSharedMemoryFunction(size_t size) {
   return RenderThreadImpl::Get()->HostAllocateSharedMemoryBuffer(size);
 }
 
-void EnableWebCoreLogChannels(const std::string& channels) {
+void EnableBlinkPlatformLogChannels(const std::string& channels) {
   if (channels.empty())
     return;
   base::StringTokenizer t(channels, ", ");
@@ -242,8 +273,82 @@ void EnableWebCoreLogChannels(const std::string& channels) {
     blink::enableLogChannel(t.token().c_str());
 }
 
+void NotifyTimezoneChangeOnThisThread() {
+  v8::Isolate* isolate = v8::Isolate::GetCurrent();
+  if (!isolate)
+    return;
+  v8::Date::DateTimeConfigurationChangeNotification(isolate);
+}
+
+class RenderFrameSetupImpl : public mojo::InterfaceImpl<RenderFrameSetup> {
+ public:
+  RenderFrameSetupImpl()
+      : routing_id_highmark_(-1) {
+  }
+
+  void GetServiceProviderForFrame(
+      int32_t frame_routing_id,
+      mojo::InterfaceRequest<mojo::ServiceProvider> request) override {
+    // TODO(morrita): This is for investigating http://crbug.com/415059 and
+    // should be removed once it is fixed.
+    CHECK_LT(routing_id_highmark_, frame_routing_id);
+    routing_id_highmark_ = frame_routing_id;
+
+    RenderFrameImpl* frame = RenderFrameImpl::FromRoutingID(frame_routing_id);
+    // We can receive a GetServiceProviderForFrame message for a frame not yet
+    // created due to a race between the message and a ViewMsg_New IPC that
+    // triggers creation of the RenderFrame we want.
+    if (!frame) {
+      RenderThreadImpl::current()->RegisterPendingRenderFrameConnect(
+          frame_routing_id, request.PassMessagePipe());
+      return;
+    }
+
+    frame->BindServiceRegistry(request.PassMessagePipe());
+  }
+
+ private:
+  int32_t routing_id_highmark_;
+};
+
+void CreateRenderFrameSetup(mojo::InterfaceRequest<RenderFrameSetup> request) {
+  mojo::BindToRequest(new RenderFrameSetupImpl(), &request);
+}
+
+bool ShouldUseMojoChannel() {
+  return CommandLine::ForCurrentProcess()->HasSwitch(
+             switches::kEnableRendererMojoChannel) ||
+         IPC::ChannelMojo::ShouldBeUsed();
+}
+
+blink::WebGraphicsContext3D::Attributes GetOffscreenAttribs() {
+  blink::WebGraphicsContext3D::Attributes attributes;
+  attributes.shareResources = true;
+  attributes.depth = false;
+  attributes.stencil = false;
+  attributes.antialias = false;
+  attributes.noAutomaticFlushes = true;
+  return attributes;
+}
+
 }  // namespace
 
+// For measuring memory usage after each task. Behind a command line flag.
+class MemoryObserver : public base::MessageLoop::TaskObserver {
+ public:
+  MemoryObserver() {}
+  ~MemoryObserver() override {}
+
+  void WillProcessTask(const base::PendingTask& pending_task) override {}
+
+  void DidProcessTask(const base::PendingTask& pending_task) override {
+    LOCAL_HISTOGRAM_MEMORY_KB("Memory.RendererUsed", GetMemoryUsageKB());
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(MemoryObserver);
+};
+
 RenderThreadImpl::HistogramCustomizer::HistogramCustomizer() {
   custom_histograms_.insert("V8.MemoryExternalFragmentationTotal");
   custom_histograms_.insert("V8.MemoryHeapSampleTotalCommitted");
@@ -283,7 +388,7 @@ void RenderThreadImpl::HistogramCustomizer::SetCommonHost(
   if (host != common_host_) {
     common_host_ = host;
     common_host_histogram_suffix_ = HostToCustomHistogramSuffix(host);
-    v8::V8::SetCreateHistogramFunction(CreateHistogram);
+    blink::mainThreadIsolate()->SetCreateHistogramFunction(CreateHistogram);
   }
 }
 
@@ -293,12 +398,13 @@ RenderThreadImpl* RenderThreadImpl::current() {
 
 // When we run plugins in process, we actually run them on the render thread,
 // which means that we need to make the render thread pump UI events.
-RenderThreadImpl::RenderThreadImpl() {
+RenderThreadImpl::RenderThreadImpl()
+    : ChildThread(Options(ShouldUseMojoChannel())) {
   Init();
 }
 
 RenderThreadImpl::RenderThreadImpl(const std::string& channel_name)
-    : ChildThread(channel_name) {
+    : ChildThread(Options(channel_name, ShouldUseMojoChannel())) {
   Init();
 }
 
@@ -309,10 +415,6 @@ void RenderThreadImpl::Init() {
       base::PlatformThread::CurrentId(),
       kTraceEventRendererMainThreadSortIndex);
 
-  v8::V8::SetCounterFunction(base::StatsTable::FindLocation);
-  v8::V8::SetCreateHistogramFunction(CreateHistogram);
-  v8::V8::SetAddHistogramSampleFunction(AddHistogramSample);
-
 #if defined(OS_MACOSX) || defined(OS_ANDROID)
   // On Mac and Android, the select popups are rendered by the browser.
   blink::WebView::setUseExternalPopupMenus(true);
@@ -332,13 +434,13 @@ void RenderThreadImpl::Init() {
   idle_notification_delay_in_ms_ = kInitialIdleHandlerDelayMs;
   idle_notifications_to_skip_ = 0;
   layout_test_mode_ = false;
-  shutdown_event_ = NULL;
 
   appcache_dispatcher_.reset(
       new AppCacheDispatcher(Get(), new AppCacheFrontendImpl()));
   dom_storage_dispatcher_.reset(new DomStorageDispatcher());
   main_thread_indexed_db_dispatcher_.reset(new IndexedDBDispatcher(
       thread_safe_sender()));
+  renderer_scheduler_ = RendererScheduler::Create();
   embedded_worker_dispatcher_.reset(new EmbeddedWorkerDispatcher());
 
   media_stream_center_ = NULL;
@@ -359,9 +461,13 @@ void RenderThreadImpl::Init() {
 
   webrtc_identity_service_.reset(new WebRTCIdentityService());
 
-  media_stream_factory_.reset(new MediaStreamDependencyFactory(
+  aec_dump_message_filter_ =
+      new AecDumpMessageFilter(GetIOMessageLoopProxy(),
+                               message_loop()->message_loop_proxy());
+  AddFilter(aec_dump_message_filter_.get());
+
+  peer_connection_factory_.reset(new PeerConnectionDependencyFactory(
       p2p_socket_dispatcher_.get()));
-  AddObserver(media_stream_factory_.get());
 #endif  // defined(ENABLE_WEBRTC)
 
   audio_input_message_filter_ =
@@ -371,7 +477,7 @@ void RenderThreadImpl::Init() {
   audio_message_filter_ = new AudioMessageFilter(GetIOMessageLoopProxy());
   AddFilter(audio_message_filter_.get());
 
-  midi_message_filter_ = new MIDIMessageFilter(GetIOMessageLoopProxy());
+  midi_message_filter_ = new MidiMessageFilter(GetIOMessageLoopProxy());
   AddFilter(midi_message_filter_.get());
 
   AddFilter((new IndexedDBMessageFilter(thread_safe_sender()))->GetFilter());
@@ -380,9 +486,47 @@ void RenderThreadImpl::Init() {
 
   GetContentClient()->renderer()->RenderThreadStarted();
 
+  InitSkiaEventTracer();
+
   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
-  if (command_line.HasSwitch(switches::kEnableGpuBenchmarking))
-      RegisterExtension(GpuBenchmarkingExtension::Get());
+
+  is_impl_side_painting_enabled_ =
+      command_line.HasSwitch(switches::kEnableImplSidePainting);
+  cc_blink::WebLayerImpl::SetImplSidePaintingEnabled(
+      is_impl_side_painting_enabled_);
+
+  is_zero_copy_enabled_ = command_line.HasSwitch(switches::kEnableZeroCopy);
+
+#if defined(OS_MACOSX) || defined(OS_ANDROID)
+  is_one_copy_enabled_ = command_line.HasSwitch(switches::kEnableOneCopy);
+#else
+  is_one_copy_enabled_ = !command_line.HasSwitch(switches::kDisableOneCopy);
+#endif
+
+  if (command_line.HasSwitch(switches::kDisableLCDText)) {
+    is_lcd_text_enabled_ = false;
+  } else if (command_line.HasSwitch(switches::kEnableLCDText)) {
+    is_lcd_text_enabled_ = true;
+  } else {
+#if defined(OS_ANDROID)
+    is_lcd_text_enabled_ = false;
+#else
+    is_lcd_text_enabled_ = true;
+#endif
+  }
+
+  is_gpu_rasterization_enabled_ =
+      command_line.HasSwitch(switches::kEnableGpuRasterization);
+  is_gpu_rasterization_forced_ =
+      command_line.HasSwitch(switches::kForceGpuRasterization);
+
+  if (command_line.HasSwitch(switches::kDisableDistanceFieldText)) {
+    is_distance_field_text_enabled_ = false;
+  } else if (command_line.HasSwitch(switches::kEnableDistanceFieldText)) {
+    is_distance_field_text_enabled_ = true;
+  } else {
+    is_distance_field_text_enabled_ = false;
+  }
 
   // Note that under Linux, the media library will normally already have
   // been initialized by the Zygote before this instance became a Renderer.
@@ -417,32 +561,33 @@ void RenderThreadImpl::Init() {
 
   base::DiscardableMemory::SetPreferredType(type);
 
-  // Allow discardable memory implementations to register memory pressure
-  // listeners.
-  base::DiscardableMemory::RegisterMemoryPressureListeners();
-
-  // AllocateGpuMemoryBuffer must be used exclusively on one thread but
-  // it doesn't have to be the same thread RenderThreadImpl is created on.
-  allocate_gpu_memory_buffer_thread_checker_.DetachFromThread();
-
-  if (command_line.HasSwitch(switches::kNumRasterThreads)) {
-    int num_raster_threads;
+  if (is_impl_side_painting_enabled_) {
+    int num_raster_threads = 0;
     std::string string_value =
         command_line.GetSwitchValueASCII(switches::kNumRasterThreads);
-    if (base::StringToInt(string_value, &num_raster_threads) &&
-        num_raster_threads >= kMinRasterThreads &&
-        num_raster_threads <= kMaxRasterThreads) {
-      cc::RasterWorkerPool::SetNumRasterThreads(num_raster_threads);
-    } else {
-      LOG(WARNING) << "Failed to parse switch " <<
-                      switches::kNumRasterThreads  << ": " << string_value;
-    }
+    bool parsed_num_raster_threads =
+        base::StringToInt(string_value, &num_raster_threads);
+    DCHECK(parsed_num_raster_threads) << string_value;
+    DCHECK_GT(num_raster_threads, 0);
+    cc::RasterWorkerPool::SetNumRasterThreads(num_raster_threads);
   }
 
+  base::DiscardableMemoryShmemAllocator::SetInstance(
+      ChildThread::discardable_shared_memory_manager());
+
+  service_registry()->AddService<RenderFrameSetup>(
+      base::Bind(CreateRenderFrameSetup));
+
   TRACE_EVENT_END_ETW("RenderThreadImpl::Init", 0, "");
 }
 
 RenderThreadImpl::~RenderThreadImpl() {
+  for (std::map<int, mojo::MessagePipeHandle>::iterator it =
+           pending_render_frame_connects_.begin();
+       it != pending_render_frame_connects_.end();
+       ++it) {
+    mojo::CloseRaw(it->second);
+  }
 }
 
 void RenderThreadImpl::Shutdown() {
@@ -451,10 +596,20 @@ void RenderThreadImpl::Shutdown() {
 
   ChildThread::Shutdown();
 
+  if (memory_observer_) {
+    message_loop()->RemoveTaskObserver(memory_observer_.get());
+    memory_observer_.reset();
+  }
+
   // Wait for all databases to be closed.
-  if (webkit_platform_support_) {
-    webkit_platform_support_->web_database_observer_impl()->
-        WaitForAllDatabasesToClose();
+  if (blink_platform_impl_) {
+    // WaitForAllDatabasesToClose might run a nested message loop. To avoid
+    // processing timer events while we're already in the process of shutting
+    // down blink, put a ScopePageLoadDeferrer on the stack.
+    WebView::willEnterModalLoop();
+    blink_platform_impl_->web_database_observer_impl()
+        ->WaitForAllDatabasesToClose();
+    WebView::didExitModalLoop();
   }
 
   // Shutdown in reverse of the initialization order.
@@ -466,13 +621,10 @@ void RenderThreadImpl::Shutdown() {
   RemoveFilter(audio_input_message_filter_.get());
   audio_input_message_filter_ = NULL;
 
-  RemoveFilter(audio_message_filter_.get());
-  audio_message_filter_ = NULL;
-
-  // |media_stream_factory_| produces users of |vc_manager_| so it must be
-  // destroyed first.
 #if defined(ENABLE_WEBRTC)
-  media_stream_factory_.reset();
+  RTCPeerConnectionHandler::DestructAllHandlers();
+
+  peer_connection_factory_.reset();
 #endif
   RemoveFilter(vc_manager_->video_capture_message_filter());
   vc_manager_.reset();
@@ -489,6 +641,12 @@ void RenderThreadImpl::Shutdown() {
     compositor_output_surface_filter_ = NULL;
   }
 
+  media_thread_.reset();
+
+  // AudioMessageFilter may be accessed on |media_thread_|, so shutdown after.
+  RemoveFilter(audio_message_filter_.get());
+  audio_message_filter_ = NULL;
+
   compositor_thread_.reset();
   input_handler_manager_.reset();
   if (input_event_filter_.get()) {
@@ -496,11 +654,18 @@ void RenderThreadImpl::Shutdown() {
     input_event_filter_ = NULL;
   }
 
+  // RemoveEmbeddedWorkerRoute may be called while deleting
+  // EmbeddedWorkerDispatcher. So it must be deleted before deleting
+  // RenderThreadImpl.
+  embedded_worker_dispatcher_.reset();
+
   // Ramp down IDB before we ramp down WebKit (and V8), since IDB classes might
   // hold pointers to V8 objects (e.g., via pending requests).
   main_thread_indexed_db_dispatcher_.reset();
 
-  if (webkit_platform_support_)
+  main_thread_compositor_task_runner_ = NULL;
+
+  if (blink_platform_impl_)
     blink::shutdown();
 
   lazy_tls.Pointer()->Set(NULL);
@@ -510,11 +675,6 @@ void RenderThreadImpl::Shutdown() {
   // Clean up plugin channels before this thread goes away.
   NPChannelBase::CleanupChannels();
 #endif
-
-  // Leak shared contexts on other threads, as we can not get to the correct
-  // thread to destroy them.
-  if (offscreen_compositor_contexts_.get())
-    offscreen_compositor_contexts_->set_leak_on_destroy();
 }
 
 bool RenderThreadImpl::Send(IPC::Message* msg) {
@@ -546,7 +706,7 @@ bool RenderThreadImpl::Send(IPC::Message* msg) {
 
   if (pumping_events) {
     if (suspend_webkit_shared_timer)
-      webkit_platform_support_->SuspendSharedTimer();
+      blink_platform_impl_->SuspendSharedTimer();
 
     if (notify_webkit_of_modal_loop)
       WebView::willEnterModalLoop();
@@ -575,7 +735,7 @@ bool RenderThreadImpl::Send(IPC::Message* msg) {
       WebView::didExitModalLoop();
 
     if (suspend_webkit_shared_timer)
-      webkit_platform_support_->ResumeSharedTimer();
+      blink_platform_impl_->ResumeSharedTimer();
   }
 
   return rv;
@@ -609,23 +769,62 @@ scoped_refptr<base::MessageLoopProxy>
 }
 
 void RenderThreadImpl::AddRoute(int32 routing_id, IPC::Listener* listener) {
-  ChildThread::AddRoute(routing_id, listener);
+  ChildThread::GetRouter()->AddRoute(routing_id, listener);
+  std::map<int, mojo::MessagePipeHandle>::iterator it =
+      pending_render_frame_connects_.find(routing_id);
+  if (it == pending_render_frame_connects_.end())
+    return;
+
+  RenderFrameImpl* frame = RenderFrameImpl::FromRoutingID(routing_id);
+  if (!frame)
+    return;
+
+  mojo::ScopedMessagePipeHandle handle(it->second);
+  pending_render_frame_connects_.erase(it);
+  frame->BindServiceRegistry(handle.Pass());
 }
 
 void RenderThreadImpl::RemoveRoute(int32 routing_id) {
-  ChildThread::RemoveRoute(routing_id);
+  ChildThread::GetRouter()->RemoveRoute(routing_id);
+}
+
+void RenderThreadImpl::AddEmbeddedWorkerRoute(int32 routing_id,
+                                              IPC::Listener* listener) {
+  AddRoute(routing_id, listener);
+  if (devtools_agent_message_filter_.get()) {
+    devtools_agent_message_filter_->AddEmbeddedWorkerRouteOnMainThread(
+        routing_id);
+  }
 }
+
+void RenderThreadImpl::RemoveEmbeddedWorkerRoute(int32 routing_id) {
+  RemoveRoute(routing_id);
+  if (devtools_agent_message_filter_.get()) {
+    devtools_agent_message_filter_->RemoveEmbeddedWorkerRouteOnMainThread(
+        routing_id);
+  }
+}
+
+void RenderThreadImpl::RegisterPendingRenderFrameConnect(
+    int routing_id,
+    mojo::ScopedMessagePipeHandle handle) {
+  std::pair<std::map<int, mojo::MessagePipeHandle>::iterator, bool> result =
+      pending_render_frame_connects_.insert(
+          std::make_pair(routing_id, handle.release()));
+  CHECK(result.second) << "Inserting a duplicate item.";
+}
+
 int RenderThreadImpl::GenerateRoutingID() {
   int routing_id = MSG_ROUTING_NONE;
   Send(new ViewHostMsg_GenerateRoutingID(&routing_id));
   return routing_id;
 }
 
-void RenderThreadImpl::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
+void RenderThreadImpl::AddFilter(IPC::MessageFilter* filter) {
   channel()->AddFilter(filter);
 }
 
-void RenderThreadImpl::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) {
+void RenderThreadImpl::RemoveFilter(IPC::MessageFilter* filter) {
   channel()->RemoveFilter(filter);
 }
 
@@ -643,15 +842,25 @@ void RenderThreadImpl::SetResourceDispatcherDelegate(
 }
 
 void RenderThreadImpl::EnsureWebKitInitialized() {
-  if (webkit_platform_support_)
+  if (blink_platform_impl_)
     return;
 
-  webkit_platform_support_.reset(new RendererWebKitPlatformSupportImpl);
-  blink::initialize(webkit_platform_support_.get());
+  blink_platform_impl_.reset(
+      new RendererBlinkPlatformImpl(renderer_scheduler_.get()));
+  blink::initialize(blink_platform_impl_.get());
+
+  v8::Isolate* isolate = blink::mainThreadIsolate();
+
+  isolate->SetCounterFunction(base::StatsTable::FindLocation);
+  isolate->SetCreateHistogramFunction(CreateHistogram);
+  isolate->SetAddHistogramSampleFunction(AddHistogramSample);
 
   const CommandLine& command_line = *CommandLine::ForCurrentProcess();
 
-  bool enable = command_line.HasSwitch(switches::kEnableThreadedCompositing);
+  main_thread_compositor_task_runner_ =
+      renderer_scheduler()->CompositorTaskRunner();
+
+  bool enable = !command_line.HasSwitch(switches::kDisableThreadedCompositing);
   if (enable) {
 #if defined(OS_ANDROID)
     if (SynchronousCompositorFactory* factory =
@@ -682,7 +891,9 @@ void RenderThreadImpl::EnsureWebKitInitialized() {
 #endif
     if (!input_handler_manager_client) {
       input_event_filter_ =
-          new InputEventFilter(this, compositor_message_loop_proxy_);
+          new InputEventFilter(this,
+                               main_thread_compositor_task_runner_,
+                               compositor_message_loop_proxy_);
       AddFilter(input_event_filter_.get());
       input_handler_manager_client = input_event_filter_.get();
     }
@@ -701,17 +912,14 @@ void RenderThreadImpl::EnsureWebKitInitialized() {
       CompositorOutputSurface::CreateFilter(output_surface_loop.get());
   AddFilter(compositor_output_surface_filter_.get());
 
-  WebScriptController::enableV8SingleThreadMode();
-
   RenderThreadImpl::RegisterSchemes();
 
-  EnableWebCoreLogChannels(
-      command_line.GetSwitchValueASCII(switches::kWebCoreLogChannels));
+  EnableBlinkPlatformLogChannels(
+      command_line.GetSwitchValueASCII(switches::kBlinkPlatformLogChannels));
 
   SetRuntimeFeaturesDefaultsAndUpdateFromArgs(command_line);
 
   if (!media::IsMediaLibraryInitialized()) {
-    WebRuntimeFeatures::enableMediaPlayer(false);
     WebRuntimeFeatures::enableWebAudio(false);
   }
 
@@ -723,20 +931,21 @@ void RenderThreadImpl::EnsureWebKitInitialized() {
   if (GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden())
     ScheduleIdleHandler(kLongIdleHandlerDelayMs);
 
-  webkit::SetSharedMemoryAllocationFunction(AllocateSharedMemoryFunction);
-
-  // Limit use of the scaled image cache to when deferred image decoding
-  // is enabled.
-  // TODO(reveman): Allow use of this cache on Android once
-  // SkDiscardablePixelRef is used for decoded images. crbug.com/330041
-  bool use_skia_scaled_image_cache = false;
-#if !defined(OS_ANDROID)
-  use_skia_scaled_image_cache =
-      command_line.HasSwitch(switches::kEnableDeferredImageDecoding) ||
-      cc::switches::IsImplSidePaintingEnabled();
-#endif
-  if (!use_skia_scaled_image_cache)
-    SkGraphics::SetImageCacheByteLimit(0u);
+  cc_blink::SetSharedMemoryAllocationFunction(AllocateSharedMemoryFunction);
+
+  // Limit use of the scaled image cache to when deferred image decoding is
+  // enabled.
+  if (!command_line.HasSwitch(switches::kEnableDeferredImageDecoding) &&
+      !is_impl_side_painting_enabled_)
+    SkGraphics::SetResourceCacheTotalByteLimit(0u);
+
+  SkGraphics::SetResourceCacheSingleAllocationByteLimit(
+      kImageCacheSingleAllocationByteLimit);
+
+  if (command_line.HasSwitch(switches::kMemoryMetrics)) {
+    memory_observer_.reset(new MemoryObserver());
+    message_loop()->AddTaskObserver(memory_observer_.get());
+  }
 }
 
 void RenderThreadImpl::RegisterSchemes() {
@@ -747,6 +956,12 @@ void RenderThreadImpl::RegisterSchemes() {
   WebSecurityPolicy::registerURLSchemeAsEmptyDocument(swappedout_scheme);
 }
 
+void RenderThreadImpl::NotifyTimezoneChange() {
+  NotifyTimezoneChangeOnThisThread();
+  RenderThread::Get()->PostTaskToAllWebWorkers(
+      base::Bind(&NotifyTimezoneChangeOnThisThread));
+}
+
 void RenderThreadImpl::RecordAction(const base::UserMetricsAction& action) {
   Send(new ViewHostMsg_UserMetricsRecordAction(action.str_));
 }
@@ -797,34 +1012,49 @@ void RenderThreadImpl::IdleHandler() {
                                GetContentClient()->renderer()->
                                    RunIdleHandlerWhenWidgetsHidden();
   if (run_in_foreground_tab) {
-    IdleHandlerInForegroundTab();
+    if (idle_notifications_to_skip_ > 0) {
+      --idle_notifications_to_skip_;
+    } else {
+      base::allocator::ReleaseFreeMemory();
+      base::DiscardableMemory::ReduceMemoryUsage();
+    }
+    ScheduleIdleHandler(kLongIdleHandlerDelayMs);
     return;
   }
 
   base::allocator::ReleaseFreeMemory();
+  base::DiscardableMemory::ReleaseFreeMemory();
 
   // Continue the idle timer if the webkit shared timer is not suspended or
   // something is left to do.
   bool continue_timer = !webkit_shared_timer_suspended_;
 
-  if (!v8::V8::IdleNotification()) {
+  if (blink::mainThreadIsolate() &&
+      !blink::mainThreadIsolate()->IdleNotification(1000)) {
+    continue_timer = true;
+  }
+  if (!base::DiscardableMemory::ReduceMemoryUsage()) {
     continue_timer = true;
   }
 
-  // Schedule next invocation.
+  // Schedule next invocation. When the tab is originally hidden, an invocation
+  // is scheduled for kInitialIdleHandlerDelayMs in
+  // RenderThreadImpl::WidgetHidden in order to race to a minimal heap.
+  // After that, idle calls can be much less frequent, so run at a maximum of
+  // once every kLongIdleHandlerDelayMs.
   // Dampen the delay using the algorithm (if delay is in seconds):
   //    delay = delay + 1 / (delay + 2)
   // Using floor(delay) has a dampening effect such as:
-  //    1s, 1, 1, 2, 2, 2, 2, 3, 3, ...
+  //    30s, 30, 30, 31, 31, 31, 31, 32, 32, ...
   // If the delay is in milliseconds, the above formula is equivalent to:
   //    delay_ms / 1000 = delay_ms / 1000 + 1 / (delay_ms / 1000 + 2)
   // which is equivalent to
   //    delay_ms = delay_ms + 1000*1000 / (delay_ms + 2000).
-  // Note that idle_notification_delay_in_ms_ would be reset to
-  // kInitialIdleHandlerDelayMs in RenderThreadImpl::WidgetHidden.
   if (continue_timer) {
-    ScheduleIdleHandler(idle_notification_delay_in_ms_ +
-                        1000000 / (idle_notification_delay_in_ms_ + 2000));
+    ScheduleIdleHandler(
+        std::max(kLongIdleHandlerDelayMs,
+                 idle_notification_delay_in_ms_ +
+                 1000000 / (idle_notification_delay_in_ms_ + 2000)));
 
   } else {
     idle_timer_.Stop();
@@ -833,33 +1063,6 @@ void RenderThreadImpl::IdleHandler() {
   FOR_EACH_OBSERVER(RenderProcessObserver, observers_, IdleNotification());
 }
 
-void RenderThreadImpl::IdleHandlerInForegroundTab() {
-  // Increase the delay in the same way as in IdleHandler,
-  // but make it periodic by reseting it once it is too big.
-  int64 new_delay_ms = idle_notification_delay_in_ms_ +
-                       1000000 / (idle_notification_delay_in_ms_ + 2000);
-  if (new_delay_ms >= kLongIdleHandlerDelayMs)
-    new_delay_ms = kShortIdleHandlerDelayMs;
-
-  if (idle_notifications_to_skip_ > 0) {
-    idle_notifications_to_skip_--;
-  } else  {
-    int cpu_usage = 0;
-    Send(new ViewHostMsg_GetCPUUsage(&cpu_usage));
-    // Idle notification hint roughly specifies the expected duration of the
-    // idle pause. We set it proportional to the idle timer delay.
-    int idle_hint = static_cast<int>(new_delay_ms / 10);
-    if (cpu_usage < kIdleCPUUsageThresholdInPercents) {
-      base::allocator::ReleaseFreeMemory();
-      if (v8::V8::IdleNotification(idle_hint)) {
-        // V8 finished collecting garbage.
-        new_delay_ms = kLongIdleHandlerDelayMs;
-      }
-    }
-  }
-  ScheduleIdleHandler(new_delay_ms);
-}
-
 int64 RenderThreadImpl::GetIdleNotificationDelayInMs() const {
   return idle_notification_delay_in_ms_;
 }
@@ -874,8 +1077,7 @@ void RenderThreadImpl::UpdateHistograms(int sequence_number) {
 }
 
 int RenderThreadImpl::PostTaskToAllWebWorkers(const base::Closure& closure) {
-  return webkit_glue::WorkerTaskRunner::Instance()->PostTaskToAllThreads(
-      closure);
+  return WorkerTaskRunner::Instance()->PostTaskToAllThreads(closure);
 }
 
 bool RenderThreadImpl::ResolveProxy(const GURL& url, std::string* proxy_list) {
@@ -888,45 +1090,47 @@ void RenderThreadImpl::PostponeIdleNotification() {
   idle_notifications_to_skip_ = 2;
 }
 
-scoped_refptr<RendererGpuVideoAcceleratorFactories>
+scoped_refptr<media::GpuVideoAcceleratorFactories>
 RenderThreadImpl::GetGpuFactories() {
   DCHECK(IsMainThread());
 
   scoped_refptr<GpuChannelHost> gpu_channel_host = GetGpuChannel();
   const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
-  scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories;
+  scoped_refptr<media::GpuVideoAcceleratorFactories> gpu_factories;
+  scoped_refptr<base::SingleThreadTaskRunner> media_task_runner =
+      GetMediaThreadTaskRunner();
   if (!cmd_line->HasSwitch(switches::kDisableAcceleratedVideoDecode)) {
-    if (!gpu_va_context_provider_ ||
+    if (!gpu_va_context_provider_.get() ||
         gpu_va_context_provider_->DestroyedOnMainThread()) {
-      if (!gpu_channel_host) {
+      if (!gpu_channel_host.get()) {
         gpu_channel_host = EstablishGpuChannelSync(
             CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE);
       }
+      blink::WebGraphicsContext3D::Attributes attributes;
+      bool lose_context_when_out_of_memory = false;
       gpu_va_context_provider_ = ContextProviderCommandBuffer::Create(
           make_scoped_ptr(
               WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
                   gpu_channel_host.get(),
-                  blink::WebGraphicsContext3D::Attributes(),
+                  attributes,
+                  lose_context_when_out_of_memory,
                   GURL("chrome://gpu/RenderThreadImpl::GetGpuVDAContext3D"),
-                  WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits())),
+                  WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
+                  NULL)),
           "GPU-VideoAccelerator-Offscreen");
     }
   }
-  if (gpu_channel_host) {
-    gpu_factories = new RendererGpuVideoAcceleratorFactories(
-        gpu_channel_host.get(), gpu_va_context_provider_);
+  if (gpu_va_context_provider_.get()) {
+    gpu_factories = RendererGpuVideoAcceleratorFactories::Create(
+        gpu_channel_host.get(), media_task_runner, gpu_va_context_provider_);
   }
   return gpu_factories;
 }
 
 scoped_ptr<WebGraphicsContext3DCommandBufferImpl>
 RenderThreadImpl::CreateOffscreenContext3d() {
-  blink::WebGraphicsContext3D::Attributes attributes;
-  attributes.shareResources = true;
-  attributes.depth = false;
-  attributes.stencil = false;
-  attributes.antialias = false;
-  attributes.noAutomaticFlushes = true;
+  blink::WebGraphicsContext3D::Attributes attributes(GetOffscreenAttribs());
+  bool lose_context_when_out_of_memory = true;
 
   scoped_refptr<GpuChannelHost> gpu_channel_host(EstablishGpuChannelSync(
       CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE));
@@ -934,60 +1138,33 @@ RenderThreadImpl::CreateOffscreenContext3d() {
       WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
           gpu_channel_host.get(),
           attributes,
+          lose_context_when_out_of_memory,
           GURL("chrome://gpu/RenderThreadImpl::CreateOffscreenContext3d"),
-          WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits()));
-}
-
-scoped_refptr<cc::ContextProvider>
-RenderThreadImpl::OffscreenCompositorContextProvider() {
-  DCHECK(IsMainThread());
-
-#if defined(OS_ANDROID)
-  if (SynchronousCompositorFactory* factory =
-      SynchronousCompositorFactory::GetInstance()) {
-    if (compositor_message_loop_proxy_)
-      return factory->GetOffscreenContextProviderForCompositorThread();
-    return factory->GetOffscreenContextProviderForMainThread();
-  }
-#endif
-
-  if (!offscreen_compositor_contexts_.get() ||
-      offscreen_compositor_contexts_->DestroyedOnMainThread()) {
-    offscreen_compositor_contexts_ = ContextProviderCommandBuffer::Create(
-        CreateOffscreenContext3d(),
-        "Compositor-Offscreen");
-  }
-  return offscreen_compositor_contexts_;
+          WebGraphicsContext3DCommandBufferImpl::SharedMemoryLimits(),
+          NULL));
 }
 
 scoped_refptr<webkit::gpu::ContextProviderWebContext>
 RenderThreadImpl::SharedMainThreadContextProvider() {
   DCHECK(IsMainThread());
+  if (!shared_main_thread_contexts_.get() ||
+      shared_main_thread_contexts_->DestroyedOnMainThread()) {
+    shared_main_thread_contexts_ = NULL;
 #if defined(OS_ANDROID)
-  if (SynchronousCompositorFactory* factory =
-      SynchronousCompositorFactory::GetInstance())
-    return factory->GetOffscreenContextProviderForMainThread();
+    if (SynchronousCompositorFactory* factory =
+            SynchronousCompositorFactory::GetInstance()) {
+      shared_main_thread_contexts_ = factory->CreateOffscreenContextProvider(
+          GetOffscreenAttribs(), "Offscreen-MainThread");
+    }
 #endif
-
-  if (!shared_main_thread_contexts_ ||
-      shared_main_thread_contexts_->DestroyedOnMainThread()) {
-    if (compositor_message_loop_proxy_) {
-      // In threaded compositing mode, we have to create a new ContextProvider
-      // to bind to the main thread since the compositor's is bound to the
-      // compositor thread.
-      shared_main_thread_contexts_ =
-          ContextProviderCommandBuffer::Create(CreateOffscreenContext3d(),
-                                               "Offscreen-MainThread");
-    } else {
-      // In single threaded mode, we can use the same context provider.
-      shared_main_thread_contexts_ =
-          static_cast<ContextProviderCommandBuffer*>(
-                OffscreenCompositorContextProvider().get());
+    if (!shared_main_thread_contexts_.get()) {
+      shared_main_thread_contexts_ = ContextProviderCommandBuffer::Create(
+          CreateOffscreenContext3d(), "Offscreen-MainThread");
     }
+    if (shared_main_thread_contexts_.get() &&
+        !shared_main_thread_contexts_->BindToCurrentThread())
+      shared_main_thread_contexts_ = NULL;
   }
-  if (shared_main_thread_contexts_ &&
-      !shared_main_thread_contexts_->BindToCurrentThread())
-    shared_main_thread_contexts_ = NULL;
   return shared_main_thread_contexts_;
 }
 
@@ -1015,6 +1192,10 @@ media::AudioHardwareConfig* RenderThreadImpl::GetAudioHardwareConfig() {
   return audio_hardware_config_.get();
 }
 
+base::WaitableEvent* RenderThreadImpl::GetShutdownEvent() {
+  return ChildProcess::current()->GetShutDownEvent();
+}
+
 #if defined(OS_WIN)
 void RenderThreadImpl::PreCacheFontCharacters(const LOGFONT& log_font,
                                               const base::string16& str) {
@@ -1031,6 +1212,10 @@ void RenderThreadImpl::ReleaseCachedFonts() {
 
 #endif  // OS_WIN
 
+ServiceRegistry* RenderThreadImpl::GetServiceRegistry() {
+  return service_registry();
+}
+
 bool RenderThreadImpl::IsMainThread() {
   return !!current();
 }
@@ -1043,76 +1228,32 @@ scoped_refptr<base::MessageLoopProxy> RenderThreadImpl::GetIOLoopProxy() {
   return io_message_loop_proxy_;
 }
 
-base::WaitableEvent* RenderThreadImpl::GetShutDownEvent() {
-  return shutdown_event_;
-}
-
 scoped_ptr<base::SharedMemory> RenderThreadImpl::AllocateSharedMemory(
     size_t size) {
   return scoped_ptr<base::SharedMemory>(
       HostAllocateSharedMemoryBuffer(size));
 }
 
-int32 RenderThreadImpl::CreateViewCommandBuffer(
-      int32 surface_id, const GPUCreateCommandBufferConfig& init_params) {
+CreateCommandBufferResult RenderThreadImpl::CreateViewCommandBuffer(
+      int32 surface_id,
+      const GPUCreateCommandBufferConfig& init_params,
+      int32 route_id) {
   TRACE_EVENT1("gpu",
                "RenderThreadImpl::CreateViewCommandBuffer",
                "surface_id",
                surface_id);
 
-  int32 route_id = MSG_ROUTING_NONE;
+  CreateCommandBufferResult result = CREATE_COMMAND_BUFFER_FAILED;
   IPC::Message* message = new GpuHostMsg_CreateViewCommandBuffer(
       surface_id,
       init_params,
-      &route_id);
+      route_id,
+      &result);
 
   // Allow calling this from the compositor thread.
   thread_safe_sender()->Send(message);
 
-  return route_id;
-}
-
-void RenderThreadImpl::CreateImage(
-    gfx::PluginWindowHandle window,
-    int32 image_id,
-    const CreateImageCallback& callback) {
-  NOTREACHED();
-}
-
-void RenderThreadImpl::DeleteImage(int32 image_id, int32 sync_point) {
-  NOTREACHED();
-}
-
-scoped_ptr<gfx::GpuMemoryBuffer> RenderThreadImpl::AllocateGpuMemoryBuffer(
-    size_t width,
-    size_t height,
-    unsigned internalformat) {
-  DCHECK(allocate_gpu_memory_buffer_thread_checker_.CalledOnValidThread());
-
-  if (!GpuMemoryBufferImpl::IsFormatValid(internalformat))
-    return scoped_ptr<gfx::GpuMemoryBuffer>();
-
-  gfx::GpuMemoryBufferHandle handle;
-  bool success;
-  IPC::Message* message =
-      new ChildProcessHostMsg_SyncAllocateGpuMemoryBuffer(width,
-                                                          height,
-                                                          internalformat,
-                                                          &handle);
-
-  // Allow calling this from the compositor thread.
-  if (base::MessageLoop::current() == message_loop())
-    success = ChildThread::Send(message);
-  else
-    success = sync_message_filter()->Send(message);
-
-  if (!success)
-    return scoped_ptr<gfx::GpuMemoryBuffer>();
-
-  return GpuMemoryBufferImpl::Create(
-      handle,
-      gfx::Size(width, height),
-      internalformat).PassAs<gfx::GpuMemoryBuffer>();
+  return result;
 }
 
 void RenderThreadImpl::DoNotSuspendWebKitSharedTimer() {
@@ -1123,13 +1264,6 @@ void RenderThreadImpl::DoNotNotifyWebKitOfModalLoop() {
   notify_webkit_of_modal_loop_ = false;
 }
 
-void RenderThreadImpl::OnSetZoomLevelForCurrentURL(const std::string& scheme,
-                                                   const std::string& host,
-                                                   double zoom_level) {
-  RenderViewZoomer zoomer(scheme, host, zoom_level);
-  RenderView::ForEach(&zoomer);
-}
-
 bool RenderThreadImpl::OnControlMessageReceived(const IPC::Message& msg) {
   ObserverListBase<RenderProcessObserver>::Iterator it(observers_);
   RenderProcessObserver* observer;
@@ -1147,14 +1281,17 @@ bool RenderThreadImpl::OnControlMessageReceived(const IPC::Message& msg) {
 
   bool handled = true;
   IPC_BEGIN_MESSAGE_MAP(RenderThreadImpl, msg)
+    IPC_MESSAGE_HANDLER(FrameMsg_NewFrame, OnCreateNewFrame)
+    IPC_MESSAGE_HANDLER(FrameMsg_NewFrameProxy, OnCreateNewFrameProxy)
     IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForCurrentURL,
                         OnSetZoomLevelForCurrentURL)
     // TODO(port): removed from render_messages_internal.h;
     // is there a new non-windows message I should add here?
     IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)
-    IPC_MESSAGE_HANDLER(ViewMsg_PurgePluginListCache, OnPurgePluginListCache)
-    IPC_MESSAGE_HANDLER(ViewMsg_NetworkStateChanged, OnNetworkStateChanged)
+    IPC_MESSAGE_HANDLER(ViewMsg_NetworkTypeChanged, OnNetworkTypeChanged)
     IPC_MESSAGE_HANDLER(ViewMsg_TempCrashWithData, OnTempCrashWithData)
+    IPC_MESSAGE_HANDLER(WorkerProcessMsg_CreateWorker, OnCreateNewSharedWorker)
+    IPC_MESSAGE_HANDLER(ViewMsg_TimezoneChange, OnUpdateTimezone)
 #if defined(OS_ANDROID)
     IPC_MESSAGE_HANDLER(ViewMsg_SetWebKitSharedTimersSuspended,
                         OnSetWebKitSharedTimersSuspended)
@@ -1162,30 +1299,53 @@ bool RenderThreadImpl::OnControlMessageReceived(const IPC::Message& msg) {
 #if defined(OS_MACOSX)
     IPC_MESSAGE_HANDLER(ViewMsg_UpdateScrollbarTheme, OnUpdateScrollbarTheme)
 #endif
+#if defined(ENABLE_PLUGINS)
+    IPC_MESSAGE_HANDLER(ViewMsg_PurgePluginListCache, OnPurgePluginListCache)
+#endif
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   return handled;
 }
 
+void RenderThreadImpl::OnCreateNewFrame(int routing_id,
+                                        int parent_routing_id,
+                                        int proxy_routing_id) {
+  RenderFrameImpl::CreateFrame(routing_id, parent_routing_id, proxy_routing_id);
+}
+
+void RenderThreadImpl::OnCreateNewFrameProxy(int routing_id,
+                                             int parent_routing_id,
+                                             int render_view_routing_id) {
+  RenderFrameProxy::CreateFrameProxy(
+      routing_id, parent_routing_id, render_view_routing_id);
+}
+
+void RenderThreadImpl::OnSetZoomLevelForCurrentURL(const std::string& scheme,
+                                                   const std::string& host,
+                                                   double zoom_level) {
+  RenderViewZoomer zoomer(scheme, host, zoom_level);
+  RenderView::ForEach(&zoomer);
+}
+
 void RenderThreadImpl::OnCreateNewView(const ViewMsg_New_Params& params) {
   EnsureWebKitInitialized();
   // When bringing in render_view, also bring in webkit's glue and jsbindings.
-  RenderViewImpl::Create(
-      params.opener_route_id,
-      params.renderer_preferences,
-      params.web_preferences,
-      params.view_id,
-      params.main_frame_routing_id,
-      params.surface_id,
-      params.session_storage_namespace_id,
-      params.frame_name,
-      false,
-      params.swapped_out,
-      params.hidden,
-      params.next_page_id,
-      params.screen_info,
-      params.accessibility_mode,
-      params.allow_partial_swap);
+  RenderViewImpl::Create(params.opener_route_id,
+                         params.window_was_created_with_opener,
+                         params.renderer_preferences,
+                         params.web_preferences,
+                         params.view_id,
+                         params.main_frame_routing_id,
+                         params.surface_id,
+                         params.session_storage_namespace_id,
+                         params.frame_name,
+                         false,
+                         params.swapped_out,
+                         params.proxy_routing_id,
+                         params.hidden,
+                         params.never_visible,
+                         params.next_page_id,
+                         params.screen_info);
 }
 
 GpuChannelHost* RenderThreadImpl::EstablishGpuChannelSync(
@@ -1223,9 +1383,13 @@ GpuChannelHost* RenderThreadImpl::EstablishGpuChannelSync(
   // Cache some variables that are needed on the compositor thread for our
   // implementation of GpuChannelHostFactory.
   io_message_loop_proxy_ = ChildProcess::current()->io_message_loop_proxy();
-  shutdown_event_ = ChildProcess::current()->GetShutDownEvent();
 
-  gpu_channel_ = GpuChannelHost::Create(this, gpu_info, channel_handle);
+  gpu_channel_ =
+      GpuChannelHost::Create(this,
+                             gpu_info,
+                             channel_handle,
+                             ChildProcess::current()->GetShutDownEvent(),
+                             gpu_memory_buffer_manager());
   return gpu_channel_.get();
 }
 
@@ -1243,8 +1407,7 @@ blink::WebMediaStreamCenter* RenderThreadImpl::CreateMediaStreamCenter(
         ->OverrideCreateWebMediaStreamCenter(client);
     if (!media_stream_center_) {
       scoped_ptr<MediaStreamCenter> media_stream_center(
-          new MediaStreamCenter(client, GetMediaStreamDependencyFactory()));
-      AddObserver(media_stream_center.get());
+          new MediaStreamCenter(client, GetPeerConnectionDependencyFactory()));
       media_stream_center_ = media_stream_center.release();
     }
   }
@@ -1252,10 +1415,12 @@ blink::WebMediaStreamCenter* RenderThreadImpl::CreateMediaStreamCenter(
   return media_stream_center_;
 }
 
-MediaStreamDependencyFactory*
-RenderThreadImpl::GetMediaStreamDependencyFactory() {
-  return media_stream_factory_.get();
+#if defined(ENABLE_WEBRTC)
+PeerConnectionDependencyFactory*
+RenderThreadImpl::GetPeerConnectionDependencyFactory() {
+  return peer_connection_factory_.get();
 }
+#endif
 
 GpuChannelHost* RenderThreadImpl::GetGpuChannel() {
   if (!gpu_channel_.get())
@@ -1267,22 +1432,30 @@ GpuChannelHost* RenderThreadImpl::GetGpuChannel() {
   return gpu_channel_.get();
 }
 
+#if defined(ENABLE_PLUGINS)
 void RenderThreadImpl::OnPurgePluginListCache(bool reload_pages) {
   EnsureWebKitInitialized();
   // The call below will cause a GetPlugins call with refresh=true, but at this
   // point we already know that the browser has refreshed its list, so disable
   // refresh temporarily to prevent each renderer process causing the list to be
   // regenerated.
-  webkit_platform_support_->set_plugin_refresh_allowed(false);
+  blink_platform_impl_->set_plugin_refresh_allowed(false);
   blink::resetPluginCache(reload_pages);
-  webkit_platform_support_->set_plugin_refresh_allowed(true);
+  blink_platform_impl_->set_plugin_refresh_allowed(true);
 
   FOR_EACH_OBSERVER(RenderProcessObserver, observers_, PluginListChanged());
 }
+#endif
 
-void RenderThreadImpl::OnNetworkStateChanged(bool online) {
+void RenderThreadImpl::OnNetworkTypeChanged(
+    net::NetworkChangeNotifier::ConnectionType type) {
   EnsureWebKitInitialized();
+  bool online = type != net::NetworkChangeNotifier::CONNECTION_NONE;
   WebNetworkStateNotifier::setOnLine(online);
+  FOR_EACH_OBSERVER(
+      RenderProcessObserver, observers_, NetworkStateChanged(online));
+  WebNetworkStateNotifier::setWebConnectionType(
+      NetConnectionTypeToWebConnectionType(type));
 }
 
 void RenderThreadImpl::OnTempCrashWithData(const GURL& data) {
@@ -1290,14 +1463,20 @@ void RenderThreadImpl::OnTempCrashWithData(const GURL& data) {
   CHECK(false);
 }
 
+void RenderThreadImpl::OnUpdateTimezone() {
+  if (!blink_platform_impl_)
+    return;
+  NotifyTimezoneChange();
+}
+
 #if defined(OS_ANDROID)
 void RenderThreadImpl::OnSetWebKitSharedTimersSuspended(bool suspend) {
   if (suspend_webkit_shared_timer_) {
     EnsureWebKitInitialized();
     if (suspend) {
-      webkit_platform_support_->SuspendSharedTimer();
+      blink_platform_impl_->SuspendSharedTimer();
     } else {
-      webkit_platform_support_->ResumeSharedTimer();
+      blink_platform_impl_->ResumeSharedTimer();
     }
     webkit_shared_timer_suspended_ = suspend;
   }
@@ -1311,32 +1490,50 @@ void RenderThreadImpl::OnUpdateScrollbarTheme(
     bool jump_on_track_click,
     blink::ScrollerStyle preferred_scroller_style,
     bool redraw) {
+  EnsureWebKitInitialized();
+  static_cast<WebScrollbarBehaviorImpl*>(
+      blink_platform_impl_->scrollbarBehavior())
+      ->set_jump_on_track_click(jump_on_track_click);
   blink::WebScrollbarTheme::updateScrollbars(initial_button_delay,
                                              autoscroll_button_delay,
-                                             jump_on_track_click,
                                              preferred_scroller_style,
                                              redraw);
 }
 #endif
 
+void RenderThreadImpl::OnCreateNewSharedWorker(
+    const WorkerProcessMsg_CreateWorker_Params& params) {
+  // EmbeddedSharedWorkerStub will self-destruct.
+  new EmbeddedSharedWorkerStub(params.url,
+                               params.name,
+                               params.content_security_policy,
+                               params.security_policy_type,
+                               params.pause_on_start,
+                               params.route_id);
+}
+
 void RenderThreadImpl::OnMemoryPressure(
     base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
   base::allocator::ReleaseFreeMemory();
 
+  // Trigger full v8 garbage collection on critical memory notification. This
+  // will potentially hang the renderer for a long time, however, when we
+  // receive a memory pressure notification, we might be about to be killed.
+  if (blink_platform_impl_ && blink::mainThreadIsolate()) {
+    blink::mainThreadIsolate()->LowMemoryNotification();
+  }
+
   if (memory_pressure_level ==
-      base::MemoryPressureListener::MEMORY_PRESSURE_CRITICAL) {
-    // Trigger full v8 garbage collection on critical memory notification.
-    v8::V8::LowMemoryNotification();
-    // Clear the image cache.
-    blink::WebImageCache::clear();
+      base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL) {
+    if (blink_platform_impl_) {
+      // Clear the image cache. Do not call into blink if it is not initialized.
+      blink::WebImageCache::clear();
+    }
+
     // Purge Skia font cache, by setting it to 0 and then again to the previous
     // limit.
     size_t font_cache_limit = SkGraphics::SetFontCacheLimit(0);
     SkGraphics::SetFontCacheLimit(font_cache_limit);
-  } else {
-    // Otherwise trigger a couple of v8 GCs using IdleNotification.
-    if (!v8::V8::IdleNotification())
-      v8::V8::IdleNotification();
   }
 }
 
@@ -1350,8 +1547,8 @@ RenderThreadImpl::GetFileThreadMessageLoopProxy() {
   return file_thread_->message_loop_proxy();
 }
 
-scoped_refptr<base::MessageLoopProxy>
-RenderThreadImpl::GetMediaThreadMessageLoopProxy() {
+scoped_refptr<base::SingleThreadTaskRunner>
+RenderThreadImpl::GetMediaThreadTaskRunner() {
   DCHECK(message_loop() == base::MessageLoop::current());
   if (!media_thread_) {
     media_thread_.reset(new base::Thread("Media"));
@@ -1365,18 +1562,8 @@ RenderThreadImpl::GetMediaThreadMessageLoopProxy() {
   return media_thread_->message_loop_proxy();
 }
 
-void RenderThreadImpl::SetFlingCurveParameters(
-    const std::vector<float>& new_touchpad,
-    const std::vector<float>& new_touchscreen) {
-  webkit_platform_support_->SetFlingCurveParameters(new_touchpad,
-                                                    new_touchscreen);
-
-}
-
 void RenderThreadImpl::SampleGamepads(blink::WebGamepads* data) {
-  if (!gamepad_shared_memory_reader_)
-    gamepad_shared_memory_reader_.reset(new GamepadSharedMemoryReader);
-  gamepad_shared_memory_reader_->SampleGamepads(*data);
+  blink_platform_impl_->sampleGamepads(*data);
 }
 
 void RenderThreadImpl::WidgetCreated() {
@@ -1392,12 +1579,12 @@ void RenderThreadImpl::WidgetHidden() {
   hidden_widget_count_++;
 
   if (widget_count_ && hidden_widget_count_ == widget_count_) {
-#if !defined(SYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE)
-    // TODO(vollick): Remove this this heavy-handed approach once we're polling
-    // the real system memory pressure.
-    base::MemoryPressureListener::NotifyMemoryPressure(
-        base::MemoryPressureListener::MEMORY_PRESSURE_MODERATE);
-#endif
+    // TODO(reveman): Remove this when we have a better mechanism to prevent
+    // total discardable memory used by all renderers from growing too large.
+    base::internal::DiscardableMemoryEmulated::
+        ReduceMemoryUsageUntilWithinLimit(
+            kEmulatedDiscardableMemoryBytesToKeepWhenWidgetsHidden);
+
     if (GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden())
       ScheduleIdleHandler(kInitialIdleHandlerDelayMs);
   }