filters: Linear: Run one thread on in-place filter
[gfxprim.git] / libs / filters / GP_LinearThreads.c
blobda55ce9b952e07889597f9aded120794e234d966
1 /*****************************************************************************
2 * This file is part of gfxprim library. *
3 * *
4 * Gfxprim is free software; you can redistribute it and/or *
5 * modify it under the terms of the GNU Lesser General Public *
6 * License as published by the Free Software Foundation; either *
7 * version 2.1 of the License, or (at your option) any later version. *
8 * *
9 * Gfxprim 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 GNU *
12 * Lesser General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU Lesser General Public *
15 * License along with gfxprim; if not, write to the Free Software *
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
17 * Boston, MA 02110-1301 USA *
18 * *
19 * Copyright (C) 2009-2012 Cyril Hrubis <metan@ucw.cz> *
20 * *
21 *****************************************************************************/
23 #include <unistd.h>
24 #include <pthread.h>
25 #include <string.h>
27 #include "core/GP_Common.h"
28 #include "core/GP_Debug.h"
29 #include "core/GP_Threads.h"
31 #include "GP_Linear.h"
32 #include "GP_LinearThreads.h"
34 static void *h_linear_convolution(void *arg)
36 struct GP_ConvolutionParams *params = arg;
38 long ret = GP_FilterHConvolution_Raw(params);
40 return (void*)ret;
43 static void *v_linear_convolution(void *arg)
45 struct GP_ConvolutionParams *params = arg;
47 long ret = GP_FilterVConvolution_Raw(params);
49 return (void*)ret;
52 static void *linear_convolution(void *arg)
54 struct GP_ConvolutionParams *params = arg;
56 long ret = GP_FilterConvolution_Raw(params);
58 return (void*)ret;
61 int GP_FilterHConvolutionMP_Raw(const GP_ConvolutionParams *params)
63 int i, t = GP_NrThreads(params->w_src, params->h_src, params->callback);
65 if (t == 1)
66 return GP_FilterHConvolution_Raw(params);
68 if (params->src == params->dst) {
69 GP_DEBUG(1, "In-place filter detected, running in one thread.");
70 return GP_FilterHConvolution_Raw(params);
73 GP_PROGRESS_CALLBACK_MP(callback_mp, params->callback);
75 /* Run t threads */
76 pthread_t threads[t];
77 struct GP_ConvolutionParams convs[t];
78 GP_Size h = params->h_src/t;
80 for (i = 0; i < t; i++) {
81 GP_Coord y_src_2 = params->y_src + i * h;
82 GP_Coord y_dst_2 = params->y_dst + i * h;
83 GP_Size h_src_2 = h;
85 if (i == t - 1)
86 h_src_2 = params->h_src - i * h;
88 convs[i] = *params;
89 convs[i].y_src = y_src_2;
90 convs[i].h_src = h_src_2;
91 convs[i].y_dst = y_dst_2;
92 convs[i].callback = params->callback ? &callback_mp : NULL;
94 pthread_create(&threads[i], NULL, h_linear_convolution, &convs[i]);
97 int ret = 0;
99 for (i = 0; i < t; i++) {
100 long r;
102 pthread_join(threads[i], (void*)&r);
104 ret |= (int)r;
107 return ret;
111 int GP_FilterVConvolutionMP_Raw(const GP_ConvolutionParams *params)
113 int i, t = GP_NrThreads(params->w_src, params->h_src, params->callback);
115 if (t == 1)
116 return GP_FilterVConvolution_Raw(params);
118 if (params->src == params->dst) {
119 GP_DEBUG(1, "In-place filter detected, running in one thread.");
120 return GP_FilterVConvolution_Raw(params);
123 GP_PROGRESS_CALLBACK_MP(callback_mp, params->callback);
125 /* Run t threads */
126 pthread_t threads[t];
127 struct GP_ConvolutionParams convs[t];
128 GP_Size h = params->h_src/t;
130 for (i = 0; i < t; i++) {
131 GP_Coord y_src_2 = params->y_src + i * h;
132 GP_Coord y_dst_2 = params->y_dst + i * h;
133 GP_Size h_src_2 = h;
135 if (i == t - 1)
136 h_src_2 = params->h_src - i * h;
138 convs[i] = *params;
139 convs[i].y_src = y_src_2;
140 convs[i].h_src = h_src_2;
141 convs[i].y_dst = y_dst_2;
142 convs[i].callback = params->callback ? &callback_mp : NULL;
144 pthread_create(&threads[i], NULL, v_linear_convolution, &convs[i]);
147 int ret = 0;
149 for (i = 0; i < t; i++) {
150 long r;
151 pthread_join(threads[i], (void*)&r);
153 ret |= (int)r;
156 return ret;
160 int GP_FilterConvolutionMP_Raw(const GP_ConvolutionParams *params)
162 int i, t = GP_NrThreads(params->w_src, params->h_src, params->callback);
164 if (t == 1)
165 return GP_FilterConvolution_Raw(params);
167 if (params->src == params->dst) {
168 GP_DEBUG(1, "In-place filter detected, running in one thread.");
169 return GP_FilterConvolution_Raw(params);
172 GP_PROGRESS_CALLBACK_MP(callback_mp, params->callback);
174 /* Run t threads */
175 pthread_t threads[t];
176 struct GP_ConvolutionParams convs[t];
177 GP_Size h = params->h_src/t;
179 for (i = 0; i < t; i++) {
180 GP_Coord y_src_2 = params->y_src + i * h;
181 GP_Coord y_dst_2 = params->y_dst + i * h;
182 GP_Size h_src_2 = h;
184 if (i == t - 1)
185 h_src_2 = params->h_src - i * h;
187 convs[i] = *params;
188 convs[i].y_src = y_src_2;
189 convs[i].h_src = h_src_2;
190 convs[i].y_dst = y_dst_2;
191 convs[i].callback = params->callback ? &callback_mp : NULL;
193 pthread_create(&threads[i], NULL, linear_convolution, &convs[i]);
196 int ret = 0;
198 for (i = 0; i < t; i++) {
199 long r;
200 pthread_join(threads[i], (void*)&r);
202 ret |= (int)r;
205 return ret;