Line data Source code
1 :
2 : /* Copyright (c) 2006-2017, Stefan Eilemann <eile@equalizergraphics.com>
3 : * Cedric Stalder <cedric.stalder@gmail.com>
4 : *
5 : * This library is free software; you can redistribute it and/or modify it under
6 : * the terms of the GNU Lesser General Public License version 2.1 as published
7 : * by the Free Software Foundation.
8 : *
9 : * This library is distributed in the hope that it will be useful, but WITHOUT
10 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12 : * details.
13 : *
14 : * You should have received a copy of the GNU Lesser General Public License
15 : * along with this library; if not, write to the Free Software Foundation, Inc.,
16 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 : */
18 :
19 : #include "frame.h"
20 :
21 : #include "compound.h"
22 : #include "frameData.h"
23 : #include "node.h"
24 :
25 : #include <co/dataIStream.h>
26 : #include <co/dataOStream.h>
27 :
28 : namespace eq
29 : {
30 : namespace server
31 : {
32 5548 : Frame::Frame()
33 : : _compound(0)
34 : , _buffers(Buffer::undefined)
35 : , _type(TYPE_MEMORY)
36 : , _native()
37 5548 : , _masterFrameData(0)
38 : {
39 5548 : setNativeZoom(Zoom(0.f, 0.f)); // set invalid zoom to detect 'set' state
40 22192 : for (unsigned i = 0; i < NUM_EYES; ++i)
41 16644 : _frameData[i] = 0;
42 5548 : }
43 :
44 0 : Frame::Frame(const Frame& from)
45 : : fabric::Frame(from)
46 : , _compound(0)
47 : , _vp(from._vp)
48 0 : , _buffers(from._buffers)
49 0 : , _type(from._type)
50 : , _native(from._native)
51 0 : , _masterFrameData(0)
52 : {
53 0 : for (unsigned i = 0; i < NUM_EYES; ++i)
54 0 : _frameData[i] = 0;
55 0 : }
56 :
57 16644 : Frame::~Frame()
58 : {
59 5548 : LBASSERT(_datas.empty());
60 5548 : _compound = 0;
61 5548 : _masterFrameData = 0;
62 11096 : }
63 :
64 64 : void Frame::flush()
65 : {
66 64 : unsetData();
67 :
68 72 : while (!_datas.empty())
69 : {
70 4 : FrameData* data = _datas.front();
71 4 : _datas.pop_front();
72 4 : getLocalNode()->deregisterObject(data);
73 4 : delete data;
74 : }
75 64 : }
76 :
77 64 : void Frame::unsetData()
78 : {
79 256 : for (unsigned i = 0; i < NUM_EYES; ++i)
80 : {
81 192 : _frameData[i] = 0;
82 192 : _inputFrames[i].clear();
83 192 : _getInputNodes(i).clear();
84 192 : _getInputNetNodes(i).clear();
85 : }
86 64 : }
87 :
88 4 : void Frame::commitData()
89 : {
90 4 : if (!_masterFrameData) // not used
91 0 : return;
92 :
93 16 : for (unsigned i = 0; i < NUM_EYES; ++i)
94 : {
95 12 : if (_frameData[i])
96 : {
97 4 : if (_frameData[i] != _masterFrameData)
98 0 : _frameData[i]->fabric::FrameData::operator=(*_masterFrameData);
99 :
100 4 : _frameData[i]->commit();
101 : }
102 : }
103 : }
104 :
105 8 : uint128_t Frame::commit(const uint32_t incarnation)
106 : {
107 32 : for (unsigned i = 0; i < NUM_EYES; ++i)
108 24 : _setDataVersion(i, co::ObjectVersion(_frameData[i]));
109 8 : return co::Object::commit(incarnation);
110 : }
111 :
112 4 : void Frame::cycleData(const uint32_t frameNumber, const Compound* compound)
113 : {
114 4 : _masterFrameData = 0;
115 16 : for (unsigned i = 0; i < NUM_EYES; ++i)
116 : {
117 12 : _inputFrames[i].clear();
118 :
119 12 : const Eye eye = Eye(1 << i);
120 12 : if (!compound->isInheritActive(eye)) // eye pass not used
121 : {
122 8 : _frameData[i] = 0;
123 8 : continue;
124 : }
125 :
126 : // reuse unused frame data
127 4 : FrameData* data = _datas.empty() ? 0 : _datas.back();
128 4 : const uint32_t latency = getAutoObsolete();
129 4 : const uint32_t dataAge = data ? data->getFrameNumber() : 0;
130 :
131 4 : if (data && dataAge < frameNumber - latency && frameNumber > latency)
132 : // not used anymore
133 0 : _datas.pop_back();
134 : else // still used - allocate new data
135 : {
136 4 : data = new FrameData;
137 :
138 4 : getLocalNode()->registerObject(data);
139 4 : data->setAutoObsolete(1); // current + in use by render nodes
140 : }
141 :
142 4 : data->setFrameNumber(frameNumber);
143 :
144 4 : _datas.push_front(data);
145 4 : _frameData[i] = data;
146 4 : _getInputNodes(i).clear();
147 4 : _getInputNetNodes(i).clear();
148 4 : if (!_masterFrameData)
149 4 : _masterFrameData = data;
150 : }
151 4 : }
152 :
153 4 : void Frame::addInputFrame(Frame* frame, const Compound* compound)
154 : {
155 16 : for (unsigned i = 0; i < NUM_EYES; ++i)
156 : {
157 : // eye pass not used && no output frame for eye pass
158 12 : const Eye eye = Eye(1 << i);
159 12 : if (compound->isInheritActive(eye) && _frameData[i])
160 : {
161 4 : frame->_frameData[i] = _frameData[i];
162 4 : _inputFrames[i].push_back(frame);
163 :
164 4 : const Node* inputNode = frame->getNode();
165 4 : if (inputNode != getNode())
166 : {
167 0 : co::NodePtr inputNetNode = inputNode->getNode();
168 0 : _getInputNodes(i).push_back(inputNode->getID());
169 0 : _getInputNetNodes(i).push_back(inputNetNode->getNodeID());
170 : }
171 : }
172 : else
173 : {
174 8 : frame->_frameData[i] = 0;
175 : }
176 : }
177 4 : }
178 :
179 2870 : std::ostream& operator<<(std::ostream& os, const Frame& frame)
180 : {
181 2870 : os << lunchbox::disableFlush << "frame" << std::endl
182 2870 : << "{" << std::endl
183 5740 : << lunchbox::indent << "name \"" << frame.getName() << "\""
184 2870 : << std::endl;
185 :
186 2870 : const Frame::Buffer buffers = frame.getBuffers();
187 2870 : if (buffers != Frame::Buffer::undefined)
188 : {
189 132 : os << "buffers [";
190 132 : if (buffers & Frame::Buffer::color)
191 132 : os << " COLOR";
192 132 : if (buffers & Frame::Buffer::depth)
193 8 : os << " DEPTH";
194 132 : os << " ]" << std::endl;
195 : }
196 :
197 2870 : const Frame::Type frameType = frame.getType();
198 2870 : if (frameType != Frame::TYPE_MEMORY)
199 70 : os << frameType;
200 :
201 2870 : const Viewport& vp = frame.getViewport();
202 2870 : if (vp != Viewport::FULL)
203 750 : os << "viewport " << vp << std::endl;
204 :
205 2870 : const Zoom& zoom = frame.getZoom();
206 2870 : if (zoom.isValid() && zoom != Zoom::NONE)
207 0 : os << zoom << std::endl;
208 :
209 2870 : return os << lunchbox::exdent << "}" << lunchbox::enableFlush;
210 : }
211 : }
212 60 : }
|