Upstream version 9.37.195.0
[platform/framework/web/crosswalk.git] / src / content / common / gpu / gpu_channel.cc
index fe6bb5b..005a4aa 100644 (file)
 #include "base/command_line.h"
 #include "base/debug/trace_event.h"
 #include "base/message_loop/message_loop_proxy.h"
-#include "base/rand_util.h"
+#include "base/stl_util.h"
 #include "base/strings/string_util.h"
 #include "base/timer/timer.h"
+#include "content/common/gpu/devtools_gpu_agent.h"
 #include "content/common/gpu/gpu_channel_manager.h"
 #include "content/common/gpu/gpu_messages.h"
-#include "content/common/gpu/media/gpu_video_encode_accelerator.h"
 #include "content/common/gpu/sync_point_manager.h"
 #include "content/public/common/content_switches.h"
-#include "crypto/hmac.h"
 #include "gpu/command_buffer/common/mailbox.h"
 #include "gpu/command_buffer/service/gpu_scheduler.h"
 #include "gpu/command_buffer/service/image_manager.h"
 #include "gpu/command_buffer/service/mailbox_manager.h"
 #include "ipc/ipc_channel.h"
-#include "ipc/ipc_channel_proxy.h"
+#include "ipc/message_filter.h"
 #include "ui/gl/gl_context.h"
 #include "ui/gl/gl_image.h"
 #include "ui/gl/gl_surface.h"
 #include "ipc/ipc_channel_posix.h"
 #endif
 
