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