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

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: no change - update/merge Created 8 years, 8 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/id_map.h"
11 #include "base/lazy_instance.h"
10 #include "base/threading/thread.h" 12 #include "base/threading/thread.h"
11 #include "content/browser/gpu/gpu_surface_tracker.h" 13 #include "content/browser/gpu/gpu_surface_tracker.h"
12 #include "content/browser/renderer_host/render_process_host_impl.h" 14 #include "content/browser/renderer_host/render_process_host_impl.h"
13 #include "content/browser/renderer_host/render_view_host_impl.h" 15 #include "content/browser/renderer_host/render_view_host_impl.h"
14 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h" 16 #include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
15 #include "content/common/view_messages.h" 17 #include "content/common/view_messages.h"
16 #include "content/public/browser/browser_thread.h"
17 18
18 using content::BrowserThread; 19 using content::BrowserThread;
19 using content::RenderViewHostImpl; 20 using content::RenderViewHostImpl;
20 using content::ResourceDispatcherHostImpl; 21 using content::ResourceDispatcherHostImpl;
21 22
22 // A helper used with DidReceiveUpdateMsg that we hold a pointer to in 23 namespace {
24
25 base::LazyInstance<IDMap<RenderWidgetHelper> > g_widget_helpers =
darin (slow to review) 2012/04/23 16:47:14 it looks like you aren't using IDMap to create ide
jbates 2012/04/23 20:48:18 You're right, I had copied another instance of a L
26 LAZY_INSTANCE_INITIALIZER;
27
28 } // namespace
29
30 // A helper used with DidReceiveBackingStoreMsg that we hold a pointer to in
23 // pending_paints_. 31 // pending_paints_.
24 class RenderWidgetHelper::UpdateMsgProxy { 32 class RenderWidgetHelper::BackingStoreMsgProxy {
25 public: 33 public:
26 UpdateMsgProxy(RenderWidgetHelper* h, const IPC::Message& m); 34 BackingStoreMsgProxy(RenderWidgetHelper* h, const IPC::Message& m);
27 ~UpdateMsgProxy(); 35 ~BackingStoreMsgProxy();
28 void Run(); 36 void Run();
29 void Cancel() { cancelled_ = true; } 37 void Cancel() { cancelled_ = true; }
30 38
31 const IPC::Message& message() const { return message_; } 39 const IPC::Message& message() const { return message_; }
32 40
33 private: 41 private:
34 scoped_refptr<RenderWidgetHelper> helper_; 42 scoped_refptr<RenderWidgetHelper> helper_;
35 IPC::Message message_; 43 IPC::Message message_;
36 bool cancelled_; // If true, then the message will not be dispatched. 44 bool cancelled_; // If true, then the message will not be dispatched.
37 45
38 DISALLOW_COPY_AND_ASSIGN(UpdateMsgProxy); 46 DISALLOW_COPY_AND_ASSIGN(BackingStoreMsgProxy);
39 }; 47 };
40 48
41 RenderWidgetHelper::UpdateMsgProxy::UpdateMsgProxy( 49 RenderWidgetHelper::BackingStoreMsgProxy::BackingStoreMsgProxy(
42 RenderWidgetHelper* h, const IPC::Message& m) 50 RenderWidgetHelper* h, const IPC::Message& m)
43 : helper_(h), 51 : helper_(h),
44 message_(m), 52 message_(m),
45 cancelled_(false) { 53 cancelled_(false) {
46 } 54 }
47 55
48 RenderWidgetHelper::UpdateMsgProxy::~UpdateMsgProxy() { 56 RenderWidgetHelper::BackingStoreMsgProxy::~BackingStoreMsgProxy() {
49 // If the paint message was never dispatched, then we need to let the 57 // If the paint message was never dispatched, then we need to let the
50 // helper know that we are going away. 58 // helper know that we are going away.
51 if (!cancelled_ && helper_) 59 if (!cancelled_ && helper_)
52 helper_->OnDiscardUpdateMsg(this); 60 helper_->OnDiscardBackingStoreMsg(this);
53 } 61 }
54 62
55 void RenderWidgetHelper::UpdateMsgProxy::Run() { 63 void RenderWidgetHelper::BackingStoreMsgProxy::Run() {
56 if (!cancelled_) { 64 if (!cancelled_) {
57 helper_->OnDispatchUpdateMsg(this); 65 helper_->OnDispatchBackingStoreMsg(this);
58 helper_ = NULL; 66 helper_ = NULL;
59 } 67 }
60 } 68 }
61 69
62 RenderWidgetHelper::RenderWidgetHelper() 70 RenderWidgetHelper::RenderWidgetHelper()
63 : render_process_id_(-1), 71 : render_process_id_(-1),
64 #if defined(OS_WIN) 72 #if defined(OS_WIN)
65 event_(CreateEvent(NULL, FALSE /* auto-reset */, FALSE, NULL)), 73 event_(CreateEvent(NULL, FALSE /* auto-reset */, FALSE, NULL)),
66 #elif defined(OS_POSIX) 74 #elif defined(OS_POSIX)
67 event_(false /* auto-reset */, false), 75 event_(false /* auto-reset */, false),
68 #endif 76 #endif
69 resource_dispatcher_host_(NULL) { 77 resource_dispatcher_host_(NULL) {
70 } 78 }
71 79
72 RenderWidgetHelper::~RenderWidgetHelper() { 80 RenderWidgetHelper::~RenderWidgetHelper() {
81 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
82 g_widget_helpers.Get().Remove(render_process_id_);
83
73 // The elements of pending_paints_ each hold an owning reference back to this 84 // 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! 85 // object, so we should not be destroyed unless pending_paints_ is empty!
75 DCHECK(pending_paints_.empty()); 86 DCHECK(pending_paints_.empty());
76 87
77 #if defined(OS_MACOSX) 88 #if defined(OS_MACOSX)
78 ClearAllocatedDIBs(); 89 ClearAllocatedDIBs();
79 #endif 90 #endif
80 } 91 }
81 92
82 void RenderWidgetHelper::Init( 93 void RenderWidgetHelper::Init(
83 int render_process_id, 94 int render_process_id,
84 ResourceDispatcherHostImpl* resource_dispatcher_host) { 95 ResourceDispatcherHostImpl* resource_dispatcher_host) {
85 render_process_id_ = render_process_id; 96 render_process_id_ = render_process_id;
86 resource_dispatcher_host_ = resource_dispatcher_host; 97 resource_dispatcher_host_ = resource_dispatcher_host;
98
99 BrowserThread::PostTask(
100 BrowserThread::IO, FROM_HERE,
101 base::Bind(&IDMap<RenderWidgetHelper>::AddWithID,
102 base::Unretained(g_widget_helpers.Pointer()),
103 make_scoped_refptr(this), render_process_id_));
87 } 104 }
88 105
89 int RenderWidgetHelper::GetNextRoutingID() { 106 int RenderWidgetHelper::GetNextRoutingID() {
90 return next_routing_id_.GetNext() + 1; 107 return next_routing_id_.GetNext() + 1;
91 } 108 }
92 109
110 // static
111 RenderWidgetHelper* RenderWidgetHelper::FromProcessHostID(
112 int render_process_host_id) {
113 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
114 return g_widget_helpers.Get().Lookup(render_process_host_id);
115 }
116
93 void RenderWidgetHelper::CancelResourceRequests(int render_widget_id) { 117 void RenderWidgetHelper::CancelResourceRequests(int render_widget_id) {
94 if (render_process_id_ == -1) 118 if (render_process_id_ == -1)
95 return; 119 return;
96 120
97 BrowserThread::PostTask( 121 BrowserThread::PostTask(
98 BrowserThread::IO, FROM_HERE, 122 BrowserThread::IO, FROM_HERE,
99 base::Bind(&RenderWidgetHelper::OnCancelResourceRequests, 123 base::Bind(&RenderWidgetHelper::OnCancelResourceRequests,
100 this, 124 this,
101 render_widget_id)); 125 render_widget_id));
102 } 126 }
103 127
104 void RenderWidgetHelper::SimulateSwapOutACK( 128 void RenderWidgetHelper::SimulateSwapOutACK(
105 const ViewMsg_SwapOut_Params& params) { 129 const ViewMsg_SwapOut_Params& params) {
106 BrowserThread::PostTask( 130 BrowserThread::PostTask(
107 BrowserThread::IO, FROM_HERE, 131 BrowserThread::IO, FROM_HERE,
108 base::Bind(&RenderWidgetHelper::OnSimulateSwapOutACK, 132 base::Bind(&RenderWidgetHelper::OnSimulateSwapOutACK,
109 this, 133 this,
110 params)); 134 params));
111 } 135 }
112 136
113 bool RenderWidgetHelper::WaitForUpdateMsg(int render_widget_id, 137 bool RenderWidgetHelper::WaitForBackingStoreMsg(
114 const base::TimeDelta& max_delay, 138 int render_widget_id,
115 IPC::Message* msg) { 139 const base::TimeDelta& max_delay,
140 IPC::Message* msg) {
116 base::TimeTicks time_start = base::TimeTicks::Now(); 141 base::TimeTicks time_start = base::TimeTicks::Now();
117 142
118 for (;;) { 143 for (;;) {
119 UpdateMsgProxy* proxy = NULL; 144 BackingStoreMsgProxy* proxy = NULL;
120 { 145 {
121 base::AutoLock lock(pending_paints_lock_); 146 base::AutoLock lock(pending_paints_lock_);
122 147
123 UpdateMsgProxyMap::iterator it = pending_paints_.find(render_widget_id); 148 BackingStoreMsgProxyMap::iterator it =
149 pending_paints_.find(render_widget_id);
124 if (it != pending_paints_.end()) { 150 if (it != pending_paints_.end()) {
125 UpdateMsgProxyQueue &queue = it->second; 151 BackingStoreMsgProxyQueue &queue = it->second;
126 DCHECK(!queue.empty()); 152 DCHECK(!queue.empty());
127 proxy = queue.front(); 153 proxy = queue.front();
128 154
129 // Flag the proxy as cancelled so that when it is run as a task it will 155 // Flag the proxy as cancelled so that when it is run as a task it will
130 // do nothing. 156 // do nothing.
131 proxy->Cancel(); 157 proxy->Cancel();
132 158
133 queue.pop_front(); 159 queue.pop_front();
134 if (queue.empty()) 160 if (queue.empty())
135 pending_paints_.erase(it); 161 pending_paints_.erase(it);
(...skipping 11 matching lines...) Expand all
147 max_delay - (base::TimeTicks::Now() - time_start); 173 max_delay - (base::TimeTicks::Now() - time_start);
148 if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0)) 174 if (max_sleep_time <= base::TimeDelta::FromMilliseconds(0))
149 break; 175 break;
150 176
151 event_.TimedWait(max_sleep_time); 177 event_.TimedWait(max_sleep_time);
152 } 178 }
153 179
154 return false; 180 return false;
155 } 181 }
156 182
157 void RenderWidgetHelper::DidReceiveUpdateMsg(const IPC::Message& msg) { 183 void RenderWidgetHelper::DidReceiveBackingStoreMsg(const IPC::Message& msg) {
158 int render_widget_id = msg.routing_id(); 184 int render_widget_id = msg.routing_id();
159 185
160 UpdateMsgProxy* proxy = new UpdateMsgProxy(this, msg); 186 BackingStoreMsgProxy* proxy = new BackingStoreMsgProxy(this, msg);
161 { 187 {
162 base::AutoLock lock(pending_paints_lock_); 188 base::AutoLock lock(pending_paints_lock_);
163 189
164 pending_paints_[render_widget_id].push_back(proxy); 190 pending_paints_[render_widget_id].push_back(proxy);
165 } 191 }
166 192
167 // Notify anyone waiting on the UI thread that there is a new entry in the 193 // 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 194 // proxy map. If they don't find the entry they are looking for, then they
169 // will just continue waiting. 195 // will just continue waiting.
170 event_.Signal(); 196 event_.Signal();
171 197
172 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 198 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
173 base::Bind(&UpdateMsgProxy::Run, base::Owned(proxy))); 199 base::Bind(&BackingStoreMsgProxy::Run, base::Owned(proxy)));
174 } 200 }
175 201
176 void RenderWidgetHelper::OnDiscardUpdateMsg(UpdateMsgProxy* proxy) { 202 void RenderWidgetHelper::OnDiscardBackingStoreMsg(BackingStoreMsgProxy* proxy) {
177 const IPC::Message& msg = proxy->message(); 203 const IPC::Message& msg = proxy->message();
178 204
179 // Remove the proxy from the map now that we are going to handle it normally. 205 // Remove the proxy from the map now that we are going to handle it normally.
180 { 206 {
181 base::AutoLock lock(pending_paints_lock_); 207 base::AutoLock lock(pending_paints_lock_);
182 208
183 UpdateMsgProxyMap::iterator it = pending_paints_.find(msg.routing_id()); 209 BackingStoreMsgProxyMap::iterator it =
210 pending_paints_.find(msg.routing_id());
184 DCHECK(it != pending_paints_.end()); 211 DCHECK(it != pending_paints_.end());
185 UpdateMsgProxyQueue &queue = it->second; 212 BackingStoreMsgProxyQueue &queue = it->second;
186 DCHECK(queue.front() == proxy); 213 DCHECK(queue.front() == proxy);
187 214
188 queue.pop_front(); 215 queue.pop_front();
189 if (queue.empty()) 216 if (queue.empty())
190 pending_paints_.erase(it); 217 pending_paints_.erase(it);
191 } 218 }
192 } 219 }
193 220
194 void RenderWidgetHelper::OnDispatchUpdateMsg(UpdateMsgProxy* proxy) { 221 void RenderWidgetHelper::OnDispatchBackingStoreMsg(
195 OnDiscardUpdateMsg(proxy); 222 BackingStoreMsgProxy* proxy) {
223 OnDiscardBackingStoreMsg(proxy);
196 224
197 // It is reasonable for the host to no longer exist. 225 // It is reasonable for the host to no longer exist.
198 content::RenderProcessHost* host = 226 content::RenderProcessHost* host =
199 content::RenderProcessHost::FromID(render_process_id_); 227 content::RenderProcessHost::FromID(render_process_id_);
200 if (host) 228 if (host)
201 host->OnMessageReceived(proxy->message()); 229 host->OnMessageReceived(proxy->message());
202 } 230 }
203 231
204 void RenderWidgetHelper::OnCancelResourceRequests( 232 void RenderWidgetHelper::OnCancelResourceRequests(
205 int render_widget_id) { 233 int render_widget_id) {
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after
356 void RenderWidgetHelper::ClearAllocatedDIBs() { 384 void RenderWidgetHelper::ClearAllocatedDIBs() {
357 for (std::map<TransportDIB::Id, int>::iterator 385 for (std::map<TransportDIB::Id, int>::iterator
358 i = allocated_dibs_.begin(); i != allocated_dibs_.end(); ++i) { 386 i = allocated_dibs_.begin(); i != allocated_dibs_.end(); ++i) {
359 if (HANDLE_EINTR(close(i->second)) < 0) 387 if (HANDLE_EINTR(close(i->second)) < 0)
360 PLOG(ERROR) << "close: " << i->first; 388 PLOG(ERROR) << "close: " << i->first;
361 } 389 }
362 390
363 allocated_dibs_.clear(); 391 allocated_dibs_.clear();
364 } 392 }
365 #endif 393 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698