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