PointSampleRenderer.cpp
Go to the documentation of this file.00001 /**<!--------------------------------------------------------------------> 00002 @file PointSampleRenderer.cpp 00003 @author Travis Fischer (fisch0920@gmail.com) 00004 @author Matthew Jacobs (jacobs.mh@gmail.com) 00005 @date Fall 2008 00006 00007 @brief 00008 Abstraction of renderers which construct their output by point sampling 00009 a 2D domain (the film plane). The steps of generating point 00010 samples across this domain (SampleGenerator), evaluating the samples 00011 (PointSampleRenderer/SampleConsumer), and storing/using the evaluated 00012 samples (RenderOutput) have been abstracted from each other. 00013 <!-------------------------------------------------------------------->**/ 00014 00015 #include "PointSampleRenderer.h" 00016 #include "RenderOutput.h" 00017 00018 #include <generators.h> 00019 #include <QtCore> 00020 using namespace std; 00021 00022 void PointSampleRenderer::render() { 00023 if (!m_initted) 00024 init(); 00025 00026 QMutexLocker lock(&m_renderMutex); 00027 m_output->init(); 00028 00029 // parse parameters 00030 unsigned noConsumers = getValue<unsigned>("noRenderThreads", 1); 00031 ASSERT(noConsumers > 0); 00032 00033 // initialize timer to begin counting 00034 m_timer.reset(); 00035 00036 cout << endl; 00037 cout << "rendering with " << noConsumers << 00038 (noConsumers == 1 ? " thread" : " threads") << endl; 00039 00040 // create and start sample generator 00041 SampleGeneratorThread *generator = _getGenerator(); 00042 generator->init(); 00043 generator->start(); 00044 00045 // create and start sample consumers (render threads) 00046 SampleConsumerList consumers; 00047 00048 for(unsigned i = noConsumers; i--;) { 00049 SampleConsumer *consumer = _getConsumer(); 00050 consumers.push_back(consumer); 00051 00052 consumer->init(); 00053 consumer->start(); 00054 } 00055 00056 //cout << "waiting on generator" << endl; 00057 00058 // join with generator thread (wait until it has completed execution) 00059 while(!generator->wait()); 00060 safeDelete(generator); 00061 00062 // join with consumer threads (wait until they have all completed execution) 00063 for(unsigned i = noConsumers; i--;) { 00064 SampleConsumer *consumer = consumers[i]; 00065 00066 //cout << "waiting on consumer " << (noConsumers - i) << " / " << noConsumers << endl; 00067 while(!consumer->wait()); 00068 00069 safeDelete(consumer); 00070 } 00071 00072 m_output->finalize(); 00073 finalize(); 00074 00075 cout << endl << "done rendering in " << getElapsedTime() << endl << endl; 00076 } 00077 00078 void PointSampleRenderer::finalize() 00079 { } 00080 00081 void PointSampleRenderer::addSharedSample(const PointSample &s) { 00082 QMutexLocker lock(&m_mutex); 00083 ASSERT(m_noProducers > 0); 00084 00085 while(m_sharedShamples.size() > MAX_SHARED_SAMPLES_SIZE) 00086 m_producer.wait(&m_mutex); 00087 00088 m_sharedShamples.push_back(s); 00089 00090 m_consumer.wakeOne(); 00091 } 00092 00093 void PointSampleRenderer::addSharedSamples(const PointSampleList &s) { 00094 QMutexLocker lock(&m_mutex); 00095 ASSERT(m_noProducers > 0); 00096 00097 while(m_sharedShamples.size() >= MAX_SHARED_SAMPLES_SIZE) 00098 m_producer.wait(&m_mutex); 00099 00100 FOREACH(PointSampleListConstIter, s, iter) { 00101 m_sharedShamples.push_back(*iter); 00102 } 00103 00104 m_consumer.wakeAll(); 00105 } 00106 00107 bool PointSampleRenderer::getSharedSample(PointSample &outSample) { 00108 QMutexLocker lock(&m_mutex); 00109 00110 while(m_sharedShamples.size() == 0) { 00111 if (m_sharedShamples.empty() && !m_noProducers) 00112 return false; 00113 00114 m_consumer.wait(&m_mutex); 00115 } 00116 00117 outSample = m_sharedShamples.front(); 00118 m_sharedShamples.pop_front(); 00119 00120 m_producer.wakeAll(); 00121 00122 return true; 00123 } 00124 00125 void PointSampleRenderer::addProducer() { 00126 QMutexLocker lock(&m_mutex); 00127 00128 ++m_noProducers; 00129 } 00130 00131 void PointSampleRenderer::removeProducer() { 00132 QMutexLocker lock(&m_mutex); 00133 00134 ASSERT(0 < m_noProducers); 00135 00136 if (0 == --m_noProducers) // completely done with sample generation 00137 m_consumer.wakeAll(); 00138 } 00139 00140 SampleGeneratorThread *PointSampleRenderer::_getGenerator() { 00141 const std::string &generator = getValue<std::string>("generator", 00142 std::string("default")); 00143 SampleGeneratorThread *sampleGenerator = 00144 SampleGeneratorThread::create(generator); 00145 00146 sampleGenerator->inherit(*this); 00147 sampleGenerator->setRenderer(this); 00148 sampleGenerator->setViewport(m_output->getViewport()); 00149 00150 return sampleGenerator; 00151 } 00152 00153 SampleConsumer *PointSampleRenderer::_getConsumer() { 00154 // TODO: consider making this customizable via parameters? 00155 00156 return new SampleConsumer(this); 00157 } 00158
Generated on 28 Feb 2009 for Milton by
1.5.6