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 "gpu/command_buffer/common/constants.h" |
| 18 #include "ui/gfx/gl/gl_switches.h" |
| 19 |
| 20 #if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT) |
17 #include "content/common/gpu/image_transport_surface.h" | 21 #include "content/common/gpu/image_transport_surface.h" |
18 #include "gpu/command_buffer/common/constants.h" | 22 #endif |
19 #include "ui/gfx/gl/gl_bindings.h" | |
20 #include "ui/gfx/gl/gl_switches.h" | |
21 | 23 |
22 GpuCommandBufferStub::GpuCommandBufferStub( | 24 GpuCommandBufferStub::GpuCommandBufferStub( |
23 GpuChannel* channel, | 25 GpuChannel* channel, |
24 GpuCommandBufferStub* share_group, | 26 GpuCommandBufferStub* share_group, |
25 gfx::PluginWindowHandle handle, | 27 gfx::PluginWindowHandle handle, |
26 const gfx::Size& size, | 28 const gfx::Size& size, |
27 const gpu::gles2::DisallowedFeatures& disallowed_features, | 29 const gpu::gles2::DisallowedFeatures& disallowed_features, |
28 const std::string& allowed_extensions, | 30 const std::string& allowed_extensions, |
29 const std::vector<int32>& attribs, | 31 const std::vector<int32>& attribs, |
30 gfx::GpuPreference gpu_preference, | 32 gfx::GpuPreference gpu_preference, |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
116 } | 118 } |
117 | 119 |
118 bool GpuCommandBufferStub::Send(IPC::Message* message) { | 120 bool GpuCommandBufferStub::Send(IPC::Message* message) { |
119 return channel_->Send(message); | 121 return channel_->Send(message); |
120 } | 122 } |
121 | 123 |
122 bool GpuCommandBufferStub::IsScheduled() { | 124 bool GpuCommandBufferStub::IsScheduled() { |
123 return !scheduler_.get() || scheduler_->IsScheduled(); | 125 return !scheduler_.get() || scheduler_->IsScheduled(); |
124 } | 126 } |
125 | 127 |
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 | |
139 void GpuCommandBufferStub::Destroy() { | 128 void GpuCommandBufferStub::Destroy() { |
140 // The scheduler has raw references to the decoder and the command buffer so | 129 // The scheduler has raw references to the decoder and the command buffer so |
141 // destroy it before those. | 130 // destroy it before those. |
142 scheduler_.reset(); | 131 scheduler_.reset(); |
143 | 132 |
144 if (decoder_.get()) { | 133 if (decoder_.get()) { |
145 decoder_->Destroy(); | 134 decoder_->Destroy(); |
146 decoder_.reset(); | 135 decoder_.reset(); |
147 } | 136 } |
148 | 137 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 NULL)); | 179 NULL)); |
191 | 180 |
192 decoder_->set_engine(scheduler_.get()); | 181 decoder_->set_engine(scheduler_.get()); |
193 | 182 |
194 if (handle_) { | 183 if (handle_) { |
195 #if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT) | 184 #if defined(OS_MACOSX) || defined(UI_COMPOSITOR_IMAGE_TRANSPORT) |
196 if (software_) { | 185 if (software_) { |
197 OnInitializeFailed(reply_message); | 186 OnInitializeFailed(reply_message); |
198 return; | 187 return; |
199 } | 188 } |
200 #endif | |
201 | 189 |
202 surface_ = ImageTransportSurface::CreateSurface( | 190 surface_ = ImageTransportSurface::CreateSurface( |
203 channel_->gpu_channel_manager(), | 191 channel_->gpu_channel_manager(), |
204 render_view_id_, | 192 render_view_id_, |
205 renderer_id_, | 193 renderer_id_, |
206 route_id_, | 194 route_id_, |
207 handle_); | 195 handle_); |
| 196 #elif defined(OS_WIN) || defined(OS_LINUX) || defined(OS_OPENBSD) |
| 197 surface_ = gfx::GLSurface::CreateViewGLSurface(software_, handle_); |
| 198 #endif |
208 } else { | 199 } else { |
209 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(software_, | 200 surface_ = gfx::GLSurface::CreateOffscreenGLSurface(software_, |
210 gfx::Size(1, 1)); | 201 gfx::Size(1, 1)); |
211 } | 202 } |
212 | 203 |
213 if (!surface_.get()) { | 204 if (!surface_.get()) { |
214 // Ensure the decoder is not destroyed if it is not initialized. | 205 // Ensure the decoder is not destroyed if it is not initialized. |
215 decoder_.reset(); | 206 decoder_.reset(); |
216 | 207 |
217 DLOG(ERROR) << "Failed to create surface.\n"; | 208 DLOG(ERROR) << "Failed to create surface.\n"; |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 SetSwapInterval(); | 247 SetSwapInterval(); |
257 | 248 |
258 command_buffer_->SetPutOffsetChangeCallback( | 249 command_buffer_->SetPutOffsetChangeCallback( |
259 NewCallback(scheduler_.get(), | 250 NewCallback(scheduler_.get(), |
260 &gpu::GpuScheduler::PutChanged)); | 251 &gpu::GpuScheduler::PutChanged)); |
261 command_buffer_->SetParseErrorCallback( | 252 command_buffer_->SetParseErrorCallback( |
262 NewCallback(this, &GpuCommandBufferStub::OnParseError)); | 253 NewCallback(this, &GpuCommandBufferStub::OnParseError)); |
263 scheduler_->SetScheduledCallback( | 254 scheduler_->SetScheduledCallback( |
264 NewCallback(channel_, &GpuChannel::OnScheduled)); | 255 NewCallback(channel_, &GpuChannel::OnScheduled)); |
265 | 256 |
| 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 |
266 if (watchdog_) { | 267 if (watchdog_) { |
267 scheduler_->SetCommandProcessedCallback( | 268 scheduler_->SetCommandProcessedCallback( |
268 NewCallback(this, &GpuCommandBufferStub::OnCommandProcessed)); | 269 NewCallback(this, &GpuCommandBufferStub::OnCommandProcessed)); |
269 } | 270 } |
270 | 271 |
271 if (parent_stub_for_initialization_) { | 272 if (parent_stub_for_initialization_) { |
272 decoder_->SetParent(parent_stub_for_initialization_->decoder_.get(), | 273 decoder_->SetParent(parent_stub_for_initialization_->decoder_.get(), |
273 parent_texture_for_initialization_); | 274 parent_texture_for_initialization_); |
274 parent_stub_for_initialization_.reset(); | 275 parent_stub_for_initialization_.reset(); |
275 parent_texture_for_initialization_ = 0; | 276 parent_texture_for_initialization_ = 0; |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
422 transfer_buffer, | 423 transfer_buffer, |
423 size); | 424 size); |
424 Send(reply_message); | 425 Send(reply_message); |
425 } | 426 } |
426 | 427 |
427 void GpuCommandBufferStub::OnCommandProcessed() { | 428 void GpuCommandBufferStub::OnCommandProcessed() { |
428 if (watchdog_) | 429 if (watchdog_) |
429 watchdog_->CheckArmed(); | 430 watchdog_->CheckArmed(); |
430 } | 431 } |
431 | 432 |
| 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 |
432 void GpuCommandBufferStub::ReportState() { | 475 void GpuCommandBufferStub::ReportState() { |
433 gpu::CommandBuffer::State state = command_buffer_->GetState(); | 476 gpu::CommandBuffer::State state = command_buffer_->GetState(); |
434 if (state.error == gpu::error::kLostContext && | 477 if (state.error == gpu::error::kLostContext && |
435 gfx::GLContext::LosesAllContextsOnContextLost()) { | 478 gfx::GLContext::LosesAllContextsOnContextLost()) { |
436 channel_->LoseAllContexts(); | 479 channel_->LoseAllContexts(); |
437 } else { | 480 } else { |
438 IPC::Message* msg = new GpuCommandBufferMsg_UpdateState(route_id_, state); | 481 IPC::Message* msg = new GpuCommandBufferMsg_UpdateState(route_id_, state); |
439 msg->set_unblock(true); | 482 msg->set_unblock(true); |
440 Send(msg); | 483 Send(msg); |
441 } | 484 } |
442 } | 485 } |
443 | 486 |
| 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 |
444 void GpuCommandBufferStub::OnCreateVideoDecoder( | 500 void GpuCommandBufferStub::OnCreateVideoDecoder( |
445 media::VideoDecodeAccelerator::Profile profile, | 501 media::VideoDecodeAccelerator::Profile profile, |
446 IPC::Message* reply_message) { | 502 IPC::Message* reply_message) { |
447 int decoder_route_id = channel_->GenerateRouteID(); | 503 int decoder_route_id = channel_->GenerateRouteID(); |
448 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams( | 504 GpuCommandBufferMsg_CreateVideoDecoder::WriteReplyParams( |
449 reply_message, decoder_route_id); | 505 reply_message, decoder_route_id); |
450 GpuVideoDecodeAccelerator* decoder = | 506 GpuVideoDecodeAccelerator* decoder = |
451 new GpuVideoDecodeAccelerator(this, decoder_route_id, this); | 507 new GpuVideoDecodeAccelerator(this, decoder_route_id, this); |
452 video_decoders_.AddWithID(decoder, decoder_route_id); | 508 video_decoders_.AddWithID(decoder, decoder_route_id); |
453 channel_->AddRoute(decoder_route_id, decoder); | 509 channel_->AddRoute(decoder_route_id, decoder); |
454 decoder->Initialize(profile, reply_message); | 510 decoder->Initialize(profile, reply_message); |
455 } | 511 } |
456 | 512 |
457 void GpuCommandBufferStub::OnDestroyVideoDecoder(int decoder_route_id) { | 513 void GpuCommandBufferStub::OnDestroyVideoDecoder(int decoder_route_id) { |
458 channel_->RemoveRoute(decoder_route_id); | 514 channel_->RemoveRoute(decoder_route_id); |
459 video_decoders_.Remove(decoder_route_id); | 515 video_decoders_.Remove(decoder_route_id); |
460 } | 516 } |
461 | 517 |
462 void GpuCommandBufferStub::OnSetSurfaceVisible(bool visible) { | 518 void GpuCommandBufferStub::OnSetSurfaceVisible(bool visible) { |
463 surface_->SetVisible(visible); | 519 surface_->SetVisible(visible); |
464 } | 520 } |
465 | 521 |
466 #endif // defined(ENABLE_GPU) | 522 #endif // defined(ENABLE_GPU) |
OLD | NEW |