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 #include "content/common/gpu/client/gpu_channel_host.h" | 5 #include "content/common/gpu/client/gpu_channel_host.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/atomic_sequence_num.h" | 10 #include "base/atomic_sequence_num.h" |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/location.h" | 12 #include "base/location.h" |
13 #include "base/posix/eintr_wrapper.h" | 13 #include "base/posix/eintr_wrapper.h" |
14 #include "base/single_thread_task_runner.h" | 14 #include "base/single_thread_task_runner.h" |
15 #include "base/thread_task_runner_handle.h" | 15 #include "base/thread_task_runner_handle.h" |
16 #include "base/threading/thread_restrictions.h" | 16 #include "base/threading/thread_restrictions.h" |
17 #include "base/trace_event/trace_event.h" | 17 #include "base/trace_event/trace_event.h" |
18 #include "build/build_config.h" | 18 #include "build/build_config.h" |
19 #include "content/common/gpu/client/command_buffer_proxy_impl.h" | 19 #include "content/common/gpu/client/command_buffer_proxy_impl.h" |
| 20 #include "content/common/gpu/client/gpu_channel_host_factory.h" |
20 #include "content/common/gpu/client/gpu_jpeg_decode_accelerator_host.h" | 21 #include "content/common/gpu/client/gpu_jpeg_decode_accelerator_host.h" |
21 #include "content/common/gpu/gpu_messages.h" | 22 #include "content/common/gpu/client/ipc/gpu_host_ipc_transport_factory.h" |
22 #include "ipc/ipc_sync_message_filter.h" | 23 #include "content/common/gpu/gpu_create_command_buffer_config.h" |
23 #include "url/gurl.h" | 24 #include "url/gurl.h" |
24 | 25 |
25 #if defined(OS_WIN) || defined(OS_MACOSX) | 26 #if defined(OS_WIN) || defined(OS_MACOSX) |
26 #include "content/public/common/sandbox_init.h" | 27 #include "content/public/common/sandbox_init.h" |
27 #endif | 28 #endif |
28 | 29 |
29 using base::AutoLock; | 30 using base::AutoLock; |
30 | 31 |
31 namespace content { | 32 namespace content { |
32 namespace { | 33 namespace { |
33 | 34 |
34 // Global atomic to generate unique transfer buffer IDs. | 35 // Global atomic to generate unique transfer buffer IDs. |
35 base::StaticAtomicSequenceNumber g_next_transfer_buffer_id; | 36 base::StaticAtomicSequenceNumber g_next_transfer_buffer_id; |
36 | 37 |
37 } // namespace | 38 } // namespace |
38 | 39 |
39 GpuChannelHost::StreamFlushInfo::StreamFlushInfo() | 40 GpuChannelHost::StreamFlushInfo::StreamFlushInfo() |
40 : next_stream_flush_id(1), | 41 : next_stream_flush_id(1), |
41 flushed_stream_flush_id(0), | 42 flushed_stream_flush_id(0), |
42 verified_stream_flush_id(0), | 43 verified_stream_flush_id(0), |
43 flush_pending(false), | 44 flush_pending(false), |
44 route_id(MSG_ROUTING_NONE), | 45 transport(nullptr), |
45 put_offset(0), | 46 put_offset(0), |
46 flush_count(0), | 47 flush_count(0), |
47 flush_id(0) {} | 48 flush_id(0) {} |
48 | 49 |
49 GpuChannelHost::StreamFlushInfo::~StreamFlushInfo() {} | 50 GpuChannelHost::StreamFlushInfo::~StreamFlushInfo() {} |
50 | 51 |
51 // static | 52 // static |
52 scoped_refptr<GpuChannelHost> GpuChannelHost::Create( | 53 scoped_refptr<GpuChannelHost> GpuChannelHost::Create( |
53 GpuChannelHostFactory* factory, | 54 scoped_ptr<GpuChannelHostIPCTransport> transport, |
54 int channel_id, | |
55 const gpu::GPUInfo& gpu_info, | 55 const gpu::GPUInfo& gpu_info, |
56 const IPC::ChannelHandle& channel_handle, | |
57 base::WaitableEvent* shutdown_event, | |
58 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) { | 56 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) { |
59 DCHECK(factory->IsMainThread()); | 57 return new GpuChannelHost(std::move(transport), gpu_info, |
60 scoped_refptr<GpuChannelHost> host = | 58 gpu_memory_buffer_manager); |
61 new GpuChannelHost(factory, channel_id, gpu_info, | |
62 gpu_memory_buffer_manager); | |
63 host->Connect(channel_handle, shutdown_event); | |
64 return host; | |
65 } | 59 } |
66 | 60 |
67 GpuChannelHost::GpuChannelHost( | 61 GpuChannelHost::GpuChannelHost( |
68 GpuChannelHostFactory* factory, | 62 scoped_ptr<GpuChannelHostIPCTransport> transport, |
69 int channel_id, | |
70 const gpu::GPUInfo& gpu_info, | 63 const gpu::GPUInfo& gpu_info, |
71 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) | 64 gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) |
72 : factory_(factory), | 65 : gpu_info_(gpu_info), |
73 channel_id_(channel_id), | 66 gpu_memory_buffer_manager_(gpu_memory_buffer_manager), |
74 gpu_info_(gpu_info), | 67 transport_(std::move(transport)) { |
75 gpu_memory_buffer_manager_(gpu_memory_buffer_manager) { | |
76 next_image_id_.GetNext(); | 68 next_image_id_.GetNext(); |
77 next_route_id_.GetNext(); | |
78 next_stream_id_.GetNext(); | 69 next_stream_id_.GetNext(); |
79 } | 70 } |
80 | 71 |
81 void GpuChannelHost::Connect(const IPC::ChannelHandle& channel_handle, | |
82 base::WaitableEvent* shutdown_event) { | |
83 DCHECK(factory_->IsMainThread()); | |
84 // Open a channel to the GPU process. We pass NULL as the main listener here | |
85 // since we need to filter everything to route it to the right thread. | |
86 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = | |
87 factory_->GetIOThreadTaskRunner(); | |
88 channel_ = | |
89 IPC::SyncChannel::Create(channel_handle, IPC::Channel::MODE_CLIENT, NULL, | |
90 io_task_runner.get(), true, shutdown_event); | |
91 | |
92 sync_filter_ = channel_->CreateSyncMessageFilter(); | |
93 | |
94 channel_filter_ = new MessageFilter(); | |
95 | |
96 // Install the filter last, because we intercept all leftover | |
97 // messages. | |
98 channel_->AddFilter(channel_filter_.get()); | |
99 } | |
100 | |
101 bool GpuChannelHost::Send(IPC::Message* msg) { | |
102 // Callee takes ownership of message, regardless of whether Send is | |
103 // successful. See IPC::Sender. | |
104 scoped_ptr<IPC::Message> message(msg); | |
105 // The GPU process never sends synchronous IPCs so clear the unblock flag to | |
106 // preserve order. | |
107 message->set_unblock(false); | |
108 | |
109 // Currently we need to choose between two different mechanisms for sending. | |
110 // On the main thread we use the regular channel Send() method, on another | |
111 // thread we use SyncMessageFilter. We also have to be careful interpreting | |
112 // IsMainThread() since it might return false during shutdown, | |
113 // impl we are actually calling from the main thread (discard message then). | |
114 // | |
115 // TODO: Can we just always use sync_filter_ since we setup the channel | |
116 // without a main listener? | |
117 if (factory_->IsMainThread()) { | |
118 // channel_ is only modified on the main thread, so we don't need to take a | |
119 // lock here. | |
120 if (!channel_) { | |
121 DVLOG(1) << "GpuChannelHost::Send failed: Channel already destroyed"; | |
122 return false; | |
123 } | |
124 // http://crbug.com/125264 | |
125 base::ThreadRestrictions::ScopedAllowWait allow_wait; | |
126 bool result = channel_->Send(message.release()); | |
127 if (!result) | |
128 DVLOG(1) << "GpuChannelHost::Send failed: Channel::Send failed"; | |
129 return result; | |
130 } | |
131 | |
132 bool result = sync_filter_->Send(message.release()); | |
133 return result; | |
134 } | |
135 | |
136 uint32_t GpuChannelHost::OrderingBarrier( | 72 uint32_t GpuChannelHost::OrderingBarrier( |
137 int32_t route_id, | 73 CommandBufferIPCTransport* transport, |
138 int32_t stream_id, | 74 int32_t stream_id, |
139 int32_t put_offset, | 75 int32_t put_offset, |
140 uint32_t flush_count, | 76 uint32_t flush_count, |
141 const std::vector<ui::LatencyInfo>& latency_info, | 77 const std::vector<ui::LatencyInfo>& latency_info, |
142 bool put_offset_changed, | 78 bool put_offset_changed, |
143 bool do_flush) { | 79 bool do_flush) { |
144 AutoLock lock(context_lock_); | 80 AutoLock lock(context_lock_); |
145 StreamFlushInfo& flush_info = stream_flush_info_[stream_id]; | 81 StreamFlushInfo& flush_info = stream_flush_info_[stream_id]; |
146 if (flush_info.flush_pending && flush_info.route_id != route_id) | 82 if (flush_info.flush_pending && flush_info.transport != transport) |
147 InternalFlush(&flush_info); | 83 InternalFlush(&flush_info); |
148 | 84 |
149 if (put_offset_changed) { | 85 if (put_offset_changed) { |
150 const uint32_t flush_id = flush_info.next_stream_flush_id++; | 86 const uint32_t flush_id = flush_info.next_stream_flush_id++; |
151 flush_info.flush_pending = true; | 87 flush_info.flush_pending = true; |
152 flush_info.route_id = route_id; | 88 flush_info.transport = transport; |
153 flush_info.put_offset = put_offset; | 89 flush_info.put_offset = put_offset; |
154 flush_info.flush_count = flush_count; | 90 flush_info.flush_count = flush_count; |
155 flush_info.flush_id = flush_id; | 91 flush_info.flush_id = flush_id; |
156 flush_info.latency_info.insert(flush_info.latency_info.end(), | 92 flush_info.latency_info.insert(flush_info.latency_info.end(), |
157 latency_info.begin(), latency_info.end()); | 93 latency_info.begin(), latency_info.end()); |
158 | 94 |
159 if (do_flush) | 95 if (do_flush) |
160 InternalFlush(&flush_info); | 96 InternalFlush(&flush_info); |
161 | 97 |
162 return flush_id; | 98 return flush_id; |
(...skipping 10 matching lines...) Expand all Loading... |
173 StreamFlushInfo& flush_info = flush_info_iter->second; | 109 StreamFlushInfo& flush_info = flush_info_iter->second; |
174 if (flush_info.flush_pending) | 110 if (flush_info.flush_pending) |
175 InternalFlush(&flush_info); | 111 InternalFlush(&flush_info); |
176 } | 112 } |
177 | 113 |
178 void GpuChannelHost::InternalFlush(StreamFlushInfo* flush_info) { | 114 void GpuChannelHost::InternalFlush(StreamFlushInfo* flush_info) { |
179 context_lock_.AssertAcquired(); | 115 context_lock_.AssertAcquired(); |
180 DCHECK(flush_info); | 116 DCHECK(flush_info); |
181 DCHECK(flush_info->flush_pending); | 117 DCHECK(flush_info->flush_pending); |
182 DCHECK_LT(flush_info->flushed_stream_flush_id, flush_info->flush_id); | 118 DCHECK_LT(flush_info->flushed_stream_flush_id, flush_info->flush_id); |
183 Send(new GpuCommandBufferMsg_AsyncFlush( | 119 transport_->AsyncFlush(flush_info->transport, flush_info->put_offset, |
184 flush_info->route_id, flush_info->put_offset, flush_info->flush_count, | 120 flush_info->flush_count, flush_info->latency_info); |
185 flush_info->latency_info)); | |
186 flush_info->latency_info.clear(); | 121 flush_info->latency_info.clear(); |
187 flush_info->flush_pending = false; | 122 flush_info->flush_pending = false; |
188 | 123 |
189 flush_info->flushed_stream_flush_id = flush_info->flush_id; | 124 flush_info->flushed_stream_flush_id = flush_info->flush_id; |
190 } | 125 } |
191 | 126 |
192 scoped_ptr<CommandBufferProxyImpl> GpuChannelHost::CreateViewCommandBuffer( | 127 scoped_ptr<CommandBufferProxyImpl> GpuChannelHost::CreateViewCommandBuffer( |
193 int32_t surface_id, | 128 int32_t surface_id, |
194 CommandBufferProxyImpl* share_group, | 129 CommandBufferProxyImpl* share_group, |
195 int32_t stream_id, | 130 int32_t stream_id, |
196 GpuStreamPriority stream_priority, | 131 GpuStreamPriority stream_priority, |
197 const std::vector<int32_t>& attribs, | 132 const std::vector<int32_t>& attribs, |
198 const GURL& active_url, | 133 const GURL& active_url, |
199 gfx::GpuPreference gpu_preference) { | 134 gfx::GpuPreference gpu_preference) { |
200 DCHECK(!share_group || (stream_id == share_group->stream_id())); | 135 DCHECK(!share_group || (stream_id == share_group->stream_id())); |
201 TRACE_EVENT1("gpu", | 136 TRACE_EVENT1("gpu", |
202 "GpuChannelHost::CreateViewCommandBuffer", | 137 "GpuChannelHost::CreateViewCommandBuffer", |
203 "surface_id", | 138 "surface_id", |
204 surface_id); | 139 surface_id); |
205 | 140 |
206 GPUCreateCommandBufferConfig init_params; | 141 content::GpuCreateCommandBufferConfig init_params; |
207 init_params.share_group_id = | 142 init_params.share_group_id = |
208 share_group ? share_group->route_id() : MSG_ROUTING_NONE; | 143 share_group ? share_group->transport()->GetShareGroupID() : -2; |
209 init_params.stream_id = stream_id; | 144 init_params.stream_id = stream_id; |
210 init_params.stream_priority = stream_priority; | 145 init_params.stream_priority = stream_priority; |
211 init_params.attribs = attribs; | 146 init_params.attribs = attribs; |
212 init_params.active_url = active_url; | 147 init_params.active_url = active_url; |
213 init_params.gpu_preference = gpu_preference; | 148 init_params.gpu_preference = gpu_preference; |
214 | 149 |
215 int32_t route_id = GenerateRouteID(); | 150 CreateCommandBufferResult result = |
216 | 151 CREATE_COMMAND_BUFFER_FAILED_AND_CHANNEL_LOST; |
217 CreateCommandBufferResult result = factory_->CreateViewCommandBuffer( | 152 scoped_ptr<CommandBufferIPCTransport> command_buffer_transport( |
218 surface_id, init_params, route_id); | 153 GpuHostIPCTransportFactory::Get()->CreateCommandBufferIPCTransport()); |
| 154 transport_->CreateViewCommandBuffer(surface_id, init_params, |
| 155 command_buffer_transport.get(), &result); |
219 if (result != CREATE_COMMAND_BUFFER_SUCCEEDED) { | 156 if (result != CREATE_COMMAND_BUFFER_SUCCEEDED) { |
220 LOG(ERROR) << "GpuChannelHost::CreateViewCommandBuffer failed."; | 157 LOG(ERROR) << "GpuChannelHost::CreateViewCommandBuffer failed."; |
221 | 158 return nullptr; |
222 if (result == CREATE_COMMAND_BUFFER_FAILED_AND_CHANNEL_LOST) { | |
223 // The GPU channel needs to be considered lost. The caller will | |
224 // then set up a new connection, and the GPU channel and any | |
225 // view command buffers will all be associated with the same GPU | |
226 // process. | |
227 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = | |
228 factory_->GetIOThreadTaskRunner(); | |
229 io_task_runner->PostTask( | |
230 FROM_HERE, base::Bind(&GpuChannelHost::MessageFilter::OnChannelError, | |
231 channel_filter_.get())); | |
232 } | |
233 | |
234 return NULL; | |
235 } | 159 } |
236 | 160 |
237 scoped_ptr<CommandBufferProxyImpl> command_buffer = | 161 scoped_ptr<CommandBufferProxyImpl> command_buffer = |
238 make_scoped_ptr(new CommandBufferProxyImpl(this, route_id, stream_id)); | 162 make_scoped_ptr(new CommandBufferProxyImpl( |
239 AddRoute(route_id, command_buffer->AsWeakPtr()); | 163 this, std::move(command_buffer_transport), stream_id)); |
240 | 164 |
241 return command_buffer; | 165 return command_buffer; |
242 } | 166 } |
243 | 167 |
244 scoped_ptr<CommandBufferProxyImpl> GpuChannelHost::CreateOffscreenCommandBuffer( | 168 scoped_ptr<CommandBufferProxyImpl> GpuChannelHost::CreateOffscreenCommandBuffer( |
245 const gfx::Size& size, | 169 const gfx::Size& size, |
246 CommandBufferProxyImpl* share_group, | 170 CommandBufferProxyImpl* share_group, |
247 int32_t stream_id, | 171 int32_t stream_id, |
248 GpuStreamPriority stream_priority, | 172 GpuStreamPriority stream_priority, |
249 const std::vector<int32_t>& attribs, | 173 const std::vector<int32_t>& attribs, |
250 const GURL& active_url, | 174 const GURL& active_url, |
251 gfx::GpuPreference gpu_preference) { | 175 gfx::GpuPreference gpu_preference) { |
252 DCHECK(!share_group || (stream_id == share_group->stream_id())); | 176 DCHECK(!share_group || (stream_id == share_group->stream_id())); |
253 TRACE_EVENT0("gpu", "GpuChannelHost::CreateOffscreenCommandBuffer"); | 177 TRACE_EVENT0("gpu", "GpuChannelHost::CreateOffscreenCommandBuffer"); |
254 | 178 |
255 GPUCreateCommandBufferConfig init_params; | 179 GpuCreateCommandBufferConfig init_params; |
256 init_params.share_group_id = | 180 init_params.share_group_id = |
257 share_group ? share_group->route_id() : MSG_ROUTING_NONE; | 181 share_group ? share_group->transport()->GetShareGroupID() : -2; |
258 init_params.stream_id = stream_id; | 182 init_params.stream_id = stream_id; |
259 init_params.stream_priority = stream_priority; | 183 init_params.stream_priority = stream_priority; |
260 init_params.attribs = attribs; | 184 init_params.attribs = attribs; |
261 init_params.active_url = active_url; | 185 init_params.active_url = active_url; |
262 init_params.gpu_preference = gpu_preference; | 186 init_params.gpu_preference = gpu_preference; |
263 | 187 |
264 int32_t route_id = GenerateRouteID(); | 188 scoped_ptr<CommandBufferIPCTransport> command_buffer_transport( |
| 189 GpuHostIPCTransportFactory::Get()->CreateCommandBufferIPCTransport()); |
265 | 190 |
266 bool succeeded = false; | 191 bool succeeded = false; |
267 if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer( | 192 if (!transport_->CreateOffscreenCommandBuffer( |
268 size, init_params, route_id, &succeeded))) { | 193 size, init_params, command_buffer_transport.get(), &succeeded)) { |
269 LOG(ERROR) << "Failed to send GpuChannelMsg_CreateOffscreenCommandBuffer."; | 194 LOG(ERROR) << "Failed to send CreateOffscreenCommandBuffer."; |
270 return NULL; | 195 return nullptr; |
271 } | 196 } |
272 | 197 |
273 if (!succeeded) { | 198 if (!succeeded) { |
274 LOG(ERROR) | 199 LOG(ERROR) << "CreateOffscreenCommandBuffer returned failure."; |
275 << "GpuChannelMsg_CreateOffscreenCommandBuffer returned failure."; | 200 return nullptr; |
276 return NULL; | |
277 } | 201 } |
278 | 202 |
279 scoped_ptr<CommandBufferProxyImpl> command_buffer = | 203 scoped_ptr<CommandBufferProxyImpl> command_buffer = |
280 make_scoped_ptr(new CommandBufferProxyImpl(this, route_id, stream_id)); | 204 make_scoped_ptr(new CommandBufferProxyImpl( |
281 AddRoute(route_id, command_buffer->AsWeakPtr()); | 205 this, std::move(command_buffer_transport), stream_id)); |
282 | 206 |
283 return command_buffer; | 207 return command_buffer; |
284 } | 208 } |
285 | 209 |
286 scoped_ptr<media::JpegDecodeAccelerator> GpuChannelHost::CreateJpegDecoder( | 210 scoped_ptr<media::JpegDecodeAccelerator> GpuChannelHost::CreateJpegDecoder( |
287 media::JpegDecodeAccelerator::Client* client) { | 211 media::JpegDecodeAccelerator::Client* client) { |
288 TRACE_EVENT0("gpu", "GpuChannelHost::CreateJpegDecoder"); | 212 scoped_ptr<GpuJpegDecodeAcceleratorHostIPCTransport> jpeg_decode_transport( |
| 213 GpuHostIPCTransportFactory::Get() |
| 214 ->CreateJpegDecodeAcceleratorHostIPCTransport()); |
289 | 215 |
290 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = | 216 bool succeeded = false; |
291 factory_->GetIOThreadTaskRunner(); | 217 if (!transport_->CreateJpegDecoder(jpeg_decode_transport.get(), &succeeded)) { |
292 int32_t route_id = GenerateRouteID(); | 218 LOG(ERROR) << "Failed to send CreateJpegDecoder"; |
293 scoped_ptr<GpuJpegDecodeAcceleratorHost> decoder( | |
294 new GpuJpegDecodeAcceleratorHost(this, route_id, io_task_runner)); | |
295 if (!decoder->Initialize(client)) { | |
296 return nullptr; | 219 return nullptr; |
297 } | 220 } |
298 | 221 |
299 // The reply message of jpeg decoder should run on IO thread. | 222 if (!succeeded) { |
300 io_task_runner->PostTask(FROM_HERE, | 223 LOG(ERROR) << "CreateJpegDecoder returned failure."; |
301 base::Bind(&GpuChannelHost::MessageFilter::AddRoute, | 224 return nullptr; |
302 channel_filter_.get(), route_id, | 225 } |
303 decoder->GetReceiver(), io_task_runner)); | |
304 | 226 |
305 return std::move(decoder); | 227 scoped_ptr<media::JpegDecodeAccelerator> decoder( |
| 228 new GpuJpegDecodeAcceleratorHost(this, std::move(jpeg_decode_transport))); |
| 229 if (!decoder->Initialize(client)) |
| 230 return nullptr; |
| 231 |
| 232 return decoder; |
306 } | 233 } |
307 | 234 |
308 void GpuChannelHost::DestroyCommandBuffer( | 235 void GpuChannelHost::DestroyCommandBuffer( |
309 CommandBufferProxyImpl* command_buffer) { | 236 CommandBufferProxyImpl* command_buffer) { |
310 TRACE_EVENT0("gpu", "GpuChannelHost::DestroyCommandBuffer"); | 237 TRACE_EVENT0("gpu", "GpuChannelHost::DestroyCommandBuffer"); |
311 | 238 |
312 int32_t route_id = command_buffer->route_id(); | 239 transport_->DestroyCommandBuffer(command_buffer->transport()); |
313 int32_t stream_id = command_buffer->stream_id(); | 240 int32_t stream_id = command_buffer->stream_id(); |
314 Send(new GpuChannelMsg_DestroyCommandBuffer(route_id)); | |
315 RemoveRoute(route_id); | |
316 | 241 |
317 AutoLock lock(context_lock_); | 242 AutoLock lock(context_lock_); |
318 StreamFlushInfo& flush_info = stream_flush_info_[stream_id]; | 243 StreamFlushInfo& flush_info = stream_flush_info_[stream_id]; |
319 if (flush_info.flush_pending && flush_info.route_id == route_id) | 244 if (flush_info.flush_pending && |
| 245 flush_info.transport == command_buffer->transport()) |
320 flush_info.flush_pending = false; | 246 flush_info.flush_pending = false; |
321 } | 247 } |
322 | 248 |
323 void GpuChannelHost::DestroyChannel() { | 249 void GpuChannelHost::DestroyChannel() { |
324 DCHECK(factory_->IsMainThread()); | |
325 AutoLock lock(context_lock_); | 250 AutoLock lock(context_lock_); |
326 channel_.reset(); | 251 transport_.reset(); |
327 } | |
328 | |
329 void GpuChannelHost::AddRoute( | |
330 int route_id, base::WeakPtr<IPC::Listener> listener) { | |
331 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = | |
332 factory_->GetIOThreadTaskRunner(); | |
333 io_task_runner->PostTask(FROM_HERE, | |
334 base::Bind(&GpuChannelHost::MessageFilter::AddRoute, | |
335 channel_filter_.get(), route_id, listener, | |
336 base::ThreadTaskRunnerHandle::Get())); | |
337 } | |
338 | |
339 void GpuChannelHost::RemoveRoute(int route_id) { | |
340 scoped_refptr<base::SingleThreadTaskRunner> io_task_runner = | |
341 factory_->GetIOThreadTaskRunner(); | |
342 io_task_runner->PostTask( | |
343 FROM_HERE, base::Bind(&GpuChannelHost::MessageFilter::RemoveRoute, | |
344 channel_filter_.get(), route_id)); | |
345 } | 252 } |
346 | 253 |
347 base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess( | 254 base::SharedMemoryHandle GpuChannelHost::ShareToGpuProcess( |
348 base::SharedMemoryHandle source_handle) { | 255 base::SharedMemoryHandle source_handle) { |
349 if (IsLost()) | 256 AutoLock lock(context_lock_); |
350 return base::SharedMemory::NULLHandle(); | 257 return transport_->ShareToGpuProcess(source_handle); |
351 | |
352 #if defined(OS_WIN) || defined(OS_MACOSX) | |
353 // Windows and Mac need to explicitly duplicate the handle out to another | |
354 // process. | |
355 base::SharedMemoryHandle target_handle; | |
356 base::ProcessId peer_pid; | |
357 { | |
358 AutoLock lock(context_lock_); | |
359 if (!channel_) | |
360 return base::SharedMemory::NULLHandle(); | |
361 peer_pid = channel_->GetPeerPID(); | |
362 } | |
363 bool success = BrokerDuplicateSharedMemoryHandle(source_handle, peer_pid, | |
364 &target_handle); | |
365 if (!success) | |
366 return base::SharedMemory::NULLHandle(); | |
367 | |
368 return target_handle; | |
369 #else | |
370 return base::SharedMemory::DuplicateHandle(source_handle); | |
371 #endif // defined(OS_WIN) || defined(OS_MACOSX) | |
372 } | 258 } |
373 | 259 |
374 int32_t GpuChannelHost::ReserveTransferBufferId() { | 260 int32_t GpuChannelHost::ReserveTransferBufferId() { |
375 // 0 is a reserved value. | 261 // 0 is a reserved value. |
376 return g_next_transfer_buffer_id.GetNext() + 1; | 262 return g_next_transfer_buffer_id.GetNext() + 1; |
377 } | 263 } |
378 | 264 |
379 gfx::GpuMemoryBufferHandle GpuChannelHost::ShareGpuMemoryBufferToGpuProcess( | 265 gfx::GpuMemoryBufferHandle GpuChannelHost::ShareGpuMemoryBufferToGpuProcess( |
380 const gfx::GpuMemoryBufferHandle& source_handle, | 266 const gfx::GpuMemoryBufferHandle& source_handle, |
381 bool* requires_sync_point) { | 267 bool* requires_sync_point) { |
(...skipping 15 matching lines...) Expand all Loading... |
397 default: | 283 default: |
398 NOTREACHED(); | 284 NOTREACHED(); |
399 return gfx::GpuMemoryBufferHandle(); | 285 return gfx::GpuMemoryBufferHandle(); |
400 } | 286 } |
401 } | 287 } |
402 | 288 |
403 int32_t GpuChannelHost::ReserveImageId() { | 289 int32_t GpuChannelHost::ReserveImageId() { |
404 return next_image_id_.GetNext(); | 290 return next_image_id_.GetNext(); |
405 } | 291 } |
406 | 292 |
407 int32_t GpuChannelHost::GenerateRouteID() { | |
408 return next_route_id_.GetNext(); | |
409 } | |
410 | |
411 int32_t GpuChannelHost::GenerateStreamID() { | 293 int32_t GpuChannelHost::GenerateStreamID() { |
412 const int32_t stream_id = next_stream_id_.GetNext(); | 294 const int32_t stream_id = next_stream_id_.GetNext(); |
413 DCHECK_NE(0, stream_id); | 295 DCHECK_NE(0, stream_id); |
414 DCHECK_NE(kDefaultStreamId, stream_id); | 296 DCHECK_NE(kDefaultStreamId, stream_id); |
415 return stream_id; | 297 return stream_id; |
416 } | 298 } |
417 | 299 |
418 uint32_t GpuChannelHost::ValidateFlushIDReachedServer(int32_t stream_id, | 300 uint32_t GpuChannelHost::ValidateFlushIDReachedServer(int32_t stream_id, |
419 bool force_validate) { | 301 bool force_validate) { |
420 // Store what flush ids we will be validating for all streams. | 302 // Store what flush ids we will be validating for all streams. |
(...skipping 16 matching lines...) Expand all Loading... |
437 std::make_pair(iter_stream_id, flush_info.flushed_stream_flush_id)); | 319 std::make_pair(iter_stream_id, flush_info.flushed_stream_flush_id)); |
438 } | 320 } |
439 } | 321 } |
440 } | 322 } |
441 | 323 |
442 if (!force_validate && flushed_stream_flush_id == verified_stream_flush_id) { | 324 if (!force_validate && flushed_stream_flush_id == verified_stream_flush_id) { |
443 // Current stream has no unverified flushes. | 325 // Current stream has no unverified flushes. |
444 return verified_stream_flush_id; | 326 return verified_stream_flush_id; |
445 } | 327 } |
446 | 328 |
447 if (Send(new GpuChannelMsg_Nop())) { | 329 if (transport_->Nop()) { |
448 // Update verified flush id for all streams. | 330 // Update verified flush id for all streams. |
449 uint32_t highest_flush_id = 0; | 331 uint32_t highest_flush_id = 0; |
450 AutoLock lock(context_lock_); | 332 AutoLock lock(context_lock_); |
451 for (const auto& iter : validate_flushes) { | 333 for (const auto& iter : validate_flushes) { |
452 const int32_t validated_stream_id = iter.first; | 334 const int32_t validated_stream_id = iter.first; |
453 const uint32_t validated_flush_id = iter.second; | 335 const uint32_t validated_flush_id = iter.second; |
454 StreamFlushInfo& flush_info = stream_flush_info_[validated_stream_id]; | 336 StreamFlushInfo& flush_info = stream_flush_info_[validated_stream_id]; |
455 if (flush_info.verified_stream_flush_id < validated_flush_id) { | 337 if (flush_info.verified_stream_flush_id < validated_flush_id) { |
456 flush_info.verified_stream_flush_id = validated_flush_id; | 338 flush_info.verified_stream_flush_id = validated_flush_id; |
457 } | 339 } |
(...skipping 10 matching lines...) Expand all Loading... |
468 | 350 |
469 uint32_t GpuChannelHost::GetHighestValidatedFlushID(int32_t stream_id) { | 351 uint32_t GpuChannelHost::GetHighestValidatedFlushID(int32_t stream_id) { |
470 AutoLock lock(context_lock_); | 352 AutoLock lock(context_lock_); |
471 StreamFlushInfo& flush_info = stream_flush_info_[stream_id]; | 353 StreamFlushInfo& flush_info = stream_flush_info_[stream_id]; |
472 return flush_info.verified_stream_flush_id; | 354 return flush_info.verified_stream_flush_id; |
473 } | 355 } |
474 | 356 |
475 GpuChannelHost::~GpuChannelHost() { | 357 GpuChannelHost::~GpuChannelHost() { |
476 #if DCHECK_IS_ON() | 358 #if DCHECK_IS_ON() |
477 AutoLock lock(context_lock_); | 359 AutoLock lock(context_lock_); |
478 DCHECK(!channel_) | 360 DCHECK(!transport_) |
479 << "GpuChannelHost::DestroyChannel must be called before destruction."; | 361 << "GpuChannelHost::DestroyChannel must be called before destruction."; |
480 #endif | 362 #endif |
481 } | 363 } |
482 | 364 |
483 GpuChannelHost::MessageFilter::ListenerInfo::ListenerInfo() {} | |
484 | |
485 GpuChannelHost::MessageFilter::ListenerInfo::~ListenerInfo() {} | |
486 | |
487 GpuChannelHost::MessageFilter::MessageFilter() | |
488 : lost_(false) { | |
489 } | |
490 | |
491 GpuChannelHost::MessageFilter::~MessageFilter() {} | |
492 | |
493 void GpuChannelHost::MessageFilter::AddRoute( | |
494 int32_t route_id, | |
495 base::WeakPtr<IPC::Listener> listener, | |
496 scoped_refptr<base::SingleThreadTaskRunner> task_runner) { | |
497 DCHECK(listeners_.find(route_id) == listeners_.end()); | |
498 DCHECK(task_runner); | |
499 ListenerInfo info; | |
500 info.listener = listener; | |
501 info.task_runner = task_runner; | |
502 listeners_[route_id] = info; | |
503 } | |
504 | |
505 void GpuChannelHost::MessageFilter::RemoveRoute(int32_t route_id) { | |
506 listeners_.erase(route_id); | |
507 } | |
508 | |
509 bool GpuChannelHost::MessageFilter::OnMessageReceived( | |
510 const IPC::Message& message) { | |
511 // Never handle sync message replies or we will deadlock here. | |
512 if (message.is_reply()) | |
513 return false; | |
514 | |
515 auto it = listeners_.find(message.routing_id()); | |
516 if (it == listeners_.end()) | |
517 return false; | |
518 | |
519 const ListenerInfo& info = it->second; | |
520 info.task_runner->PostTask( | |
521 FROM_HERE, | |
522 base::Bind(base::IgnoreResult(&IPC::Listener::OnMessageReceived), | |
523 info.listener, message)); | |
524 return true; | |
525 } | |
526 | |
527 void GpuChannelHost::MessageFilter::OnChannelError() { | |
528 // Set the lost state before signalling the proxies. That way, if they | |
529 // themselves post a task to recreate the context, they will not try to re-use | |
530 // this channel host. | |
531 { | |
532 AutoLock lock(lock_); | |
533 lost_ = true; | |
534 } | |
535 | |
536 // Inform all the proxies that an error has occurred. This will be reported | |
537 // via OpenGL as a lost context. | |
538 for (const auto& kv : listeners_) { | |
539 const ListenerInfo& info = kv.second; | |
540 info.task_runner->PostTask( | |
541 FROM_HERE, base::Bind(&IPC::Listener::OnChannelError, info.listener)); | |
542 } | |
543 | |
544 listeners_.clear(); | |
545 } | |
546 | |
547 bool GpuChannelHost::MessageFilter::IsLost() const { | |
548 AutoLock lock(lock_); | |
549 return lost_; | |
550 } | |
551 | |
552 } // namespace content | 365 } // namespace content |
OLD | NEW |