Line data Source code
1 :
2 : /* Copyright (c) 2010-2013, Stefan Eilemann <eile@eyescale.ch>
3 : * 2012, Daniel Nachbaur <danielnachbaur@gmail.com>
4 : * 2010, Cedric Stalder <cedric.stalder@gmail.com>
5 : *
6 : * This library is free software; you can redistribute it and/or modify it under
7 : * the terms of the GNU Lesser General Public License version 2.1 as published
8 : * by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 : * details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public License
16 : * along with this library; if not, write to the Free Software Foundation, Inc.,
17 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #include "segment.h"
21 :
22 : #include "leafVisitor.h"
23 : #include "log.h"
24 : #include "paths.h"
25 :
26 : #include <co/dataIStream.h>
27 : #include <co/dataOStream.h>
28 :
29 : namespace eq
30 : {
31 : namespace fabric
32 : {
33 : template <class C, class S, class CH>
34 793 : Segment<C, S, CH>::Segment(C* canvas)
35 : : _canvas(canvas)
36 : , _channel(0)
37 : , _eyes(EYES_ALL)
38 793 : , _swapBarrier(canvas->getSwapBarrier())
39 : {
40 793 : LBASSERT(canvas);
41 793 : canvas->_addChild(static_cast<S*>(this));
42 793 : LBLOG(LOG_INIT) << "New " << lunchbox::className(this) << std::endl;
43 793 : }
44 :
45 : template <class C, class S, class CH>
46 791 : Segment<C, S, CH>::~Segment()
47 : {
48 791 : LBLOG(LOG_INIT) << "Delete " << lunchbox::className(this) << std::endl;
49 791 : _canvas->_removeChild(static_cast<S*>(this));
50 791 : _channel = 0;
51 1582 : }
52 :
53 : template <class C, class S, class CH>
54 3 : uint128_t Segment<C, S, CH>::commit(const uint32_t incarnation)
55 : {
56 3 : if (Serializable::isDirty(DIRTY_CHANNEL) && _channel)
57 0 : commitChild<typename CH::Parent>(_channel->getWindow(), incarnation);
58 3 : return Object::commit(incarnation);
59 : }
60 :
61 : template <class C, class S, class CH>
62 108 : void Segment<C, S, CH>::setEyes(const uint32_t eyes)
63 : {
64 108 : if (_eyes == eyes)
65 0 : return;
66 108 : setDirty(DIRTY_EYES);
67 108 : _eyes = eyes;
68 : }
69 :
70 : template <class C, class S, class CH>
71 2 : void Segment<C, S, CH>::serialize(co::DataOStream& os, const uint64_t dirtyBits)
72 : {
73 2 : Object::serialize(os, dirtyBits);
74 2 : if (dirtyBits & DIRTY_VIEWPORT)
75 2 : os << _vp;
76 2 : if (dirtyBits & DIRTY_FRUSTUM)
77 2 : Frustum::serialize(os);
78 2 : if (dirtyBits & DIRTY_CHANNEL)
79 2 : os << co::ObjectVersion(_channel);
80 2 : if (dirtyBits & DIRTY_EYES)
81 2 : os << _eyes;
82 2 : }
83 :
84 : template <class C, class S, class CH>
85 1 : void Segment<C, S, CH>::deserialize(co::DataIStream& is,
86 : const uint64_t dirtyBits)
87 : {
88 1 : Object::deserialize(is, dirtyBits);
89 1 : if (dirtyBits & DIRTY_VIEWPORT)
90 1 : is >> _vp;
91 1 : if (dirtyBits & DIRTY_FRUSTUM)
92 1 : Frustum::deserialize(is);
93 1 : if (dirtyBits & DIRTY_CHANNEL)
94 : {
95 1 : LBASSERT(_canvas->_mapViewObjects())
96 :
97 1 : co::ObjectVersion ov;
98 1 : is >> ov;
99 :
100 1 : _channel = 0;
101 1 : if (ov.identifier != 0)
102 : {
103 1 : _canvas->getConfig()->find(ov.identifier, &_channel);
104 1 : LBASSERT(!isMaster() || _channel);
105 : }
106 : }
107 1 : if (dirtyBits & DIRTY_EYES)
108 1 : is >> _eyes;
109 1 : }
110 :
111 : template <class C, class S, class CH>
112 2284 : void Segment<C, S, CH>::setDirty(const uint64_t dirtyBits)
113 : {
114 2284 : Object::setDirty(dirtyBits);
115 2284 : _canvas->setDirty(C::DIRTY_SEGMENTS);
116 2284 : }
117 :
118 : template <class C, class S, class CH>
119 8237 : VisitorResult Segment<C, S, CH>::accept(Visitor& visitor)
120 : {
121 8237 : return visitor.visit(static_cast<S*>(this));
122 : }
123 :
124 : template <class C, class S, class CH>
125 0 : VisitorResult Segment<C, S, CH>::accept(Visitor& visitor) const
126 : {
127 0 : return visitor.visit(static_cast<const S*>(this));
128 : }
129 :
130 : template <class C, class S, class CH>
131 2 : void Segment<C, S, CH>::backup()
132 : {
133 2 : Frustum::backup();
134 2 : Object::backup();
135 2 : }
136 :
137 : template <class C, class S, class CH>
138 0 : void Segment<C, S, CH>::restore()
139 : {
140 0 : Object::restore();
141 0 : Frustum::restore();
142 0 : }
143 :
144 : template <class C, class S, class CH>
145 304 : void Segment<C, S, CH>::setViewport(const Viewport& vp)
146 : {
147 304 : if (_vp == vp)
148 0 : return;
149 :
150 304 : _vp = vp;
151 304 : setDirty(DIRTY_VIEWPORT);
152 304 : inheritFrustum();
153 : }
154 :
155 : template <class C, class S, class CH>
156 0 : void Segment<C, S, CH>::setSwapBarrier(SwapBarrierPtr barrier)
157 : {
158 0 : if (barrier.isValid() && barrier->getName().empty())
159 : {
160 0 : const std::string& name = getName();
161 0 : std::stringstream out;
162 0 : out << "barrier.segment.";
163 0 : if (name.empty())
164 0 : if (getCanvas())
165 0 : out << getCanvas()->getPath().canvasIndex;
166 : else
167 0 : out << (void*)this;
168 : else
169 0 : out << name;
170 :
171 0 : barrier->setName(out.str());
172 : }
173 :
174 0 : _swapBarrier = barrier;
175 0 : }
176 :
177 : template <class C, class S, class CH>
178 304 : void Segment<C, S, CH>::inheritFrustum()
179 : {
180 304 : if (getCurrentType() != TYPE_NONE || _canvas->getCurrentType() == TYPE_NONE)
181 0 : return;
182 :
183 : // if segment has no frustum...
184 304 : Wall wall(_canvas->getWall());
185 304 : wall.apply(_vp);
186 :
187 304 : switch (_canvas->getCurrentType())
188 : {
189 : case TYPE_WALL:
190 304 : setWall(wall);
191 304 : break;
192 :
193 : case TYPE_PROJECTION:
194 : {
195 0 : Projection projection(_canvas->getProjection()); // keep distance
196 0 : projection = wall;
197 0 : setProjection(projection);
198 0 : break;
199 : }
200 : default:
201 0 : LBUNIMPLEMENTED;
202 : case TYPE_NONE:
203 0 : break;
204 : }
205 : }
206 :
207 : template <class C, class S, class CH>
208 560 : void Segment<C, S, CH>::setWall(const Wall& wall)
209 : {
210 560 : if (getWall() == wall && getCurrentType() == TYPE_WALL)
211 88 : return;
212 :
213 472 : Frustum::setWall(wall);
214 472 : setDirty(DIRTY_FRUSTUM);
215 : }
216 :
217 : template <class C, class S, class CH>
218 68 : void Segment<C, S, CH>::setProjection(const Projection& projection)
219 : {
220 68 : if (getProjection() == projection && getCurrentType() == TYPE_PROJECTION)
221 0 : return;
222 :
223 68 : Frustum::setProjection(projection);
224 68 : setDirty(DIRTY_FRUSTUM);
225 : }
226 :
227 : template <class C, class S, class CH>
228 0 : void Segment<C, S, CH>::unsetFrustum()
229 : {
230 0 : if (getCurrentType() == TYPE_NONE)
231 0 : return;
232 :
233 0 : Frustum::unsetFrustum();
234 0 : setDirty(DIRTY_FRUSTUM);
235 : }
236 :
237 : template <class C, class S, class CH>
238 398 : std::ostream& operator<<(std::ostream& os, const Segment<C, S, CH>& s)
239 : {
240 398 : const S& segment = static_cast<const S&>(s);
241 398 : os << lunchbox::disableFlush << lunchbox::disableHeader << "segment"
242 : << std::endl;
243 398 : os << "{" << std::endl << lunchbox::indent;
244 :
245 398 : const std::string& name = segment.getName();
246 398 : if (!name.empty())
247 0 : os << "name \"" << name << "\"" << std::endl;
248 :
249 398 : if (segment.getChannel())
250 : {
251 398 : const std::string& channelName = segment.getChannel()->getName();
252 398 : if (segment.getConfig()->findChannel(channelName) ==
253 : segment.getChannel())
254 : {
255 398 : os << "channel \"" << channelName << "\"" << std::endl;
256 : }
257 : else
258 0 : os << "channel " << segment.getChannel()->getPath() << std::endl;
259 : }
260 :
261 398 : const uint32_t eyes = segment.getEyes();
262 398 : if (eyes != EYES_ALL)
263 : {
264 54 : os << "eye [ ";
265 54 : if (eyes & EYE_CYCLOP)
266 48 : os << "CYCLOP ";
267 54 : if (eyes & EYE_LEFT)
268 26 : os << "LEFT ";
269 54 : if (eyes & EYE_RIGHT)
270 26 : os << "RIGHT ";
271 54 : os << "]" << std::endl;
272 : }
273 398 : const Viewport& vp = segment.getViewport();
274 398 : if (vp.isValid() && vp != Viewport::FULL)
275 152 : os << "viewport " << vp << std::endl;
276 :
277 796 : SwapBarrierConstPtr barrier = segment.getSwapBarrier();
278 398 : if (barrier && barrier != segment.getCanvas()->getSwapBarrier())
279 0 : os << *segment.getSwapBarrier();
280 398 : os << static_cast<const Frustum&>(segment);
281 :
282 796 : os << lunchbox::exdent << "}" << std::endl
283 398 : << lunchbox::enableHeader << lunchbox::enableFlush;
284 796 : return os;
285 : }
286 : }
287 : }
|