Home | History | Annotate | Download | only in renderer
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "content/renderer/render_frame_proxy.h"
      6 
      7 #include <map>
      8 
      9 #include "base/lazy_instance.h"
     10 #include "content/common/frame_messages.h"
     11 #include "content/common/swapped_out_messages.h"
     12 #include "content/renderer/child_frame_compositing_helper.h"
     13 #include "content/renderer/render_frame_impl.h"
     14 #include "content/renderer/render_thread_impl.h"
     15 #include "content/renderer/render_view_impl.h"
     16 #include "third_party/WebKit/public/web/WebView.h"
     17 
     18 namespace content {
     19 
     20 namespace {
     21 
     22 typedef std::map<int, RenderFrameProxy*> RoutingIDProxyMap;
     23 static base::LazyInstance<RoutingIDProxyMap> g_routing_id_proxy_map =
     24     LAZY_INSTANCE_INITIALIZER;
     25 
     26 }  // namespace
     27 
     28 // static
     29 RenderFrameProxy* RenderFrameProxy::CreateFrameProxy(int routing_id,
     30                                                      int frame_routing_id) {
     31   DCHECK_NE(routing_id, MSG_ROUTING_NONE);
     32   RenderFrameProxy* proxy = new RenderFrameProxy(routing_id, frame_routing_id);
     33   return proxy;
     34 }
     35 
     36 // static
     37 RenderFrameProxy* RenderFrameProxy::FromRoutingID(int32 routing_id) {
     38   RoutingIDProxyMap* proxies = g_routing_id_proxy_map.Pointer();
     39   RoutingIDProxyMap::iterator it = proxies->find(routing_id);
     40   return it == proxies->end() ? NULL : it->second;
     41 }
     42 
     43 RenderFrameProxy::RenderFrameProxy(int routing_id, int frame_routing_id)
     44     : routing_id_(routing_id),
     45       frame_routing_id_(frame_routing_id) {
     46   std::pair<RoutingIDProxyMap::iterator, bool> result =
     47     g_routing_id_proxy_map.Get().insert(std::make_pair(routing_id_, this));
     48   CHECK(result.second) << "Inserting a duplicate item.";
     49   RenderThread::Get()->AddRoute(routing_id_, this);
     50 
     51   render_frame_ = RenderFrameImpl::FromRoutingID(frame_routing_id);
     52   CHECK(render_frame_);
     53   render_frame_->render_view()->RegisterRenderFrameProxy(this);
     54 }
     55 
     56 RenderFrameProxy::~RenderFrameProxy() {
     57   render_frame_->render_view()->UnregisterRenderFrameProxy(this);
     58   RenderThread::Get()->RemoveRoute(routing_id_);
     59   g_routing_id_proxy_map.Get().erase(routing_id_);
     60 }
     61 
     62 blink::WebFrame* RenderFrameProxy::GetWebFrame() {
     63   return render_frame_->GetWebFrame();
     64 }
     65 
     66 void RenderFrameProxy::DidCommitCompositorFrame() {
     67   if (compositing_helper_)
     68     compositing_helper_->DidCommitCompositorFrame();
     69 }
     70 
     71 bool RenderFrameProxy::OnMessageReceived(const IPC::Message& msg) {
     72   bool handled = true;
     73   IPC_BEGIN_MESSAGE_MAP(RenderFrameProxy, msg)
     74     IPC_MESSAGE_HANDLER(FrameMsg_DeleteProxy, OnDeleteProxy)
     75     IPC_MESSAGE_HANDLER(FrameMsg_ChildFrameProcessGone, OnChildFrameProcessGone)
     76     IPC_MESSAGE_HANDLER(FrameMsg_BuffersSwapped, OnBuffersSwapped)
     77     IPC_MESSAGE_HANDLER_GENERIC(FrameMsg_CompositorFrameSwapped,
     78                                 OnCompositorFrameSwapped(msg))
     79     IPC_MESSAGE_UNHANDLED(handled = false)
     80   IPC_END_MESSAGE_MAP()
     81 
     82   if (!handled)
     83     return render_frame_->OnMessageReceived(msg);
     84 
     85   return handled;
     86 }
     87 
     88 bool RenderFrameProxy::Send(IPC::Message* message) {
     89   if (!SwappedOutMessages::CanSendWhileSwappedOut(message)) {
     90     delete message;
     91     return false;
     92   }
     93   message->set_routing_id(routing_id_);
     94   return RenderThread::Get()->Send(message);
     95 }
     96 
     97 void RenderFrameProxy::OnDeleteProxy() {
     98   RenderFrameImpl* render_frame =
     99       RenderFrameImpl::FromRoutingID(frame_routing_id_);
    100   CHECK(render_frame);
    101   render_frame->set_render_frame_proxy(NULL);
    102 
    103   delete this;
    104 }
    105 
    106 void RenderFrameProxy::OnChildFrameProcessGone() {
    107   if (compositing_helper_)
    108     compositing_helper_->ChildFrameGone();
    109 }
    110 
    111 void RenderFrameProxy::OnBuffersSwapped(
    112     const FrameMsg_BuffersSwapped_Params& params) {
    113   if (!compositing_helper_.get()) {
    114     compositing_helper_ =
    115         ChildFrameCompositingHelper::CreateCompositingHelperForRenderFrame(
    116             GetWebFrame(), this, routing_id_);
    117     compositing_helper_->EnableCompositing(true);
    118   }
    119   compositing_helper_->OnBuffersSwapped(
    120       params.size,
    121       params.mailbox,
    122       params.gpu_route_id,
    123       params.gpu_host_id,
    124       render_frame_->render_view()->GetWebView()->deviceScaleFactor());
    125 }
    126 
    127 void RenderFrameProxy::OnCompositorFrameSwapped(const IPC::Message& message) {
    128   FrameMsg_CompositorFrameSwapped::Param param;
    129   if (!FrameMsg_CompositorFrameSwapped::Read(&message, &param))
    130     return;
    131 
    132   scoped_ptr<cc::CompositorFrame> frame(new cc::CompositorFrame);
    133   param.a.frame.AssignTo(frame.get());
    134 
    135   if (!compositing_helper_.get()) {
    136     compositing_helper_ =
    137         ChildFrameCompositingHelper::CreateCompositingHelperForRenderFrame(
    138             GetWebFrame(), this, routing_id_);
    139     compositing_helper_->EnableCompositing(true);
    140   }
    141   compositing_helper_->OnCompositorFrameSwapped(frame.Pass(),
    142                                                 param.a.producing_route_id,
    143                                                 param.a.output_surface_id,
    144                                                 param.a.producing_host_id,
    145                                                 param.a.shared_memory_handle);
    146 }
    147 
    148 }  // namespace
    149