Cycles: merge of changes from tomato branch.
[blender-staging.git] / intern / cycles / device / device_task.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 <stdlib.h>
20 #include <string.h>
21
22 #include "device_task.h"
23
24 #include "util_algorithm.h"
25 #include "util_time.h"
26
27 CCL_NAMESPACE_BEGIN
28
29 /* Device Task */
30
31 DeviceTask::DeviceTask(Type type_)
32 : type(type_), x(0), y(0), w(0), h(0), rgba(0), buffer(0),
33   sample(0), num_samples(1), resolution(0),
34   shader_input(0), shader_output(0),
35   shader_eval_type(0), shader_x(0), shader_w(0)
36 {
37         last_update_time = time_dt();
38 }
39
40 void DeviceTask::split_max_size(list<DeviceTask>& tasks, int max_size)
41 {
42         int num;
43
44         if(type == SHADER) {
45                 num = (shader_w + max_size - 1)/max_size;
46         }
47         else {
48                 max_size = max(1, max_size/w);
49                 num = (h + max_size - 1)/max_size;
50         }
51
52         split(tasks, num);
53 }
54
55 void DeviceTask::split(list<DeviceTask>& tasks, int num)
56 {
57         if(type == SHADER) {
58                 num = min(shader_w, num);
59
60                 for(int i = 0; i < num; i++) {
61                         int tx = shader_x + (shader_w/num)*i;
62                         int tw = (i == num-1)? shader_w - i*(shader_w/num): shader_w/num;
63
64                         DeviceTask task = *this;
65
66                         task.shader_x = tx;
67                         task.shader_w = tw;
68
69                         tasks.push_back(task);
70                 }
71         }
72         else if(type == PATH_TRACE) {
73                 for(int i = 0; i < num; i++)
74                         tasks.push_back(*this);
75         }
76         else {
77                 num = min(h, num);
78
79                 for(int i = 0; i < num; i++) {
80                         int ty = y + (h/num)*i;
81                         int th = (i == num-1)? h - i*(h/num): h/num;
82
83                         DeviceTask task = *this;
84
85                         task.y = ty;
86                         task.h = th;
87
88                         tasks.push_back(task);
89                 }
90         }
91 }
92
93 void DeviceTask::update_progress(RenderTile &rtile)
94 {
95         if (type != PATH_TRACE)
96                 return;
97
98         if(update_progress_sample)
99                 update_progress_sample();
100
101         if(update_tile_sample) {
102                 double current_time = time_dt();
103
104                 if (current_time - last_update_time >= 1.0f) {
105                         update_tile_sample(rtile);
106
107                         last_update_time = current_time;
108                 }
109         }
110 }
111
112 CCL_NAMESPACE_END
113