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 #if defined(ENABLE_GPU) | 5 #if defined(ENABLE_GPU) |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/shared_memory.h" | 10 #include "base/shared_memory.h" |
11 #include "build/build_config.h" | 11 #include "build/build_config.h" |
12 #include "content/common/gpu/gpu_channel.h" | 12 #include "content/common/gpu/gpu_channel.h" |
13 #include "content/common/gpu/gpu_channel_manager.h" | 13 #include "content/common/gpu/gpu_channel_manager.h" |
14 #include "content/common/gpu/gpu_command_buffer_stub.h" | 14 #include "content/common/gpu/gpu_command_buffer_stub.h" |
15 #include "content/common/gpu/gpu_messages.h" | 15 #include "content/common/gpu/gpu_messages.h" |
16 #include "content/common/gpu/gpu_watchdog.h" | 16 #include "content/common/gpu/gpu_watchdog.h" |
| 17 #include "content/common/gpu/image_transport_surface.h" |
17 #include "gpu/command_buffer/common/constants.h" | 18 #include "gpu/command_buffer/common/constants.h" |
| 19 #include "ui/gfx/gl/gl_bindings.h" |
18 #include "ui/gfx/gl/gl_switches.h" | 20 #include "ui/gfx/gl/gl_switches.h" |
19 | 21 |
20 #if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT) | |
21 #include "content/common/gpu/image_transport_surface.h" | |
22 #endif | |
23 | |
24 GpuCommandBufferStub::GpuCommandBufferStub( | 22 GpuCommandBufferStub::GpuCommandBufferStub( |
25 GpuChannel* channel, | 23 GpuChannel* channel, |
26 GpuCommandBufferStub* share_group, | 24 GpuCommandBufferStub* share_group, |
27 gfx::PluginWindowHandle handle, | 25 gfx::PluginWindowHandle handle, |
28 const gfx::Size& size, | 26 const gfx::Size& size, |
29 const gpu::gles2::DisallowedFeatures& disallowed_features, | 27 const gpu::gles2::DisallowedFeatures& disallowed_features, |
30 const std::string& allowed_extensions, | 28 const std::string& allowed_extensions, |
31 const std::vector<int32>& attribs, | 29 const std::vector<int32>& attribs, |
32 gfx::GpuPreference gpu_preference, | 30 gfx::GpuPreference gpu_preference, |
33 int32 route_id, | 31 int32 route_id, |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 } | 116 } |
119 | 117 |
120 bool GpuCommandBufferStub::Send(IPC::Message* message) { | 118 bool GpuCommandBufferStub::Send(IPC::Message* message) { |
121 return channel_->Send(message); | 119 return channel_->Send(message); |
122 } | 120 } |
123 | 121 |
124 bool GpuCommandBufferStub::IsScheduled() { | 122 bool GpuCommandBufferStub::IsScheduled() { |
125 return !scheduler_.get() || scheduler_->IsScheduled(); | 123 return !scheduler_.get() || scheduler_->IsScheduled(); |
126 } | 124 } |
127 | 125 |
| 126 void GpuCommandBufferStub::SetSwapInterval() { |
| 127 #if !defined(OS_MACOSX) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) |
| 128 // Set up swap interval for onscreen contexts. |
| 129 if (!surface_->IsOffscreen()) { |
| 130 decoder_->MakeCurrent(); |
| 131 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) |
| 132 context_->SetSwapInterval(0); |
| 133 else |
| 134 context_->SetSwapInterval(1); |
| 135 } |
| 136 #endif |
| 137 } |
| 138 |
128 void GpuCommandBufferStub::Destroy() { | 139 void GpuCommandBufferStub::Destroy() { |
129 // The scheduler has raw references to the decoder and the command buffer so | 140 // The scheduler has raw references to the decoder and the command buffer so |
130 // destroy it before those. | 141 // destroy it before those. |
131 scheduler_.reset(); | 142 scheduler_.reset(); |
132 | 143 |
133 if (decoder_.get()) { | 144 if (decoder_.get()) { |
134 decoder_->Destroy(); | 145 decoder_->Destroy(); |
135 decoder_.reset(); | 146 decoder_.reset(); |
136 } | 147 } |
137 | 148 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 NULL)); | 190 NULL)); |
180 | 191 |
181 decoder_->set_engine(scheduler_.get()); | 192 decoder_->set_engine(scheduler_.get()); |
182 | 193 |
183 if (handle_) { | 194 if (handle_) { |
184 #if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT) | 195 #if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT) |
185 if (software_) { | 196 if (software_) { |
186 OnInitializeFailed(reply_message); | 197 OnInitializeFailed(reply_message); |
187 return; | 198 return; |
188 } | 199 } |
| 200 #endif |
189 | 201 |
190 surface_ = ImageTransportSurface::CreateSurface( | 202 surface_ = ImageTransportSurface::CreateSurface( |
191 channel_->gpu_channel_manager(), | 203 channel_->gpu_channel_manager(), |
192 render_view_id_, | 204 render_view_id_, |
193 renderer_id_, | 205 renderer_id_, |
194 route_id_, | 206 route_id_, |
195 handle_); | 207 handle_); |
196 #elif defined(OS_WIN) || defined(OS_LINUX) | |
197 surface_ = gfx::GLSurface::CreateViewGLSurface(software_, handle_); | |
198 #endif | |
199 } else { | 208 } else { |
200 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(software_, | 209 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(software_, |
201 gfx::Size(1, 1)); | 210 gfx::Size(1, 1)); |
202 } | 211 } |
203 | 212 |
204 if (!surface_.get()) { | 213 if (!surface_.get()) { |
205 // Ensure the decoder is not destroyed if it is not initialized. | 214 // Ensure the decoder is not destroyed if it is not initialized. |
206 decoder_.reset(); | 215 decoder_.reset(); |
207 | 216 |
208 DLOG(ERROR) << "Failed to create surface.\n"; | 217 DLOG(ERROR) << "Failed to create surface.\n"; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
247 SetSwapInterval(); | 256 SetSwapInterval(); |
248 | 257 |
249 command_buffer_->SetPutOffsetChangeCallback( | 258 command_buffer_->SetPutOffsetChangeCallback( |
250 NewCallback(scheduler_.get(), | 259 NewCallback(scheduler_.get(), |
251 &gpu::GpuScheduler::PutChanged)); | 260 &gpu::GpuScheduler::PutChanged)); |
252 command_buffer_->SetParseErrorCallback( | 261 command_buffer_->SetParseErrorCallback( |
253 NewCallback(this, &GpuCommandBufferStub::OnParseError)); | 262 NewCallback(this, &GpuCommandBufferStub::OnParseError)); |
254 scheduler_->SetScheduledCallback( | 263 scheduler_->SetScheduledCallback( |
255 NewCallback(channel_, &GpuChannel::OnScheduled)); | 264 NewCallback(channel_, &GpuChannel::OnScheduled)); |
256 | 265 |
257 // On platforms that use an ImageTransportSurface, the surface | |
258 // handles co-ordinating the resize with the browser process. The | |
259 // surface sets it's own resize callback, so we shouldn't do it here. | |
260 #if !defined(OS_MACOSX) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) | |
261 if (handle_ != gfx::kNullPluginWindow) { | |
262 decoder_->SetResizeCallback( | |
263 NewCallback(this, &GpuCommandBufferStub::OnResize)); | |
264 } | |
265 #endif | |
266 | |
267 if (watchdog_) { | 266 if (watchdog_) { |
268 scheduler_->SetCommandProcessedCallback( | 267 scheduler_->SetCommandProcessedCallback( |
269 NewCallback(this, &GpuCommandBufferStub::OnCommandProcessed)); | 268 NewCallback(this, &GpuCommandBufferStub::OnCommandProcessed)); |
270 } | 269 } |
271 | 270 |
272 if (parent_stub_for_initialization_) { | 271 if (parent_stub_for_initialization_) { |
273 decoder_->SetParent(parent_stub_for_initialization_->decoder_.get(), | 272 decoder_->SetParent(parent_stub_for_initialization_->decoder_.get(), |
274 parent_texture_for_initialization_); | 273 parent_texture_for_initialization_); |
275 parent_stub_for_initialization_.reset(); | 274 parent_stub_for_initialization_.reset(); |
276 parent_texture_for_initialization_ = 0; | 275 parent_texture_for_initialization_ = 0; |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
423 transfer_buffer, | 422 transfer_buffer, |
424 size); | 423 size); |
425 Send(reply_message); | 424 Send(reply_message); |
426 } | 425 } |
427 | 426 |
428 void GpuCommandBufferStub::OnCommandProcessed() { | 427 void GpuCommandBufferStub::OnCommandProcessed() { |
429 if (watchdog_) | 428 if (watchdog_) |
430 watchdog_->CheckArmed(); | 429 watchdog_->CheckArmed(); |
431 } | 430 } |
432 | 431 |
433 void GpuCommandBufferStub::OnResize(gfx::Size size) { | |
434 if (handle_ == gfx::kNullPluginWindow) | |
435 return; | |
436 | |
437 #if defined(TOOLKIT_USES_GTK) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) || \ | |
438 defined(OS_WIN) | |
439 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); | |
440 | |
441 // On Windows, Linux, we need to coordinate resizing of onscreen | |
442 // contexts with the resizing of the actual OS-level window. We do this by | |
443 // sending a resize message to the browser process and descheduling the | |
444 // context until the ViewResized message comes back in reply. | |
445 // Send the resize message if needed | |
446 gpu_channel_manager->Send( | |
447 new GpuHostMsg_ResizeView(renderer_id_, | |
448 render_view_id_, | |
449 route_id_, | |
450 size)); | |
451 | |
452 scheduler_->SetScheduled(false); | |
453 #endif | |
454 } | |
455 | |
456 void GpuCommandBufferStub::ViewResized() { | |
457 #if defined(TOOLKIT_USES_GTK) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) || \ | |
458 defined(OS_WIN) | |
459 DCHECK(handle_ != gfx::kNullPluginWindow); | |
460 scheduler_->SetScheduled(true); | |
461 #endif | |
462 | |
463 #if defined(OS_WIN) | |
464 // Recreate the view surface to match the window size. Swap chains do not | |
465 // automatically resize with window size with D3D. | |
466 context_->ReleaseCurrent(surface_.get()); | |
467 if (surface_.get()) { | |
468 surface_->Destroy(); | |
469 surface_->Initialize(); | |
470 SetSwapInterval(); | |
471 } | |
472 #endif | |
473 } | |
474 | |
475 void GpuCommandBufferStub::ReportState() { | 432 void GpuCommandBufferStub::ReportState() { |
476 gpu::CommandBuffer::State state = command_buffer_->GetState(); | 433 gpu::CommandBuffer::State state = command_buffer_->GetState(); |
477 if (state.error == gpu::error::kLostContext && | 434 if (state.error == gpu::error::kLostContext && |
478 gfx::GLContext::LosesAllContextsOnContextLost()) { | 435 gfx::GLContext::LosesAllContextsOnContextLost()) { |
479 channel_->LoseAllContexts(); | 436 channel_->LoseAllContexts(); |
480 } else { | 437 } else { |
481 IPC::Message* msg = new GpuCommandBufferMsg_UpdateState(route_id_, state); | 438 IPC::Message* msg = new GpuCommandBufferMsg_UpdateState(route_id_, state); |
482 msg->set_unblock(true); | 439 msg->set_unblock(true); |
483 Send(msg); | 440 Send(msg); |
484 } | 441 } |
485 } | 442 } |
486 | 443 |
487 void GpuCommandBufferStub::SetSwapInterval() { | |
488 #if !defined(OS_MACOSX) && !defined(UI_COMPOSITOR_IMAGE_TRANSPORT) | |
489 // Set up swap interval for onscreen contexts. | |
490 if (!surface_->IsOffscreen()) { | |
491 decoder_->MakeCurrent(); | |
492 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kDisableGpuVsync)) | |
493 context_->SetSwapInterval(0); | |
494 else | |
495 context_->SetSwapInterval(1); | |
496 } | |
497 #endif | |
498 } | |
499 | |
500 void GpuCommandBufferStub::OnCreateVideoDecoder( | 444 void GpuCommandBufferStub::OnCreateVideoDecoder( |
501 media::VideoDecodeAccelerator::Profile profile, | 445 media::VideoDecodeAccelerator::Profile profile, |
502 IPC::Message* reply_message) { | 446 IPC::Message* reply_message) { |
503 int decoder_route_id = channel_->GenerateRouteID(); | 447 int decoder_route_id = channel_->GenerateRouteID(); |
504 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams( | 448 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams( |
505 reply_message, decoder_route_id); | 449 reply_message, decoder_route_id); |
506 GpuVideoDecodeAccelerator* decoder = | 450 GpuVideoDecodeAccelerator* decoder = |
507 new GpuVideoDecodeAccelerator(this, decoder_route_id, this); | 451 new GpuVideoDecodeAccelerator(this, decoder_route_id, this); |
508 video_decoders_.AddWithID(decoder, decoder_route_id); | 452 video_decoders_.AddWithID(decoder, decoder_route_id); |
509 channel_->AddRoute(decoder_route_id, decoder); | 453 channel_->AddRoute(decoder_route_id, decoder); |
510 decoder->Initialize(profile, reply_message); | 454 decoder->Initialize(profile, reply_message); |
511 } | 455 } |
512 | 456 |
513 void GpuCommandBufferStub::OnDestroyVideoDecoder(int decoder_route_id) { | 457 void GpuCommandBufferStub::OnDestroyVideoDecoder(int decoder_route_id) { |
514 channel_->RemoveRoute(decoder_route_id); | 458 channel_->RemoveRoute(decoder_route_id); |
515 video_decoders_.Remove(decoder_route_id); | 459 video_decoders_.Remove(decoder_route_id); |
516 } | 460 } |
517 | 461 |
518 void GpuCommandBufferStub::OnSetSurfaceVisible(bool visible) { | 462 void GpuCommandBufferStub::OnSetSurfaceVisible(bool visible) { |
519 surface_->SetVisible(visible); | 463 surface_->SetVisible(visible); |
520 } | 464 } |
521 | 465 |
522 #endif // defined(ENABLE_GPU) | 466 #endif // defined(ENABLE_GPU) |
OLD | NEW |