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 "dfrEqualizer.h"
19 :
20 : #include "../compound.h"
21 : #include "../compoundVisitor.h"
22 : #include "../config.h"
23 : #include "../log.h"
24 :
25 : #include <eq/client/statistic.h>
26 : #include <eq/fabric/zoom.h>
27 : #include <lunchbox/debug.h>
28 :
29 : namespace eq
30 : {
31 : namespace server
32 : {
33 :
34 8 : DFREqualizer::DFREqualizer()
35 8 : : _current ( getFrameRate( ))
36 16 : , _lastTime( 0 )
37 : {
38 8 : LBINFO << "New DFREqualizer @" << (void*)this << std::endl;
39 8 : }
40 :
41 24 : DFREqualizer::~DFREqualizer()
42 : {
43 8 : attach( 0 );
44 8 : LBINFO << "Delete DFREqualizer @" << (void*)this << std::endl;
45 16 : }
46 :
47 24 : void DFREqualizer::attach( Compound* compound )
48 : {
49 24 : Compound* oldCompound = getCompound();
50 24 : if( oldCompound )
51 : {
52 8 : Channel* channel = oldCompound->getChannel();
53 8 : LBASSERT( channel );
54 :
55 : // Unsubscribe to channel load notification
56 8 : channel->removeListener( this );
57 : }
58 :
59 24 : Equalizer::attach( compound );
60 :
61 24 : if( compound )
62 : {
63 8 : Channel* channel = compound->getChannel();
64 8 : LBASSERT( channel );
65 :
66 : // Subscribe to channel load notification
67 8 : if( compound->getParent() && channel )
68 8 : channel->addListener( this );
69 : }
70 24 : }
71 :
72 0 : void DFREqualizer::notifyUpdatePre( Compound* compound, const uint32_t/*frame*/)
73 : {
74 0 : LBASSERT( compound == getCompound( ));
75 :
76 0 : if( isFrozen() || !compound->isActive() || !isActive( ))
77 : {
78 0 : compound->setZoom( Zoom::NONE );
79 0 : return;
80 : }
81 :
82 0 : LBASSERT( getDamping() >= 0.f );
83 0 : LBASSERT( getDamping() <= 1.f );
84 :
85 0 : const float factor = ( sqrtf( _current / getFrameRate( )) - 1.f ) *
86 0 : getDamping() + 1.f;
87 :
88 0 : Zoom newZoom( compound->getZoom( ));
89 0 : newZoom *= factor;
90 :
91 : //LBINFO << _current << ": " << factor << " = " << newZoom << std::endl;
92 :
93 : // clip zoom factor to min( 128px ), max( channel pvp )
94 0 : const Compound* parent = compound->getParent();
95 0 : const eq::PixelViewport& pvp = parent->getInheritPixelViewport();
96 :
97 0 : const Channel* channel = compound->getChannel();
98 0 : const eq::PixelViewport& channelPVP = channel->getPixelViewport();
99 :
100 0 : const float minZoom = 128.f / LB_MIN( static_cast< float >( pvp.h ),
101 : static_cast< float >( pvp.w ));
102 0 : const float maxZoom = LB_MIN( static_cast< float >( channelPVP.w ) /
103 : static_cast< float >( pvp.w ),
104 : static_cast< float >( channelPVP.h ) /
105 : static_cast< float >( pvp.h ));
106 :
107 0 : newZoom.x() = LB_MAX( newZoom.x(), minZoom );
108 0 : newZoom.x() = LB_MIN( newZoom.x(), maxZoom );
109 0 : newZoom.y() = newZoom.x();
110 :
111 0 : compound->setZoom( newZoom );
112 : }
113 :
114 0 : void DFREqualizer::notifyLoadData( Channel* channel, const uint32_t frameNumber,
115 : const Statistics& statistics,
116 : const Viewport& /*region*/ )
117 : {
118 : // gather and notify load data
119 0 : int64_t endTime = 0;
120 0 : for( size_t i = 0; i < statistics.size(); ++i )
121 : {
122 0 : const eq::Statistic& data = statistics[i];
123 0 : switch( data.type )
124 : {
125 : case eq::Statistic::CHANNEL_CLEAR:
126 : case eq::Statistic::CHANNEL_DRAW:
127 : case eq::Statistic::CHANNEL_ASSEMBLE:
128 : case eq::Statistic::CHANNEL_READBACK:
129 0 : endTime = LB_MAX( endTime, data.endTime );
130 0 : break;
131 :
132 : default:
133 0 : break;
134 : }
135 : }
136 :
137 0 : if( endTime == 0 )
138 0 : return;
139 :
140 0 : const int64_t time = endTime - _lastTime;
141 0 : _lastTime = endTime;
142 :
143 0 : if( _lastTime <= 0 || time <= 0 )
144 0 : return;
145 :
146 0 : _current = 1000.0f / static_cast< float >( time );
147 0 : LBLOG( LOG_LB1 ) << "Frame " << frameNumber << " channel "
148 0 : << channel->getName() << " time " << time << std::endl;
149 : }
150 :
151 4 : std::ostream& operator << ( std::ostream& os, const DFREqualizer* lb )
152 : {
153 4 : if( !lb )
154 0 : return os;
155 :
156 4 : os << lunchbox::disableFlush
157 4 : << "DFR_equalizer " << std::endl
158 4 : << '{' << std::endl
159 8 : << " framerate " << lb->getFrameRate() << std::endl;
160 :
161 4 : if( lb->getDamping() != 0.5f )
162 0 : os << " damping " << lb->getDamping() << std::endl;
163 :
164 4 : os << '}' << std::endl << lunchbox::enableFlush;
165 4 : return os;
166 : }
167 :
168 : }
169 27 : }
|