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/callback.h" | 8 #include "base/callback.h" |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/process_util.h" | 10 #include "base/process_util.h" |
11 #include "base/shared_memory.h" | 11 #include "base/shared_memory.h" |
12 #include "build/build_config.h" | 12 #include "build/build_config.h" |
13 #include "content/common/child_thread.h" | 13 #include "content/common/child_thread.h" |
14 #include "content/common/gpu/gpu_channel.h" | 14 #include "content/common/gpu/gpu_channel.h" |
15 #include "content/common/gpu/gpu_channel_manager.h" | 15 #include "content/common/gpu/gpu_channel_manager.h" |
16 #include "content/common/gpu/gpu_command_buffer_stub.h" | 16 #include "content/common/gpu/gpu_command_buffer_stub.h" |
17 #include "content/common/gpu/gpu_messages.h" | 17 #include "content/common/gpu/gpu_messages.h" |
18 #include "content/common/gpu/gpu_watchdog.h" | 18 #include "content/common/gpu/gpu_watchdog.h" |
19 #include "gpu/command_buffer/common/constants.h" | 19 #include "gpu/command_buffer/common/constants.h" |
20 #include "ui/gfx/gl/gl_context.h" | 20 #include "ui/gfx/gl/gl_context.h" |
21 #include "ui/gfx/gl/gl_surface.h" | 21 #include "ui/gfx/gl/gl_surface.h" |
22 | 22 |
23 #if defined(OS_WIN) | 23 #if defined(OS_WIN) |
24 #include "base/win/wrapped_window_proc.h" | 24 #include "base/win/wrapped_window_proc.h" |
| 25 #elif defined(TOUCH_UI) |
| 26 #include "content/common/gpu/image_transport_surface_linux.h" |
25 #endif | 27 #endif |
26 | 28 |
27 using gpu::Buffer; | 29 using gpu::Buffer; |
28 | 30 |
29 GpuCommandBufferStub::GpuCommandBufferStub( | 31 GpuCommandBufferStub::GpuCommandBufferStub( |
30 GpuChannel* channel, | 32 GpuChannel* channel, |
31 gfx::PluginWindowHandle handle, | 33 gfx::PluginWindowHandle handle, |
32 const gfx::Size& size, | 34 const gfx::Size& size, |
33 const gpu::gles2::DisallowedExtensions& disallowed_extensions, | 35 const gpu::gles2::DisallowedExtensions& disallowed_extensions, |
34 const std::string& allowed_extensions, | 36 const std::string& allowed_extensions, |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
108 } | 110 } |
109 | 111 |
110 bool GpuCommandBufferStub::Send(IPC::Message* message) { | 112 bool GpuCommandBufferStub::Send(IPC::Message* message) { |
111 return channel_->Send(message); | 113 return channel_->Send(message); |
112 } | 114 } |
113 | 115 |
114 bool GpuCommandBufferStub::IsScheduled() { | 116 bool GpuCommandBufferStub::IsScheduled() { |
115 return !scheduler_.get() || scheduler_->IsScheduled(); | 117 return !scheduler_.get() || scheduler_->IsScheduled(); |
116 } | 118 } |
117 | 119 |
| 120 void GpuCommandBufferStub::OnInitializeFailed(IPC::Message* reply_message) { |
| 121 scheduler_.reset(); |
| 122 command_buffer_.reset(); |
| 123 GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, false); |
| 124 Send(reply_message); |
| 125 } |
| 126 |
118 void GpuCommandBufferStub::OnInitialize( | 127 void GpuCommandBufferStub::OnInitialize( |
119 base::SharedMemoryHandle ring_buffer, | 128 base::SharedMemoryHandle ring_buffer, |
120 int32 size, | 129 int32 size, |
121 IPC::Message* reply_message) { | 130 IPC::Message* reply_message) { |
122 DCHECK(!command_buffer_.get()); | 131 DCHECK(!command_buffer_.get()); |
123 | 132 |
124 bool result = false; | |
125 | |
126 command_buffer_.reset(new gpu::CommandBufferService); | 133 command_buffer_.reset(new gpu::CommandBufferService); |
127 | 134 |
128 #if defined(OS_WIN) | 135 #if defined(OS_WIN) |
129 // Windows dups the shared memory handle it receives into the current process | 136 // Windows dups the shared memory handle it receives into the current process |
130 // and closes it when this variable goes out of scope. | 137 // and closes it when this variable goes out of scope. |
131 base::SharedMemory shared_memory(ring_buffer, | 138 base::SharedMemory shared_memory(ring_buffer, |
132 false, | 139 false, |
133 channel_->renderer_process()); | 140 channel_->renderer_process()); |
134 #else | 141 #else |
135 // POSIX receives a dup of the shared memory handle and closes the dup when | 142 // POSIX receives a dup of the shared memory handle and closes the dup when |
136 // this variable goes out of scope. | 143 // this variable goes out of scope. |
137 base::SharedMemory shared_memory(ring_buffer, false); | 144 base::SharedMemory shared_memory(ring_buffer, false); |
138 #endif | 145 #endif |
139 | 146 |
140 // Initialize the CommandBufferService and GpuScheduler. | 147 // Initialize the CommandBufferService and GpuScheduler. |
141 if (command_buffer_->Initialize(&shared_memory, size)) { | 148 if (command_buffer_->Initialize(&shared_memory, size)) { |
142 scheduler_.reset(gpu::GpuScheduler::Create(command_buffer_.get(), | 149 scheduler_.reset(gpu::GpuScheduler::Create(command_buffer_.get(), |
143 channel_, | 150 channel_, |
144 NULL)); | 151 NULL)); |
| 152 #if defined(TOUCH_UI) |
| 153 if (software_) { |
| 154 OnInitializeFailed(reply_message); |
| 155 return; |
| 156 } |
| 157 |
| 158 scoped_refptr<gfx::GLSurface> surface; |
| 159 if (handle_) |
| 160 surface = ImageTransportSurface::CreateSurface(this); |
| 161 else |
| 162 surface = gfx::GLSurface::CreateOffscreenGLSurface(software_, |
| 163 gfx::Size(1, 1)); |
| 164 if (!surface.get()) { |
| 165 LOG(ERROR) << "GpuCommandBufferStub: failed to create surface."; |
| 166 OnInitializeFailed(reply_message); |
| 167 return; |
| 168 } |
| 169 |
| 170 scoped_refptr<gfx::GLContext> context( |
| 171 gfx::GLContext::CreateGLContext(channel_->share_group(), |
| 172 surface.get())); |
| 173 if (!context.get()) { |
| 174 LOG(ERROR) << "GpuCommandBufferStub: failed to create context."; |
| 175 OnInitializeFailed(reply_message); |
| 176 return; |
| 177 } |
| 178 |
| 179 if (scheduler_->InitializeCommon( |
| 180 surface, |
| 181 context, |
| 182 initial_size_, |
| 183 disallowed_extensions_, |
| 184 allowed_extensions_.c_str(), |
| 185 requested_attribs_)) { |
| 186 #else |
145 if (scheduler_->Initialize( | 187 if (scheduler_->Initialize( |
146 handle_, | 188 handle_, |
147 initial_size_, | 189 initial_size_, |
148 software_, | 190 software_, |
149 disallowed_extensions_, | 191 disallowed_extensions_, |
150 allowed_extensions_.c_str(), | 192 allowed_extensions_.c_str(), |
151 requested_attribs_, | 193 requested_attribs_, |
152 channel_->share_group())) { | 194 channel_->share_group())) { |
| 195 #endif |
153 command_buffer_->SetPutOffsetChangeCallback( | 196 command_buffer_->SetPutOffsetChangeCallback( |
154 NewCallback(scheduler_.get(), | 197 NewCallback(scheduler_.get(), |
155 &gpu::GpuScheduler::PutChanged)); | 198 &gpu::GpuScheduler::PutChanged)); |
156 command_buffer_->SetParseErrorCallback( | 199 command_buffer_->SetParseErrorCallback( |
157 NewCallback(this, &GpuCommandBufferStub::OnParseError)); | 200 NewCallback(this, &GpuCommandBufferStub::OnParseError)); |
158 scheduler_->SetSwapBuffersCallback( | 201 scheduler_->SetSwapBuffersCallback( |
159 NewCallback(this, &GpuCommandBufferStub::OnSwapBuffers)); | 202 NewCallback(this, &GpuCommandBufferStub::OnSwapBuffers)); |
160 scheduler_->SetScheduledCallback( | 203 scheduler_->SetScheduledCallback( |
161 NewCallback(channel_, &GpuChannel::OnScheduled)); | 204 NewCallback(channel_, &GpuChannel::OnScheduled)); |
162 scheduler_->SetTokenCallback(base::Bind( | 205 scheduler_->SetTokenCallback(base::Bind( |
163 &GpuCommandBufferStub::OnSetToken, base::Unretained(this))); | 206 &GpuCommandBufferStub::OnSetToken, base::Unretained(this))); |
164 if (watchdog_) | 207 if (watchdog_) |
165 scheduler_->SetCommandProcessedCallback( | 208 scheduler_->SetCommandProcessedCallback( |
166 NewCallback(this, &GpuCommandBufferStub::OnCommandProcessed)); | 209 NewCallback(this, &GpuCommandBufferStub::OnCommandProcessed)); |
167 | 210 |
168 #if defined(OS_MACOSX) || defined(TOUCH_UI) | 211 #if defined(OS_MACOSX) |
169 if (handle_) { | 212 if (handle_) { |
170 // This context conceptually puts its output directly on the | 213 // This context conceptually puts its output directly on the |
171 // screen, rendered by the accelerated plugin layer in | 214 // screen, rendered by the accelerated plugin layer in |
172 // RenderWidgetHostViewMac. Set up a pathway to notify the | 215 // RenderWidgetHostViewMac. Set up a pathway to notify the |
173 // browser process when its contents change. | 216 // browser process when its contents change. |
174 scheduler_->SetSwapBuffersCallback( | 217 scheduler_->SetSwapBuffersCallback( |
175 NewCallback(this, | 218 NewCallback(this, |
176 &GpuCommandBufferStub::SwapBuffersCallback)); | 219 &GpuCommandBufferStub::SwapBuffersCallback)); |
177 } | 220 } |
178 #endif // defined(OS_MACOSX) || defined(TOUCH_UI) | 221 #endif // defined(OS_MACOSX) |
179 | 222 |
180 // Set up a pathway for resizing the output window or framebuffer at the | 223 // Set up a pathway for resizing the output window or framebuffer at the |
181 // right time relative to other GL commands. | 224 // right time relative to other GL commands. |
| 225 #if defined(TOUCH_UI) |
| 226 if (handle_ == gfx::kNullPluginWindow) { |
| 227 scheduler_->SetResizeCallback( |
| 228 NewCallback(this, &GpuCommandBufferStub::ResizeCallback)); |
| 229 } |
| 230 #else |
182 scheduler_->SetResizeCallback( | 231 scheduler_->SetResizeCallback( |
183 NewCallback(this, &GpuCommandBufferStub::ResizeCallback)); | 232 NewCallback(this, &GpuCommandBufferStub::ResizeCallback)); |
| 233 #endif |
184 | 234 |
185 if (parent_stub_for_initialization_) { | 235 if (parent_stub_for_initialization_) { |
186 scheduler_->SetParent(parent_stub_for_initialization_->scheduler_.get(), | 236 scheduler_->SetParent(parent_stub_for_initialization_->scheduler_.get(), |
187 parent_texture_for_initialization_); | 237 parent_texture_for_initialization_); |
188 parent_stub_for_initialization_.reset(); | 238 parent_stub_for_initialization_.reset(); |
189 parent_texture_for_initialization_ = 0; | 239 parent_texture_for_initialization_ = 0; |
190 } | 240 } |
191 | 241 |
192 result = true; | |
193 } else { | 242 } else { |
194 scheduler_.reset(); | 243 OnInitializeFailed(reply_message); |
195 command_buffer_.reset(); | 244 return; |
196 } | 245 } |
197 } | 246 } |
198 | 247 |
199 GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, result); | 248 GpuCommandBufferMsg_Initialize::WriteReplyParams(reply_message, true); |
200 Send(reply_message); | 249 Send(reply_message); |
201 } | 250 } |
202 | 251 |
203 void GpuCommandBufferStub::OnSetParent(int32 parent_route_id, | 252 void GpuCommandBufferStub::OnSetParent(int32 parent_route_id, |
204 uint32 parent_texture_id, | 253 uint32 parent_texture_id, |
205 IPC::Message* reply_message) { | 254 IPC::Message* reply_message) { |
206 | 255 |
207 GpuCommandBufferStub* parent_stub = NULL; | 256 GpuCommandBufferStub* parent_stub = NULL; |
208 if (parent_route_id != MSG_ROUTING_NONE) { | 257 if (parent_route_id != MSG_ROUTING_NONE) { |
209 parent_stub = channel_->LookupCommandBuffer(parent_route_id); | 258 parent_stub = channel_->LookupCommandBuffer(parent_route_id); |
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 params.render_view_id = render_view_id_; | 480 params.render_view_id = render_view_id_; |
432 params.window = handle_; | 481 params.window = handle_; |
433 params.surface_id = scheduler_->GetSurfaceId(); | 482 params.surface_id = scheduler_->GetSurfaceId(); |
434 params.route_id = route_id(); | 483 params.route_id = route_id(); |
435 params.swap_buffers_count = scheduler_->swap_buffers_count(); | 484 params.swap_buffers_count = scheduler_->swap_buffers_count(); |
436 gpu_channel_manager->Send( | 485 gpu_channel_manager->Send( |
437 new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params)); | 486 new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params)); |
438 | 487 |
439 scheduler_->SetScheduled(false); | 488 scheduler_->SetScheduled(false); |
440 } | 489 } |
441 #endif // defined(OS_MACOSX) | |
442 | |
443 #if defined(TOUCH_UI) | |
444 void GpuCommandBufferStub::SwapBuffersCallback() { | |
445 TRACE_EVENT0("gpu", "GpuCommandBufferStub::SwapBuffersCallback"); | |
446 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); | |
447 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; | |
448 params.renderer_id = renderer_id_; | |
449 params.render_view_id = render_view_id_; | |
450 params.surface_id = scheduler_->GetFrontSurfaceId(); | |
451 params.route_id = route_id(); | |
452 params.swap_buffers_count = scheduler_->swap_buffers_count(); | |
453 gpu_channel_manager->Send( | |
454 new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params)); | |
455 | |
456 scheduler_->SetScheduled(false); | |
457 } | |
458 | 490 |
459 void GpuCommandBufferStub::AcceleratedSurfaceIOSurfaceSet(uint64 surface_id) { | |
460 scheduler_->SetScheduled(true); | |
461 } | |
462 | |
463 void GpuCommandBufferStub::AcceleratedSurfaceReleased(uint64 surface_id) { | |
464 scheduler_->ReleaseSurface(surface_id); | |
465 } | |
466 #endif // defined(TOUCH_UI) | |
467 | |
468 #if defined(OS_MACOSX) || defined(TOUCH_UI) | |
469 void GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped( | 491 void GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped( |
470 uint64 swap_buffers_count) { | 492 uint64 swap_buffers_count) { |
471 TRACE_EVENT1("gpu", | 493 TRACE_EVENT1("gpu", |
472 "GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped", | 494 "GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped", |
473 "frame", swap_buffers_count); | 495 "frame", swap_buffers_count); |
474 | 496 |
475 // Multiple swapbuffers may get consolidated together into a single | 497 // Multiple swapbuffers may get consolidated together into a single |
476 // AcceleratedSurfaceBuffersSwapped call. Since OnSwapBuffers expects to be | 498 // AcceleratedSurfaceBuffersSwapped call. Since OnSwapBuffers expects to be |
477 // called one time for every swap, make up the difference here. | 499 // called one time for every swap, make up the difference here. |
478 uint64 delta = swap_buffers_count - | 500 uint64 delta = swap_buffers_count - |
479 scheduler_->acknowledged_swap_buffers_count(); | 501 scheduler_->acknowledged_swap_buffers_count(); |
480 scheduler_->set_acknowledged_swap_buffers_count(swap_buffers_count); | 502 scheduler_->set_acknowledged_swap_buffers_count(swap_buffers_count); |
481 | 503 |
482 for(uint64 i = 0; i < delta; i++) { | 504 for(uint64 i = 0; i < delta; i++) { |
483 OnSwapBuffers(); | 505 OnSwapBuffers(); |
484 // Wake up the GpuScheduler to start doing work again. | 506 // Wake up the GpuScheduler to start doing work again. |
485 scheduler_->SetScheduled(true); | 507 scheduler_->SetScheduled(true); |
486 } | 508 } |
487 } | 509 } |
488 #endif // defined(OS_MACOSX) || defined(TOUCH_UI) | 510 #endif // defined(OS_MACOSX) |
489 | 511 |
490 void GpuCommandBufferStub::AddSetTokenCallback( | 512 void GpuCommandBufferStub::AddSetTokenCallback( |
491 const base::Callback<void(int32)>& callback) { | 513 const base::Callback<void(int32)>& callback) { |
492 set_token_callbacks_.push_back(callback); | 514 set_token_callbacks_.push_back(callback); |
493 } | 515 } |
494 | 516 |
495 void GpuCommandBufferStub::OnSetToken(int32 token) { | 517 void GpuCommandBufferStub::OnSetToken(int32 token) { |
496 for (size_t i = 0; i < set_token_callbacks_.size(); ++i) | 518 for (size_t i = 0; i < set_token_callbacks_.size(); ++i) |
497 set_token_callbacks_[i].Run(token); | 519 set_token_callbacks_[i].Run(token); |
498 } | 520 } |
499 | 521 |
500 void GpuCommandBufferStub::ResizeCallback(gfx::Size size) { | 522 void GpuCommandBufferStub::ResizeCallback(gfx::Size size) { |
501 if (handle_ == gfx::kNullPluginWindow) { | 523 if (handle_ == gfx::kNullPluginWindow) { |
502 scheduler_->decoder()->ResizeOffscreenFrameBuffer(size); | 524 scheduler_->decoder()->ResizeOffscreenFrameBuffer(size); |
503 scheduler_->decoder()->UpdateOffscreenFrameBufferSize(); | 525 scheduler_->decoder()->UpdateOffscreenFrameBufferSize(); |
504 } else { | 526 } else { |
505 #if defined(TOOLKIT_USES_GTK) && !defined(TOUCH_UI) || defined(OS_WIN) | 527 #if defined(TOOLKIT_USES_GTK) && !defined(TOUCH_UI) || defined(OS_WIN) |
506 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); | 528 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); |
507 gpu_channel_manager->Send( | 529 gpu_channel_manager->Send( |
508 new GpuHostMsg_ResizeView(renderer_id_, | 530 new GpuHostMsg_ResizeView(renderer_id_, |
509 render_view_id_, | 531 render_view_id_, |
510 route_id_, | 532 route_id_, |
511 size)); | 533 size)); |
512 | 534 |
513 scheduler_->SetScheduled(false); | 535 scheduler_->SetScheduled(false); |
514 #elif defined(TOUCH_UI) | |
515 if (scheduler_->GetBackSurfaceId()) { | |
516 GpuHostMsg_AcceleratedSurfaceRelease_Params params; | |
517 params.renderer_id = renderer_id_; | |
518 params.render_view_id = render_view_id_; | |
519 params.identifier = scheduler_->GetBackSurfaceId(); | |
520 params.route_id = route_id(); | |
521 | |
522 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); | |
523 gpu_channel_manager->Send( | |
524 new GpuHostMsg_AcceleratedSurfaceRelease(params)); | |
525 } | |
526 scheduler_->CreateBackSurface(size); | |
527 GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params params; | |
528 params.renderer_id = renderer_id_; | |
529 params.render_view_id = render_view_id_; | |
530 params.width = size.width(); | |
531 params.height = size.height(); | |
532 params.identifier = scheduler_->GetBackSurfaceId(); | |
533 params.route_id = route_id(); | |
534 | |
535 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); | |
536 gpu_channel_manager->Send( | |
537 new GpuHostMsg_AcceleratedSurfaceSetIOSurface(params)); | |
538 scheduler_->SetScheduled(false); | |
539 #endif | 536 #endif |
540 } | 537 } |
541 } | 538 } |
542 | 539 |
543 void GpuCommandBufferStub::ViewResized() { | 540 void GpuCommandBufferStub::ViewResized() { |
544 #if defined(TOOLKIT_USES_GTK) && !defined(TOUCH_UI) || defined(OS_WIN) | 541 #if defined(TOOLKIT_USES_GTK) && !defined(TOUCH_UI) || defined(OS_WIN) |
545 DCHECK(handle_ != gfx::kNullPluginWindow); | 542 DCHECK(handle_ != gfx::kNullPluginWindow); |
546 scheduler_->SetScheduled(true); | 543 scheduler_->SetScheduled(true); |
547 | 544 |
548 // Recreate the view surface to match the window size. TODO(apatrick): this is | 545 // Recreate the view surface to match the window size. TODO(apatrick): this is |
(...skipping 26 matching lines...) Expand all Loading... |
575 new GpuVideoDecodeAccelerator(this, route_id_, this)); | 572 new GpuVideoDecodeAccelerator(this, route_id_, this)); |
576 video_decoder_->Initialize(configs); | 573 video_decoder_->Initialize(configs); |
577 } | 574 } |
578 | 575 |
579 void GpuCommandBufferStub::OnDestroyVideoDecoder() { | 576 void GpuCommandBufferStub::OnDestroyVideoDecoder() { |
580 LOG(ERROR) << "GpuCommandBufferStub::OnDestroyVideoDecoder"; | 577 LOG(ERROR) << "GpuCommandBufferStub::OnDestroyVideoDecoder"; |
581 video_decoder_.reset(); | 578 video_decoder_.reset(); |
582 } | 579 } |
583 | 580 |
584 #endif // defined(ENABLE_GPU) | 581 #endif // defined(ENABLE_GPU) |
OLD | NEW |