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