OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HELPER_H_ | 5 #ifndef CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HELPER_H_ |
6 #define CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HELPER_H_ | 6 #define CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HELPER_H_ |
7 #pragma once | 7 #pragma once |
8 | 8 |
9 #include <map> | 9 // TODO(jam): remove this file when all files have been converted. |
10 | 10 #include "content/browser/renderer_host/render_widget_helper.h" |
11 #include "app/surface/transport_dib.h" | |
12 #include "base/atomic_sequence_num.h" | |
13 #include "base/hash_tables.h" | |
14 #include "base/process.h" | |
15 #include "base/ref_counted.h" | |
16 #include "base/synchronization/lock.h" | |
17 #include "base/synchronization/waitable_event.h" | |
18 #include "chrome/common/window_container_type.h" | |
19 #include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupType.h" | |
20 | |
21 namespace IPC { | |
22 class Message; | |
23 } | |
24 | |
25 namespace base { | |
26 class TimeDelta; | |
27 } | |
28 | |
29 class ResourceDispatcherHost; | |
30 struct ViewHostMsg_CreateWindow_Params; | |
31 struct ViewMsg_ClosePage_Params; | |
32 | |
33 | |
34 // Instantiated per RenderProcessHost to provide various optimizations on | |
35 // behalf of a RenderWidgetHost. This class bridges between the IO thread | |
36 // where the RenderProcessHost's MessageFilter lives and the UI thread where | |
37 // the RenderWidgetHost lives. | |
38 // | |
39 // | |
40 // OPTIMIZED RESIZE | |
41 // | |
42 // RenderWidgetHelper is used to implement optimized resize. When the | |
43 // RenderWidgetHost is resized, it sends a Resize message to its RenderWidget | |
44 // counterpart in the renderer process. The RenderWidget generates a | |
45 // UpdateRect message in response to the Resize message, and it sets the | |
46 // IS_RESIZE_ACK flag in the UpdateRect message to true. | |
47 // | |
48 // Back in the browser process, when the RenderProcessHost's MessageFilter | |
49 // sees a UpdateRect message, it directs it to the RenderWidgetHelper by | |
50 // calling the DidReceiveUpdateMsg method. That method stores the data for | |
51 // the UpdateRect message in a map, where it can be directly accessed by the | |
52 // RenderWidgetHost on the UI thread during a call to RenderWidgetHost's | |
53 // GetBackingStore method. | |
54 // | |
55 // When the RenderWidgetHost's GetBackingStore method is called, it first | |
56 // checks to see if it is waiting for a resize ack. If it is, then it calls | |
57 // the RenderWidgetHelper's WaitForUpdateMsg to check if there is already a | |
58 // resulting UpdateRect message (or to wait a short amount of time for one to | |
59 // arrive). The main goal of this mechanism is to short-cut the usual way in | |
60 // which IPC messages are proxied over to the UI thread via InvokeLater. | |
61 // This approach is necessary since window resize is followed up immediately | |
62 // by a request to repaint the window. | |
63 // | |
64 // | |
65 // OPTIMIZED TAB SWITCHING | |
66 // | |
67 // When a RenderWidgetHost is in a background tab, it is flagged as hidden. | |
68 // This causes the corresponding RenderWidget to stop sending UpdateRect | |
69 // messages. The RenderWidgetHost also discards its backingstore when it is | |
70 // hidden, which helps free up memory. As a result, when a RenderWidgetHost | |
71 // is restored, it can be momentarily without a backingstore. (Restoring a | |
72 // RenderWidgetHost results in a WasRestored message being sent to the | |
73 // RenderWidget, which triggers a full UpdateRect message.) This can lead to | |
74 // an observed rendering glitch as the TabContents will just have to fill | |
75 // white overtop the RenderWidgetHost until the RenderWidgetHost receives a | |
76 // UpdateRect message to refresh its backingstore. | |
77 // | |
78 // To avoid this 'white flash', the RenderWidgetHost again makes use of the | |
79 // RenderWidgetHelper's WaitForUpdateMsg method. When the RenderWidgetHost's | |
80 // GetBackingStore method is called, it will call WaitForUpdateMsg if it has | |
81 // no backingstore. | |
82 // | |
83 // TRANSPORT DIB CREATION | |
84 // | |
85 // On some platforms (currently the Mac) the renderer cannot create transport | |
86 // DIBs because of sandbox limitations. Thus, it has to make synchronous IPCs | |
87 // to the browser for them. Since these requests are synchronous, they cannot | |
88 // terminate on the UI thread. Thus, in this case, this object performs the | |
89 // allocation and maintains the set of allocated transport DIBs which the | |
90 // renderers can refer to. | |
91 // | |
92 class RenderWidgetHelper | |
93 : public base::RefCountedThreadSafe<RenderWidgetHelper> { | |
94 public: | |
95 RenderWidgetHelper(); | |
96 | |
97 void Init(int render_process_id, | |
98 ResourceDispatcherHost* resource_dispatcher_host); | |
99 | |
100 // Gets the next available routing id. This is thread safe. | |
101 int GetNextRoutingID(); | |
102 | |
103 | |
104 // UI THREAD ONLY ----------------------------------------------------------- | |
105 | |
106 // These three functions provide the backend implementation of the | |
107 // corresponding functions in RenderProcessHost. See those declarations | |
108 // for documentation. | |
109 void CancelResourceRequests(int render_widget_id); | |
110 void CrossSiteClosePageACK(const ViewMsg_ClosePage_Params& params); | |
111 bool WaitForUpdateMsg(int render_widget_id, | |
112 const base::TimeDelta& max_delay, | |
113 IPC::Message* msg); | |
114 | |
115 #if defined(OS_MACOSX) | |
116 // Given the id of a transport DIB, return a mapping to it or NULL on error. | |
117 TransportDIB* MapTransportDIB(TransportDIB::Id dib_id); | |
118 #endif | |
119 | |
120 | |
121 // IO THREAD ONLY ----------------------------------------------------------- | |
122 | |
123 // Called on the IO thread when a UpdateRect message is received. | |
124 void DidReceiveUpdateMsg(const IPC::Message& msg); | |
125 | |
126 void CreateNewWindow(const ViewHostMsg_CreateWindow_Params& params, | |
127 base::ProcessHandle render_process, | |
128 int* route_id); | |
129 void CreateNewWidget(int opener_id, | |
130 WebKit::WebPopupType popup_type, | |
131 int* route_id); | |
132 void CreateNewFullscreenWidget(int opener_id, int* route_id); | |
133 | |
134 #if defined(OS_MACOSX) | |
135 // Called on the IO thread to handle the allocation of a TransportDIB. If | |
136 // |cache_in_browser| is |true|, then a copy of the shmem is kept by the | |
137 // browser, and it is the caller's repsonsibility to call | |
138 // FreeTransportDIB(). In all cases, the caller is responsible for deleting | |
139 // the resulting TransportDIB. | |
140 void AllocTransportDIB(size_t size, | |
141 bool cache_in_browser, | |
142 TransportDIB::Handle* result); | |
143 | |
144 // Called on the IO thread to handle the freeing of a transport DIB | |
145 void FreeTransportDIB(TransportDIB::Id dib_id); | |
146 #endif | |
147 | |
148 private: | |
149 // A class used to proxy a paint message. PaintMsgProxy objects are created | |
150 // on the IO thread and destroyed on the UI thread. | |
151 class UpdateMsgProxy; | |
152 friend class UpdateMsgProxy; | |
153 friend class base::RefCountedThreadSafe<RenderWidgetHelper>; | |
154 | |
155 // Map from render_widget_id to live PaintMsgProxy instance. | |
156 typedef base::hash_map<int, UpdateMsgProxy*> UpdateMsgProxyMap; | |
157 | |
158 ~RenderWidgetHelper(); | |
159 | |
160 // Called on the UI thread to discard a paint message. | |
161 void OnDiscardUpdateMsg(UpdateMsgProxy* proxy); | |
162 | |
163 // Called on the UI thread to dispatch a paint message if necessary. | |
164 void OnDispatchUpdateMsg(UpdateMsgProxy* proxy); | |
165 | |
166 // Called on the UI thread to finish creating a window. | |
167 void OnCreateWindowOnUI(const ViewHostMsg_CreateWindow_Params& params, | |
168 int route_id); | |
169 | |
170 // Called on the IO thread after a window was created on the UI thread. | |
171 void OnCreateWindowOnIO(int route_id); | |
172 | |
173 // Called on the UI thread to finish creating a widget. | |
174 void OnCreateWidgetOnUI(int opener_id, | |
175 int route_id, | |
176 WebKit::WebPopupType popup_type); | |
177 | |
178 // Called on the UI thread to create a fullscreen widget. | |
179 void OnCreateFullscreenWidgetOnUI(int opener_id, int route_id); | |
180 | |
181 // Called on the IO thread to cancel resource requests for the render widget. | |
182 void OnCancelResourceRequests(int render_widget_id); | |
183 | |
184 // Called on the IO thread to resume a cross-site response. | |
185 void OnCrossSiteClosePageACK(const ViewMsg_ClosePage_Params& params); | |
186 | |
187 #if defined(OS_MACOSX) | |
188 // Called on destruction to release all allocated transport DIBs | |
189 void ClearAllocatedDIBs(); | |
190 | |
191 // On OSX we keep file descriptors to all the allocated DIBs around until | |
192 // the renderer frees them. | |
193 base::Lock allocated_dibs_lock_; | |
194 std::map<TransportDIB::Id, int> allocated_dibs_; | |
195 #endif | |
196 | |
197 // A map of live paint messages. Must hold pending_paints_lock_ to access. | |
198 // The UpdateMsgProxy objects are not owned by this map. (See UpdateMsgProxy | |
199 // for details about how the lifetime of instances are managed.) | |
200 UpdateMsgProxyMap pending_paints_; | |
201 base::Lock pending_paints_lock_; | |
202 | |
203 int render_process_id_; | |
204 | |
205 // Event used to implement WaitForUpdateMsg. | |
206 base::WaitableEvent event_; | |
207 | |
208 // The next routing id to use. | |
209 base::AtomicSequenceNumber next_routing_id_; | |
210 | |
211 ResourceDispatcherHost* resource_dispatcher_host_; | |
212 | |
213 DISALLOW_COPY_AND_ASSIGN(RenderWidgetHelper); | |
214 }; | |
215 | 11 |
216 #endif // CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HELPER_H_ | 12 #endif // CHROME_BROWSER_RENDERER_HOST_RENDER_WIDGET_HELPER_H_ |
OLD | NEW |