Line data Source code
1 :
2 : /* Copyright (c) 2006-2011, Stefan Eilemann <eile@equalizergraphics.com>
3 : * 2010, 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 "loader.h"
20 :
21 : #include "canvas.h"
22 : #include "compound.h"
23 : #include "configVisitor.h"
24 : #include "connectionDescription.h"
25 : #include "config.h"
26 : #include "global.h"
27 : #include "layout.h"
28 : #include "node.h"
29 : #include "observer.h"
30 : #include "segment.h"
31 : #include "view.h"
32 :
33 : #include <eq/fabric/elementVisitor.h>
34 :
35 : namespace eq
36 : {
37 : namespace server
38 : {
39 : #include "convert11Visitor.h"
40 : #include "convert12Visitor.h"
41 :
42 : namespace
43 : {
44 112 : class UnusedOutputChannelFinder : public ConfigVisitor
45 : {
46 : public:
47 112 : UnusedOutputChannelFinder() : _candidate( 0 ) {}
48 :
49 5736 : virtual VisitorResult visit( Channel* channel )
50 : {
51 5736 : if( _candidate ) // testing a candidate (see below)
52 4971 : return TRAVERSE_CONTINUE;
53 :
54 765 : const View* view = channel->getView();
55 765 : if( !view )
56 416 : return TRAVERSE_CONTINUE;
57 :
58 : // see if it is used as a destination channel
59 349 : _candidate = channel;
60 349 : Config* config = channel->getConfig();
61 349 : config->accept( *this );
62 :
63 349 : if( _candidate ) // survived - not a destination channel yet
64 136 : _channels.push_back( _candidate );
65 349 : _candidate = 0;
66 :
67 349 : return TRAVERSE_CONTINUE;
68 : };
69 :
70 1968 : virtual VisitorResult visit( Compound* compound )
71 : {
72 1968 : if( !_candidate ) // not testing a candidate (see above)
73 133 : return TRAVERSE_PRUNE;
74 :
75 1835 : const Channel* channel = compound->getChannel();
76 1835 : if( !channel )
77 333 : return TRAVERSE_CONTINUE;
78 :
79 1502 : if( _candidate == channel )
80 : {
81 213 : _candidate = 0; // channel already used
82 213 : return TRAVERSE_TERMINATE;
83 : }
84 1289 : return TRAVERSE_PRUNE; // only check destination channels
85 : }
86 :
87 112 : const Channels& getResult() const { return _channels; }
88 :
89 : private:
90 : Channel* _candidate;
91 : Channels _channels;
92 : };
93 :
94 : }
95 :
96 126 : Compounds Loader::addOutputCompounds( ServerPtr server )
97 : {
98 126 : Compounds result;
99 :
100 126 : const Configs& configs = server->getConfigs();
101 238 : for( Configs::const_iterator i = configs.begin(); i != configs.end(); ++i )
102 : {
103 112 : UnusedOutputChannelFinder finder;
104 112 : Config* config = *i;
105 112 : config->accept( finder );
106 :
107 224 : Channels channels = finder.getResult();
108 319 : while( !channels.empty( ))
109 : {
110 95 : const Layout* layout = channels.front()->getLayout();
111 :
112 95 : Compound* group = new Compound( config );
113 566 : for( ChannelsIter j = channels.begin(); j != channels.end(); )
114 : {
115 376 : Channel* channel = *j;
116 376 : if( channel->getLayout() == layout )
117 : {
118 136 : Compound* compound = new Compound( group );
119 136 : compound->setChannel( channel );
120 136 : j = channels.erase( j );
121 : }
122 : else
123 240 : ++j;
124 : }
125 95 : result.push_back( group );
126 : }
127 112 : }
128 126 : return result;
129 : }
130 :
131 118 : void Loader::convertTo11( ServerPtr server )
132 : {
133 118 : ConvertTo11Visitor visitor;
134 118 : server->accept( visitor );
135 118 : }
136 :
137 118 : void Loader::convertTo12( ServerPtr server )
138 : {
139 118 : ConvertTo12Visitor visitor;
140 118 : server->accept( visitor );
141 118 : }
142 :
143 : namespace
144 : {
145 0 : static void _addDestinationViews( Compound* compound )
146 : {
147 0 : Channel* channel = compound->getChannel();
148 :
149 0 : if( channel ) // stand-alone channel
150 : {
151 0 : if( channel->getView( ))
152 0 : return;
153 :
154 0 : Config* config = compound->getConfig();
155 0 : Layout* layout = new Layout( config );
156 0 : View* view = new View( layout );
157 0 : *static_cast< eq::Frustum* >( view ) = compound->getFrustum();
158 :
159 0 : Canvas* canvas = new Canvas( config );
160 0 : canvas->addLayout( layout );
161 :
162 0 : Segment* segment = new Segment( canvas );
163 0 : segment->setChannel( channel );
164 :
165 0 : config->activateCanvas( canvas );
166 :
167 0 : Channel* newChannel = config->findChannel( segment, view );
168 0 : LBASSERT( newChannel );
169 :
170 0 : compound->setChannel( newChannel );
171 0 : compound->setViewport( Viewport::FULL );
172 :
173 0 : return;
174 : }
175 :
176 : // segment group
177 0 : Compounds segments;
178 0 : const Compounds& children = compound->getChildren();
179 0 : for( Compounds::const_iterator i = children.begin();
180 0 : i != children.end(); ++i )
181 : {
182 0 : Compound* child = *i;
183 0 : Channel* childChannel = child->getChannel();
184 0 : if( childChannel )
185 : {
186 0 : if( !childChannel->getView( ))
187 0 : segments.push_back( child );
188 : }
189 : else
190 0 : _addDestinationViews( child );
191 : }
192 :
193 0 : if( segments.empty( ))
194 0 : return;
195 :
196 0 : Config* config = compound->getConfig();
197 0 : Layout* layout = new Layout( config );
198 0 : View* view = new View( layout );
199 0 : Canvas* canvas = new Canvas( config );
200 :
201 0 : canvas->addLayout( layout );
202 0 : *static_cast< eq::Frustum* >( canvas ) = compound->getFrustum();
203 :
204 0 : for( Compounds::const_iterator i = segments.begin();
205 0 : i != segments.end(); ++i )
206 : {
207 0 : Compound* child = *i;
208 0 : Segment* segment = new Segment( canvas );
209 :
210 0 : segment->setChannel( child->getChannel( ));
211 0 : segment->setViewport( child->getViewport( ));
212 0 : *static_cast< eq::Frustum* >( segment ) = child->getFrustum();
213 : }
214 :
215 0 : config->activateCanvas( canvas );
216 :
217 0 : for( size_t i = 0; i < segments.size(); ++i )
218 : {
219 0 : Segment* segment = canvas->getSegments()[ i ];
220 0 : Channel* newChannel = config->findChannel( segment, view );
221 0 : LBASSERT( newChannel );
222 :
223 0 : segments[i]->setChannel( newChannel );
224 0 : segments[i]->setViewport( Viewport::FULL );
225 0 : }
226 : }
227 :
228 236 : class AddDestinationViewVisitor : public ServerVisitor
229 : {
230 104 : virtual VisitorResult visitPre( Config* config )
231 : {
232 104 : if( config->getCanvases().empty( ))
233 0 : return TRAVERSE_CONTINUE;
234 :
235 104 : return TRAVERSE_PRUNE; // Config has already canvases, ignore.
236 : }
237 :
238 0 : virtual VisitorResult visit( Compound* compound )
239 : {
240 0 : _addDestinationViews( compound );
241 0 : return TRAVERSE_PRUNE;
242 : }
243 : };
244 :
245 : }
246 :
247 118 : void Loader::addDestinationViews( ServerPtr server )
248 : {
249 118 : AddDestinationViewVisitor visitor;
250 118 : server->accept( visitor );
251 118 : }
252 :
253 : namespace
254 : {
255 236 : class AddObserverVisitor : public ServerVisitor
256 : {
257 104 : virtual VisitorResult visitPre( Config* config )
258 : {
259 104 : const Observers& observers = config->getObservers();
260 104 : if( !observers.empty( ))
261 98 : return TRAVERSE_PRUNE;
262 :
263 6 : new Observer( config );
264 6 : return TRAVERSE_CONTINUE;
265 : }
266 :
267 13 : virtual VisitorResult visit( View* view )
268 : {
269 13 : const Observers& observers = view->getConfig()->getObservers();
270 13 : LBASSERT( observers.size() == 1 );
271 :
272 13 : view->setObserver( observers.front( ));
273 13 : return TRAVERSE_CONTINUE;
274 : }
275 : };
276 :
277 : }
278 :
279 118 : void Loader::addDefaultObserver( ServerPtr server )
280 : {
281 118 : AddObserverVisitor visitor;
282 118 : server->accept( visitor );
283 118 : }
284 :
285 : }
286 27 : }
|