Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: chrome/gpu/gpu_command_buffer_stub.cc

Issue 6684015: Move chrome\gpu to content\gpu. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/gpu/gpu_command_buffer_stub.h ('k') | chrome/gpu/gpu_config.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #if defined(ENABLE_GPU)
6
7 #include "base/process_util.h"
8 #include "base/shared_memory.h"
9 #include "build/build_config.h"
10 #include "chrome/gpu/gpu_channel.h"
11 #include "chrome/gpu/gpu_command_buffer_stub.h"
12 #include "chrome/gpu/gpu_thread.h"
13 #include "content/common/child_thread.h"
14 #include "content/common/gpu_messages.h"
15
16 using gpu::Buffer;
17
18 #if defined(OS_WIN)
19 #define kCompositorWindowOwner L"CompositorWindowOwner"
20 #endif // defined(OS_WIN)
21
22 GpuCommandBufferStub::GpuCommandBufferStub(
23 GpuChannel* channel,
24 gfx::PluginWindowHandle handle,
25 GpuCommandBufferStub* parent,
26 const gfx::Size& size,
27 const std::string& allowed_extensions,
28 const std::vector<int32>& attribs,
29 uint32 parent_texture_id,
30 int32 route_id,
31 int32 renderer_id,
32 int32 render_view_id)
33 : channel_(channel),
34 handle_(handle),
35 parent_(
36 parent ? parent->AsWeakPtr() : base::WeakPtr<GpuCommandBufferStub>()),
37 initial_size_(size),
38 allowed_extensions_(allowed_extensions),
39 requested_attribs_(attribs),
40 parent_texture_id_(parent_texture_id),
41 route_id_(route_id),
42 #if defined(OS_WIN)
43 compositor_window_(NULL),
44 #endif // defined(OS_WIN)
45 renderer_id_(renderer_id),
46 render_view_id_(render_view_id) {
47 }
48
49 #if defined(OS_WIN)
50 static LRESULT CALLBACK CompositorWindowProc(
51 HWND hwnd,
52 UINT message,
53 WPARAM wparam,
54 LPARAM lparam) {
55 switch (message) {
56 case WM_ERASEBKGND:
57 return 0;
58 case WM_DESTROY:
59 RemoveProp(hwnd, kCompositorWindowOwner);
60 return 0;
61 case WM_PAINT: {
62 PAINTSTRUCT paint;
63 HDC dc = BeginPaint(hwnd, &paint);
64 if (dc) {
65 HANDLE h = GetProp(hwnd, kCompositorWindowOwner);
66 if (h) {
67 GpuCommandBufferStub* stub =
68 reinterpret_cast<GpuCommandBufferStub*>(h);
69 stub->OnCompositorWindowPainted();
70 }
71 EndPaint(hwnd, &paint);
72 }
73 break;
74 }
75 default:
76 return DefWindowProc(hwnd, message, wparam, lparam);
77 }
78 return 0;
79 }
80
81 bool GpuCommandBufferStub::CreateCompositorWindow() {
82 DCHECK(handle_ != gfx::kNullPluginWindow);
83 HWND host_window = static_cast<HWND>(handle_);
84
85 // Create the compositor window itself.
86 DCHECK(host_window);
87 static ATOM window_class = 0;
88 if (!window_class) {
89 WNDCLASSEX wcex;
90 wcex.cbSize = sizeof(wcex);
91 wcex.style = 0;
92 wcex.lpfnWndProc = CompositorWindowProc;
93 wcex.cbClsExtra = 0;
94 wcex.cbWndExtra = 0;
95 wcex.hInstance = GetModuleHandle(NULL);
96 wcex.hIcon = 0;
97 wcex.hCursor = 0;
98 wcex.hbrBackground = NULL;
99 wcex.lpszMenuName = 0;
100 wcex.lpszClassName = L"CompositorWindowClass";
101 wcex.hIconSm = 0;
102 window_class = RegisterClassEx(&wcex);
103 DCHECK(window_class);
104 }
105
106 HWND compositor_window = CreateWindowEx(
107 WS_EX_LEFT | WS_EX_LTRREADING | WS_EX_RIGHTSCROLLBAR,
108 MAKEINTATOM(window_class),
109 0,
110 WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_DISABLED,
111 0, 0,
112 0, 0,
113 host_window,
114 0,
115 GetModuleHandle(NULL),
116 0);
117 if (!compositor_window) {
118 compositor_window_ = gfx::kNullPluginWindow;
119 return false;
120 }
121 SetProp(compositor_window, kCompositorWindowOwner,
122 reinterpret_cast<HANDLE>(this));
123
124 RECT parent_rect;
125 GetClientRect(host_window, &parent_rect);
126
127 UINT flags = SWP_NOSENDCHANGING | SWP_NOCOPYBITS | SWP_NOZORDER |
128 SWP_NOACTIVATE | SWP_DEFERERASE | SWP_SHOWWINDOW;
129 SetWindowPos(compositor_window,
130 NULL,
131 0, 0,
132 parent_rect.right - parent_rect.left,
133 parent_rect.bottom - parent_rect.top,
134 flags);
135 compositor_window_ = static_cast<gfx::PluginWindowHandle>(compositor_window);
136 return true;
137 }
138
139 void GpuCommandBufferStub::OnCompositorWindowPainted() {
140 GpuThread* gpu_thread = channel_->gpu_thread();
141 gpu_thread->Send(new GpuHostMsg_ScheduleComposite(
142 renderer_id_, render_view_id_));
143 }
144 #endif // defined(OS_WIN)
145
146
147 GpuCommandBufferStub::~GpuCommandBufferStub() {
148 if (processor_.get()) {
149 processor_->Destroy();
150 }
151 #if defined(OS_WIN)
152 if (compositor_window_) {
153 DestroyWindow(static_cast<HWND>(compositor_window_));
154 compositor_window_ = NULL;
155 }
156 #endif // defined(OS_WIN)
157
158 GpuThread* gpu_thread = channel_->gpu_thread();
159 gpu_thread->Send(new GpuHostMsg_DestroyCommandBuffer(
160 handle_, renderer_id_, render_view_id_));
161 }
162
163 bool GpuCommandBufferStub::OnMessageReceived(const IPC::Message& message) {
164 bool handled = true;
165 IPC_BEGIN_MESSAGE_MAP(GpuCommandBufferStub, message)
166 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Initialize, OnInitialize);
167 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetState, OnGetState);
168 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncGetState, OnAsyncGetState);
169 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_Flush, OnFlush);
170 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_AsyncFlush, OnAsyncFlush);
171 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_CreateTransferBuffer,
172 OnCreateTransferBuffer);
173 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_RegisterTransferBuffer,
174 OnRegisterTransferBuffer);
175 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_DestroyTransferBuffer,
176 OnDestroyTransferBuffer);
177 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_GetTransferBuffer,
178 OnGetTransferBuffer);
179 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_ResizeOffscreenFrameBuffer,
180 OnResizeOffscreenFrameBuffer);
181 #if defined(OS_MACOSX)
182 IPC_MESSAGE_HANDLER(GpuCommandBufferMsg_SetWindowSize, OnSetWindowSize);
183 #endif // defined(OS_MACOSX)
184 IPC_MESSAGE_UNHANDLED(handled = false)
185 IPC_END_MESSAGE_MAP()
186 DCHECK(handled);
187 return handled;
188 }
189
190 bool GpuCommandBufferStub::Send(IPC::Message* message) {
191 return channel_->Send(message);
192 }
193
194 void GpuCommandBufferStub::OnInitialize(
195 base::SharedMemoryHandle ring_buffer,
196 int32 size,
197 bool* result) {
198 DCHECK(!command_buffer_.get());
199
200 *result = false;
201
202 command_buffer_.reset(new gpu::CommandBufferService);
203
204 // Create the child window, if needed
205 #if defined(OS_WIN)
206 gfx::PluginWindowHandle output_window_handle;
207 if (handle_) {
208 if (!CreateCompositorWindow()) {
209 return;
210 }
211 output_window_handle = compositor_window_;
212 } else {
213 output_window_handle = handle_;
214 }
215 #else
216 gfx::PluginWindowHandle output_window_handle = handle_;
217 #endif // defined(OS_WIN)
218
219 #if defined(OS_WIN)
220 // Windows dups the shared memory handle it receives into the current process
221 // and closes it when this variable goes out of scope.
222 base::SharedMemory shared_memory(ring_buffer,
223 false,
224 channel_->renderer_process());
225 #else
226 // POSIX receives a dup of the shared memory handle and closes the dup when
227 // this variable goes out of scope.
228 base::SharedMemory shared_memory(ring_buffer, false);
229 #endif
230
231 // Initialize the CommandBufferService and GPUProcessor.
232 if (command_buffer_->Initialize(&shared_memory, size)) {
233 gpu::GPUProcessor* parent_processor =
234 parent_ ? parent_->processor_.get() : NULL;
235 processor_.reset(new gpu::GPUProcessor(command_buffer_.get(), NULL));
236 if (processor_->Initialize(
237 output_window_handle,
238 initial_size_,
239 allowed_extensions_.c_str(),
240 requested_attribs_,
241 parent_processor,
242 parent_texture_id_)) {
243 command_buffer_->SetPutOffsetChangeCallback(
244 NewCallback(processor_.get(),
245 &gpu::GPUProcessor::ProcessCommands));
246 processor_->SetSwapBuffersCallback(
247 NewCallback(this, &GpuCommandBufferStub::OnSwapBuffers));
248
249 #if defined(OS_MACOSX)
250 if (handle_) {
251 // This context conceptually puts its output directly on the
252 // screen, rendered by the accelerated plugin layer in
253 // RenderWidgetHostViewMac. Set up a pathway to notify the
254 // browser process when its contents change.
255 processor_->SetSwapBuffersCallback(
256 NewCallback(this,
257 &GpuCommandBufferStub::SwapBuffersCallback));
258 }
259 #endif // defined(OS_MACOSX)
260
261 // Set up a pathway for resizing the output window or framebuffer at the
262 // right time relative to other GL commands.
263 processor_->SetResizeCallback(
264 NewCallback(this, &GpuCommandBufferStub::ResizeCallback));
265
266 *result = true;
267 } else {
268 processor_.reset();
269 command_buffer_.reset();
270 }
271 }
272 }
273
274 void GpuCommandBufferStub::OnGetState(gpu::CommandBuffer::State* state) {
275 *state = command_buffer_->GetState();
276 }
277
278 void GpuCommandBufferStub::OnAsyncGetState() {
279 gpu::CommandBuffer::State state = command_buffer_->GetState();
280 Send(new GpuCommandBufferMsg_UpdateState(route_id_, state));
281 }
282
283 void GpuCommandBufferStub::OnFlush(int32 put_offset,
284 gpu::CommandBuffer::State* state) {
285 #if defined(OS_MACOSX)
286 // See comment in |DidDestroySurface()| in gpu_processor_mac.cc.
287 if (channel_->IsRenderViewGone(render_view_id_))
288 processor_->DidDestroySurface();
289 #endif
290 *state = command_buffer_->FlushSync(put_offset);
291 }
292
293 void GpuCommandBufferStub::OnAsyncFlush(int32 put_offset) {
294 gpu::CommandBuffer::State state = command_buffer_->FlushSync(put_offset);
295 Send(new GpuCommandBufferMsg_UpdateState(route_id_, state));
296 }
297
298 void GpuCommandBufferStub::OnCreateTransferBuffer(int32 size, int32* id) {
299 *id = command_buffer_->CreateTransferBuffer(size);
300 }
301
302 void GpuCommandBufferStub::OnRegisterTransferBuffer(
303 base::SharedMemoryHandle transfer_buffer,
304 size_t size,
305 int32* id) {
306 #if defined(OS_WIN)
307 // Windows dups the shared memory handle it receives into the current process
308 // and closes it when this variable goes out of scope.
309 base::SharedMemory shared_memory(transfer_buffer,
310 false,
311 channel_->renderer_process());
312 #else
313 // POSIX receives a dup of the shared memory handle and closes the dup when
314 // this variable goes out of scope.
315 base::SharedMemory shared_memory(transfer_buffer, false);
316 #endif
317
318 *id = command_buffer_->RegisterTransferBuffer(&shared_memory, size);
319 }
320
321 void GpuCommandBufferStub::OnDestroyTransferBuffer(int32 id) {
322 command_buffer_->DestroyTransferBuffer(id);
323 }
324
325 void GpuCommandBufferStub::OnGetTransferBuffer(
326 int32 id,
327 base::SharedMemoryHandle* transfer_buffer,
328 uint32* size) {
329 *transfer_buffer = base::SharedMemoryHandle();
330 *size = 0;
331
332 // Fail if the renderer process has not provided its process handle.
333 if (!channel_->renderer_process())
334 return;
335
336 Buffer buffer = command_buffer_->GetTransferBuffer(id);
337 if (buffer.shared_memory) {
338 // Assume service is responsible for duplicating the handle to the calling
339 // process.
340 buffer.shared_memory->ShareToProcess(channel_->renderer_process(),
341 transfer_buffer);
342 *size = buffer.size;
343 }
344 }
345
346 void GpuCommandBufferStub::OnResizeOffscreenFrameBuffer(const gfx::Size& size) {
347 processor_->ResizeOffscreenFrameBuffer(size);
348 }
349
350 void GpuCommandBufferStub::OnSwapBuffers() {
351 Send(new GpuCommandBufferMsg_SwapBuffers(route_id_));
352 }
353
354 #if defined(OS_MACOSX)
355 void GpuCommandBufferStub::OnSetWindowSize(const gfx::Size& size) {
356 GpuThread* gpu_thread = channel_->gpu_thread();
357 // Try using the IOSurface version first.
358 uint64 new_backing_store = processor_->SetWindowSizeForIOSurface(size);
359 if (new_backing_store) {
360 GpuHostMsg_AcceleratedSurfaceSetIOSurface_Params params;
361 params.renderer_id = renderer_id_;
362 params.render_view_id = render_view_id_;
363 params.window = handle_;
364 params.width = size.width();
365 params.height = size.height();
366 params.identifier = new_backing_store;
367 gpu_thread->Send(new GpuHostMsg_AcceleratedSurfaceSetIOSurface(params));
368 } else {
369 // TODO(kbr): figure out what to do here. It wouldn't be difficult
370 // to support the compositor on 10.5, but the performance would be
371 // questionable.
372 NOTREACHED();
373 }
374 }
375
376 void GpuCommandBufferStub::SwapBuffersCallback() {
377 OnSwapBuffers();
378 GpuThread* gpu_thread = channel_->gpu_thread();
379 GpuHostMsg_AcceleratedSurfaceBuffersSwapped_Params params;
380 params.renderer_id = renderer_id_;
381 params.render_view_id = render_view_id_;
382 params.window = handle_;
383 params.surface_id = processor_->GetSurfaceId();
384 params.route_id = route_id();
385 params.swap_buffers_count = processor_->swap_buffers_count();
386 gpu_thread->Send(new GpuHostMsg_AcceleratedSurfaceBuffersSwapped(params));
387 }
388
389 void GpuCommandBufferStub::AcceleratedSurfaceBuffersSwapped(
390 uint64 swap_buffers_count) {
391 processor_->set_acknowledged_swap_buffers_count(swap_buffers_count);
392 // Wake up the GpuProcessor to start doing work again.
393 processor_->ScheduleProcessCommands();
394 }
395 #endif // defined(OS_MACOSX)
396
397 void GpuCommandBufferStub::ResizeCallback(gfx::Size size) {
398 if (handle_ == gfx::kNullPluginWindow) {
399 processor_->decoder()->ResizeOffscreenFrameBuffer(size);
400 processor_->decoder()->UpdateOffscreenFrameBufferSize();
401 } else {
402 #if defined(OS_LINUX) && !defined(TOUCH_UI)
403 GpuThread* gpu_thread = channel_->gpu_thread();
404 bool result = false;
405 gpu_thread->Send(
406 new GpuHostMsg_ResizeXID(handle_, size, &result));
407 #elif defined(OS_WIN)
408 HWND hwnd = static_cast<HWND>(compositor_window_);
409 UINT swp_flags = SWP_NOSENDCHANGING | SWP_NOOWNERZORDER | SWP_NOCOPYBITS |
410 SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_DEFERERASE;
411 SetWindowPos(hwnd, NULL, 0, 0, size.width(), size.height(), swp_flags);
412 #endif // defined(OS_LINUX)
413 }
414 }
415
416 #endif // defined(ENABLE_GPU)
OLDNEW
« no previous file with comments | « chrome/gpu/gpu_command_buffer_stub.h ('k') | chrome/gpu/gpu_config.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698