Line data Source code
1 :
2 : /* Copyright (c) 2009-2013, Stefan Eilemann <eile@equalizergraphics.com>
3 : *
4 : * This library is free software; you can redistribute it and/or modify it under
5 : * the terms of the GNU Lesser General Public License version 2.1 as published
6 : * by the Free Software Foundation.
7 : *
8 : * This library is distributed in the hope that it will be useful, but WITHOUT
9 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
10 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
11 : * details.
12 : *
13 : * You should have received a copy of the GNU Lesser General Public License
14 : * along with this library; if not, write to the Free Software Foundation, Inc.,
15 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
16 : */
17 :
18 : #include "monitorEqualizer.h"
19 :
20 : #include "../compound.h"
21 : #include "../compoundVisitor.h"
22 : #include "../config.h"
23 : #include "../frame.h"
24 : #include "../log.h"
25 : #include "../segment.h"
26 : #include "../view.h"
27 :
28 : #include <eq/fabric/viewport.h>
29 : #include <eq/fabric/zoom.h>
30 : #include <lunchbox/debug.h>
31 :
32 : namespace eq
33 : {
34 : namespace server
35 : {
36 : namespace
37 : {
38 : class OutputFrameFinder : public CompoundVisitor
39 : {
40 : public:
41 0 : explicit OutputFrameFinder(const std::string& name)
42 0 : : _frame(0)
43 0 : , _name(name)
44 : {
45 0 : }
46 :
47 0 : virtual ~OutputFrameFinder() {}
48 0 : virtual VisitorResult visit(const Compound* compound)
49 : {
50 0 : const Frames& outputFrames = compound->getOutputFrames();
51 0 : for (Frames::const_iterator i = outputFrames.begin();
52 0 : i != outputFrames.end(); ++i)
53 : {
54 0 : Frame* frame = *i;
55 :
56 0 : if (frame->getName() == _name)
57 : {
58 0 : _frame = frame;
59 0 : return TRAVERSE_TERMINATE;
60 : }
61 : }
62 0 : return TRAVERSE_CONTINUE;
63 : }
64 :
65 0 : Frame* getResult() { return _frame; }
66 : private:
67 : Frame* _frame;
68 : const std::string& _name;
69 : };
70 : }
71 :
72 4 : MonitorEqualizer::MonitorEqualizer()
73 : {
74 4 : LBINFO << "New monitor equalizer @" << (void*)this << std::endl;
75 4 : }
76 :
77 0 : MonitorEqualizer::MonitorEqualizer(const MonitorEqualizer& from)
78 0 : : Equalizer(from)
79 : {
80 0 : }
81 :
82 12 : MonitorEqualizer::~MonitorEqualizer()
83 : {
84 4 : attach(0);
85 4 : LBINFO << "Delete monitor equalizer @" << (void*)this << std::endl;
86 8 : }
87 :
88 12 : void MonitorEqualizer::attach(Compound* compound)
89 : {
90 12 : _outputFrames.clear();
91 12 : _viewports.clear();
92 12 : Equalizer::attach(compound);
93 12 : }
94 :
95 0 : void MonitorEqualizer::notifyUpdatePre(Compound*, const uint32_t)
96 : {
97 0 : _updateViewports();
98 0 : _updateZoomAndOffset();
99 0 : }
100 :
101 0 : void MonitorEqualizer::_updateViewports()
102 : {
103 0 : if (!_outputFrames.empty())
104 0 : return;
105 :
106 0 : Compound* compound = getCompound();
107 0 : if (!compound)
108 0 : return;
109 :
110 0 : const Frames& inputFrames = compound->getInputFrames();
111 0 : for (Frames::const_iterator i = inputFrames.begin(); i != inputFrames.end();
112 : ++i)
113 : {
114 0 : const Frame* frame = *i;
115 0 : const Compound* root = compound->getRoot();
116 :
117 : // find the output frame
118 0 : OutputFrameFinder frameFinder(frame->getName());
119 0 : root->accept(frameFinder);
120 0 : Frame* outputFrame = frameFinder.getResult();
121 :
122 0 : _outputFrames.push_back(outputFrame);
123 0 : _viewports.push_back(Viewport::FULL);
124 :
125 0 : if (outputFrame)
126 : {
127 0 : const Channel* channel = outputFrame->getChannel();
128 0 : const Segment* segment = channel->getSegment();
129 0 : const View* view = channel->getView();
130 :
131 0 : if (view)
132 : {
133 0 : Viewport viewport(segment->getViewport());
134 0 : viewport.intersect(view->getViewport());
135 :
136 0 : _viewports.back() = viewport;
137 : }
138 : }
139 : }
140 : }
141 :
142 0 : void MonitorEqualizer::_updateZoomAndOffset()
143 : {
144 0 : const Compound* compound(getCompound());
145 0 : const PixelViewport& pvp(compound->getInheritPixelViewport());
146 :
147 0 : const Frames& inputFrames(compound->getInputFrames());
148 0 : const size_t size(inputFrames.size());
149 0 : LBASSERTINFO(size == _outputFrames.size(), size << " != "
150 : << _outputFrames.size());
151 0 : LBASSERT(size == _viewports.size());
152 :
153 0 : for (size_t i = 0; i < size; ++i)
154 : {
155 0 : Frame* frame = inputFrames[i];
156 0 : Frame* outputFrame = _outputFrames[i];
157 0 : if (!outputFrame)
158 0 : continue;
159 :
160 0 : const Compound* srcCompound = outputFrame->getCompound();
161 0 : const Viewport& viewport = _viewports[i];
162 :
163 : // compute and apply input frame offset
164 0 : const int32_t offsetX = int32_t(float(pvp.w) * viewport.x);
165 0 : const int32_t offsetY = int32_t(float(pvp.h) * viewport.y);
166 0 : frame->setNativeOffset(Vector2i(offsetX, offsetY));
167 :
168 : // compute and apply output frame zoom
169 0 : const int32_t width = int32_t(float(pvp.w) * viewport.w);
170 0 : const int32_t height = int32_t(float(pvp.h) * viewport.h);
171 0 : const PixelViewport& srcPVP(srcCompound->getInheritPixelViewport());
172 0 : const Zoom zoom(float(width) / float(srcPVP.w),
173 0 : float(height) / float(srcPVP.h));
174 0 : outputFrame->setNativeZoom(zoom);
175 : }
176 0 : }
177 :
178 2 : std::ostream& operator<<(std::ostream& os, const MonitorEqualizer* equalizer)
179 : {
180 2 : if (equalizer)
181 2 : os << "monitor_equalizer {}" << std::endl;
182 2 : return os;
183 : }
184 : }
185 60 : }
|