00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef LUX_CONTRIBUTION_H
00024 #define LUX_CONTRIBUTION_H
00025
00026 #include "lux.h"
00027 #include "memory.h"
00028 #include "color.h"
00029 #include "fastmutex.h"
00030
00031 #include <boost/thread/mutex.hpp>
00032
00033 namespace lux
00034 {
00035
00036
00037
00038 #define CONTRIB_BUF_SIZE 4096
00039
00040
00041
00042 #define CONTRIB_BUF_KEEPALIVE 8
00043
00044
00045 #define CONTRIB_DEBUG false
00046
00047 class Contribution {
00048 public:
00049 Contribution(float x=0.f, float y=0.f, const XYZColor &c=0.f, float a=0.f, float zd=0.f,
00050 float v=0.f, int b=0, int g=0) :
00051 imageX(x), imageY(y), color(c), alpha(a), zdepth(zd), variance(v),
00052 buffer(b), bufferGroup(g) { }
00053
00054 float imageX, imageY;
00055 XYZColor color;
00056 float alpha, zdepth, variance;
00057 int buffer, bufferGroup;
00058 };
00059
00060 class ContributionBuffer {
00061 class Buffer {
00062 public:
00063 Buffer() : pos(0) {
00064 contribs = AllocAligned<Contribution>(CONTRIB_BUF_SIZE);
00065 }
00066
00067 ~Buffer() {
00068 FreeAligned(contribs);
00069 }
00070
00071 bool Add(Contribution* c, float weight=1.f) {
00072 if(pos == CONTRIB_BUF_SIZE)
00073 return false;
00074
00075 contribs[pos] = *c;
00076 contribs[pos].variance = weight;
00077
00078 ++pos;
00079
00080 return true;
00081 }
00082
00083 void Splat(Film *film);
00084
00085 private:
00086 u_int pos;
00087 Contribution *contribs;
00088 };
00089 public:
00090 ContributionBuffer() : sampleCount(0.f), buffers(0) { }
00091
00092 ~ContributionBuffer() {
00093 for (u_int i = 0; i < buffers.size(); ++i) {
00094 for (u_int j = 0; j < buffers[i].size(); ++j)
00095 delete buffers[i][j];
00096 }
00097 }
00098
00099 bool Add(Contribution* c, float weight=1.f) {
00100 while (c->bufferGroup >= int(buffers.size()))
00101 buffers.push_back(vector<Buffer *>(0));
00102 while (c->buffer >= int(buffers[c->bufferGroup].size()))
00103 buffers[c->bufferGroup].push_back(new Buffer());
00104 return buffers[c->bufferGroup][c->buffer]->Add(c, weight);
00105 }
00106
00107 void AddSampleCount(float c) {
00108 sampleCount += c;
00109 }
00110
00111 void Splat(Film *film);
00112
00113 private:
00114 float sampleCount;
00115 vector<vector<Buffer *> > buffers;
00116 };
00117
00118 class ContributionPool {
00119 public:
00120
00121 ContributionPool();
00122
00123 void SetFilm(Film *f) { film = f; }
00124
00125 void End(ContributionBuffer *c);
00126
00127 ContributionBuffer* Next(ContributionBuffer *c);
00128
00129
00130
00131 void Flush();
00132 void Delete();
00133
00134
00135
00136 void CheckFilmWriteOuputInterval();
00137
00138 private:
00139 unsigned int total;
00140 vector<ContributionBuffer*> CFree;
00141 vector<ContributionBuffer*> CFull;
00142 vector<ContributionBuffer*> CSplat;
00143
00144 Film *film;
00145 fast_mutex poolMutex;
00146 boost::mutex splattingMutex;
00147 };
00148
00149 }
00150
00151 #endif // LUX_CONTRIBUTION_H