| 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 |