-#if defined(OS_ANDROID)
-#include "content/common/gpu/stream_texture_manager_android.h"
-#endif
-
 namespace content {
 namespace {
 
@@ -75,50 +70,37 @@ const int64 kStopPreemptThresholdMs = kVsyncIntervalMs;
 //   posting a task to insert the GpuCommandBufferMsg_RetireSyncPoint message
 //   into the channel's queue.
 // - it generates mailbox names for clients of the GPU process on the IO thread.
-class GpuChannelMessageFilter : public IPC::ChannelProxy::MessageFilter {
+class GpuChannelMessageFilter : public IPC::MessageFilter {
  public:
-  // Takes ownership of gpu_channel (see below).
-  GpuChannelMessageFilter(const std::string& private_key,
-                          base::WeakPtr<GpuChannel>* gpu_channel,
+  GpuChannelMessageFilter(base::WeakPtr<GpuChannel> gpu_channel,
                           scoped_refptr<SyncPointManager> sync_point_manager,
                           scoped_refptr<base::MessageLoopProxy> message_loop)
       : preemption_state_(IDLE),
         gpu_channel_(gpu_channel),
-        channel_(NULL),
+        sender_(NULL),
         sync_point_manager_(sync_point_manager),
         message_loop_(message_loop),
         messages_forwarded_to_channel_(0),
-        a_stub_is_descheduled_(false),
-        hmac_(crypto::HMAC::SHA256) {
-    bool success = hmac_.Init(base::StringPiece(private_key));
-    DCHECK(success);
-  }
+        a_stub_is_descheduled_(false) {}
 
-  virtual void OnFilterAdded(IPC::Channel* channel) OVERRIDE {
-    DCHECK(!channel_);
-    channel_ = channel;
+  virtual void OnFilterAdded(IPC::Sender* sender) OVERRIDE {
+    DCHECK(!sender_);
+    sender_ = sender;
   }
 
   virtual void OnFilterRemoved() OVERRIDE {
-    DCHECK(channel_);
-    channel_ = NULL;
+    DCHECK(sender_);
+    sender_ = NULL;
   }
 
   virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
-    DCHECK(channel_);
-
-    bool handled = true;
-    IPC_BEGIN_MESSAGE_MAP(GpuChannelMessageFilter, message)
-      IPC_MESSAGE_HANDLER(GpuChannelMsg_GenerateMailboxNames,
-                          OnGenerateMailboxNames)
-      IPC_MESSAGE_HANDLER(GpuChannelMsg_GenerateMailboxNamesAsync,
-                          OnGenerateMailboxNamesAsync)
-      IPC_MESSAGE_UNHANDLED(handled = false)
-    IPC_END_MESSAGE_MAP()
+    DCHECK(sender_);
 
+    bool handled = false;
     if (message.type() == GpuCommandBufferMsg_RetireSyncPoint::ID) {
       // This message should not be sent explicitly by the renderer.
-      NOTREACHED();
+      DLOG(ERROR) << "Client should not send "
+                     "GpuCommandBufferMsg_RetireSyncPoint message";
       handled = true;
     }
 
@@ -166,42 +148,13 @@ class GpuChannelMessageFilter : public IPC::ChannelProxy::MessageFilter {
   }
 
   bool Send(IPC::Message* message) {
-    return channel_->Send(message);
+    return sender_->Send(message);
   }
 
  protected:
-  virtual ~GpuChannelMessageFilter() {
-    message_loop_->PostTask(FROM_HERE, base::Bind(
-        &GpuChannelMessageFilter::DeleteWeakPtrOnMainThread, gpu_channel_));
-  }
+  virtual ~GpuChannelMessageFilter() {}
 
  private:
-  // Message handlers.
-  void OnGenerateMailboxNames(unsigned num, std::vector<gpu::Mailbox>* result) {
-    TRACE_EVENT1("gpu", "OnGenerateMailboxNames", "num", num);
-
-    result->resize(num);
-
-    for (unsigned i = 0; i < num; ++i) {
-      char name[GL_MAILBOX_SIZE_CHROMIUM];
-      base::RandBytes(name, sizeof(name) / 2);
-
-      bool success = hmac_.Sign(
-          base::StringPiece(name, sizeof(name) / 2),
-          reinterpret_cast<unsigned char*>(name) + sizeof(name) / 2,
-          sizeof(name) / 2);
-      DCHECK(success);
-
-      (*result)[i].SetName(reinterpret_cast<int8*>(name));
-    }
-  }
-
-  void OnGenerateMailboxNamesAsync(unsigned num) {
-    std::vector<gpu::Mailbox> names;
-    OnGenerateMailboxNames(num, &names);
-    Send(new GpuChannelMsg_GenerateMailboxNamesReply(names));
-  }
-
   enum PreemptionState {
     // Either there's no other channel to preempt, there are no messages
     // pending processing, or we just finished preempting and have to wait
@@ -380,7 +333,7 @@ class GpuChannelMessageFilter : public IPC::ChannelProxy::MessageFilter {
   }
 
   static void InsertSyncPointOnMainThread(
-      base::WeakPtr<GpuChannel>* gpu_channel,
+      base::WeakPtr<GpuChannel> gpu_channel,
       scoped_refptr<SyncPointManager> manager,
       int32 routing_id,
       uint32 sync_point) {
@@ -389,31 +342,24 @@ class GpuChannelMessageFilter : public IPC::ChannelProxy::MessageFilter {
     // with it, but if that fails for any reason (channel or stub already
     // deleted, invalid routing id), we need to retire the sync point
     // immediately.
-    if (gpu_channel->get()) {
-      GpuCommandBufferStub* stub = gpu_channel->get()->LookupCommandBuffer(
-          routing_id);
+    if (gpu_channel) {
+      GpuCommandBufferStub* stub = gpu_channel->LookupCommandBuffer(routing_id);
       if (stub) {
         stub->AddSyncPoint(sync_point);
         GpuCommandBufferMsg_RetireSyncPoint message(routing_id, sync_point);
-        gpu_channel->get()->OnMessageReceived(message);
+        gpu_channel->OnMessageReceived(message);
         return;
       } else {
-        gpu_channel->get()->MessageProcessed();
+        gpu_channel->MessageProcessed();
       }
     }
     manager->RetireSyncPoint(sync_point);
   }
 
-  static void DeleteWeakPtrOnMainThread(
-      base::WeakPtr<GpuChannel>* gpu_channel) {
-    delete gpu_channel;
-  }
-
-  // NOTE: this is a pointer to a weak pointer. It is never dereferenced on the
-  // IO thread, it's only passed through - therefore the WeakPtr assumptions are
-  // respected.
-  base::WeakPtr<GpuChannel>* gpu_channel_;
-  IPC::Channel* channel_;
+  // NOTE: this weak pointer is never dereferenced on the IO thread, it's only
+  // passed through - therefore the WeakPtr assumptions are respected.
+  base::WeakPtr<GpuChannel> gpu_channel_;
+  IPC::Sender* sender_;
   scoped_refptr<SyncPointManager> sync_point_manager_;
   scoped_refptr<base::MessageLoopProxy> message_loop_;
   scoped_refptr<gpu::PreemptionFlag> preempting_flag_;
@@ -426,8 +372,6 @@ class GpuChannelMessageFilter : public IPC::ChannelProxy::MessageFilter {
   base::OneShotTimer<GpuChannelMessageFilter> timer_;
 
   bool a_stub_is_descheduled_;
-
-  crypto::HMAC hmac_;
 };
 
 GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager,
@@ -445,7 +389,6 @@ GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager,
       watchdog_(watchdog),
       software_(software),
       handle_messages_scheduled_(false),
-      processed_get_state_fast_(false),
       currently_processing_message_(NULL),
       weak_factory_(this),
       num_stubs_descheduled_(0) {
@@ -455,39 +398,34 @@ GpuChannel::GpuChannel(GpuChannelManager* gpu_channel_manager,
   channel_id_ = IPC::Channel::GenerateVerifiedChannelID("gpu");
   const CommandLine* command_line = CommandLine::ForCurrentProcess();
   log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages);
-  disallowed_features_.multisampling =
-      command_line->HasSwitch(switches::kDisableGLMultisampling);
-#if defined(OS_ANDROID)
-  stream_texture_manager_.reset(new StreamTextureManagerAndroid(this));
-#endif
 }
 
+GpuChannel::~GpuChannel() {
+  STLDeleteElements(&deferred_messages_);
+  if (preempting_flag_.get())
+    preempting_flag_->Reset();
+}
 
-bool GpuChannel::Init(base::MessageLoopProxy* io_message_loop,
+void GpuChannel::Init(base::MessageLoopProxy* io_message_loop,
                       base::WaitableEvent* shutdown_event) {
   DCHECK(!channel_.get());
 
   // Map renderer ID to a (single) channel to that process.
-  channel_.reset(new IPC::SyncChannel(
-      channel_id_,
-      IPC::Channel::MODE_SERVER,
-      this,
-      io_message_loop,
-      false,
-      shutdown_event));
-
-  base::WeakPtr<GpuChannel>* weak_ptr(new base::WeakPtr<GpuChannel>(
-      weak_factory_.GetWeakPtr()));
-
-  filter_ = new GpuChannelMessageFilter(
-      mailbox_manager_->private_key(),
-      weak_ptr,
-      gpu_channel_manager_->sync_point_manager(),
-      base::MessageLoopProxy::current());
+  channel_ = IPC::SyncChannel::Create(channel_id_,
+                                      IPC::Channel::MODE_SERVER,
+                                      this,
+                                      io_message_loop,
+                                      false,
+                                      shutdown_event);
+
+  filter_ =
+      new GpuChannelMessageFilter(weak_factory_.GetWeakPtr(),
+                                  gpu_channel_manager_->sync_point_manager(),
+                                  base::MessageLoopProxy::current());
   io_message_loop_ = io_message_loop;
   channel_->AddFilter(filter_.get());
 
-  return true;
+  devtools_gpu_agent_.reset(new DevToolsGpuAgent(this));
 }
 
 std::string GpuChannel::GetChannelName() {
@@ -510,27 +448,11 @@ bool GpuChannel::OnMessageReceived(const IPC::Message& message) {
              << " with type " << message.type();
   }
 
-  if (message.type() == GpuCommandBufferMsg_GetStateFast::ID) {
-    if (processed_get_state_fast_) {
-      // Require a non-GetStateFast message in between two GetStateFast
-      // messages, to ensure progress is made.
-      std::deque<IPC::Message*>::iterator point = deferred_messages_.begin();
-
-      while (point != deferred_messages_.end() &&
-             (*point)->type() == GpuCommandBufferMsg_GetStateFast::ID) {
-        ++point;
-      }
-
-      if (point != deferred_messages_.end()) {
-        ++point;
-      }
-
-      deferred_messages_.insert(point, new IPC::Message(message));
-    } else {
-      // Move GetStateFast commands to the head of the queue, so the renderer
-      // doesn't have to wait any longer than necessary.
-      deferred_messages_.push_front(new IPC::Message(message));
-    }
+  if (message.type() == GpuCommandBufferMsg_WaitForTokenInRange::ID ||
+      message.type() == GpuCommandBufferMsg_WaitForGetOffsetInRange::ID) {
+    // Move Wait commands to the head of the queue, so the renderer
+    // doesn't have to wait any longer than necessary.
+    deferred_messages_.push_front(new IPC::Message(message));
   } else {
     deferred_messages_.push_back(new IPC::Message(message));
   }
@@ -605,18 +527,16 @@ void GpuChannel::StubSchedulingChanged(bool scheduled) {
   }
 }
 
-void GpuChannel::CreateViewCommandBuffer(
+CreateCommandBufferResult GpuChannel::CreateViewCommandBuffer(
     const gfx::GLSurfaceHandle& window,
     int32 surface_id,
     const GPUCreateCommandBufferConfig& init_params,
-    int32* route_id) {
+    int32 route_id) {
   TRACE_EVENT1("gpu",
                "GpuChannel::CreateViewCommandBuffer",
                "surface_id",
                surface_id);
 
-  *route_id = MSG_ROUTING_NONE;
-
   GpuCommandBufferStub* share_group = stubs_.Lookup(init_params.share_group_id);
 
   // Virtualize compositor contexts on OS X to prevent performance regressions
@@ -627,7 +547,6 @@ void GpuChannel::CreateViewCommandBuffer(
   use_virtualized_gl_context = true;
 #endif
 
-  *route_id = GenerateRouteID();
   scoped_ptr<GpuCommandBufferStub> stub(
       new GpuCommandBufferStub(this,
                                share_group,
@@ -639,15 +558,20 @@ void GpuChannel::CreateViewCommandBuffer(
                                init_params.attribs,
                                init_params.gpu_preference,
                                use_virtualized_gl_context,
-                               *route_id,
+                               route_id,
                                surface_id,
                                watchdog_,
                                software_,
                                init_params.active_url));
   if (preempted_flag_.get())
     stub->SetPreemptByFlag(preempted_flag_);
-  router_.AddRoute(*route_id, stub.get());
-  stubs_.AddWithID(stub.release(), *route_id);
+  if (!router_.AddRoute(route_id, stub.get())) {
+    DLOG(ERROR) << "GpuChannel::CreateViewCommandBuffer(): "
+                   "failed to add route";
+    return CREATE_COMMAND_BUFFER_FAILED_AND_CHANNEL_LOST;
+  }
+  stubs_.AddWithID(stub.release(), route_id);
+  return CREATE_COMMAND_BUFFER_SUCCEEDED;
 }
 
 GpuCommandBufferStub* GpuChannel::LookupCommandBuffer(int32 route_id) {
@@ -698,18 +622,8 @@ void GpuChannel::MarkAllContextsLost() {
   }
 }
 
-void GpuChannel::DestroySoon() {
-  base::MessageLoop::current()->PostTask(
-      FROM_HERE, base::Bind(&GpuChannel::OnDestroy, this));
-}
-
-int GpuChannel::GenerateRouteID() {
-  static int last_id = 0;
-  return ++last_id;
-}
-
-void GpuChannel::AddRoute(int32 route_id, IPC::Listener* listener) {
-  router_.AddRoute(route_id, listener);
+bool GpuChannel::AddRoute(int32 route_id, IPC::Listener* listener) {
+  return router_.AddRoute(route_id, listener);
 }
 
 void GpuChannel::RemoveRoute(int32 route_id) {
@@ -737,11 +651,6 @@ void GpuChannel::SetPreemptByFlag(
   }
 }
 
-GpuChannel::~GpuChannel() {
-  if (preempting_flag_.get())
-    preempting_flag_->Reset();
-}
-
 void GpuChannel::OnDestroy() {
   TRACE_EVENT0("gpu", "GpuChannel::OnDestroy");
   gpu_channel_manager_->RemoveChannel(client_id_);
@@ -754,20 +663,10 @@ bool GpuChannel::OnControlMessageReceived(const IPC::Message& msg) {
                         OnCreateOffscreenCommandBuffer)
     IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyCommandBuffer,
                         OnDestroyCommandBuffer)
-    IPC_MESSAGE_HANDLER(GpuChannelMsg_CreateVideoEncoder, OnCreateVideoEncoder)
-    IPC_MESSAGE_HANDLER(GpuChannelMsg_DestroyVideoEncoder,
-                        OnDestroyVideoEncoder)
-#if defined(OS_ANDROID)
-    IPC_MESSAGE_HANDLER(GpuChannelMsg_RegisterStreamTextureProxy,
-                        OnRegisterStreamTextureProxy)
-    IPC_MESSAGE_HANDLER(GpuChannelMsg_EstablishStreamTexture,
-                        OnEstablishStreamTexture)
-    IPC_MESSAGE_HANDLER(GpuChannelMsg_SetStreamTextureSize,
-                        OnSetStreamTextureSize)
-#endif
-    IPC_MESSAGE_HANDLER(
-        GpuChannelMsg_CollectRenderingStatsForSurface,
-        OnCollectRenderingStatsForSurface)
+    IPC_MESSAGE_HANDLER(GpuChannelMsg_DevToolsStartEventsRecording,
+                        OnDevToolsStartEventsRecording)
+    IPC_MESSAGE_HANDLER(GpuChannelMsg_DevToolsStopEventsRecording,
+                        OnDevToolsStopEventsRecording)
     IPC_MESSAGE_UNHANDLED(handled = false)
   IPC_END_MESSAGE_MAP()
   DCHECK(handled) << msg.type();
@@ -797,9 +696,6 @@ void GpuChannel::HandleMessage() {
     deferred_messages_.pop_front();
     bool message_processed = true;
 
-    processed_get_state_fast_ =
-        (message->type() == GpuCommandBufferMsg_GetStateFast::ID);
-
     currently_processing_message_ = message.get();
     bool result;
     if (message->routing_id() == MSG_ROUTING_CONTROL)
@@ -850,12 +746,11 @@ void GpuChannel::HandleMessage() {
 void GpuChannel::OnCreateOffscreenCommandBuffer(
     const gfx::Size& size,
     const GPUCreateCommandBufferConfig& init_params,
-    int32* route_id) {
+    int32 route_id,
+    bool* succeeded) {
   TRACE_EVENT0("gpu", "GpuChannel::OnCreateOffscreenCommandBuffer");
   GpuCommandBufferStub* share_group = stubs_.Lookup(init_params.share_group_id);
 
-  *route_id = GenerateRouteID();
-
   scoped_ptr<GpuCommandBufferStub> stub(new GpuCommandBufferStub(
       this,
       share_group,
@@ -867,17 +762,23 @@ void GpuChannel::OnCreateOffscreenCommandBuffer(
       init_params.attribs,
       init_params.gpu_preference,
       false,
-      *route_id,
+      route_id,
       0,
       watchdog_,
       software_,
       init_params.active_url));
   if (preempted_flag_.get())
     stub->SetPreemptByFlag(preempted_flag_);
-  router_.AddRoute(*route_id, stub.get());
-  stubs_.AddWithID(stub.release(), *route_id);
+  if (!router_.AddRoute(route_id, stub.get())) {
+    DLOG(ERROR) << "GpuChannel::OnCreateOffscreenCommandBuffer(): "
+                   "failed to add route";
+    *succeeded = false;
+    return;
+  }
+  stubs_.AddWithID(stub.release(), route_id);
   TRACE_EVENT1("gpu", "GpuChannel::OnCreateOffscreenCommandBuffer",
                "route_id", route_id);
+  *succeeded = true;
 }
 
 void GpuChannel::OnDestroyCommandBuffer(int32 route_id) {
@@ -898,74 +799,13 @@ void GpuChannel::OnDestroyCommandBuffer(int32 route_id) {
   }
 }
 
-void GpuChannel::OnCreateVideoEncoder(int32* route_id) {
-  TRACE_EVENT0("gpu", "GpuChannel::OnCreateVideoEncoder");
-
-  *route_id = GenerateRouteID();
-  GpuVideoEncodeAccelerator* encoder =
-      new GpuVideoEncodeAccelerator(this, *route_id);
-  router_.AddRoute(*route_id, encoder);
-  video_encoders_.AddWithID(encoder, *route_id);
-}
-
-void GpuChannel::OnDestroyVideoEncoder(int32 route_id) {
-  TRACE_EVENT1(
-      "gpu", "GpuChannel::OnDestroyVideoEncoder", "route_id", route_id);
-  GpuVideoEncodeAccelerator* encoder = video_encoders_.Lookup(route_id);
-  if (!encoder)
-    return;
-  router_.RemoveRoute(route_id);
-  video_encoders_.Remove(route_id);
-}
-
-#if defined(OS_ANDROID)
-void GpuChannel::OnRegisterStreamTextureProxy(
-    int32 stream_id, int32* route_id) {
-  // Note that route_id is only used for notifications sent out from here.
-  // StreamTextureManager owns all texture objects and for incoming messages
-  // it finds the correct object based on stream_id.
-  *route_id = GenerateRouteID();
-  stream_texture_manager_->RegisterStreamTextureProxy(stream_id, *route_id);
-}
-
-void GpuChannel::OnEstablishStreamTexture(
-    int32 stream_id, int32 primary_id, int32 secondary_id) {
-  stream_texture_manager_->EstablishStreamTexture(
-      stream_id, primary_id, secondary_id);
+void GpuChannel::OnDevToolsStartEventsRecording(int32 route_id,
+                                                bool* succeeded) {
+  *succeeded = devtools_gpu_agent_->StartEventsRecording(route_id);
 }
 
-void GpuChannel::OnSetStreamTextureSize(
-    int32 stream_id, const gfx::Size& size) {
-  stream_texture_manager_->SetStreamTextureSize(stream_id, size);
-}
-#endif
-
-void GpuChannel::OnCollectRenderingStatsForSurface(
-    int32 surface_id, GpuRenderingStats* stats) {
-  for (StubMap::Iterator<GpuCommandBufferStub> it(&stubs_);
-       !it.IsAtEnd(); it.Advance()) {
-    int texture_upload_count =
-        it.GetCurrentValue()->decoder()->GetTextureUploadCount();
-    base::TimeDelta total_texture_upload_time =
-        it.GetCurrentValue()->decoder()->GetTotalTextureUploadTime();
-    base::TimeDelta total_processing_commands_time =
-        it.GetCurrentValue()->decoder()->GetTotalProcessingCommandsTime();
-
-    stats->global_texture_upload_count += texture_upload_count;
-    stats->global_total_texture_upload_time += total_texture_upload_time;
-    stats->global_total_processing_commands_time +=
-        total_processing_commands_time;
-    if (it.GetCurrentValue()->surface_id() == surface_id) {
-      stats->texture_upload_count += texture_upload_count;
-      stats->total_texture_upload_time += total_texture_upload_time;
-      stats->total_processing_commands_time += total_processing_commands_time;
-    }
-  }
-
-  GPUVideoMemoryUsageStats usage_stats;
-  gpu_channel_manager_->gpu_memory_manager()->GetVideoMemoryUsageStats(
-      &usage_stats);
-  stats->global_video_memory_bytes_allocated = usage_stats.bytes_allocated;
+void GpuChannel::OnDevToolsStopEventsRecording() {
+  devtools_gpu_agent_->StopEventsRecording();
 }
 
 void GpuChannel::MessageProcessed() {
@@ -985,12 +825,21 @@ void GpuChannel::CacheShader(const std::string& key,
       new GpuHostMsg_CacheShader(client_id_, key, shader));
 }
 
-void GpuChannel::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
+void GpuChannel::AddFilter(IPC::MessageFilter* filter) {
   channel_->AddFilter(filter);
 }
 
-void GpuChannel::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) {
+void GpuChannel::RemoveFilter(IPC::MessageFilter* filter) {
   channel_->RemoveFilter(filter);
 }
 
+uint64 GpuChannel::GetMemoryUsage() {
+  uint64 size = 0;
+  for (StubMap::Iterator<GpuCommandBufferStub> it(&stubs_);
+       !it.IsAtEnd(); it.Advance()) {
+    size += it.GetCurrentValue()->GetMemoryUsage();
+  }
+  return size;
+}
+
 }  // namespace content