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