OLD | NEW |
| (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 #include "chrome/renderer/gpu_channel_host.h" | |
6 | |
7 #include "chrome/renderer/command_buffer_proxy.h" | |
8 #include "chrome/renderer/gpu_video_service_host.h" | |
9 #include "chrome/renderer/render_thread.h" | |
10 #include "content/common/child_process.h" | |
11 #include "content/common/gpu_messages.h" | |
12 | |
13 GpuChannelHost::GpuChannelHost() : state_(kUnconnected) { | |
14 } | |
15 | |
16 GpuChannelHost::~GpuChannelHost() { | |
17 } | |
18 | |
19 void GpuChannelHost::Connect( | |
20 const IPC::ChannelHandle& channel_handle, | |
21 base::ProcessHandle renderer_process_for_gpu) { | |
22 // Open a channel to the GPU process. | |
23 channel_.reset(new IPC::SyncChannel( | |
24 channel_handle, IPC::Channel::MODE_CLIENT, this, | |
25 ChildProcess::current()->io_message_loop(), true, | |
26 ChildProcess::current()->GetShutDownEvent())); | |
27 | |
28 // It is safe to send IPC messages before the channel completes the connection | |
29 // and receives the hello message from the GPU process. The messages get | |
30 // cached. | |
31 state_ = kConnected; | |
32 | |
33 // Notify the GPU process of our process handle. This gives it the ability | |
34 // to map renderer handles into the GPU process. | |
35 Send(new GpuChannelMsg_Initialize(renderer_process_for_gpu)); | |
36 } | |
37 | |
38 void GpuChannelHost::set_gpu_info(const GPUInfo& gpu_info) { | |
39 gpu_info_ = gpu_info; | |
40 } | |
41 | |
42 const GPUInfo& GpuChannelHost::gpu_info() const { | |
43 return gpu_info_; | |
44 } | |
45 | |
46 void GpuChannelHost::SetStateLost() { | |
47 state_ = kLost; | |
48 } | |
49 | |
50 bool GpuChannelHost::OnMessageReceived(const IPC::Message& message) { | |
51 DCHECK(message.routing_id() != MSG_ROUTING_CONTROL); | |
52 | |
53 // The object to which the message is addressed might have been destroyed. | |
54 // This is expected, for example an asynchronous SwapBuffers notification | |
55 // to a command buffer proxy that has since been destroyed. This function | |
56 // fails silently in that case. | |
57 return router_.RouteMessage(message); | |
58 } | |
59 | |
60 void GpuChannelHost::OnChannelConnected(int32 peer_pid) { | |
61 // When the channel is connected we create a GpuVideoServiceHost and add it | |
62 // as a message filter. | |
63 gpu_video_service_host_ = new GpuVideoServiceHost(); | |
64 channel_->AddFilter(gpu_video_service_host_.get()); | |
65 } | |
66 | |
67 void GpuChannelHost::OnChannelError() { | |
68 state_ = kLost; | |
69 | |
70 // Channel is invalid and will be reinitialized if this host is requested | |
71 // again. | |
72 channel_.reset(); | |
73 | |
74 // Inform all the proxies that an error has occured. This will be reported via | |
75 // OpenGL as a lost context. | |
76 for (ProxyMap::iterator iter = proxies_.begin(); | |
77 iter != proxies_.end(); iter++) { | |
78 router_.RemoveRoute(iter->first); | |
79 iter->second->OnChannelError(); | |
80 } | |
81 | |
82 // The proxies are reference counted so this will not result in their | |
83 // destruction if the client still holds a reference. The proxy will report | |
84 // a lost context, indicating to the client that it needs to be recreated. | |
85 proxies_.clear(); | |
86 } | |
87 | |
88 bool GpuChannelHost::Send(IPC::Message* message) { | |
89 if (channel_.get()) | |
90 return channel_->Send(message); | |
91 | |
92 // Callee takes ownership of message, regardless of whether Send is | |
93 // successful. See IPC::Message::Sender. | |
94 delete message; | |
95 return false; | |
96 } | |
97 | |
98 CommandBufferProxy* GpuChannelHost::CreateViewCommandBuffer( | |
99 int render_view_id, | |
100 const std::string& allowed_extensions, | |
101 const std::vector<int32>& attribs) { | |
102 #if defined(ENABLE_GPU) | |
103 // An error occurred. Need to get the host again to reinitialize it. | |
104 if (!channel_.get()) | |
105 return NULL; | |
106 | |
107 GPUCreateCommandBufferConfig init_params; | |
108 init_params.allowed_extensions = allowed_extensions; | |
109 init_params.attribs = attribs; | |
110 int32 route_id; | |
111 if (!RenderThread::current()->Send( | |
112 new GpuHostMsg_CreateViewCommandBuffer( | |
113 render_view_id, init_params, &route_id))) { | |
114 return NULL; | |
115 } | |
116 | |
117 if (route_id == MSG_ROUTING_NONE) | |
118 return NULL; | |
119 | |
120 CommandBufferProxy* command_buffer = new CommandBufferProxy(this, route_id); | |
121 router_.AddRoute(route_id, command_buffer); | |
122 proxies_[route_id] = command_buffer; | |
123 return command_buffer; | |
124 #else | |
125 return NULL; | |
126 #endif | |
127 } | |
128 | |
129 CommandBufferProxy* GpuChannelHost::CreateOffscreenCommandBuffer( | |
130 CommandBufferProxy* parent, | |
131 const gfx::Size& size, | |
132 const std::string& allowed_extensions, | |
133 const std::vector<int32>& attribs, | |
134 uint32 parent_texture_id) { | |
135 #if defined(ENABLE_GPU) | |
136 // An error occurred. Need to get the host again to reinitialize it. | |
137 if (!channel_.get()) | |
138 return NULL; | |
139 | |
140 GPUCreateCommandBufferConfig init_params; | |
141 init_params.allowed_extensions = allowed_extensions; | |
142 init_params.attribs = attribs; | |
143 int32 parent_route_id = parent ? parent->route_id() : 0; | |
144 int32 route_id; | |
145 if (!Send(new GpuChannelMsg_CreateOffscreenCommandBuffer(parent_route_id, | |
146 size, | |
147 init_params, | |
148 parent_texture_id, | |
149 &route_id))) { | |
150 return NULL; | |
151 } | |
152 | |
153 if (route_id == MSG_ROUTING_NONE) | |
154 return NULL; | |
155 | |
156 CommandBufferProxy* command_buffer = new CommandBufferProxy(this, route_id); | |
157 router_.AddRoute(route_id, command_buffer); | |
158 proxies_[route_id] = command_buffer; | |
159 return command_buffer; | |
160 #else | |
161 return NULL; | |
162 #endif | |
163 } | |
164 | |
165 void GpuChannelHost::DestroyCommandBuffer(CommandBufferProxy* command_buffer) { | |
166 #if defined(ENABLE_GPU) | |
167 Send(new GpuChannelMsg_DestroyCommandBuffer(command_buffer->route_id())); | |
168 | |
169 // Check the proxy has not already been removed after a channel error. | |
170 int route_id = command_buffer->route_id(); | |
171 if (proxies_.find(command_buffer->route_id()) != proxies_.end()) { | |
172 proxies_.erase(route_id); | |
173 router_.RemoveRoute(route_id); | |
174 } | |
175 | |
176 delete command_buffer; | |
177 #endif | |
178 } | |
OLD | NEW |