1 /*****************************************************************************
4 ** Name: threadraster.cpp
5 ** Purpose: Threaded rasterizer class
6 ** Programmer: Kevin Rosenberg
7 ** Date Started: February 2001
9 ** This is part of the CTSim program
10 ** Copyright (C) 1983-2009 Kevin Rosenberg
12 ** This program is free software; you can redistribute it and/or modify
13 ** it under the terms of the GNU General Public License (version 2) as
14 ** published by the Free Software Foundation.
16 ** This program is distributed in the hope that it will be useful,
17 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ** GNU General Public License for more details.
21 ** You should have received a copy of the GNU General Public License
22 ** along with this program; if not, write to the Free Software
23 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 ******************************************************************************/
27 #if defined(HAVE_CONFIG_H)
31 #include "wx/wxprec.h"
46 #include "threadraster.h"
47 #include "backgroundmgr.h"
48 #include "backgroundsupr.h"
51 /////////////////////////////////////////////////////////////////////
53 // Class RasterizerSupervisorThread -- Thread for Background Supervisor
55 /////////////////////////////////////////////////////////////////////
57 RasterizerSupervisorThread::RasterizerSupervisorThread (PhantomFileView* pProjView, int iNX, int iNY,
58 int iNSample, double dViewRatio, wxChar const* pszLabel)
59 : SupervisorThread(), m_pPhantomView(pProjView), m_iNX(iNX), m_iNY(iNY), m_iNSample(iNSample), m_dViewRatio(dViewRatio), m_strLabel(pszLabel)
64 RasterizerSupervisorThread::Entry()
66 RasterizerSupervisor rasterSupervisor (this, m_pPhantomView, m_iNX, m_iNY, m_iNSample, m_dViewRatio, m_strLabel);
68 rasterSupervisor.start();
70 while (! rasterSupervisor.workersDone() && ! rasterSupervisor.fail() && ! rasterSupervisor.cancelled()) {
74 if (rasterSupervisor.fail())
76 wxString msg (_T("Error starting Rasterizer supervisor: "));
77 msg += rasterSupervisor.getFailMessage();
79 wxCommandEvent eventLog (wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT );
80 eventLog.SetString( msg );
81 wxPostEvent( theApp->getMainFrame(), eventLog ); // send log event
84 if (! rasterSupervisor.cancelled())
85 rasterSupervisor.onDone();
86 rasterSupervisor.deleteWorkers();
88 return static_cast<wxThread::ExitCode>(0);
92 RasterizerSupervisorThread::OnExit()
97 /////////////////////////////////////////////////////////////////////
99 // Class RasterizerSupervisor -- A Background Supervisor
101 /////////////////////////////////////////////////////////////////////
103 RasterizerSupervisor::RasterizerSupervisor (SupervisorThread* pThread, PhantomFileView* pPhantomView, int iNX, int iNY,
104 int iNSample, double dViewRatio, wxChar const* pszLabel)
105 : BackgroundSupervisor (pThread, pPhantomView->GetFrame(), pPhantomView->GetDocument(), _T("Rasterizing"), iNX),
106 m_pPhantomView(pPhantomView), m_pPhantomDoc(pPhantomView->GetDocument()),
107 m_iNX(iNX), m_iNY(iNY), m_iNSample(iNSample), m_dViewRatio(dViewRatio), m_strLabel(pszLabel)
109 m_vecpChildImageFiles.reserve (getNumWorkers());
110 for (int iThread = 0; iThread < getNumWorkers(); iThread++) {
111 m_vecpChildImageFiles[iThread] = new ImageFile;
115 RasterizerSupervisor::~RasterizerSupervisor()
117 for (int i = 0; i < getNumWorkers(); i++)
118 delete m_vecpChildImageFiles[i];
121 BackgroundWorkerThread*
122 RasterizerSupervisor::createWorker (int iThread, int iStartUnit, int iNumUnits)
124 RasterizerWorker* pThread = new RasterizerWorker (this, iThread, iStartUnit, iNumUnits);
125 m_vecpChildImageFiles[iThread]->setArraySize (iNumUnits, m_iNY);
126 pThread->SetParameters (m_pPhantomView, m_vecpChildImageFiles[iThread], m_iNX, m_iNY, m_iNSample, m_dViewRatio);
132 RasterizerSupervisor::onDone()
134 wxCriticalSection doneSection;
135 wxCriticalSectionLocker critsect (doneSection);
137 ImageFile* pImageFile = getImageFile();
138 pImageFile->labelAdd (m_strLabel.mb_str(wxConvUTF8), getTimerEnd());
140 wxCommandEvent eventLog (wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT );
141 wxString msg (m_strLabel);
143 eventLog.SetString( msg );
144 wxPostEvent( theApp->getMainFrame(), eventLog ); // send log event
146 wxCommandEvent newImageEvent (wxEVT_COMMAND_MENU_SELECTED, NEW_IMAGEFILE_EVENT);
147 newImageEvent.SetClientData (pImageFile);
148 wxPostEvent (theApp->getMainFrame(), newImageEvent);
155 RasterizerSupervisor::getImageFile()
157 ImageFile* pImageFile = new ImageFile (m_iNX, m_iNY);
159 size_t iColSize = sizeof(ImageFileValue) * m_iNY;
161 ImageFileArray globalArray = pImageFile->getArray();
163 for (int iw = 0; iw < getNumWorkers(); iw++) {
164 ImageFileArray childArray = m_vecpChildImageFiles[iw]->getArray();
165 for (unsigned int iCol = 0; iCol < m_vecpChildImageFiles[iw]->nx(); iCol++) {
166 memcpy (globalArray[iGlobalCol++], childArray[iCol], iColSize);
173 /////////////////////////////////////////////////////////////////////
175 // Class RasterizerWorker -- A worker thread
177 /////////////////////////////////////////////////////////////////////
180 RasterizerWorker::SetParameters (PhantomFileView* pPhantomView, ImageFile* pImageFile, int iNX, int iNY, int iNSample, double dViewRatio)
182 m_pImageFile = pImageFile;
185 m_pPhantomView = pPhantomView;
186 m_iNSample = iNSample;
187 m_dViewRatio = dViewRatio;
191 RasterizerWorker::Entry ()
193 const Phantom& rPhantom = m_pPhantomView->GetDocument()->getPhantom();
194 wxCommandEvent eventProgress (wxEVT_COMMAND_MENU_SELECTED, BackgroundSupervisor::MSG_WORKER_THREAD_UNIT_TICK);
195 for (int iUnit = 0; iUnit < m_iNumUnits; iUnit++) {
198 if (theApp->getVerboseLogging()) {
200 msg.Printf(_T("Worker thread: Received destroy message at work unit #%d\n"), iUnit);
201 wxCommandEvent event( wxEVT_COMMAND_MENU_SELECTED, MAINMENU_LOG_EVENT );
202 event.SetString( msg );
203 wxPostEvent( theApp->getMainFrame(), event );
208 rPhantom.convertToImagefile (*m_pImageFile, m_iNX, m_dViewRatio, m_iNSample, Trace::TRACE_NONE, iUnit + m_iStartUnit, 1, iUnit);
209 m_pSupervisor->onWorkerUnitTick();
212 m_pSupervisor->onWorkerDone (m_iThread);
214 while (! TestDestroy())
217 return static_cast<wxThread::ExitCode>(0);
221 RasterizerWorker::OnExit ()
225 #endif // HAVE_WXTHREADS