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

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

Issue 4815001: Use inner HWND for accelerated rendering on windows (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 10 years 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/renderer/render_widget.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « chrome/gpu/gpu_command_buffer_stub.h ('k') | chrome/renderer/render_widget.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698