• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HELPER_H_
6 #define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HELPER_H_
7 
8 #include <map>
9 
10 #include "base/atomic_sequence_num.h"
11 #include "base/containers/hash_tables.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/process/process.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/content_browser_client.h"
16 #include "content/public/browser/global_request_id.h"
17 #include "content/public/common/window_container_type.h"
18 #include "third_party/WebKit/public/web/WebPopupType.h"
19 #include "ui/gfx/native_widget_types.h"
20 #include "ui/surface/transport_dib.h"
21 
22 namespace IPC {
23 class Message;
24 }
25 
26 namespace base {
27 class TimeDelta;
28 }
29 
30 struct GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params;
31 struct ViewHostMsg_CreateWindow_Params;
32 struct ViewMsg_SwapOut_Params;
33 
34 namespace content {
35 class GpuProcessHost;
36 class ResourceDispatcherHostImpl;
37 class SessionStorageNamespace;
38 
39 // Instantiated per RenderProcessHost to provide various optimizations on
40 // behalf of a RenderWidgetHost.  This class bridges between the IO thread
41 // where the RenderProcessHost's MessageFilter lives and the UI thread where
42 // the RenderWidgetHost lives.
43 //
44 //
45 // OPTIMIZED TAB SWITCHING
46 //
47 //   When a RenderWidgetHost is in a background tab, it is flagged as hidden.
48 //   This causes the corresponding RenderWidget to stop sending BackingStore
49 //   messages. The RenderWidgetHost also discards its backingstore when it is
50 //   hidden, which helps free up memory.  As a result, when a RenderWidgetHost
51 //   is restored, it can be momentarily be without a backingstore.  (Restoring
52 //   a RenderWidgetHost results in a WasShown message being sent to the
53 //   RenderWidget, which triggers a full BackingStore message.)  This can lead
54 //   to an observed rendering glitch as the WebContentsImpl will just have to
55 //   fill white overtop the RenderWidgetHost until the RenderWidgetHost
56 //   receives a BackingStore message to refresh its backingstore.
57 //
58 //   To avoid this 'white flash', the RenderWidgetHost again makes use of the
59 //   RenderWidgetHelper's WaitForBackingStoreMsg method.  When the
60 //   RenderWidgetHost's GetBackingStore method is called, it will call
61 //   WaitForBackingStoreMsg if it has no backingstore.
62 //
63 // TRANSPORT DIB CREATION
64 //
65 //   On some platforms (currently the Mac) the renderer cannot create transport
66 //   DIBs because of sandbox limitations. Thus, it has to make synchronous IPCs
67 //   to the browser for them. Since these requests are synchronous, they cannot
68 //   terminate on the UI thread. Thus, in this case, this object performs the
69 //   allocation and maintains the set of allocated transport DIBs which the
70 //   renderers can refer to.
71 //
72 
73 class RenderWidgetHelper
74     : public base::RefCountedThreadSafe<RenderWidgetHelper,
75                                         BrowserThread::DeleteOnIOThread> {
76  public:
77   RenderWidgetHelper();
78 
79   void Init(int render_process_id,
80             ResourceDispatcherHostImpl* resource_dispatcher_host);
81 
82   // Gets the next available routing id.  This is thread safe.
83   int GetNextRoutingID();
84 
85   // IO THREAD ONLY -----------------------------------------------------------
86 
87   // Lookup the RenderWidgetHelper from the render_process_host_id. Returns NULL
88   // if not found. NOTE: The raw pointer is for temporary use only. To retain,
89   // store in a scoped_refptr.
90   static RenderWidgetHelper* FromProcessHostID(int render_process_host_id);
91 
92   // UI THREAD ONLY -----------------------------------------------------------
93 
94   // These four functions provide the backend implementation of the
95   // corresponding functions in RenderProcessHost. See those declarations
96   // for documentation.
97   void ResumeDeferredNavigation(const GlobalRequestID& request_id);
98   void ResumeResponseDeferredAtStart(const GlobalRequestID& request_id);
99 
100   // Called to resume the requests for a view after it's ready. The view was
101   // created by CreateNewWindow which initially blocked the requests.
102   void ResumeRequestsForView(int route_id);
103 
104   // IO THREAD ONLY -----------------------------------------------------------
105 
106   void CreateNewWindow(
107       const ViewHostMsg_CreateWindow_Params& params,
108       bool no_javascript_access,
109       base::ProcessHandle render_process,
110       int* route_id,
111       int* main_frame_route_id,
112       int* surface_id,
113       SessionStorageNamespace* session_storage_namespace);
114   void CreateNewWidget(int opener_id,
115                        blink::WebPopupType popup_type,
116                        int* route_id,
117                        int* surface_id);
118   void CreateNewFullscreenWidget(int opener_id, int* route_id, int* surface_id);
119 
120 #if defined(OS_POSIX)
121   // Called on the IO thread to handle the allocation of a TransportDIB.  If
122   // |cache_in_browser| is |true|, then a copy of the shmem is kept by the
123   // browser, and it is the caller's repsonsibility to call
124   // FreeTransportDIB().  In all cases, the caller is responsible for deleting
125   // the resulting TransportDIB.
126   void AllocTransportDIB(uint32 size,
127                          bool cache_in_browser,
128                          TransportDIB::Handle* result);
129 
130   // Called on the IO thread to handle the freeing of a transport DIB
131   void FreeTransportDIB(TransportDIB::Id dib_id);
132 #endif
133 
134  private:
135   friend class base::RefCountedThreadSafe<RenderWidgetHelper>;
136   friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
137   friend class base::DeleteHelper<RenderWidgetHelper>;
138 
139   ~RenderWidgetHelper();
140 
141   // Called on the UI thread to finish creating a window.
142   void OnCreateWindowOnUI(
143       const ViewHostMsg_CreateWindow_Params& params,
144       int route_id,
145       int main_frame_route_id,
146       SessionStorageNamespace* session_storage_namespace);
147 
148   // Called on the IO thread after a window was created on the UI thread.
149   void OnResumeRequestsForView(int route_id);
150 
151   // Called on the UI thread to finish creating a widget.
152   void OnCreateWidgetOnUI(int opener_id,
153                           int route_id,
154                           blink::WebPopupType popup_type);
155 
156   // Called on the UI thread to create a fullscreen widget.
157   void OnCreateFullscreenWidgetOnUI(int opener_id, int route_id);
158 
159   // Called on the IO thread to resume a paused navigation in the network
160   // stack without transferring it to a new renderer process.
161   void OnResumeDeferredNavigation(const GlobalRequestID& request_id);
162 
163   // Called on the IO thread to resume a navigation paused immediately after
164   // receiving response headers.
165   void OnResumeResponseDeferredAtStart(const GlobalRequestID& request_id);
166 
167 #if defined(OS_POSIX)
168   // Called on destruction to release all allocated transport DIBs
169   void ClearAllocatedDIBs();
170 
171   // On POSIX we keep file descriptors to all the allocated DIBs around until
172   // the renderer frees them.
173   base::Lock allocated_dibs_lock_;
174   std::map<TransportDIB::Id, int> allocated_dibs_;
175 #endif
176 
177   int render_process_id_;
178 
179   // The next routing id to use.
180   base::AtomicSequenceNumber next_routing_id_;
181 
182   ResourceDispatcherHostImpl* resource_dispatcher_host_;
183 
184   DISALLOW_COPY_AND_ASSIGN(RenderWidgetHelper);
185 };
186 
187 }  // namespace content
188 
189 #endif  // CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HELPER_H_
190