Blender modifications for Cycles integration.
[blender.git] / intern / cycles / device / device_network.cpp
1 /*
2  * Copyright 2011, Blender Foundation.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18
19 #include "device.h"
20 #include "device_intern.h"
21 #include "device_network.h"
22
23 #include "util_foreach.h"
24
25 CCL_NAMESPACE_BEGIN
26
27 #ifdef WITH_NETWORK
28
29 class NetworkDevice : public Device
30 {
31 public:
32         boost::asio::io_service io_service;
33         tcp::socket socket;
34
35         NetworkDevice(const char *address)
36         : socket(io_service)
37         {
38                 stringstream portstr;
39                 portstr << SERVER_PORT;
40
41                 tcp::resolver resolver(io_service);
42                 tcp::resolver::query query(address, portstr.str());
43                 tcp::resolver::iterator endpoint_iterator = resolver.resolve(query);
44                 tcp::resolver::iterator end;
45
46                 boost::system::error_code error = boost::asio::error::host_not_found;
47                 while(error && endpoint_iterator != end)
48                 {
49                         socket.close();
50                         socket.connect(*endpoint_iterator++, error);
51                 }
52                 if(error)
53                         throw boost::system::system_error(error);
54         }
55
56         ~NetworkDevice()
57         {
58         }
59
60         string description()
61         {
62                 RPCSend snd(socket, "description");
63                 snd.write();
64
65                 RPCReceive rcv(socket);
66                 string desc_string;
67
68                 *rcv.archive & desc_string;
69
70                 return desc_string + " (remote)";
71         }
72
73         void mem_alloc(device_memory& mem, MemoryType type)
74         {
75 #if 0
76                 RPCSend snd(socket, "mem_alloc");
77
78                 snd.archive & size & type;
79                 snd.write();
80
81                 RPCReceive rcv(socket);
82
83                 device_ptr mem;
84                 *rcv.archive & mem;
85
86                 return mem;
87 #endif
88         }
89
90         void mem_copy_to(device_memory& mem)
91         {
92 #if 0
93                 RPCSend snd(socket, "mem_copy_to");
94
95                 snd.archive & mem & size;
96                 snd.write();
97                 snd.write_buffer(host, size);
98 #endif
99         }
100
101         void mem_copy_from(device_memory& mem, size_t offset, size_t size)
102         {
103 #if 0
104                 RPCSend snd(socket, "mem_copy_from");
105
106                 snd.archive & mem & offset & size;
107                 snd.write();
108
109                 RPCReceive rcv(socket);
110                 rcv.read_buffer(host, size);
111 #endif
112         }
113
114         void mem_zero(device_memory& mem)
115         {
116 #if 0
117                 RPCSend snd(socket, "mem_zero");
118
119                 snd.archive & mem & size;
120                 snd.write();
121 #endif
122         }
123
124         void mem_free(device_memory& mem)
125         {
126 #if 0
127                 if(mem) {
128                         RPCSend snd(socket, "mem_free");
129
130                         snd.archive & mem;
131                         snd.write();
132                 }
133 #endif
134         }
135
136         void const_copy_to(const char *name, void *host, size_t size)
137         {
138                 RPCSend snd(socket, "const_copy_to");
139
140                 string name_string(name);
141
142                 snd.archive & name_string & size;
143                 snd.write();
144                 snd.write_buffer(host, size);
145         }
146
147         void tex_alloc(const char *name, device_memory& mem, bool interpolation, bool periodic)
148         {
149 #if 0
150                 RPCSend snd(socket, "tex_alloc");
151
152                 string name_string(name);
153
154                 snd.archive & name_string & width & height & datatype & components & interpolation;
155                 snd.write();
156
157                 size_t size = width*height*components*datatype_size(datatype);
158                 snd.write_buffer(host, size);
159
160                 RPCReceive rcv(socket);
161
162                 device_ptr mem;
163                 *rcv.archive & mem;
164
165                 return mem;
166 #endif
167         }
168
169         void tex_free(device_memory& mem)
170         {
171 #if 0
172                 if(mem) {
173                         RPCSend snd(socket, "tex_free");
174
175                         snd.archive & mem;
176                         snd.write();
177                 }
178 #endif
179         }
180
181         void path_trace(int x, int y, int w, int h, device_ptr buffer, device_ptr rng_state, int pass)
182         {
183 #if 0
184                 RPCSend snd(socket, "path_trace");
185
186                 snd.archive & x & y & w & h & buffer & rng_state & pass;
187                 snd.write();
188 #endif
189         }
190
191         void tonemap(int x, int y, int w, int h, device_ptr rgba, device_ptr buffer, int pass, int resolution)
192         {
193 #if 0
194                 RPCSend snd(socket, "tonemap");
195
196                 snd.archive & x & y & w & h & rgba & buffer & pass & resolution;
197                 snd.write();
198 #endif
199         }
200
201         void task_add(DeviceTask& task)
202         {
203                 if(task.type == DeviceTask::TONEMAP)
204                         tonemap(task.x, task.y, task.w, task.h, task.rgba, task.buffer, task.pass, task.resolution);
205                 else if(task.type == DeviceTask::PATH_TRACE)
206                         path_trace(task.x, task.y, task.w, task.h, task.buffer, task.rng_state, task.pass);
207         }
208
209         void task_wait()
210         {
211         }
212
213         void task_cancel()
214         {
215         }
216 };
217
218 Device *device_network_create(const char *address)
219 {
220         return new NetworkDevice(address);
221 }
222
223
224 void Device::server_run()
225 {
226         try
227         {
228                 /* starts thread that responds to discovery requests */
229                 ServerDiscovery discovery;
230
231                 for(;;)
232                 {
233
234                         /* accept connection */
235                         boost::asio::io_service io_service;
236                         tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), SERVER_PORT));
237
238                         tcp::socket socket(io_service);
239                         acceptor.accept(socket);
240
241                         /* receive remote function calls */
242                         for(;;) {
243                                 RPCReceive rcv(socket);
244
245                                 if(rcv.name == "description") {
246                                         string desc = description();
247
248                                         RPCSend snd(socket);
249                                         snd.archive & desc;
250                                         snd.write();
251                                 }
252                                 else if(rcv.name == "mem_alloc") {
253 #if 0
254                                         MemoryType type;
255                                         size_t size;
256                                         device_ptr mem;
257
258                                         *rcv.archive & size & type;
259                                         mem = mem_alloc(size, type);
260
261                                         RPCSend snd(socket);
262                                         snd.archive & mem;
263                                         snd.write();
264 #endif
265                                 }
266                                 else if(rcv.name == "mem_copy_to") {
267 #if 0
268                                         device_ptr mem;
269                                         size_t size;
270
271                                         *rcv.archive & mem & size;
272
273                                         vector<char> host_vector(size);
274                                         rcv.read_buffer(&host_vector[0], size);
275
276                                         mem_copy_to(mem, &host_vector[0], size);
277 #endif
278                                 }
279                                 else if(rcv.name == "mem_copy_from") {
280 #if 0
281                                         device_ptr mem;
282                                         size_t offset, size;
283
284                                         *rcv.archive & mem & offset & size;
285
286                                         vector<char> host_vector(size);
287
288                                         mem_copy_from(&host_vector[0], mem, offset, size);
289
290                                         RPCSend snd(socket);
291                                         snd.write();
292                                         snd.write_buffer(&host_vector[0], size);
293 #endif
294                                 }
295                                 else if(rcv.name == "mem_zero") {
296 #if 0
297                                         device_ptr mem;
298                                         size_t size;
299
300                                         *rcv.archive & mem & size;
301                                         mem_zero(mem, size);
302 #endif
303                                 }
304                                 else if(rcv.name == "mem_free") {
305 #if 0
306                                         device_ptr mem;
307
308                                         *rcv.archive & mem;
309                                         mem_free(mem);
310 #endif
311                                 }
312                                 else if(rcv.name == "const_copy_to") {
313                                         string name_string;
314                                         size_t size;
315
316                                         *rcv.archive & name_string & size;
317
318                                         vector<char> host_vector(size);
319                                         rcv.read_buffer(&host_vector[0], size);
320
321                                         const_copy_to(name_string.c_str(), &host_vector[0], size);
322                                 }
323                                 else if(rcv.name == "tex_alloc") {
324 #if 0
325                                         string name_string;
326                                         DataType datatype;
327                                         device_ptr mem;
328                                         size_t width, height;
329                                         int components;
330                                         bool interpolation;
331
332                                         *rcv.archive & name_string & width & height & datatype & components & interpolation;
333
334                                         size_t size = width*height*components*datatype_size(datatype);
335
336                                         vector<char> host_vector(size);
337                                         rcv.read_buffer(&host_vector[0], size);
338
339                                         mem = tex_alloc(name_string.c_str(), &host_vector[0], width, height, datatype, components, interpolation);
340
341                                         RPCSend snd(socket);
342                                         snd.archive & mem;
343                                         snd.write();
344 #endif
345                                 }
346                                 else if(rcv.name == "tex_free") {
347 #if 0
348                                         device_ptr mem;
349
350                                         *rcv.archive & mem;
351                                         tex_free(mem);
352 #endif
353                                 }
354                                 else if(rcv.name == "path_trace") {
355 #if 0
356                                         device_ptr buffer, rng_state;
357                                         int x, y, w, h;
358                                         int pass;
359
360                                         *rcv.archive & x & y & w & h & buffer & rng_state & pass;
361                                         path_trace(x, y, w, h, buffer, rng_state, pass);
362 #endif
363                                 }
364                                 else if(rcv.name == "tonemap") {
365 #if 0
366                                         device_ptr rgba, buffer;
367                                         int x, y, w, h;
368                                         int pass, resolution;
369
370                                         *rcv.archive & x & y & w & h & rgba & buffer & pass & resolution;
371                                         tonemap(x, y, w, h, rgba, buffer, pass, resolution);
372 #endif
373                                 }
374                         }
375                 }
376         }
377         catch(exception& e)
378         {
379                 cerr << "Network server exception: " << e.what() << endl;
380         }
381 }
382
383 #endif
384
385 CCL_NAMESPACE_END
386