Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(641)

Side by Side Diff: content/browser/renderer_host/render_widget_helper.cc

Issue 9980016: Delete background tab IOSurfaces on Mac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed auto-resize and fullscreen toggle Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #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/bind_helpers.h" 8 #include "base/bind_helpers.h"
9 #include "base/eintr_wrapper.h" 9 #include "base/eintr_wrapper.h"
10 #include "base/lazy_instance.h"
10 #include "base/threading/thread.h" 11 #include "base/threading/thread.h"
11 #include "content/browser/gpu/gpu_surface_tracker.h" 12 #include "content/browser/gpu/gpu_surface_tracker.h"
12 #include "content/browser/renderer_host/render_process_host_impl.h" 13 #include "content/browser/renderer_host/render_process_host_impl.h"
13 #include "content/browser/renderer_host/render_view_host_impl.h" 14 #include "content/browser/renderer_host/render_view_host_impl.h"
14 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" 15 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
15 #include "content/common/view_messages.h" 16 #include "content/common/view_messages.h"
16 #include "content/public/browser/browser_thread.h"
17 17
18 using content::BrowserThread; 18 using content::BrowserThread;
19 using content::RenderViewHostImpl; 19 using content::RenderViewHostImpl;
20 using content::ResourceDispatcherHostImpl; 20 using content::ResourceDispatcherHostImpl;
21 21
22 // A helper used with DidReceiveUpdateMsg that we hold a pointer to in 22 namespace {
23
24 typedef std::map<int, RenderWidgetHelper*> WidgetHelperMap;
25 base::LazyInstance<WidgetHelperMap> g_widget_helpers =
26 LAZY_INSTANCE_INITIALIZER;
27
28 void AddWidgetHelper(int render_process_id,
29 const scoped_refptr<RenderWidgetHelper>& widget_helper) {
30 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
31 // We don't care if RenderWidgetHelpers overwrite an existing process_id. Just
32 // want this to be up to date.
33 g_widget_helpers.Get()[render_process_id] = widget_helper.get();
34 }
35
36 } // namespace
37
38 // A helper used with DidReceiveBackingStoreMsg that we hold a pointer to in
23 // pending_paints_. 39 // pending_paints_.
24 class RenderWidgetHelper::UpdateMsgProxy { 40 class RenderWidgetHelper::BackingStoreMsgProxy {
25 public: 41 public:
26 UpdateMsgProxy(RenderWidgetHelper* h, const IPC::Message& m); 42 BackingStoreMsgProxy(RenderWidgetHelper* h, const IPC::Message& m);
27 ~UpdateMsgProxy(); 43 ~BackingStoreMsgProxy();
28 void Run(); 44 void Run();
29 void Cancel() { cancelled_ = true; } 45 void Cancel() { cancelled_ = true; }
30 46
31 const IPC::Message& message() const { return message_; } 47 const IPC::Message& message() const { return message_; }
32 48
33 private: 49 private:
34 scoped_refptr<RenderWidgetHelper> helper_; 50 scoped_refptr<RenderWidgetHelper> helper_;
35 IPC::Message message_; 51 IPC::Message message_;
36 bool cancelled_; // If true, then the message will not be dispatched. 52 bool cancelled_; // If true, then the message will not be dispatched.
37 53
38 DISALLOW_COPY_AND_ASSIGN(UpdateMsgProxy); 54 DISALLOW_COPY_AND_ASSIGN(BackingStoreMsgProxy);
39 }; 55 };
40 56
41 RenderWidgetHelper::UpdateMsgProxy::UpdateMsgProxy( 57 RenderWidgetHelper::BackingStoreMsgProxy::BackingStoreMsgProxy(
42 RenderWidgetHelper* h, const IPC::Message& m) 58 RenderWidgetHelper* h, const IPC::Message& m)
43 : helper_(h), 59 : helper_(h),
44 message_(m), 60 message_(m),
45 cancelled_(false) { 61 cancelled_(false) {
46 } 62 }
47 63
48 RenderWidgetHelper::UpdateMsgProxy::~UpdateMsgProxy() { 64 RenderWidgetHelper::BackingStoreMsgProxy::~BackingStoreMsgProxy() {
49 // If the paint message was never dispatched, then we need to let the 65 // If the paint message was never dispatched, then we need to let the
50 // helper know that we are going away. 66 // helper know that we are going away.
51 if (!cancelled_ && helper_) 67 if (!cancelled_ && helper_)
52 helper_->OnDiscardUpdateMsg(this); 68 helper_->OnDiscardBackingStoreMsg(this);
53 } 69 }
54 70
55 void RenderWidgetHelper::UpdateMsgProxy::Run() { 71 void RenderWidgetHelper::BackingStoreMsgProxy::Run() {
56 if (!cancelled_) { 72 if (!cancelled_) {
57 helper_->OnDispatchUpdateMsg(this); 73 helper_->OnDispatchBackingStoreMsg(this);
58 helper_ = NULL; 74 helper_ = NULL;
59 } 75 }
60 } 76 }
61 77
62 RenderWidgetHelper::RenderWidgetHelper() 78 RenderWidgetHelper::RenderWidgetHelper()
63 : render_process_id_(-1), 79 : render_process_id_(-1),
64 #if defined(OS_WIN) 80 #if defined(OS_WIN)
65 event_(CreateEvent(NULL, FALSE /* auto-reset */, FALSE, NULL)), 81 event_(CreateEvent(NULL, FALSE /* auto-reset */, FALSE, NULL)),
66 #elif defined(OS_POSIX) 82 #elif defined(OS_POSIX)
67 event_(false /* auto-reset */, false), 83 event_(false /* auto-reset */, false),
68 #endif 84 #endif
69 resource_dispatcher_host_(NULL) { 85 resource_dispatcher_host_(NULL) {
70 } 86 }
71 87
72 RenderWidgetHelper::~RenderWidgetHelper() { 88 RenderWidgetHelper::~RenderWidgetHelper() {
89 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
90 g_widget_helpers.Get().erase(render_process_id_);
91
73 // The elements of pending_paints_ each hold an owning reference back to this 92 // The elements of pending_paints_ each hold an owning reference back to this
74 // object, so we should not be destroyed unless pending_paints_ is empty! 93 // object, so we should not be destroyed unless pending_paints_ is empty!
75 DCHECK(pending_paints_.empty()); 94 DCHECK(pending_paints_.empty());
76 95
77 #if defined(OS_MACOSX) 96 #if defined(OS_MACOSX)
78 ClearAllocatedDIBs(); 97 ClearAllocatedDIBs();
79 #endif 98 #endif
80 } 99 }
81 100
82 void RenderWidgetHelper::Init( 101 void RenderWidgetHelper::Init(
83 int render_process_id, 102 int render_process_id,
84 ResourceDispatcherHostImpl* resource_dispatcher_host) { 103 ResourceDispatcherHostImpl* resource_dispatcher_host) {
85 render_process_id_ = render_process_id; 104 render_process_id_ = render_process_id;
86 resource_dispatcher_host_ = resource_dispatcher_host; 105 resource_dispatcher_host_ = resource_dispatcher_host;
106
107 BrowserThread::PostTask(
108 BrowserThread::IO, FROM_HERE,
109 base::Bind(&AddWidgetHelper,
110 render_process_id_, make_scoped_refptr(this)));
87 } 111 }
88 112
89 int RenderWidgetHelper::GetNextRoutingID() { 113 int RenderWidgetHelper::GetNextRoutingID() {
90 return next_routing_id_.GetNext() + 1; 114 return next_routing_id_.GetNext() + 1;
91 } 115 }
92 116
117 // static
118 RenderWidgetHelper* RenderWidgetHelper::FromProcessHostID(
119 int render_process_host_id) {
120 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
121 WidgetHelperMap::const_iterator ci = g_widget_helpers.Get().find(
122 render_process_host_id);
123 return (ci == g_widget_helpers.Get().end())? NULL : ci->second;
124 }
125
93 void RenderWidgetHelper::CancelResourceRequests(int render_widget_id) { 126 void RenderWidgetHelper::CancelResourceRequests(int render_widget_id) {
94 if (render_process_id_ == -1) 127 if (render_process_id_ == -1)
95 return; 128 return;
96 129
97 BrowserThread::PostTask( 130 BrowserThread::PostTask(
98 BrowserThread::IO, FROM_HERE, 131 BrowserThread::IO, FROM_HERE,
99 base::Bind(&RenderWidgetHelper::OnCancelResourceRequests, 132 base::Bind(&RenderWidgetHelper::OnCancelResourceRequests,
100 this, 133 this,
101 render_widget_id)); 134 render_widget_id));
102 } 135 }
103 136
104 void RenderWidgetHelper::SimulateSwapOutACK( 137 void RenderWidgetHelper::SimulateSwapOutACK(
105 const ViewMsg_SwapOut_Params& params) { 138 const ViewMsg_SwapOut_Params& params) {
106 BrowserThread::PostTask( 139 BrowserThread::PostTask(
107 BrowserThread::IO, FROM_HERE, 140 BrowserThread::IO, FROM_HERE,
108 base::Bind(&RenderWidgetHelper::OnSimulateSwapOutACK, 141 base::Bind(&RenderWidgetHelper::OnSimulateSwapOutACK,
109 this, 142 this,
110 params)); 143 params));
111 } 144 }
112 145
113 bool RenderWidgetHelper::WaitForUpdateMsg(int render_widget_id, 146 bool RenderWidgetHelper::WaitForBackingStoreMsg(
114 const base::TimeDelta& max_delay, 147 int render_widget_id,
115 IPC::Message* msg) { 148 const base::TimeDelta& max_delay,
149 IPC::Message* msg) {
116 base::TimeTicks time_start = base::TimeTicks::Now(); 150 base::TimeTicks time_start = base::TimeTicks::Now();
117 151
118 for (;;) { 152 for (;;) {
119 UpdateMsgProxy* proxy = NULL; 153 BackingStoreMsgProxy* proxy = NULL;
120 { 154 {
121 base::AutoLock lock(pending_paints_lock_); 155 base::AutoLock lock(pending_paints_lock_);
122 156
123 UpdateMsgProxyMap::iterator it = pending_paints_.find(render_widget_id); 157 BackingStoreMsgProxyMap::iterator it =
158 pending_paints_.find(render_widget_id);
124 if (it != pending_paints_.end()) { 159 if (it != pending_paints_.end()) {
125 UpdateMsgProxyQueue &queue = it->second; 160 BackingStoreMsgProxyQueue &queue = it->second;
126 DCHECK(!queue.empty()); 161 DCHECK(!queue.empty());
127 proxy = queue.front(); 162 proxy = queue.front();
128 163
129 // Flag the proxy as cancelled so that when it is run as a task it will 164 // Flag the proxy as cancelled so that when it is run as a task it will
130 // do nothing. 165 // do nothing.
131 proxy->Cancel(); 166 proxy->Cancel();
132 167
133 queue.pop_front(); 168 queue.pop_front();
134 if (queue.empty()) 169 if (queue.empty())
135 pending_paints_.erase(it); 170 pending_paints_.erase(it);
(...skipping 11 matching lines...) Expand all
147 max_delay - (base::TimeTicks::Now() - time_start); 182 max_delay - (base::TimeTicks::Now() - time_start);
148 if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0)) 183 if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0))
149 break; 184 break;
150 185
151 event_.TimedWait(max_sleep_time); 186 event_.TimedWait(max_sleep_time);
152 } 187 }
153 188
154 return false; 189 return false;
155 } 190 }
156 191
157 void RenderWidgetHelper::DidReceiveUpdateMsg(const IPC::Message& msg) { 192 void RenderWidgetHelper::DidReceiveBackingStoreMsg(const IPC::Message& msg) {
158 int render_widget_id = msg.routing_id(); 193 int render_widget_id = msg.routing_id();
159 194
160 UpdateMsgProxy* proxy = new UpdateMsgProxy(this, msg); 195 BackingStoreMsgProxy* proxy = new BackingStoreMsgProxy(this, msg);
161 { 196 {
162 base::AutoLock lock(pending_paints_lock_); 197 base::AutoLock lock(pending_paints_lock_);
163 198
164 pending_paints_[render_widget_id].push_back(proxy); 199 pending_paints_[render_widget_id].push_back(proxy);
165 } 200 }
166 201
167 // Notify anyone waiting on the UI thread that there is a new entry in the 202 // Notify anyone waiting on the UI thread that there is a new entry in the
168 // proxy map. If they don't find the entry they are looking for, then they 203 // proxy map. If they don't find the entry they are looking for, then they
169 // will just continue waiting. 204 // will just continue waiting.
170 event_.Signal(); 205 event_.Signal();
171 206
172 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 207 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
173 base::Bind(&UpdateMsgProxy::Run, base::Owned(proxy))); 208 base::Bind(&BackingStoreMsgProxy::Run, base::Owned(proxy)));
174 } 209 }
175 210
176 void RenderWidgetHelper::OnDiscardUpdateMsg(UpdateMsgProxy* proxy) { 211 void RenderWidgetHelper::OnDiscardBackingStoreMsg(BackingStoreMsgProxy* proxy) {
177 const IPC::Message& msg = proxy->message(); 212 const IPC::Message& msg = proxy->message();
178 213
179 // Remove the proxy from the map now that we are going to handle it normally. 214 // Remove the proxy from the map now that we are going to handle it normally.
180 { 215 {
181 base::AutoLock lock(pending_paints_lock_); 216 base::AutoLock lock(pending_paints_lock_);
182 217
183 UpdateMsgProxyMap::iterator it = pending_paints_.find(msg.routing_id()); 218 BackingStoreMsgProxyMap::iterator it =
219 pending_paints_.find(msg.routing_id());
184 DCHECK(it != pending_paints_.end()); 220 DCHECK(it != pending_paints_.end());
185 UpdateMsgProxyQueue &queue = it->second; 221 BackingStoreMsgProxyQueue &queue = it->second;
186 DCHECK(queue.front() == proxy); 222 DCHECK(queue.front() == proxy);
187 223
188 queue.pop_front(); 224 queue.pop_front();
189 if (queue.empty()) 225 if (queue.empty())
190 pending_paints_.erase(it); 226 pending_paints_.erase(it);
191 } 227 }
192 } 228 }
193 229
194 void RenderWidgetHelper::OnDispatchUpdateMsg(UpdateMsgProxy* proxy) { 230 void RenderWidgetHelper::OnDispatchBackingStoreMsg(
195 OnDiscardUpdateMsg(proxy); 231 BackingStoreMsgProxy* proxy) {
232 OnDiscardBackingStoreMsg(proxy);
196 233
197 // It is reasonable for the host to no longer exist. 234 // It is reasonable for the host to no longer exist.
198 content::RenderProcessHost* host = 235 content::RenderProcessHost* host =
199 content::RenderProcessHost::FromID(render_process_id_); 236 content::RenderProcessHost::FromID(render_process_id_);
200 if (host) 237 if (host)
201 host->OnMessageReceived(proxy->message()); 238 host->OnMessageReceived(proxy->message());
202 } 239 }
203 240
204 void RenderWidgetHelper::OnCancelResourceRequests( 241 void RenderWidgetHelper::OnCancelResourceRequests(
205 int render_widget_id) { 242 int render_widget_id) {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 void RenderWidgetHelper::ClearAllocatedDIBs() { 393 void RenderWidgetHelper::ClearAllocatedDIBs() {
357 for (std::map<TransportDIB::Id, int>::iterator 394 for (std::map<TransportDIB::Id, int>::iterator
358 i = allocated_dibs_.begin(); i != allocated_dibs_.end(); ++i) { 395 i = allocated_dibs_.begin(); i != allocated_dibs_.end(); ++i) {
359 if (HANDLE_EINTR(close(i->second)) < 0) 396 if (HANDLE_EINTR(close(i->second)) < 0)
360 PLOG(ERROR) << "close: " << i->first; 397 PLOG(ERROR) << "close: " << i->first;
361 } 398 }
362 399
363 allocated_dibs_.clear(); 400 allocated_dibs_.clear();
364 } 401 }
365 #endif 402 #endif
OLDNEW
« no previous file with comments | « content/browser/renderer_host/render_widget_helper.h ('k') | content/browser/renderer_host/render_widget_host_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698