Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / content / renderer / render_thread_impl.cc
index 3975856..3b2ff69 100644 (file)
@@ -21,6 +21,7 @@
 #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_number_conversions.h"
 #include "base/strings/string_tokenizer.h"
@@ -29,6 +30,8 @@
 #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/public/renderer/content_renderer_client.h"
 #include "content/public/renderer/render_process_observer.h"
 #include "content/public/renderer/render_view_visitor.h"
-#include "content/renderer/compositor_bindings/web_external_bitmap_impl.h"
-#include "content/renderer/compositor_bindings/web_layer_impl.h"
 #include "content/renderer/devtools/devtools_agent_filter.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/render_process_impl.h"
 #include "content/renderer/render_view_impl.h"
 #include "content/renderer/renderer_webkitplatformsupport_impl.h"
+#include "content/renderer/scheduler_proxy_task_runner.h"
 #include "content/renderer/service_worker/embedded_worker_context_message_filter.h"
 #include "content/renderer/service_worker/embedded_worker_dispatcher.h"
 #include "content/renderer/shared_worker/embedded_shared_worker_stub.h"
-#include "grit/content_resources.h"
 #include "ipc/ipc_channel_handle.h"
 #include "ipc/ipc_forwarding_message_filter.h"
 #include "ipc/ipc_platform_file.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"
@@ -172,11 +173,7 @@ 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
@@ -319,6 +316,13 @@ blink::WebGraphicsContext3D::Attributes GetOffscreenAttribs() {
   return attributes;
 }
 
+void DeletedGpuMemoryBuffer(ThreadSafeSender* sender,
+                            gfx::GpuMemoryBufferType type,
+                            const gfx::GpuMemoryBufferId& id) {
+  TRACE_EVENT0("renderer", "RenderThreadImpl::DeletedGpuMemoryBuffer");
+  sender->Send(new ChildProcessHostMsg_DeletedGpuMemoryBuffer(type, id));
+}
+
 }  // namespace
 
 // For measuring memory usage after each task. Behind a command line flag.
@@ -331,7 +335,7 @@ class MemoryObserver : public base::MessageLoop::TaskObserver {
   }
 
   virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE {
-    HISTOGRAM_MEMORY_KB("Memory.RendererUsed", GetMemoryUsageKB());
+    LOCAL_HISTOGRAM_MEMORY_KB("Memory.RendererUsed", GetMemoryUsageKB());
   }
 
  private:
