Line data Source code
1 :
2 : /* Copyright (c) 2008-2017, Stefan Eilemann <eile@equalizergraphics.com>
3 : * Daniel Nachbaur <danielnachbaur@gmail.com>
4 : * 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 "view.h"
21 :
22 : #include "equalizerTypes.h"
23 : #include "leafVisitor.h"
24 : #include "log.h"
25 : #include "paths.h"
26 :
27 : #include <co/dataIStream.h>
28 : #include <co/dataOStream.h>
29 :
30 : namespace eq
31 : {
32 : namespace fabric
33 : {
34 : namespace
35 : {
36 : #define _MAKE_ATTR_STRING(attr) (std::string("EQ_VIEW_") + #attr)
37 320 : static std::string _sAttributeStrings[] = {_MAKE_ATTR_STRING(
38 : SATTR_DEFLECT_HOST),
39 240 : _MAKE_ATTR_STRING(SATTR_DEFLECT_ID)};
40 : }
41 :
42 : template <class L, class V, class O>
43 720 : View<L, V, O>::View(L* layout)
44 : : _layout(layout)
45 : , _observer(0)
46 : , _minimumCapabilities(LB_BIT_NONE)
47 : , _maximumCapabilities(LB_BIT_ALL_64)
48 : , _capabilities(LB_BIT_ALL_64)
49 : , _equalizers(EQUALIZER_ALL)
50 : , _modelUnit(EQ_M)
51 720 : , _screenshotBuffers(Frame::Buffer::none)
52 : {
53 : // Note: Views are an exception to the strong structuring, since render
54 : // client views are multi-buffered (once per pipe) and do not have a parent
55 720 : if (layout)
56 719 : layout->_addChild(static_cast<V*>(this));
57 720 : LBLOG(LOG_INIT) << "New " << lunchbox::className(this) << std::endl;
58 720 : }
59 :
60 : template <class L, class V, class O>
61 718 : View<L, V, O>::~View()
62 : {
63 718 : LBLOG(LOG_INIT) << "Delete " << lunchbox::className(this) << std::endl;
64 718 : if (_layout)
65 717 : _layout->_removeChild(static_cast<V*>(this));
66 1436 : }
67 :
68 : template <class L, class V, class O>
69 1440 : View<L, V, O>::BackupData::BackupData()
70 1440 : : mode(MODE_MONO)
71 : {
72 1440 : }
73 :
74 : template <class L, class V, class O>
75 94 : void View<L, V, O>::serialize(co::DataOStream& os, const uint64_t dirtyBits)
76 : {
77 94 : Object::serialize(os, dirtyBits);
78 94 : if (dirtyBits & DIRTY_OBSERVER)
79 64 : os << co::ObjectVersion(_observer);
80 94 : if (dirtyBits & DIRTY_FRUSTUM)
81 50 : Frustum::serialize(os);
82 94 : if (dirtyBits & DIRTY_VIEWPORT)
83 50 : os << _data.viewport;
84 94 : if (dirtyBits & DIRTY_OVERDRAW)
85 50 : os << _overdraw;
86 94 : if (dirtyBits & DIRTY_EQUALIZER)
87 56 : os << _equalizer;
88 94 : if (dirtyBits & DIRTY_MINCAPS)
89 50 : os << _minimumCapabilities;
90 94 : if (dirtyBits & DIRTY_MAXCAPS)
91 50 : os << _maximumCapabilities;
92 94 : if (dirtyBits & DIRTY_CAPABILITIES)
93 50 : os << _capabilities;
94 94 : if (dirtyBits & DIRTY_MODE)
95 50 : os << _data.mode;
96 94 : if (dirtyBits & DIRTY_EQUALIZERS)
97 50 : os << _equalizers;
98 94 : if (dirtyBits & DIRTY_MODELUNIT)
99 50 : os << _modelUnit;
100 94 : if (dirtyBits & DIRTY_ATTRIBUTES)
101 64 : os << co::Array<std::string>(_sAttributes, SATTR_ALL);
102 94 : if (dirtyBits & DIRTY_SCREENSHOT)
103 50 : os << _screenshotBuffers;
104 94 : }
105 :
106 : template <class L, class V, class O>
107 44 : void View<L, V, O>::deserialize(co::DataIStream& is, const uint64_t dirtyBits)
108 : {
109 44 : Object::deserialize(is, dirtyBits);
110 44 : if (dirtyBits & DIRTY_OBSERVER)
111 : {
112 16 : co::ObjectVersion observer;
113 16 : is >> observer;
114 :
115 16 : if (observer.identifier == 0)
116 : {
117 0 : if (_observer)
118 0 : _observer->removeView(static_cast<V*>(this));
119 0 : _observer = 0;
120 : }
121 : else
122 : {
123 16 : if (!_observer && _layout) // don't map render client observers yet
124 : {
125 7 : L* layout = getLayout();
126 7 : LBASSERT(layout && layout->getConfig());
127 7 : layout->getConfig()->find(observer.identifier, &_observer);
128 7 : if (_observer)
129 7 : _observer->addView(static_cast<V*>(this));
130 7 : LBASSERT(_observer);
131 7 : LBASSERT(_observer->getID() == observer.identifier);
132 : }
133 16 : if (_observer)
134 : {
135 14 : LBASSERT(_observer->getID() == observer.identifier);
136 14 : if (_observer->isMaster())
137 0 : _observer->sync();
138 : else
139 14 : _observer->sync(observer.version);
140 : }
141 : }
142 : }
143 44 : if (dirtyBits & DIRTY_FRUSTUM)
144 8 : Frustum::deserialize(is);
145 44 : if (dirtyBits & DIRTY_VIEWPORT)
146 8 : is >> _data.viewport;
147 44 : if (dirtyBits & DIRTY_OVERDRAW)
148 8 : is >> _overdraw;
149 44 : if (dirtyBits & DIRTY_EQUALIZER)
150 12 : is >> _equalizer;
151 44 : if (dirtyBits & (DIRTY_MINCAPS | DIRTY_MAXCAPS))
152 : {
153 8 : if (dirtyBits & DIRTY_MINCAPS)
154 8 : is >> _minimumCapabilities;
155 8 : if (dirtyBits & DIRTY_MAXCAPS)
156 8 : is >> _maximumCapabilities;
157 8 : updateCapabilities();
158 : }
159 44 : if (dirtyBits & DIRTY_CAPABILITIES)
160 8 : is >> _capabilities;
161 44 : if (dirtyBits & DIRTY_MODE)
162 : {
163 8 : uint32_t mode(0);
164 8 : is >> mode;
165 8 : activateMode(Mode(mode));
166 : }
167 44 : if (dirtyBits & DIRTY_EQUALIZERS)
168 8 : is >> _equalizers;
169 44 : if (dirtyBits & DIRTY_MODELUNIT)
170 8 : is >> _modelUnit;
171 44 : if (dirtyBits & DIRTY_ATTRIBUTES)
172 15 : is >> co::Array<std::string>(_sAttributes, SATTR_ALL);
173 44 : if (dirtyBits & DIRTY_SCREENSHOT)
174 8 : is >> _screenshotBuffers;
175 44 : }
176 :
177 : template <class L, class V, class O>
178 84 : void View<L, V, O>::setDirty(const uint64_t dirtyBits)
179 : {
180 84 : Object::setDirty(dirtyBits);
181 84 : if (_layout)
182 84 : _layout->setDirty(L::DIRTY_VIEWS);
183 84 : }
184 :
185 : template <class L, class V, class O>
186 176 : void View<L, V, O>::changeMode(const Mode mode)
187 : {
188 176 : if (_data.mode == mode)
189 88 : return;
190 :
191 88 : _data.mode = mode;
192 88 : setDirty(DIRTY_MODE);
193 : }
194 :
195 : template <class L, class V, class O>
196 7 : bool View<L, V, O>::isActive() const
197 : {
198 7 : const L* layout = getLayout();
199 7 : if (!layout)
200 0 : return true; // render client view, active by definition.
201 7 : return layout->isActive();
202 : }
203 :
204 : template <class L, class V, class O>
205 7 : bool View<L, V, O>::setModelUnit(const float modelUnit)
206 : {
207 7 : if (modelUnit < std::numeric_limits<float>::epsilon() ||
208 0 : _modelUnit == modelUnit)
209 : {
210 7 : return false;
211 : }
212 0 : _modelUnit = modelUnit;
213 0 : setDirty(DIRTY_MODELUNIT);
214 0 : return true;
215 : }
216 :
217 : template <class L, class V, class O>
218 158 : float View<L, V, O>::getModelUnit() const
219 : {
220 158 : LBASSERT(_modelUnit > 0.f);
221 158 : return _modelUnit;
222 : }
223 :
224 : template <class L, class V, class O>
225 236 : void View<L, V, O>::setViewport(const Viewport& viewport)
226 : {
227 236 : _data.viewport = viewport;
228 236 : setDirty(DIRTY_VIEWPORT);
229 236 : }
230 :
231 : template <class L, class V, class O>
232 14 : void View<L, V, O>::backup()
233 : {
234 14 : _backup = _data;
235 14 : Frustum::backup();
236 14 : Object::backup();
237 14 : }
238 :
239 : template <class L, class V, class O>
240 0 : void View<L, V, O>::restore()
241 : {
242 0 : Object::restore();
243 0 : Frustum::restore();
244 0 : _data = _backup;
245 0 : _overdraw = Vector2i();
246 0 : _minimumCapabilities = LB_BIT_NONE;
247 0 : _maximumCapabilities = LB_BIT_ALL_64;
248 0 : _capabilities = LB_BIT_ALL_64;
249 0 : _equalizers = EQUALIZER_ALL;
250 0 : _modelUnit = EQ_M;
251 :
252 0 : setDirty(DIRTY_VIEW_BITS);
253 0 : }
254 :
255 : template <class L, class V, class O>
256 688 : void View<L, V, O>::setObserver(O* observer)
257 : {
258 688 : if (_observer == observer)
259 0 : return;
260 :
261 688 : if (_observer)
262 0 : _observer->removeView(static_cast<V*>(this));
263 688 : _observer = observer;
264 688 : if (_observer)
265 688 : _observer->addView(static_cast<V*>(this));
266 688 : setDirty(DIRTY_OBSERVER);
267 : }
268 :
269 : template <class L, class V, class O>
270 2292 : const Viewport& View<L, V, O>::getViewport() const
271 : {
272 2292 : return _data.viewport;
273 : }
274 :
275 : template <class L, class V, class O>
276 0 : void View<L, V, O>::setOverdraw(const Vector2i& pixels)
277 : {
278 0 : if (_overdraw == pixels)
279 0 : return;
280 :
281 0 : _overdraw = pixels;
282 0 : setDirty(DIRTY_OVERDRAW);
283 : }
284 :
285 : template <class L, class V, class O>
286 0 : void View<L, V, O>::useEqualizer(uint32_t bitmask)
287 : {
288 0 : if (_equalizers == bitmask)
289 0 : return;
290 0 : _equalizers = bitmask;
291 0 : setDirty(DIRTY_EQUALIZERS);
292 : }
293 :
294 : template <class L, class V, class O>
295 0 : const Equalizer& View<L, V, O>::getEqualizer() const
296 : {
297 0 : return _equalizer;
298 : }
299 :
300 : template <class L, class V, class O>
301 18 : Equalizer& View<L, V, O>::getEqualizer()
302 : {
303 18 : setDirty(DIRTY_EQUALIZER);
304 18 : return _equalizer;
305 : }
306 :
307 : template <class L, class V, class O>
308 20366 : VisitorResult View<L, V, O>::accept(LeafVisitor<V>& visitor)
309 : {
310 20366 : return visitor.visit(static_cast<V*>(this));
311 : }
312 :
313 : template <class L, class V, class O>
314 0 : VisitorResult View<L, V, O>::accept(LeafVisitor<V>& visitor) const
315 : {
316 0 : return visitor.visit(static_cast<const V*>(this));
317 : }
318 :
319 : template <class L, class V, class O>
320 7 : uint32_t View<L, V, O>::getUserDataLatency() const
321 : {
322 7 : return static_cast<const V*>(this)->getConfig()->getLatency();
323 : }
324 :
325 : template <class L, class V, class O>
326 0 : void View<L, V, O>::setMinimumCapabilities(uint64_t bitmask)
327 : {
328 0 : if (bitmask == _minimumCapabilities)
329 0 : return;
330 :
331 0 : _minimumCapabilities = bitmask;
332 0 : setDirty(DIRTY_MINCAPS);
333 : }
334 :
335 : template <class L, class V, class O>
336 650 : uint64_t View<L, V, O>::getMinimumCapabilities() const
337 : {
338 650 : return _minimumCapabilities;
339 : }
340 :
341 : template <class L, class V, class O>
342 0 : void View<L, V, O>::setMaximumCapabilities(uint64_t bitmask)
343 : {
344 0 : if (bitmask == _maximumCapabilities)
345 0 : return;
346 :
347 0 : _maximumCapabilities = bitmask;
348 0 : setDirty(DIRTY_MAXCAPS);
349 : }
350 :
351 : template <class L, class V, class O>
352 0 : uint64_t View<L, V, O>::getMaximumCapabilities() const
353 : {
354 0 : return _maximumCapabilities;
355 : }
356 :
357 : template <class L, class V, class O>
358 0 : void View<L, V, O>::setCapabilities(uint64_t bitmask)
359 : {
360 0 : if (bitmask == _capabilities)
361 0 : return;
362 :
363 0 : _capabilities = bitmask;
364 0 : setDirty(DIRTY_CAPABILITIES);
365 : }
366 :
367 : template <class L, class V, class O>
368 0 : uint64_t View<L, V, O>::getCapabilities() const
369 : {
370 0 : return _capabilities;
371 : }
372 :
373 : template <class L, class V, class O>
374 0 : void View<L, V, O>::_setScreenshotBuffers(const Frame::Buffer buffers)
375 : {
376 0 : if (_screenshotBuffers == buffers)
377 0 : return;
378 :
379 0 : _screenshotBuffers = buffers;
380 0 : setDirty(DIRTY_SCREENSHOT);
381 : }
382 :
383 : template <class L, class V, class O>
384 1 : Frame::Buffer View<L, V, O>::getScreenshotBuffers() const
385 : {
386 1 : return _screenshotBuffers;
387 : }
388 :
389 : template <class L, class V, class O>
390 16 : const std::string& View<L, V, O>::getSAttribute(const SAttribute attr) const
391 : {
392 16 : LBASSERT(attr < SATTR_ALL);
393 16 : return _sAttributes[attr];
394 : }
395 :
396 : template <class L, class V, class O>
397 1220 : const std::string& View<L, V, O>::getSAttributeString(const SAttribute attr)
398 : {
399 1220 : return _sAttributeStrings[attr];
400 : }
401 :
402 : template <class L, class V, class O>
403 376 : std::ostream& operator<<(std::ostream& os, const View<L, V, O>& view)
404 : {
405 376 : os << lunchbox::disableFlush << lunchbox::disableHeader << "view"
406 : << std::endl;
407 376 : os << "{" << std::endl << lunchbox::indent;
408 :
409 376 : const std::string& name = view.getName();
410 376 : if (!name.empty())
411 2 : os << "name \"" << name << "\"" << std::endl;
412 :
413 376 : const Viewport& vp = view.getViewport();
414 376 : if (vp.isValid() && vp != Viewport::FULL)
415 118 : os << "viewport " << vp << std::endl;
416 :
417 376 : if (view.getMode() == View<L, V, O>::MODE_STEREO)
418 44 : os << "mode STEREO" << std::endl; // MONO is default
419 :
420 376 : const O* observer = static_cast<const O*>(view.getObserver());
421 376 : if (observer)
422 : {
423 364 : const std::string& observerName = observer->getName();
424 364 : const L* layout = view.getLayout();
425 364 : const O* foundObserver = 0;
426 364 : layout->getConfig()->find(observerName, &foundObserver);
427 :
428 364 : if (layout && foundObserver == observer)
429 : {
430 364 : os << "observer \"" << observerName << "\"" << std::endl;
431 : }
432 : else
433 0 : os << observer->getPath() << std::endl;
434 : }
435 :
436 376 : return os << static_cast<const Frustum&>(view) << lunchbox::exdent << "}"
437 376 : << std::endl
438 376 : << lunchbox::enableHeader << lunchbox::enableFlush;
439 : }
440 : }
441 : }
|