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