1 /*
2 delaboratory - color correction utility
3 Copyright (C) 2011 Jacek Poplawski
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "layer_processor_threads.h"
20 #include "layer_processor.h"
21 #include "main_window.h"
22 #include "main_frame.h"
23 #include "layer_frame_manager.h"
24 #include "layer_stack.h"
25 #include "view_manager.h"
26 #include <string>
27 #include "base_layer.h"
28 #include "channel_manager.h"
29 #include "str.h"
30 #include <wx/progdlg.h>
31 #include <iostream>
32 #include "logger.h"
33 #include "renderer.h"
34 #include "image_io.h"
35
36 class deLayerProcessorWorkerThread:public wxThread
37 {
38 private:
performTasks()39 void performTasks()
40 {
41 while (true)
42 {
43 if (processor.isClosing())
44 {
45 return;
46 }
47
48 #ifdef DEBUG_LOG
49 logInfo("worker thread wait...");
50 #endif
51 semaphore.wait();
52 Sleep(10);
53
54 if (TestDestroy())
55 {
56 return;
57 }
58
59 processor.tickWork();
60
61 if (TestDestroy())
62 {
63 return;
64 }
65 }
66 }
67
Entry()68 virtual void *Entry()
69 {
70 performTasks();
71 logInfo("worker thread finished");
72 return NULL;
73 }
74 deLayerProcessor& processor;
75 deSemaphore& semaphore;
76
77 public:
deLayerProcessorWorkerThread(deLayerProcessor & _processor,deSemaphore & _semaphore)78 deLayerProcessorWorkerThread(deLayerProcessor& _processor, deSemaphore& _semaphore)
79 :processor(_processor),
80 semaphore(_semaphore)
81 {
82 logInfo("worker thread created");
83 }
~deLayerProcessorWorkerThread()84 virtual ~deLayerProcessorWorkerThread()
85 {
86 }
87 };
88
89 class deRenderWorkerThread:public wxThread
90 {
91 private:
performTasks()92 void performTasks()
93 {
94 while (true)
95 {
96 if (processor.isClosing())
97 {
98 return;
99 }
100
101 #ifdef DEBUG_LOG
102 logInfo("render thread wait...");
103 #endif
104 semaphore.wait();
105 Sleep(10);
106
107 if (TestDestroy())
108 {
109 return;
110 }
111
112 if (processor.prepareImage())
113 {
114 processor.sendRepaintEvent();
115 }
116
117 if (TestDestroy())
118 {
119 return;
120 }
121 }
122 }
123
Entry()124 virtual void *Entry()
125 {
126 performTasks();
127 logInfo("render thread finished");
128 return NULL;
129 }
130
131 deLayerProcessor& processor;
132 deSemaphore& semaphore;
133
134 public:
deRenderWorkerThread(deLayerProcessor & _processor,deSemaphore & _semaphore)135 deRenderWorkerThread(deLayerProcessor& _processor, deSemaphore& _semaphore)
136 :processor(_processor),
137 semaphore(_semaphore)
138 {
139 logInfo("render thread created");
140 }
~deRenderWorkerThread()141 virtual ~deRenderWorkerThread()
142 {
143 }
144 };
145
146 class deHistogramWorkerThread:public wxThread
147 {
148 private:
performTasks()149 void performTasks()
150 {
151 while (true)
152 {
153 if (processor.isClosing())
154 {
155 return;
156 }
157
158 #ifdef DEBUG_LOG
159 logInfo("histogram thread wait...");
160 #endif
161 semaphore.wait();
162 Sleep(10);
163
164 if (TestDestroy())
165 {
166 return;
167 }
168
169 processor.onGenerateHistogram();
170 processor.sendHistogramEvent();
171
172 if (TestDestroy())
173 {
174 return;
175 }
176 }
177 }
178
Entry()179 virtual void *Entry()
180 {
181 performTasks();
182 logInfo("histogram thread finished");
183 return NULL;
184 }
185
186 deLayerProcessor& processor;
187 deSemaphore& semaphore;
188
189 public:
deHistogramWorkerThread(deLayerProcessor & _processor,deSemaphore & _semaphore)190 deHistogramWorkerThread(deLayerProcessor& _processor, deSemaphore& _semaphore)
191 :processor(_processor),
192 semaphore(_semaphore)
193 {
194 logInfo("histogram thread created");
195 }
~deHistogramWorkerThread()196 virtual ~deHistogramWorkerThread()
197 {
198 }
199 };
200
201
202
stopWorkerThread()203 void deLayerProcessorThreads::stopWorkerThread()
204 {
205 logInfo("stop worker, render and histogram threads");
206
207 workerSemaphore.post();
208 workerThread->Delete();
209
210 renderWorkerSemaphore.post();
211 renderWorkerThread->Delete();
212
213 histogramWorkerSemaphore.post();
214 histogramWorkerThread->Delete();
215
216 wxThread::Sleep(200);
217
218 logInfo("stopped worker, render and histogram threads");
219
220 }
221
startWorkerThread()222 void deLayerProcessorThreads::startWorkerThread()
223 {
224 logInfo("start worker, render and histogram threads");
225
226 workerThread = new deLayerProcessorWorkerThread(layerProcessor, workerSemaphore);
227
228 if ( workerThread->Create() != wxTHREAD_NO_ERROR )
229 {
230 }
231
232 if ( workerThread->Run() != wxTHREAD_NO_ERROR )
233 {
234 }
235
236 renderWorkerThread = new deRenderWorkerThread(layerProcessor, renderWorkerSemaphore);
237
238 if ( renderWorkerThread->Create() != wxTHREAD_NO_ERROR )
239 {
240 }
241
242 if ( renderWorkerThread->Run() != wxTHREAD_NO_ERROR )
243 {
244 }
245
246 histogramWorkerThread = new deHistogramWorkerThread(layerProcessor, histogramWorkerSemaphore);
247
248 if ( histogramWorkerThread->Create() != wxTHREAD_NO_ERROR )
249 {
250 }
251
252 if ( histogramWorkerThread->Run() != wxTHREAD_NO_ERROR )
253 {
254 }
255
256 logInfo("started worker, render and histogram threads");
257 }
258
259