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 #include "chrome/browser/gpu_process_host.h" | 5 #include "chrome/browser/gpu_process_host.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/singleton.h" | 8 #include "base/singleton.h" |
9 #include "base/thread.h" | 9 #include "base/thread.h" |
10 #include "chrome/browser/browser_process.h" | 10 #include "chrome/browser/browser_process.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 #elif defined(POSIX) | 55 #elif defined(POSIX) |
56 false, // Never use the zygote (GPU plugin can't be sandboxed). | 56 false, // Never use the zygote (GPU plugin can't be sandboxed). |
57 base::environment_vector(), | 57 base::environment_vector(), |
58 channel_->GetClientFileDescriptor(), | 58 channel_->GetClientFileDescriptor(), |
59 #endif | 59 #endif |
60 cmd_line, | 60 cmd_line, |
61 this)); | 61 this)); |
62 } | 62 } |
63 | 63 |
64 GpuProcessHost::~GpuProcessHost() { | 64 GpuProcessHost::~GpuProcessHost() { |
| 65 while (!queued_synchronization_replies_.empty()) { |
| 66 delete queued_synchronization_replies_.front(); |
| 67 queued_synchronization_replies_.pop(); |
| 68 } |
65 } | 69 } |
66 | 70 |
67 // static | 71 // static |
68 GpuProcessHost* GpuProcessHost::Get() { | 72 GpuProcessHost* GpuProcessHost::Get() { |
69 GpuProcessHost* host = Singleton<GpuProcessHost>::get(); | 73 GpuProcessHost* host = Singleton<GpuProcessHost>::get(); |
70 if (!host->child_process_.get()) | 74 if (!host->child_process_.get()) |
71 return NULL; // Failed to init. | 75 return NULL; // Failed to init. |
72 return host; | 76 return host; |
73 } | 77 } |
74 | 78 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 router_.RemoveRoute(routing_id); | 130 router_.RemoveRoute(routing_id); |
127 } | 131 } |
128 | 132 |
129 void GpuProcessHost::EstablishGpuChannel(int renderer_id) { | 133 void GpuProcessHost::EstablishGpuChannel(int renderer_id) { |
130 if (Send(new GpuMsg_EstablishChannel(renderer_id))) | 134 if (Send(new GpuMsg_EstablishChannel(renderer_id))) |
131 sent_requests_.push(ChannelRequest(renderer_id)); | 135 sent_requests_.push(ChannelRequest(renderer_id)); |
132 else | 136 else |
133 ReplyToRenderer(renderer_id, IPC::ChannelHandle()); | 137 ReplyToRenderer(renderer_id, IPC::ChannelHandle()); |
134 } | 138 } |
135 | 139 |
| 140 void GpuProcessHost::Synchronize(int renderer_id, IPC::Message* reply) { |
| 141 // ************ |
| 142 // TODO(kbr): the handling of this synchronous message (which is |
| 143 // needed for proper initialization semantics of APIs like WebGL) is |
| 144 // currently broken on Windows because the renderer is sending a |
| 145 // synchronous message to the browser's UI thread. To fix this, the |
| 146 // GpuProcessHost needs to move to the IO thread, and any backing |
| 147 // store handling needs to remain on the UI thread in a new |
| 148 // GpuProcessHostProxy, where work is sent from the IO thread to the |
| 149 // UI thread via PostTask. |
| 150 // ************ |
| 151 queued_synchronization_replies_.push(reply); |
| 152 CHECK(Send(new GpuMsg_Synchronize(renderer_id))); |
| 153 } |
| 154 |
136 void GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) { | 155 void GpuProcessHost::OnControlMessageReceived(const IPC::Message& message) { |
137 IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message) | 156 IPC_BEGIN_MESSAGE_MAP(GpuProcessHost, message) |
138 IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished, OnChannelEstablished) | 157 IPC_MESSAGE_HANDLER(GpuHostMsg_ChannelEstablished, OnChannelEstablished) |
| 158 IPC_MESSAGE_HANDLER(GpuHostMsg_SynchronizeReply, OnSynchronizeReply) |
139 IPC_MESSAGE_UNHANDLED_ERROR() | 159 IPC_MESSAGE_UNHANDLED_ERROR() |
140 IPC_END_MESSAGE_MAP() | 160 IPC_END_MESSAGE_MAP() |
141 } | 161 } |
142 | 162 |
143 void GpuProcessHost::OnChannelEstablished( | 163 void GpuProcessHost::OnChannelEstablished( |
144 const IPC::ChannelHandle& channel_handle) { | 164 const IPC::ChannelHandle& channel_handle) { |
145 const ChannelRequest& request = sent_requests_.front(); | 165 const ChannelRequest& request = sent_requests_.front(); |
146 | 166 |
147 ReplyToRenderer(request.renderer_id, channel_handle); | 167 ReplyToRenderer(request.renderer_id, channel_handle); |
148 sent_requests_.pop(); | 168 sent_requests_.pop(); |
149 } | 169 } |
150 | 170 |
| 171 void GpuProcessHost::OnSynchronizeReply(int renderer_id) { |
| 172 IPC::Message* reply = queued_synchronization_replies_.front(); |
| 173 queued_synchronization_replies_.pop(); |
| 174 RenderProcessHost* process_host = RenderProcessHost::FromID(renderer_id); |
| 175 if (!process_host) { |
| 176 delete reply; |
| 177 return; |
| 178 } |
| 179 CHECK(process_host->Send(reply)); |
| 180 } |
| 181 |
151 void GpuProcessHost::ReplyToRenderer( | 182 void GpuProcessHost::ReplyToRenderer( |
152 int renderer_id, | 183 int renderer_id, |
153 const IPC::ChannelHandle& channel) { | 184 const IPC::ChannelHandle& channel) { |
154 // Check whether the renderer process is still around. | 185 // Check whether the renderer process is still around. |
155 RenderProcessHost* process_host = RenderProcessHost::FromID(renderer_id); | 186 RenderProcessHost* process_host = RenderProcessHost::FromID(renderer_id); |
156 if (!process_host) | 187 if (!process_host) |
157 return; | 188 return; |
158 | 189 |
159 CHECK(process_host->Send(new ViewMsg_GpuChannelEstablished(channel))); | 190 ViewMsg_GpuChannelEstablished* msg = |
| 191 new ViewMsg_GpuChannelEstablished(channel); |
| 192 // If the renderer process is performing synchronous initialization, |
| 193 // it needs to handle this message before receiving the reply for |
| 194 // the synchronous ViewHostMsg_SynchronizeGpu message. |
| 195 msg->set_unblock(true); |
| 196 CHECK(process_host->Send(msg)); |
160 } | 197 } |
161 | 198 |
162 void GpuProcessHost::PropagateBrowserCommandLineToGpu( | 199 void GpuProcessHost::PropagateBrowserCommandLineToGpu( |
163 const CommandLine& browser_cmd, | 200 const CommandLine& browser_cmd, |
164 CommandLine* gpu_cmd) const { | 201 CommandLine* gpu_cmd) const { |
165 // Propagate the following switches to the GPU process command line (along | 202 // Propagate the following switches to the GPU process command line (along |
166 // with any associated values) if present in the browser command line. | 203 // with any associated values) if present in the browser command line. |
167 static const char* const switch_names[] = { | 204 static const char* const switch_names[] = { |
168 switches::kDisableLogging, | 205 switches::kDisableLogging, |
169 switches::kEnableLogging, | 206 switches::kEnableLogging, |
170 switches::kGpuStartupDialog, | 207 switches::kGpuStartupDialog, |
171 switches::kLoggingLevel, | 208 switches::kLoggingLevel, |
172 }; | 209 }; |
173 | 210 |
174 for (size_t i = 0; i < arraysize(switch_names); ++i) { | 211 for (size_t i = 0; i < arraysize(switch_names); ++i) { |
175 if (browser_cmd.HasSwitch(switch_names[i])) { | 212 if (browser_cmd.HasSwitch(switch_names[i])) { |
176 gpu_cmd->AppendSwitchWithValue(switch_names[i], | 213 gpu_cmd->AppendSwitchWithValue(switch_names[i], |
177 browser_cmd.GetSwitchValueASCII(switch_names[i])); | 214 browser_cmd.GetSwitchValueASCII(switch_names[i])); |
178 } | 215 } |
179 } | 216 } |
180 } | 217 } |
OLD | NEW |