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 : const float factor =
87 0 : (sqrtf(_current / getFrameRate()) - 1.f) * 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 : const float minZoom =
102 0 : MINSIZE / LB_MIN(static_cast<float>(pvp.h), static_cast<float>(pvp.w));
103 : const float maxZoom =
104 0 : LB_MIN(static_cast<float>(channelPVP.w) / static_cast<float>(pvp.w),
105 : static_cast<float>(channelPVP.h) / 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 Statistic& data = statistics[i];
123 0 : switch (data.type)
124 : {
125 : case Statistic::CHANNEL_CLEAR:
126 : case Statistic::CHANNEL_DRAW:
127 : case Statistic::CHANNEL_ASSEMBLE:
128 : case 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 8 : std::ostream& operator<<(std::ostream& os, const DFREqualizer* lb)
152 : {
153 8 : if (!lb)
154 0 : return os;
155 :
156 8 : os << lunchbox::disableFlush << "DFR_equalizer " << std::endl
157 8 : << '{' << std::endl
158 16 : << " framerate " << lb->getFrameRate() << std::endl;
159 :
160 8 : if (lb->getDamping() != 0.5f)
161 0 : os << " damping " << lb->getDamping() << std::endl;
162 :
163 8 : os << '}' << std::endl << lunchbox::enableFlush;
164 8 : return os;
165 : }
166 : }
167 60 : }
|