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 : explicit OutputFrameFinder( const std::string& name )
43 0 : : _frame(0) , _name( name ) {}
44 :
45 0 : virtual ~OutputFrameFinder(){}
46 :
47 0 : virtual VisitorResult visit( const Compound* compound )
48 : {
49 0 : const Frames& outputFrames = compound->getOutputFrames();
50 0 : for( Frames::const_iterator i = outputFrames.begin();
51 0 : i != outputFrames.end(); ++i )
52 : {
53 0 : Frame* frame = *i;
54 :
55 0 : if ( frame->getName() == _name )
56 : {
57 0 : _frame = frame;
58 0 : return TRAVERSE_TERMINATE;
59 : }
60 : }
61 0 : return TRAVERSE_CONTINUE;
62 : }
63 :
64 0 : Frame* getResult() { return _frame; }
65 :
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 0 : {}
80 :
81 12 : MonitorEqualizer::~MonitorEqualizer()
82 : {
83 4 : attach( 0 );
84 4 : LBINFO << "Delete monitor equalizer @" << (void*)this << std::endl;
85 8 : }
86 :
87 12 : void MonitorEqualizer::attach( Compound* compound )
88 : {
89 12 : _outputFrames.clear();
90 12 : _viewports.clear();
91 12 : Equalizer::attach( compound );
92 12 : }
93 :
94 0 : void MonitorEqualizer::notifyUpdatePre( Compound*, const uint32_t )
95 : {
96 0 : _updateViewports();
97 0 : _updateZoomAndOffset();
98 0 : }
99 :
100 0 : void MonitorEqualizer::_updateViewports()
101 : {
102 0 : if( !_outputFrames.empty( ))
103 0 : return;
104 :
105 0 : Compound* compound = getCompound();
106 0 : if( !compound )
107 0 : return;
108 :
109 0 : const Frames& inputFrames = compound->getInputFrames();
110 0 : for( Frames::const_iterator i = inputFrames.begin();
111 0 : i != inputFrames.end(); ++i )
112 : {
113 0 : const Frame* frame = *i;
114 0 : const Compound* root = compound->getRoot();
115 :
116 : // find the output frame
117 0 : OutputFrameFinder frameFinder( frame->getName() );
118 0 : root->accept( frameFinder );
119 0 : Frame* outputFrame = frameFinder.getResult();
120 :
121 0 : _outputFrames.push_back( outputFrame );
122 0 : _viewports.push_back( Viewport::FULL );
123 :
124 0 : if( outputFrame )
125 : {
126 0 : const Channel* channel = outputFrame->getChannel();
127 0 : const Segment* segment = channel->getSegment();
128 0 : const View* view = channel->getView();
129 :
130 0 : if( view )
131 : {
132 0 : Viewport viewport( segment->getViewport( ));
133 0 : viewport.intersect( view->getViewport( ));
134 :
135 0 : _viewports.back() = viewport;
136 : }
137 : }
138 0 : }
139 : }
140 :
141 0 : void MonitorEqualizer::_updateZoomAndOffset()
142 : {
143 0 : const Compound* compound( getCompound( ));
144 0 : const PixelViewport& pvp( compound->getInheritPixelViewport( ));
145 :
146 0 : const Frames& inputFrames( compound->getInputFrames( ));
147 0 : const size_t size( inputFrames.size( ));
148 0 : LBASSERTINFO( size == _outputFrames.size(),
149 : size << " != " << _outputFrames.size( ));
150 0 : LBASSERT( size == _viewports.size( ));
151 :
152 0 : for( size_t i = 0; i < size; ++i )
153 : {
154 0 : Frame* frame = inputFrames[ i ];
155 0 : Frame* outputFrame = _outputFrames[ i ];
156 0 : if( !outputFrame )
157 0 : continue;
158 :
159 0 : const Compound* srcCompound = outputFrame->getCompound();
160 0 : const Viewport& viewport = _viewports[ i ];
161 :
162 : // compute and apply input frame offset
163 0 : const int32_t offsetX = int32_t( float( pvp.w ) * viewport.x );
164 0 : const int32_t offsetY = int32_t( float( pvp.h ) * viewport.y );
165 0 : frame->setNativeOffset( Vector2i( offsetX, offsetY ));
166 :
167 : // compute and apply output frame zoom
168 0 : const int32_t width = int32_t( float( pvp.w ) * viewport.w );
169 0 : const int32_t height = int32_t( float( pvp.h ) * viewport.h ) ;
170 0 : const PixelViewport& srcPVP( srcCompound->getInheritPixelViewport( ));
171 : const Zoom zoom( float( width ) / float( srcPVP.w ),
172 0 : float( height ) / float( srcPVP.h ));
173 0 : outputFrame->setNativeZoom( zoom );
174 : }
175 0 : }
176 :
177 2 : std::ostream& operator << ( std::ostream& os, const MonitorEqualizer* equalizer)
178 : {
179 2 : if( equalizer )
180 2 : os << "monitor_equalizer {}" << std::endl;
181 2 : return os;
182 : }
183 :
184 : }
185 84 : }
|