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