1 /*****************************************************************************
2 * This file is part of gfxprim library. *
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. *
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. *
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 *
19 * Copyright (C) 2009-2012 Cyril Hrubis <metan@ucw.cz> *
21 *****************************************************************************/
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
);
43 static void *v_linear_convolution(void *arg
)
45 struct GP_ConvolutionParams
*params
= arg
;
47 long ret
= GP_FilterVConvolution_Raw(params
);
52 static void *linear_convolution(void *arg
)
54 struct GP_ConvolutionParams
*params
= arg
;
56 long ret
= GP_FilterConvolution_Raw(params
);
61 int GP_FilterHConvolutionMP_Raw(const GP_ConvolutionParams
*params
)
63 int i
, t
= GP_NrThreads(params
->w_src
, params
->h_src
, params
->callback
);
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
);
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
;
86 h_src_2
= params
->h_src
- i
* h
;
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
]);
99 for (i
= 0; i
< t
; i
++) {
102 pthread_join(threads
[i
], (void*)&r
);
111 int GP_FilterVConvolutionMP_Raw(const GP_ConvolutionParams
*params
)
113 int i
, t
= GP_NrThreads(params
->w_src
, params
->h_src
, params
->callback
);
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
);
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
;
136 h_src_2
= params
->h_src
- i
* h
;
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
]);
149 for (i
= 0; i
< t
; i
++) {
151 pthread_join(threads
[i
], (void*)&r
);
160 int GP_FilterConvolutionMP_Raw(const GP_ConvolutionParams
*params
)
162 int i
, t
= GP_NrThreads(params
->w_src
, params
->h_src
, params
->callback
);
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
);
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
;
185 h_src_2
= params
->h_src
- i
* h
;
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
]);
198 for (i
= 0; i
< t
; i
++) {
200 pthread_join(threads
[i
], (void*)&r
);