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 "../config.h"
22 : #include "../compoundVisitor.h"
23 : #include "../log.h"
24 : #include "../frame.h"
25 : #include "../view.h"
26 : #include "../segment.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 :
37 : namespace
38 : {
39 : class OutputFrameFinder : public CompoundVisitor
40 : {
41 : public:
42 0 : OutputFrameFinder( const std::string& name )
43 : : _frame(0)
44 0 : , _name( name ) {}
45 :
46 0 : virtual ~OutputFrameFinder(){}
47 :
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 :
67 : private:
68 : Frame* _frame;
69 : const std::string& _name;
70 : };
71 : }
72 :
73 2 : MonitorEqualizer::MonitorEqualizer()
74 : {
75 2 : LBINFO << "New monitor equalizer @" << (void*)this << std::endl;
76 2 : }
77 :
78 0 : MonitorEqualizer::MonitorEqualizer( const MonitorEqualizer& from )
79 0 : : Equalizer( from )
80 0 : {}
81 :
82 6 : MonitorEqualizer::~MonitorEqualizer()
83 : {
84 2 : attach( 0 );
85 2 : LBINFO << "Delete monitor equalizer @" << (void*)this << std::endl;
86 4 : }
87 :
88 6 : void MonitorEqualizer::attach( Compound* compound )
89 : {
90 6 : _outputFrames.clear();
91 6 : _viewports.clear();
92 6 : Equalizer::attach( compound );
93 6 : }
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();
112 0 : i != inputFrames.end(); ++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( eq::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 0 : }
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(),
150 : size << " != " << _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 : 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 1 : std::ostream& operator << ( std::ostream& os, const MonitorEqualizer* equalizer)
179 : {
180 1 : if( equalizer )
181 1 : os << "monitor_equalizer {}" << std::endl;
182 1 : return os;
183 : }
184 :
185 : }
186 27 : }
|