@@ -482,7 +486,8 @@ void RenderThreadImpl::Init() {
 
   is_impl_side_painting_enabled_ =
       command_line.HasSwitch(switches::kEnableImplSidePainting);
-  WebLayerImpl::SetImplSidePaintingEnabled(is_impl_side_painting_enabled_);
+  cc_blink::WebLayerImpl::SetImplSidePaintingEnabled(
+      is_impl_side_painting_enabled_);
 
   is_zero_copy_enabled_ = command_line.HasSwitch(switches::kEnableZeroCopy) &&
                           !command_line.HasSwitch(switches::kDisableZeroCopy);
@@ -514,12 +519,6 @@ void RenderThreadImpl::Init() {
     is_distance_field_text_enabled_ = false;
   }
 
-  is_low_res_tiling_enabled_ = true;
-  if (command_line.HasSwitch(switches::kDisableLowResTiling) &&
-      !command_line.HasSwitch(switches::kEnableLowResTiling)) {
-    is_low_res_tiling_enabled_ = false;
-  }
-
   // Note that under Linux, the media library will normally already have
   // been initialized by the Zygote before this instance became a Renderer.
   base::FilePath media_path;
@@ -557,18 +556,15 @@ void RenderThreadImpl::Init() {
   // 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);
   }
 
   service_registry()->AddService<RenderFrameSetup>(
@@ -617,9 +613,6 @@ void RenderThreadImpl::Shutdown() {
   RemoveFilter(audio_input_message_filter_.get());
   audio_input_message_filter_ = NULL;
 
-  RemoveFilter(audio_message_filter_.get());
-  audio_message_filter_ = NULL;
-
 #if defined(ENABLE_WEBRTC)
   RTCPeerConnectionHandler::DestructAllHandlers();
 
@@ -641,6 +634,11 @@ void RenderThreadImpl::Shutdown() {
   }
 
   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()) {
@@ -657,6 +655,8 @@ void RenderThreadImpl::Shutdown() {
   // hold pointers to V8 objects (e.g., via pending requests).
   main_thread_indexed_db_dispatcher_.reset();
 
+  main_thread_compositor_task_runner_ = NULL;
+
   if (webkit_platform_support_)
     blink::shutdown();
 
@@ -839,6 +839,7 @@ void RenderThreadImpl::EnsureWebKitInitialized() {
 
   webkit_platform_support_.reset(new RendererWebKitPlatformSupportImpl);
   blink::initialize(webkit_platform_support_.get());
+  main_thread_compositor_task_runner_ = base::MessageLoopProxy::current();
 
   v8::Isolate* isolate = blink::mainThreadIsolate();
 
@@ -879,7 +880,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();
     }
@@ -898,10 +901,6 @@ void RenderThreadImpl::EnsureWebKitInitialized() {
       CompositorOutputSurface::CreateFilter(output_surface_loop.get());
   AddFilter(compositor_output_surface_filter_.get());
 
-  gamepad_shared_memory_reader_.reset(
-      new GamepadSharedMemoryReader(webkit_platform_support_.get()));
-  AddObserver(gamepad_shared_memory_reader_.get());
-
   RenderThreadImpl::RegisterSchemes();
 
   EnableBlinkPlatformLogChannels(
@@ -910,7 +909,6 @@ void RenderThreadImpl::EnsureWebKitInitialized() {
   SetRuntimeFeaturesDefaultsAndUpdateFromArgs(command_line);
 
   if (!media::IsMediaLibraryInitialized()) {
-    WebRuntimeFeatures::enableMediaPlayer(false);
     WebRuntimeFeatures::enableWebAudio(false);
   }
 
@@ -922,7 +920,7 @@ void RenderThreadImpl::EnsureWebKitInitialized() {
   if (GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden())
     ScheduleIdleHandler(kLongIdleHandlerDelayMs);
 
-  SetSharedMemoryAllocationFunction(AllocateSharedMemoryFunction);
+  cc_blink::SetSharedMemoryAllocationFunction(AllocateSharedMemoryFunction);
 
   // Limit use of the scaled image cache to when deferred image decoding is
   // enabled.
@@ -1003,7 +1001,13 @@ 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;
   }
 
@@ -1021,20 +1025,24 @@ void RenderThreadImpl::IdleHandler() {
     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();
@@ -1043,42 +1051,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();
-
-      bool finished_idle_work = true;
-      if (blink::mainThreadIsolate() &&
-          !blink::mainThreadIsolate()->IdleNotification(idle_hint)) {
-        finished_idle_work = false;
-      }
-      if (!base::DiscardableMemory::ReduceMemoryUsage())
-        finished_idle_work = false;
-
-      // V8 finished collecting garbage and discardable memory system has no
-      // more idle work left.
-      if (finished_idle_work)
-        new_delay_ms = kLongIdleHandlerDelayMs;
-    }
-  }
-  ScheduleIdleHandler(new_delay_ms);
-}
-
 int64 RenderThreadImpl::GetIdleNotificationDelayInMs() const {
   return idle_notification_delay_in_ms_;
 }
@@ -1113,12 +1085,12 @@ RenderThreadImpl::GetGpuFactories() {
   scoped_refptr<GpuChannelHost> gpu_channel_host = GetGpuChannel();
   const CommandLine* cmd_line = CommandLine::ForCurrentProcess();
   scoped_refptr<media::GpuVideoAcceleratorFactories> gpu_factories;
-  scoped_refptr<base::MessageLoopProxy> media_loop_proxy =
-      GetMediaThreadMessageLoopProxy();
+  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);
       }
@@ -1136,9 +1108,9 @@ RenderThreadImpl::GetGpuFactories() {
           "GPU-VideoAccelerator-Offscreen");
     }
   }
-  if (gpu_va_context_provider_) {
+  if (gpu_va_context_provider_.get()) {
     gpu_factories = RendererGpuVideoAcceleratorFactories::Create(
-        gpu_channel_host, media_loop_proxy, gpu_va_context_provider_);
+        gpu_channel_host.get(), media_task_runner, gpu_va_context_provider_);
   }
   return gpu_factories;
 }
@@ -1163,7 +1135,7 @@ RenderThreadImpl::CreateOffscreenContext3d() {
 scoped_refptr<webkit::gpu::ContextProviderWebContext>
 RenderThreadImpl::SharedMainThreadContextProvider() {
   DCHECK(IsMainThread());
-  if (!shared_main_thread_contexts_ ||
+  if (!shared_main_thread_contexts_.get() ||
       shared_main_thread_contexts_->DestroyedOnMainThread()) {
     shared_main_thread_contexts_ = NULL;
 #if defined(OS_ANDROID)
@@ -1173,14 +1145,14 @@ RenderThreadImpl::SharedMainThreadContextProvider() {
           GetOffscreenAttribs(), "Offscreen-MainThread");
     }
 #endif
-    if (!shared_main_thread_contexts_) {
+    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_;
 }
 
@@ -1277,6 +1249,8 @@ scoped_ptr<gfx::GpuMemoryBuffer> RenderThreadImpl::AllocateGpuMemoryBuffer(
     size_t height,
     unsigned internalformat,
     unsigned usage) {
+  TRACE_EVENT0("renderer", "RenderThreadImpl::AllocateGpuMemoryBuffer");
+
   DCHECK(allocate_gpu_memory_buffer_thread_checker_.CalledOnValidThread());
 
   if (!GpuMemoryBufferImpl::IsFormatValid(internalformat))
@@ -1296,20 +1270,21 @@ scoped_ptr<gfx::GpuMemoryBuffer> RenderThreadImpl::AllocateGpuMemoryBuffer(
   if (!success)
     return scoped_ptr<gfx::GpuMemoryBuffer>();
 
-  return GpuMemoryBufferImpl::CreateFromHandle(
-             handle, gfx::Size(width, height), internalformat)
-      .PassAs<gfx::GpuMemoryBuffer>();
-}
-
-void RenderThreadImpl::DeleteGpuMemoryBuffer(
-    scoped_ptr<gfx::GpuMemoryBuffer> buffer) {
-  gfx::GpuMemoryBufferHandle handle(buffer->GetHandle());
-
-  IPC::Message* message = new ChildProcessHostMsg_DeletedGpuMemoryBuffer(
-      handle.type, handle.global_id);
+  scoped_ptr<GpuMemoryBufferImpl> buffer(GpuMemoryBufferImpl::CreateFromHandle(
+      handle,
+      gfx::Size(width, height),
+      internalformat,
+      base::Bind(&DeletedGpuMemoryBuffer,
+                 make_scoped_refptr(thread_safe_sender()),
+                 handle.type,
+                 handle.global_id)));
+  if (!buffer) {
+    thread_safe_sender()->Send(new ChildProcessHostMsg_DeletedGpuMemoryBuffer(
+        handle.type, handle.global_id));
+    return scoped_ptr<gfx::GpuMemoryBuffer>();
+  }
 
-  // Allow calling this from the compositor thread.
-  thread_safe_sender()->Send(message);
+  return buffer.PassAs<gfx::GpuMemoryBuffer>();
 }
 
 void RenderThreadImpl::DoNotSuspendWebKitSharedTimer() {
@@ -1344,7 +1319,6 @@ bool RenderThreadImpl::OnControlMessageReceived(const IPC::Message& msg) {
     // 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_NetworkTypeChanged, OnNetworkTypeChanged)
     IPC_MESSAGE_HANDLER(ViewMsg_TempCrashWithData, OnTempCrashWithData)
     IPC_MESSAGE_HANDLER(WorkerProcessMsg_CreateWorker, OnCreateNewSharedWorker)
@@ -1356,6 +1330,9 @@ 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;
@@ -1482,6 +1459,7 @@ 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
@@ -1494,6 +1472,7 @@ void RenderThreadImpl::OnPurgePluginListCache(bool reload_pages) {
 
   FOR_EACH_OBSERVER(RenderProcessObserver, observers_, PluginListChanged());
 }
+#endif
 
 void RenderThreadImpl::OnNetworkTypeChanged(
     net::NetworkChangeNotifier::ConnectionType type) {
@@ -1593,8 +1572,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"));
@@ -1608,20 +1587,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) {
-  gamepad_shared_memory_reader_->SampleGamepads(*data);
-}
-
-void RenderThreadImpl::SetGamepadListener(blink::WebGamepadListener* listener) {
-  gamepad_shared_memory_reader_->SetGamepadListener(listener);
+  webkit_platform_support_->sampleGamepads(*data);
 }
 
 void RenderThreadImpl::WidgetCreated() {