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 |