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 <GLES2/gl2.h> | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "content/renderer/transport_texture_host.h" | |
10 | |
11 // On Mac gl2.h clashes with gpu_messages.h and this problem hasn't been | |
12 // solved yet so exclude building on Mac. | |
13 #if !defined(OS_MACOSX) | |
14 | |
15 #include "base/message_loop.h" | |
16 #include "content/common/gpu/gpu_messages.h" | |
17 #include "content/renderer/renderer_gl_context.h" | |
18 #include "content/renderer/transport_texture_service.h" | |
19 | |
20 TransportTextureHost::TransportTextureHost(MessageLoop* io_message_loop, | |
21 MessageLoop* render_message_loop, | |
22 TransportTextureService* service, | |
23 IPC::Message::Sender* sender, | |
24 RendererGLContext* context, | |
25 int32 context_route_id, | |
26 int32 host_id) | |
27 : io_message_loop_(io_message_loop), | |
28 render_message_loop_(render_message_loop), | |
29 service_(service), | |
30 sender_(sender), | |
31 context_(context), | |
32 context_route_id_(context_route_id), | |
33 host_id_(host_id), | |
34 peer_id_(0) { | |
35 } | |
36 | |
37 TransportTextureHost::~TransportTextureHost() { | |
38 } | |
39 | |
40 void TransportTextureHost::Init(Task* done_task) { | |
41 if (MessageLoop::current() != io_message_loop_) { | |
42 io_message_loop_->PostTask( | |
43 FROM_HERE, | |
44 NewRunnableMethod(this, &TransportTextureHost::Init, done_task)); | |
45 return; | |
46 } | |
47 | |
48 init_task_.reset(done_task); | |
49 | |
50 // Send the message. | |
51 bool ret = sender_->Send( | |
52 new GpuChannelMsg_CreateTransportTexture(context_route_id_, host_id_)); | |
53 if (!ret) { | |
54 LOG(ERROR) << "GpuChannelMsg_CreateTransportTexture failed"; | |
55 init_task_->Run(); | |
56 init_task_.reset(); | |
57 } | |
58 } | |
59 | |
60 void TransportTextureHost::Destroy() { | |
61 ReleaseTexturesInternal(); | |
62 SendDestroyInternal(); | |
63 | |
64 service_->RemoveRoute(host_id_); | |
65 } | |
66 | |
67 void TransportTextureHost::GetTextures(TextureUpdateCallback* callback, | |
68 std::vector<int>* textures) { | |
69 textures->resize(textures_.size()); | |
70 std::copy(textures_.begin(), textures_.end(), textures->begin()); | |
71 update_callback_.reset(callback); | |
72 } | |
73 | |
74 int TransportTextureHost::GetPeerId() { | |
75 return peer_id_; | |
76 } | |
77 | |
78 void TransportTextureHost::OnChannelConnected(int32 peer_pid) { | |
79 } | |
80 | |
81 void TransportTextureHost::OnChannelError() { | |
82 } | |
83 | |
84 bool TransportTextureHost::OnMessageReceived(const IPC::Message& msg) { | |
85 bool handled = true; | |
86 IPC_BEGIN_MESSAGE_MAP(TransportTextureHost, msg) | |
87 IPC_MESSAGE_HANDLER(GpuTransportTextureHostMsg_TransportTextureCreated, | |
88 OnTransportTextureCreated) | |
89 IPC_MESSAGE_HANDLER(GpuTransportTextureHostMsg_CreateTextures, | |
90 OnCreateTextures) | |
91 IPC_MESSAGE_HANDLER(GpuTransportTextureHostMsg_ReleaseTextures, | |
92 OnReleaseTextures) | |
93 IPC_MESSAGE_HANDLER(GpuTransportTextureHostMsg_TextureUpdated, | |
94 OnTextureUpdated) | |
95 IPC_MESSAGE_UNHANDLED(handled = false) | |
96 IPC_END_MESSAGE_MAP() | |
97 DCHECK(handled); | |
98 return handled; | |
99 } | |
100 | |
101 void TransportTextureHost::ReleaseTexturesInternal() { | |
102 if (MessageLoop::current() != render_message_loop_) { | |
103 render_message_loop_->PostTask( | |
104 FROM_HERE, | |
105 NewRunnableMethod(this, | |
106 &TransportTextureHost::ReleaseTexturesInternal)); | |
107 return; | |
108 } | |
109 | |
110 scoped_array<GLuint> textures(new GLuint[textures_.size()]); | |
111 for (size_t i = 0; i < textures_.size(); ++i) | |
112 textures[i] = textures_[i]; | |
113 glDeleteTextures(textures_.size(), textures.get()); | |
114 } | |
115 | |
116 void TransportTextureHost::SendTexturesInternal(std::vector<int> textures) { | |
117 if (MessageLoop::current() != io_message_loop_) { | |
118 io_message_loop_->PostTask( | |
119 FROM_HERE, | |
120 NewRunnableMethod(this, &TransportTextureHost::SendTexturesInternal, | |
121 textures)); | |
122 return; | |
123 } | |
124 | |
125 bool ret = sender_->Send( | |
126 new GpuTransportTextureMsg_TexturesCreated(peer_id_, textures)); | |
127 if (!ret) { | |
128 LOG(ERROR) << "GpuTransportTextureMsg_TexturesCreated failed"; | |
129 } | |
130 } | |
131 | |
132 void TransportTextureHost::SendDestroyInternal() { | |
133 if (MessageLoop::current() != io_message_loop_) { | |
134 io_message_loop_->PostTask( | |
135 FROM_HERE, | |
136 NewRunnableMethod(this, &TransportTextureHost::SendDestroyInternal)); | |
137 return; | |
138 } | |
139 | |
140 bool ret = sender_->Send(new GpuTransportTextureMsg_Destroy(peer_id_)); | |
141 if (!ret) { | |
142 LOG(ERROR) << "GpuTransportTextureMsg_Destroy failed"; | |
143 } | |
144 } | |
145 | |
146 void TransportTextureHost::OnTransportTextureCreated(int32 peer_id) { | |
147 DCHECK_EQ(io_message_loop_, MessageLoop::current()); | |
148 | |
149 peer_id_ = peer_id; | |
150 init_task_->Run(); | |
151 init_task_.reset(); | |
152 } | |
153 | |
154 void TransportTextureHost::OnCreateTextures(int32 n, uint32 width, | |
155 uint32 height, int32 format) { | |
156 if (MessageLoop::current() != render_message_loop_) { | |
157 render_message_loop_->PostTask( | |
158 FROM_HERE, | |
159 NewRunnableMethod(this, &TransportTextureHost::OnCreateTextures, | |
160 n, width, height, format)); | |
161 return; | |
162 } | |
163 | |
164 // In this method we need to make the ggl context current and then generate | |
165 // textures for each video frame. We also need to allocate memory for each | |
166 // texture generated. | |
167 bool ret = RendererGLContext::MakeCurrent(context_); | |
168 CHECK(ret) << "Failed to switch context"; | |
169 | |
170 // TODO(hclam): Should do this through TextureManager instead of generating | |
171 // textures directly. | |
172 scoped_array<GLuint> textures(new GLuint[n]); | |
173 glGenTextures(n, textures.get()); | |
174 for (int i = 0; i < n; ++i) { | |
175 textures_.push_back(textures[i]); | |
176 } | |
177 glFinish(); | |
178 | |
179 // Send textures to the GPU process. | |
180 SendTexturesInternal(textures_); | |
181 } | |
182 | |
183 void TransportTextureHost::OnReleaseTextures() { | |
184 // This method will switch thread properly so just call it directly. | |
185 ReleaseTexturesInternal(); | |
186 } | |
187 | |
188 void TransportTextureHost::OnTextureUpdated(int texture_id) { | |
189 if (update_callback_.get()) | |
190 update_callback_->Run(texture_id); | |
191 } | |
192 | |
193 #endif | |
OLD | NEW |