OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 #include "content/browser/renderer_host/render_widget_helper.h" | 5 #include "content/browser/renderer_host/render_widget_helper.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/eintr_wrapper.h" | 8 #include "base/eintr_wrapper.h" |
9 #include "base/threading/thread.h" | 9 #include "base/threading/thread.h" |
10 #include "content/browser/renderer_host/render_process_host_impl.h" | 10 #include "content/browser/renderer_host/render_process_host_impl.h" |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 IPC::Message* msg) { | 102 IPC::Message* msg) { |
103 base::TimeTicks time_start = base::TimeTicks::Now(); | 103 base::TimeTicks time_start = base::TimeTicks::Now(); |
104 | 104 |
105 for (;;) { | 105 for (;;) { |
106 UpdateMsgProxy* proxy = NULL; | 106 UpdateMsgProxy* proxy = NULL; |
107 { | 107 { |
108 base::AutoLock lock(pending_paints_lock_); | 108 base::AutoLock lock(pending_paints_lock_); |
109 | 109 |
110 UpdateMsgProxyMap::iterator it = pending_paints_.find(render_widget_id); | 110 UpdateMsgProxyMap::iterator it = pending_paints_.find(render_widget_id); |
111 if (it != pending_paints_.end()) { | 111 if (it != pending_paints_.end()) { |
112 proxy = it->second; | 112 UpdateMsgProxyQueue &queue = it->second; |
| 113 DCHECK(!queue.empty()); |
| 114 proxy = queue.front(); |
113 | 115 |
114 // Flag the proxy as cancelled so that when it is run as a task it will | 116 // Flag the proxy as cancelled so that when it is run as a task it will |
115 // do nothing. | 117 // do nothing. |
116 proxy->cancelled = true; | 118 proxy->cancelled = true; |
117 | 119 |
118 pending_paints_.erase(it); | 120 queue.pop_front(); |
| 121 if (queue.empty()) |
| 122 pending_paints_.erase(it); |
119 } | 123 } |
120 } | 124 } |
121 | 125 |
122 if (proxy) { | 126 if (proxy) { |
123 *msg = proxy->message; | 127 *msg = proxy->message; |
124 DCHECK(msg->routing_id() == render_widget_id); | 128 DCHECK(msg->routing_id() == render_widget_id); |
125 return true; | 129 return true; |
126 } | 130 } |
127 | 131 |
128 // Calculate the maximum amount of time that we are willing to sleep. | 132 // Calculate the maximum amount of time that we are willing to sleep. |
129 base::TimeDelta max_sleep_time = | 133 base::TimeDelta max_sleep_time = |
130 max_delay - (base::TimeTicks::Now() - time_start); | 134 max_delay - (base::TimeTicks::Now() - time_start); |
131 if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0)) | 135 if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0)) |
132 break; | 136 break; |
133 | 137 |
134 event_.TimedWait(max_sleep_time); | 138 event_.TimedWait(max_sleep_time); |
135 } | 139 } |
136 | 140 |
137 return false; | 141 return false; |
138 } | 142 } |
139 | 143 |
140 void RenderWidgetHelper::DidReceiveUpdateMsg(const IPC::Message& msg) { | 144 void RenderWidgetHelper::DidReceiveUpdateMsg(const IPC::Message& msg) { |
141 int render_widget_id = msg.routing_id(); | 145 int render_widget_id = msg.routing_id(); |
142 | 146 |
143 UpdateMsgProxy* proxy = NULL; | 147 UpdateMsgProxy* proxy = new UpdateMsgProxy(this, msg); |
144 { | 148 { |
145 base::AutoLock lock(pending_paints_lock_); | 149 base::AutoLock lock(pending_paints_lock_); |
146 | 150 |
147 // Visual Studio 2010 has problems converting NULL to the null pointer for | 151 pending_paints_[render_widget_id].push_back(proxy); |
148 // std::pair. See http://connect.microsoft.com/VisualStudio/feedback/detail
s/520043/error-converting-from-null-to-a-pointer-type-in-std-pair | |
149 // It will work if we pass nullptr. | |
150 #if defined(_MSC_VER) && _MSC_VER >= 1600 | |
151 RenderWidgetHelper::UpdateMsgProxy* null_proxy = nullptr; | |
152 #else | |
153 RenderWidgetHelper::UpdateMsgProxy* null_proxy = NULL; | |
154 #endif | |
155 UpdateMsgProxyMap::value_type new_value(render_widget_id, null_proxy); | |
156 | |
157 // We expect only a single PaintRect message at a time. Optimize for the | |
158 // case that we don't already have an entry by using the 'insert' method. | |
159 std::pair<UpdateMsgProxyMap::iterator, bool> result = | |
160 pending_paints_.insert(new_value); | |
161 if (!result.second) { | |
162 NOTREACHED() << "Unexpected PaintRect message!"; | |
163 return; | |
164 } | |
165 | |
166 result.first->second = (proxy = new UpdateMsgProxy(this, msg)); | |
167 } | 152 } |
168 | 153 |
169 // Notify anyone waiting on the UI thread that there is a new entry in the | 154 // Notify anyone waiting on the UI thread that there is a new entry in the |
170 // proxy map. If they don't find the entry they are looking for, then they | 155 // proxy map. If they don't find the entry they are looking for, then they |
171 // will just continue waiting. | 156 // will just continue waiting. |
172 event_.Signal(); | 157 event_.Signal(); |
173 | 158 |
174 // The proxy will be deleted when it is run as a task. | 159 // The proxy will be deleted when it is run as a task. |
175 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, proxy); | 160 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, proxy); |
176 } | 161 } |
177 | 162 |
178 void RenderWidgetHelper::OnDiscardUpdateMsg(UpdateMsgProxy* proxy) { | 163 void RenderWidgetHelper::OnDiscardUpdateMsg(UpdateMsgProxy* proxy) { |
179 const IPC::Message& msg = proxy->message; | 164 const IPC::Message& msg = proxy->message; |
180 | 165 |
181 // Remove the proxy from the map now that we are going to handle it normally. | 166 // Remove the proxy from the map now that we are going to handle it normally. |
182 { | 167 { |
183 base::AutoLock lock(pending_paints_lock_); | 168 base::AutoLock lock(pending_paints_lock_); |
184 | 169 |
185 UpdateMsgProxyMap::iterator it = pending_paints_.find(msg.routing_id()); | 170 UpdateMsgProxyMap::iterator it = pending_paints_.find(msg.routing_id()); |
186 DCHECK(it != pending_paints_.end()); | 171 DCHECK(it != pending_paints_.end()); |
187 DCHECK(it->second == proxy); | 172 UpdateMsgProxyQueue &queue = it->second; |
| 173 DCHECK(queue.front() == proxy); |
188 | 174 |
189 pending_paints_.erase(it); | 175 queue.pop_front(); |
| 176 if (queue.empty()) |
| 177 pending_paints_.erase(it); |
190 } | 178 } |
191 } | 179 } |
192 | 180 |
193 void RenderWidgetHelper::OnDispatchUpdateMsg(UpdateMsgProxy* proxy) { | 181 void RenderWidgetHelper::OnDispatchUpdateMsg(UpdateMsgProxy* proxy) { |
194 OnDiscardUpdateMsg(proxy); | 182 OnDiscardUpdateMsg(proxy); |
195 | 183 |
196 // It is reasonable for the host to no longer exist. | 184 // It is reasonable for the host to no longer exist. |
197 content::RenderProcessHost* host = | 185 content::RenderProcessHost* host = |
198 content::RenderProcessHost::FromID(render_process_id_); | 186 content::RenderProcessHost::FromID(render_process_id_); |
199 if (host) | 187 if (host) |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 gfx::PluginWindowHandle RenderWidgetHelper::LookupCompositingSurface( | 338 gfx::PluginWindowHandle RenderWidgetHelper::LookupCompositingSurface( |
351 int render_widget_id) { | 339 int render_widget_id) { |
352 base::AutoLock locked(view_compositing_surface_map_lock_); | 340 base::AutoLock locked(view_compositing_surface_map_lock_); |
353 ViewCompositingSurfaceMap::iterator it = | 341 ViewCompositingSurfaceMap::iterator it = |
354 view_compositing_surface_map_.find(render_widget_id); | 342 view_compositing_surface_map_.find(render_widget_id); |
355 if (it == view_compositing_surface_map_.end()) | 343 if (it == view_compositing_surface_map_.end()) |
356 return gfx::kNullPluginWindow; | 344 return gfx::kNullPluginWindow; |
357 | 345 |
358 return it->second; | 346 return it->second; |
359 } | 347 } |
OLD | NEW |