blob: 8e48b858733c408991b01d9b75832e7814166551 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "chrome/renderer/gpu_channel_host.h"
#include "chrome/common/child_process.h"
#include "chrome/common/gpu_messages.h"
#include "chrome/renderer/command_buffer_proxy.h"
GpuChannelHost::GpuChannelHost() : state_(UNCONNECTED) {
}
GpuChannelHost::~GpuChannelHost() {
}
void GpuChannelHost::Connect(const std::string& channel_name) {
// Open a channel to the GPU process.
channel_.reset(new IPC::SyncChannel(
channel_name, IPC::Channel::MODE_CLIENT, this, NULL,
ChildProcess::current()->io_message_loop(), true,
ChildProcess::current()->GetShutDownEvent()));
}
void GpuChannelHost::OnMessageReceived(const IPC::Message& message) {
DCHECK(message.routing_id() != MSG_ROUTING_CONTROL);
if (!router_.RouteMessage(message)) {
NOTREACHED() << "GpuChannelHost failed to route message";
}
}
void GpuChannelHost::OnChannelConnected(int32 peer_pid) {
state_ = CONNECTED;
}
void GpuChannelHost::OnChannelError() {
state_ = LOST;
// Channel is invalid and will be reinitialized if this host is requested
// again.
channel_.reset();
// Inform all the proxies that an error has occured. This will be reported via
// OpenGL as a lost context.
for (ProxyMap::iterator iter = proxies_.begin();
iter != proxies_.end(); iter++) {
proxies_.erase(iter->first);
router_.RemoveRoute(iter->first);
iter->second->OnChannelError();
}
// The proxies are reference counted so this will not result in their
// destruction if the client still holds a reference. The proxy will report
// a lost context, indicating to the client that it needs to be recreated.
proxies_.clear();
}
bool GpuChannelHost::Send(IPC::Message* message) {
if (!channel_.get()) {
delete message;
return false;
}
return channel_->Send(message);
}
CommandBufferProxy* GpuChannelHost::CreateCommandBuffer() {
#if defined(ENABLE_GPU)
// An error occurred. Need to get the host again to reinitialize it.
if (!channel_.get())
return NULL;
int32 route_id;
if (!Send(new GpuChannelMsg_CreateCommandBuffer(&route_id)) &&
route_id != MSG_ROUTING_NONE) {
return NULL;
}
CommandBufferProxy* command_buffer = new CommandBufferProxy(this, route_id);
router_.AddRoute(route_id, command_buffer);
proxies_[route_id] = command_buffer;
return command_buffer;
#else
return NULL;
#endif
}
void GpuChannelHost::DestroyCommandBuffer(CommandBufferProxy* command_buffer) {
#if defined(ENABLE_GPU)
Send(new GpuChannelMsg_DestroyCommandBuffer(command_buffer->route_id()));
// Check the proxy has not already been removed after a channel error.
int route_id = command_buffer->route_id();
if (proxies_.find(command_buffer->route_id()) != proxies_.end()) {
proxies_.erase(route_id);
router_.RemoveRoute(route_id);
}
delete command_buffer;
#endif
}
|