| 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/process_util.h" | 8 #include "base/process_util.h" |
| 9 #include "base/shared_memory.h" | 9 #include "base/shared_memory.h" |
| 10 #include "build/build_config.h" | 10 #include "build/build_config.h" |
| 11 #include "content/common/child_thread.h" | 11 #include "content/common/child_thread.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" | 17 #include "gpu/command_buffer/common/constants.h" |
| 18 #include "gpu/common/gpu_trace_event.h" | 18 #include "gpu/common/gpu_trace_event.h" |
| 19 #include "ui/gfx/gl/gl_context.h" | 19 #include "ui/gfx/gl/gl_context.h" |
| 20 #include "ui/gfx/gl/gl_surface.h" |
| 20 | 21 |
| 21 #if defined(OS_WIN) | 22 #if defined(OS_WIN) |
| 22 #include "base/win/wrapped_window_proc.h" | 23 #include "base/win/wrapped_window_proc.h" |
| 23 #endif | 24 #endif |
| 24 | 25 |
| 25 using gpu::Buffer; | 26 using gpu::Buffer; |
| 26 | 27 |
| 27 #if defined(OS_WIN) | 28 #if defined(OS_WIN) |
| 28 #define kCompositorWindowOwner L"CompositorWindowOwner" | 29 #define kCompositorWindowOwner L"CompositorWindowOwner" |
| 29 #endif // defined(OS_WIN) | 30 #endif // defined(OS_WIN) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 44 : channel_(channel), | 45 : channel_(channel), |
| 45 handle_(handle), | 46 handle_(handle), |
| 46 parent_( | 47 parent_( |
| 47 parent ? parent->AsWeakPtr() : base::WeakPtr<GpuCommandBufferStub>()), | 48 parent ? parent->AsWeakPtr() : base::WeakPtr<GpuCommandBufferStub>()), |
| 48 initial_size_(size), | 49 initial_size_(size), |
| 49 disallowed_extensions_(disallowed_extensions), | 50 disallowed_extensions_(disallowed_extensions), |
| 50 allowed_extensions_(allowed_extensions), | 51 allowed_extensions_(allowed_extensions), |
| 51 requested_attribs_(attribs), | 52 requested_attribs_(attribs), |
| 52 parent_texture_id_(parent_texture_id), | 53 parent_texture_id_(parent_texture_id), |
| 53 route_id_(route_id), | 54 route_id_(route_id), |
| 54 #if defined(OS_WIN) | |
| 55 compositor_window_(NULL), | |
| 56 #endif // defined(OS_WIN) | |
| 57 renderer_id_(renderer_id), | 55 renderer_id_(renderer_id), |
| 58 render_view_id_(render_view_id), | 56 render_view_id_(render_view_id), |
| 59 watchdog_(watchdog) { | 57 watchdog_(watchdog) { |
| 60 } | 58 } |
| 61 | 59 |
| 62 #if defined(OS_WIN) | |
| 63 static LRESULT CALLBACK CompositorWindowProc( | |
| 64 HWND hwnd, | |
| 65 UINT message, | |
| 66 WPARAM wparam, | |
| 67 LPARAM lparam) { | |
| 68 switch (message) { | |
| 69 case WM_ERASEBKGND: | |
| 70 return 0; | |
| 71 case WM_DESTROY: | |
| 72 RemoveProp(hwnd, kCompositorWindowOwner); | |
| 73 return 0; | |
| 74 case WM_PAINT: { | |
| 75 PAINTSTRUCT paint; | |
| 76 HDC dc = BeginPaint(hwnd, &paint); | |
| 77 if (dc) { | |
| 78 HANDLE h = GetProp(hwnd, kCompositorWindowOwner); | |
| 79 if (h) { | |
| 80 GpuCommandBufferStub* stub = | |
| 81 reinterpret_cast<GpuCommandBufferStub*>(h); | |
| 82 stub->OnCompositorWindowPainted(); | |
| 83 } | |
| 84 EndPaint(hwnd, &paint); | |
| 85 } | |
| 86 break; | |
| 87 } | |
| 88 default: | |
| 89 return DefWindowProc(hwnd, message, wparam, lparam); | |
| 90 } | |
| 91 return 0; | |
| 92 } | |
| 93 | |
| 94 bool GpuCommandBufferStub::CreateCompositorWindow() { | |
| 95 DCHECK(handle_ != gfx::kNullPluginWindow); | |
| 96 HWND host_window = static_cast<HWND>(handle_); | |
| 97 | |
| 98 // Create the compositor window itself. | |
| 99 DCHECK(host_window); | |
| 100 static ATOM window_class = 0; | |
| 101 if (!window_class) { | |
| 102 WNDCLASSEX wcex; | |
| 103 wcex.cbSize = sizeof(wcex); | |
| 104 wcex.style = 0; | |
| 105 wcex.lpfnWndProc = base::win::WrappedWindowProc<CompositorWindowProc>; | |
| 106 wcex.cbClsExtra = 0; | |
| 107 wcex.cbWndExtra = 0; | |
| 108 wcex.hInstance = GetModuleHandle(NULL); | |
| 109 wcex.hIcon = 0; | |
| 110 wcex.hCursor = 0; | |
| 111 wcex.hbrBackground = NULL; | |
| 112 wcex.lpszMenuName = 0; | |
| 113 wcex.lpszClassName = L"CompositorWindowClass"; | |
| 114 wcex.hIconSm = 0; | |
| 115 window_class = RegisterClassEx(&wcex); | |
| 116 DCHECK(window_class); | |
| 117 } | |
| 118 | |
| 119 HWND compositor_window = CreateWindowEx( | |
| 120 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR, | |
| 121 MAKEINTATOM(window_class), | |
| 122 0, | |
| 123 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_DISABLED, | |
| 124 0, 0, | |
| 125 0, 0, | |
| 126 host_window, | |
| 127 0, | |
| 128 GetModuleHandle(NULL), | |
| 129 0); | |
| 130 if (!compositor_window) { | |
| 131 compositor_window_ = gfx::kNullPluginWindow; | |
| 132 return false; | |
| 133 } | |
| 134 SetProp(compositor_window, kCompositorWindowOwner, | |
| 135 reinterpret_cast<HANDLE>(this)); | |
| 136 | |
| 137 RECT parent_rect; | |
| 138 GetClientRect(host_window, &parent_rect); | |
| 139 | |
| 140 UINT flags = SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER | | |
| 141 SWP_NOACTIVATE | SWP_DEFERERASE | SWP_SHOWWINDOW; | |
| 142 SetWindowPos(compositor_window, | |
| 143 NULL, | |
| 144 0, 0, | |
| 145 parent_rect.right - parent_rect.left, | |
| 146 parent_rect.bottom - parent_rect.top, | |
| 147 flags); | |
| 148 compositor_window_ = static_cast<gfx::PluginWindowHandle>(compositor_window); | |
| 149 return true; | |
| 150 } | |
| 151 | |
| 152 void GpuCommandBufferStub::OnCompositorWindowPainted() { | |
| 153 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); | |
| 154 gpu_channel_manager->Send(new GpuHostMsg_ScheduleComposite( | |
| 155 renderer_id_, render_view_id_)); | |
| 156 } | |
| 157 #endif // defined(OS_WIN) | |
| 158 | |
| 159 | |
| 160 GpuCommandBufferStub::~GpuCommandBufferStub() { | 60 GpuCommandBufferStub::~GpuCommandBufferStub() { |
| 161 if (scheduler_.get()) { | 61 if (scheduler_.get()) { |
| 162 scheduler_->Destroy(); | 62 scheduler_->Destroy(); |
| 163 } | 63 } |
| 164 #if defined(OS_WIN) | |
| 165 if (compositor_window_) { | |
| 166 DestroyWindow(static_cast<HWND>(compositor_window_)); | |
| 167 compositor_window_ = NULL; | |
| 168 } | |
| 169 #endif // defined(OS_WIN) | |
| 170 | 64 |
| 171 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); | 65 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); |
| 172 gpu_channel_manager->Send(new GpuHostMsg_DestroyCommandBuffer( | 66 gpu_channel_manager->Send(new GpuHostMsg_DestroyCommandBuffer( |
| 173 handle_, renderer_id_, render_view_id_)); | 67 handle_, renderer_id_, render_view_id_)); |
| 174 } | 68 } |
| 175 | 69 |
| 176 bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { | 70 bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { |
| 177 bool handled = true; | 71 bool handled = true; |
| 178 IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message) | 72 IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message) |
| 179 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Initialize, OnInitialize); | 73 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Initialize, OnInitialize); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 207 void GpuCommandBufferStub::OnInitialize( | 101 void GpuCommandBufferStub::OnInitialize( |
| 208 base::SharedMemoryHandle ring_buffer, | 102 base::SharedMemoryHandle ring_buffer, |
| 209 int32 size, | 103 int32 size, |
| 210 bool* result) { | 104 bool* result) { |
| 211 DCHECK(!command_buffer_.get()); | 105 DCHECK(!command_buffer_.get()); |
| 212 | 106 |
| 213 *result = false; | 107 *result = false; |
| 214 | 108 |
| 215 command_buffer_.reset(new gpu::CommandBufferService); | 109 command_buffer_.reset(new gpu::CommandBufferService); |
| 216 | 110 |
| 217 // Create the child window, if needed | |
| 218 #if defined(OS_WIN) | |
| 219 gfx::PluginWindowHandle output_window_handle; | |
| 220 if (handle_) { | |
| 221 if (!CreateCompositorWindow()) { | |
| 222 return; | |
| 223 } | |
| 224 output_window_handle = compositor_window_; | |
| 225 } else { | |
| 226 output_window_handle = handle_; | |
| 227 } | |
| 228 #else | |
| 229 gfx::PluginWindowHandle output_window_handle = handle_; | |
| 230 #endif // defined(OS_WIN) | |
| 231 | |
| 232 #if defined(OS_WIN) | 111 #if defined(OS_WIN) |
| 233 // Windows dups the shared memory handle it receives into the current process | 112 // Windows dups the shared memory handle it receives into the current process |
| 234 // and closes it when this variable goes out of scope. | 113 // and closes it when this variable goes out of scope. |
| 235 base::SharedMemory shared_memory(ring_buffer, | 114 base::SharedMemory shared_memory(ring_buffer, |
| 236 false, | 115 false, |
| 237 channel_->renderer_process()); | 116 channel_->renderer_process()); |
| 238 #else | 117 #else |
| 239 // POSIX receives a dup of the shared memory handle and closes the dup when | 118 // POSIX receives a dup of the shared memory handle and closes the dup when |
| 240 // this variable goes out of scope. | 119 // this variable goes out of scope. |
| 241 base::SharedMemory shared_memory(ring_buffer, false); | 120 base::SharedMemory shared_memory(ring_buffer, false); |
| 242 #endif | 121 #endif |
| 243 | 122 |
| 244 // Initialize the CommandBufferService and GpuScheduler. | 123 // Initialize the CommandBufferService and GpuScheduler. |
| 245 if (command_buffer_->Initialize(&shared_memory, size)) { | 124 if (command_buffer_->Initialize(&shared_memory, size)) { |
| 246 gpu::GpuScheduler* parent_processor = | 125 gpu::GpuScheduler* parent_processor = |
| 247 parent_ ? parent_->scheduler_.get() : NULL; | 126 parent_ ? parent_->scheduler_.get() : NULL; |
| 248 scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), NULL)); | 127 scheduler_.reset(new gpu::GpuScheduler(command_buffer_.get(), NULL)); |
| 249 if (scheduler_->Initialize( | 128 if (scheduler_->Initialize( |
| 250 output_window_handle, | 129 handle_, |
| 251 initial_size_, | 130 initial_size_, |
| 252 disallowed_extensions_, | 131 disallowed_extensions_, |
| 253 allowed_extensions_.c_str(), | 132 allowed_extensions_.c_str(), |
| 254 requested_attribs_, | 133 requested_attribs_, |
| 255 parent_processor, | 134 parent_processor, |
| 256 parent_texture_id_)) { | 135 parent_texture_id_)) { |
| 257 command_buffer_->SetPutOffsetChangeCallback( | 136 command_buffer_->SetPutOffsetChangeCallback( |
| 258 NewCallback(scheduler_.get(), | 137 NewCallback(scheduler_.get(), |
| 259 &gpu::GpuScheduler::ProcessCommands)); | 138 &gpu::GpuScheduler::ProcessCommands)); |
| 260 scheduler_->SetSwapBuffersCallback( | 139 scheduler_->SetSwapBuffersCallback( |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); | 291 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); |
| 413 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; | 292 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params; |
| 414 params.renderer_id = renderer_id_; | 293 params.renderer_id = renderer_id_; |
| 415 params.render_view_id = render_view_id_; | 294 params.render_view_id = render_view_id_; |
| 416 params.window = handle_; | 295 params.window = handle_; |
| 417 params.surface_id = scheduler_->GetSurfaceId(); | 296 params.surface_id = scheduler_->GetSurfaceId(); |
| 418 params.route_id = route_id(); | 297 params.route_id = route_id(); |
| 419 params.swap_buffers_count = scheduler_->swap_buffers_count(); | 298 params.swap_buffers_count = scheduler_->swap_buffers_count(); |
| 420 gpu_channel_manager->Send( | 299 gpu_channel_manager->Send( |
| 421 new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params)); | 300 new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params)); |
| 301 |
| 302 scheduler_->SetScheduled(false); |
| 422 } | 303 } |
| 423 | 304 |
| 424 void GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped( | 305 void GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped( |
| 425 uint64 swap_buffers_count) { | 306 uint64 swap_buffers_count) { |
| 426 scheduler_->set_acknowledged_swap_buffers_count(swap_buffers_count); | 307 scheduler_->set_acknowledged_swap_buffers_count(swap_buffers_count); |
| 308 |
| 427 // Wake up the GpuScheduler to start doing work again. | 309 // Wake up the GpuScheduler to start doing work again. |
| 428 scheduler_->ScheduleProcessCommands(); | 310 scheduler_->SetScheduled(true); |
| 429 } | 311 } |
| 430 #endif // defined(OS_MACOSX) | 312 #endif // defined(OS_MACOSX) |
| 431 | 313 |
| 432 void GpuCommandBufferStub::ResizeCallback(gfx::Size size) { | 314 void GpuCommandBufferStub::ResizeCallback(gfx::Size size) { |
| 433 if (handle_ == gfx::kNullPluginWindow) { | 315 if (handle_ == gfx::kNullPluginWindow) { |
| 434 scheduler_->decoder()->ResizeOffscreenFrameBuffer(size); | 316 scheduler_->decoder()->ResizeOffscreenFrameBuffer(size); |
| 435 scheduler_->decoder()->UpdateOffscreenFrameBufferSize(); | 317 scheduler_->decoder()->UpdateOffscreenFrameBufferSize(); |
| 436 } else { | 318 } else { |
| 437 #if defined(OS_LINUX) && !defined(TOUCH_UI) | 319 #if defined(OS_LINUX) && !defined(TOUCH_UI) || defined(OS_WIN) |
| 438 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); | 320 GpuChannelManager* gpu_channel_manager = channel_->gpu_channel_manager(); |
| 439 bool result = false; | |
| 440 gpu_channel_manager->Send( | 321 gpu_channel_manager->Send( |
| 441 new GpuHostMsg_ResizeXID(handle_, size, &result)); | 322 new GpuHostMsg_ResizeView(renderer_id_, |
| 442 #elif defined(OS_WIN) | 323 render_view_id_, |
| 443 HWND hwnd = static_cast<HWND>(compositor_window_); | 324 route_id_, |
| 444 UINT swp_flags = SWP_NOSENDCHANGING | SWP_NOOWNERZORDER | SWP_NOCOPYBITS | | 325 size)); |
| 445 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE; | 326 |
| 446 SetWindowPos(hwnd, NULL, 0, 0, size.width(), size.height(), swp_flags); | 327 scheduler_->SetScheduled(false); |
| 447 #endif // defined(OS_LINUX) | 328 #endif |
| 448 } | 329 } |
| 449 } | 330 } |
| 450 | 331 |
| 332 void GpuCommandBufferStub::ViewResized() { |
| 333 #if defined(OS_LINUX) && !defined(TOUCH_UI) || defined(OS_WIN) |
| 334 DCHECK(handle_ != gfx::kNullPluginWindow); |
| 335 scheduler_->SetScheduled(true); |
| 336 |
| 337 // Recreate the view surface to match the window size. TODO(apatrick): this is |
| 338 // likely not necessary on all platforms. |
| 339 gfx::GLContext* context = scheduler_->decoder()->GetGLContext(); |
| 340 context->ReleaseCurrent(); |
| 341 gfx::GLSurface* surface = context->GetSurface(); |
| 342 if (surface) { |
| 343 surface->Destroy(); |
| 344 surface->Initialize(); |
| 345 } |
| 346 #endif |
| 347 } |
| 348 |
| 451 #endif // defined(ENABLE_GPU) | 349 #endif // defined(ENABLE_GPU) |
| OLD | NEW |