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