OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/process_util.h" | 7 #include "base/process_util.h" |
8 #include "base/shared_memory.h" | 8 #include "base/shared_memory.h" |
9 #include "build/build_config.h" | 9 #include "build/build_config.h" |
10 #include "chrome/common/child_thread.h" | 10 #include "chrome/common/child_thread.h" |
11 #include "chrome/common/gpu_messages.h" | 11 #include "chrome/common/gpu_messages.h" |
12 #include "chrome/gpu/gpu_channel.h" | 12 #include "chrome/gpu/gpu_channel.h" |
13 #include "chrome/gpu/gpu_command_buffer_stub.h" | 13 #include "chrome/gpu/gpu_command_buffer_stub.h" |
14 | 14 |
15 using gpu::Buffer; | 15 using gpu::Buffer; |
16 | 16 |
| 17 #if defined(OS_WIN) |
| 18 #define kCompositorWindowOwner L"CompositorWindowOwner" |
| 19 #endif |
| 20 |
17 GpuCommandBufferStub::GpuCommandBufferStub( | 21 GpuCommandBufferStub::GpuCommandBufferStub( |
18 GpuChannel* channel, | 22 GpuChannel* channel, |
19 gfx::PluginWindowHandle handle, | 23 gfx::PluginWindowHandle handle, |
20 GpuCommandBufferStub* parent, | 24 GpuCommandBufferStub* parent, |
21 const gfx::Size& size, | 25 const gfx::Size& size, |
22 const std::string& allowed_extensions, | 26 const std::string& allowed_extensions, |
23 const std::vector<int32>& attribs, | 27 const std::vector<int32>& attribs, |
24 uint32 parent_texture_id, | 28 uint32 parent_texture_id, |
25 int32 route_id, | 29 int32 route_id, |
26 int32 renderer_id, | 30 int32 renderer_id, |
27 int32 render_view_id) | 31 int32 render_view_id) |
28 : channel_(channel), | 32 : channel_(channel), |
29 handle_(handle), | 33 handle_(handle), |
30 parent_( | 34 parent_( |
31 parent ? parent->AsWeakPtr() : base::WeakPtr<GpuCommandBufferStub>()), | 35 parent ? parent->AsWeakPtr() : base::WeakPtr<GpuCommandBufferStub>()), |
32 initial_size_(size), | 36 initial_size_(size), |
33 allowed_extensions_(allowed_extensions), | 37 allowed_extensions_(allowed_extensions), |
34 requested_attribs_(attribs), | 38 requested_attribs_(attribs), |
35 parent_texture_id_(parent_texture_id), | 39 parent_texture_id_(parent_texture_id), |
36 route_id_(route_id), | 40 route_id_(route_id), |
37 renderer_id_(renderer_id), | 41 renderer_id_(renderer_id), |
38 render_view_id_(render_view_id) { | 42 render_view_id_(render_view_id) { |
39 } | 43 } |
40 | 44 |
| 45 #if defined(OS_WIN) |
| 46 static LRESULT CALLBACK CompositorWindowProc( |
| 47 HWND hwnd, |
| 48 UINT message, |
| 49 WPARAM wparam, |
| 50 LPARAM lparam) { |
| 51 switch (message) { |
| 52 case WM_ERASEBKGND: |
| 53 return 0; |
| 54 case WM_DESTROY: |
| 55 RemoveProp(hwnd, kCompositorWindowOwner); |
| 56 return 0; |
| 57 case WM_PAINT: { |
| 58 PAINTSTRUCT paint; |
| 59 HDC dc = BeginPaint(hwnd, &paint); |
| 60 if (dc) { |
| 61 HANDLE h = GetProp(hwnd, kCompositorWindowOwner); |
| 62 if (h) { |
| 63 GpuCommandBufferStub* stub = |
| 64 reinterpret_cast<GpuCommandBufferStub*>(h); |
| 65 stub->OnCompositorWindowPainted(); |
| 66 } |
| 67 EndPaint(hwnd, &paint); |
| 68 } |
| 69 break; |
| 70 } |
| 71 default: |
| 72 return DefWindowProc(hwnd, message, wparam, lparam); |
| 73 } |
| 74 return 0; |
| 75 } |
| 76 |
| 77 bool GpuCommandBufferStub::CreateCompositorWindow() { |
| 78 DCHECK(handle_ != gfx::kNullPluginWindow); |
| 79 |
| 80 // Ask the browser to create the the host window. |
| 81 ChildThread* gpu_thread = ChildThread::current(); |
| 82 gfx::PluginWindowHandle host_window_id = gfx::kNullPluginWindow; |
| 83 gpu_thread->Send(new GpuHostMsg_CreateCompositorHostWindow( |
| 84 renderer_id_, |
| 85 render_view_id_, |
| 86 &host_window_id)); |
| 87 if (host_window_id == gfx::kNullPluginWindow) |
| 88 return false; |
| 89 HWND host_window = static_cast<HWND>(host_window_id); |
| 90 |
| 91 // Create the compositor window itself. |
| 92 DCHECK(host_window); |
| 93 static ATOM window_class = 0; |
| 94 if (!window_class) { |
| 95 WNDCLASSEX wcex; |
| 96 wcex.cbSize = sizeof(wcex); |
| 97 wcex.style = 0; |
| 98 wcex.lpfnWndProc = CompositorWindowProc; |
| 99 wcex.cbClsExtra = 0; |
| 100 wcex.cbWndExtra = 0; |
| 101 wcex.hInstance = GetModuleHandle(NULL); |
| 102 wcex.hIcon = 0; |
| 103 wcex.hCursor = 0; |
| 104 wcex.hbrBackground = NULL; |
| 105 wcex.lpszMenuName = 0; |
| 106 wcex.lpszClassName = L"CompositorWindowClass"; |
| 107 wcex.hIconSm = 0; |
| 108 window_class = RegisterClassEx(&wcex); |
| 109 DCHECK(window_class); |
| 110 } |
| 111 |
| 112 HWND compositor_window = CreateWindowEx( |
| 113 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR, |
| 114 MAKEINTATOM(window_class), |
| 115 0, |
| 116 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_DISABLED, |
| 117 0, 0, |
| 118 0, 0, |
| 119 host_window, |
| 120 0, |
| 121 GetModuleHandle(NULL), |
| 122 0); |
| 123 if (!compositor_window) { |
| 124 compositor_window_ = gfx::kNullPluginWindow; |
| 125 return false; |
| 126 } |
| 127 SetProp(compositor_window, kCompositorWindowOwner, |
| 128 reinterpret_cast<HANDLE>(this)); |
| 129 |
| 130 RECT parent_rect; |
| 131 GetClientRect(host_window, &parent_rect); |
| 132 |
| 133 UINT flags = SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER | |
| 134 SWP_NOACTIVATE | SWP_DEFERERASE | SWP_SHOWWINDOW; |
| 135 SetWindowPos(compositor_window, |
| 136 NULL, |
| 137 0, 0, |
| 138 parent_rect.right - parent_rect.left, |
| 139 parent_rect.bottom - parent_rect.top, |
| 140 flags); |
| 141 compositor_window_ = static_cast<gfx::PluginWindowHandle>(compositor_window); |
| 142 return true; |
| 143 } |
| 144 |
| 145 void GpuCommandBufferStub::OnCompositorWindowPainted() { |
| 146 ChildThread* gpu_thread = ChildThread::current(); |
| 147 gpu_thread->Send(new GpuHostMsg_ScheduleComposite( |
| 148 renderer_id_, render_view_id_)); |
| 149 } |
| 150 #endif // defined(OS_WIN) |
| 151 |
| 152 |
41 GpuCommandBufferStub::~GpuCommandBufferStub() { | 153 GpuCommandBufferStub::~GpuCommandBufferStub() { |
42 if (processor_.get()) { | 154 if (processor_.get()) { |
43 processor_->Destroy(); | 155 processor_->Destroy(); |
44 } | 156 } |
| 157 #if defined(OS_WIN) |
| 158 if (compositor_window_) { |
| 159 DestroyWindow(static_cast<HWND>(compositor_window_)); |
| 160 compositor_window_ = NULL; |
| 161 } |
| 162 #endif |
45 } | 163 } |
46 | 164 |
47 void GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { | 165 void GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) { |
48 IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message) | 166 IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message) |
49 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Initialize, OnInitialize); | 167 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Initialize, OnInitialize); |
50 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetState, OnGetState); | 168 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetState, OnGetState); |
51 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncGetState, OnAsyncGetState); | 169 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncGetState, OnAsyncGetState); |
52 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Flush, OnFlush); | 170 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Flush, OnFlush); |
53 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush); | 171 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush); |
54 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateTransferBuffer, | 172 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateTransferBuffer, |
(...skipping 17 matching lines...) Expand all Loading... |
72 | 190 |
73 void GpuCommandBufferStub::OnInitialize( | 191 void GpuCommandBufferStub::OnInitialize( |
74 int32 size, | 192 int32 size, |
75 base::SharedMemoryHandle* ring_buffer) { | 193 base::SharedMemoryHandle* ring_buffer) { |
76 DCHECK(!command_buffer_.get()); | 194 DCHECK(!command_buffer_.get()); |
77 | 195 |
78 *ring_buffer = base::SharedMemory::NULLHandle(); | 196 *ring_buffer = base::SharedMemory::NULLHandle(); |
79 | 197 |
80 command_buffer_.reset(new gpu::CommandBufferService); | 198 command_buffer_.reset(new gpu::CommandBufferService); |
81 | 199 |
| 200 // Create the child window, if needed |
| 201 #if defined(OS_WIN) |
| 202 gfx::PluginWindowHandle output_window_handle; |
| 203 if (handle_) { |
| 204 if (!CreateCompositorWindow()) { |
| 205 return; |
| 206 } |
| 207 output_window_handle = compositor_window_; |
| 208 } else { |
| 209 output_window_handle = handle_; |
| 210 } |
| 211 #else |
| 212 gfx::PluginWindowHandle output_window_handle = handle_; |
| 213 #endif |
| 214 |
82 // Initialize the CommandBufferService and GPUProcessor. | 215 // Initialize the CommandBufferService and GPUProcessor. |
83 if (command_buffer_->Initialize(size)) { | 216 if (command_buffer_->Initialize(size)) { |
84 Buffer buffer = command_buffer_->GetRingBuffer(); | 217 Buffer buffer = command_buffer_->GetRingBuffer(); |
85 if (buffer.shared_memory) { | 218 if (buffer.shared_memory) { |
86 gpu::GPUProcessor* parent_processor = | 219 gpu::GPUProcessor* parent_processor = |
87 parent_ ? parent_->processor_.get() : NULL; | 220 parent_ ? parent_->processor_.get() : NULL; |
88 processor_.reset(new gpu::GPUProcessor(command_buffer_.get(), NULL)); | 221 processor_.reset(new gpu::GPUProcessor(command_buffer_.get(), NULL)); |
89 if (processor_->Initialize( | 222 if (processor_->Initialize( |
90 handle_, | 223 output_window_handle, |
91 initial_size_, | 224 initial_size_, |
92 allowed_extensions_.c_str(), | 225 allowed_extensions_.c_str(), |
93 requested_attribs_, | 226 requested_attribs_, |
94 parent_processor, | 227 parent_processor, |
95 parent_texture_id_)) { | 228 parent_texture_id_)) { |
96 command_buffer_->SetPutOffsetChangeCallback( | 229 command_buffer_->SetPutOffsetChangeCallback( |
97 NewCallback(processor_.get(), | 230 NewCallback(processor_.get(), |
98 &gpu::GPUProcessor::ProcessCommands)); | 231 &gpu::GPUProcessor::ProcessCommands)); |
99 processor_->SetSwapBuffersCallback( | 232 processor_->SetSwapBuffersCallback( |
100 NewCallback(this, &GpuCommandBufferStub::OnSwapBuffers)); | 233 NewCallback(this, &GpuCommandBufferStub::OnSwapBuffers)); |
101 | 234 |
102 // Assume service is responsible for duplicating the handle from the | 235 // Assume service is responsible for duplicating the handle from the |
103 // calling process. | 236 // calling process. |
104 buffer.shared_memory->ShareToProcess(channel_->renderer_handle(), | 237 buffer.shared_memory->ShareToProcess(channel_->renderer_handle(), |
105 ring_buffer); | 238 ring_buffer); |
106 #if defined(OS_MACOSX) | 239 #if defined(OS_MACOSX) |
107 if (handle_) { | 240 if (handle_) { |
108 // This context conceptually puts its output directly on the | 241 // This context conceptually puts its output directly on the |
109 // screen, rendered by the accelerated plugin layer in | 242 // screen, rendered by the accelerated plugin layer in |
110 // RenderWidgetHostViewMac. Set up a pathway to notify the | 243 // RenderWidgetHostViewMac. Set up a pathway to notify the |
111 // browser process when its contents change. | 244 // browser process when its contents change. |
112 processor_->SetSwapBuffersCallback( | 245 processor_->SetSwapBuffersCallback( |
113 NewCallback(this, | 246 NewCallback(this, |
114 &GpuCommandBufferStub::SwapBuffersCallback)); | 247 &GpuCommandBufferStub::SwapBuffersCallback)); |
115 } | 248 } |
116 #elif defined(OS_LINUX) | 249 #elif defined(OS_LINUX) || defined(OS_WIN) |
117 if (handle_) { | 250 if (handle_) { |
118 // Set up a pathway to allow the Gpu process to ask the browser | 251 // Set up a pathway for resizing the output window at the right time |
119 // for a window resize. | 252 // relative to other GL commands. |
120 processor_->SetResizeCallback( | 253 processor_->SetResizeCallback( |
121 NewCallback(this, | 254 NewCallback(this, |
122 &GpuCommandBufferStub::ResizeCallback)); | 255 &GpuCommandBufferStub::ResizeCallback)); |
123 } | 256 } |
124 #endif | 257 #endif |
125 } else { | 258 } else { |
126 processor_.reset(); | 259 processor_.reset(); |
127 command_buffer_.reset(); | 260 command_buffer_.reset(); |
128 } | 261 } |
129 } | 262 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 } | 353 } |
221 | 354 |
222 void GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped( | 355 void GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped( |
223 uint64 swap_buffers_count) { | 356 uint64 swap_buffers_count) { |
224 processor_->set_acknowledged_swap_buffers_count(swap_buffers_count); | 357 processor_->set_acknowledged_swap_buffers_count(swap_buffers_count); |
225 // Wake up the GpuProcessor to start doing work again. | 358 // Wake up the GpuProcessor to start doing work again. |
226 processor_->ScheduleProcessCommands(); | 359 processor_->ScheduleProcessCommands(); |
227 } | 360 } |
228 #endif // defined(OS_MACOSX) | 361 #endif // defined(OS_MACOSX) |
229 | 362 |
| 363 void GpuCommandBufferStub::ResizeCallback(gfx::Size size) { |
| 364 if (handle_ == gfx::kNullPluginWindow) |
| 365 return; |
| 366 |
230 #if defined(OS_LINUX) | 367 #if defined(OS_LINUX) |
231 void GpuCommandBufferStub::ResizeCallback(gfx::Size size) { | |
232 ChildThread* gpu_thread = ChildThread::current(); | 368 ChildThread* gpu_thread = ChildThread::current(); |
233 bool result = false; | 369 bool result = false; |
234 gpu_thread->Send( | 370 gpu_thread->Send( |
235 new GpuHostMsg_ResizeXID(handle_, size, &result)); | 371 new GpuHostMsg_ResizeXID(handle_, size, &result)); |
| 372 #elif defined(OS_WIN) |
| 373 HWND hwnd = static_cast<HWND>(compositor_window_); |
| 374 UINT swp_flags = SWP_NOSENDCHANGING | SWP_NOOWNERZORDER | SWP_NOCOPYBITS | |
| 375 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE; |
| 376 SetWindowPos(hwnd, NULL, 0, 0, size.width(), size.height(), swp_flags); |
| 377 #endif |
236 } | 378 } |
237 #endif // defined(OS_LINUX) | |
238 | 379 |
239 #endif // ENABLE_GPU | 380 #endif // ENABLE_GPU |
OLD | NEW |