Line data Source code
1 :
2 : /* Copyright (c) 2012-2016, Stefan Eilemann <eile@eyescale.ch>
3 : * Julio Delgado Mangas <julio.delgadomangas@epfl.ch>
4 : * Daniel Nachbaur <danielnachbaur@gmail.com>
5 : *
6 : * This library is free software; you can redistribute it and/or modify it under
7 : * the terms of the GNU Lesser General Public License version 2.1 as published
8 : * by the Free Software Foundation.
9 : *
10 : * This library is distributed in the hope that it will be useful, but WITHOUT
11 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 : * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
13 : * details.
14 : *
15 : * You should have received a copy of the GNU Lesser General Public License
16 : * along with this library; if not, write to the Free Software Foundation, Inc.,
17 : * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #include "../channel.h"
21 : #include "../image.h"
22 : #include "../resultImageListener.h"
23 : #include "fileFrameWriter.h"
24 :
25 : #include <boost/foreach.hpp>
26 :
27 : #ifdef EQUALIZER_USE_DEFLECT
28 : # include "../deflect/proxy.h"
29 : #endif
30 :
31 : namespace eq
32 : {
33 :
34 : namespace detail
35 : {
36 : enum State
37 : {
38 : STATE_STOPPED,
39 : STATE_INITIALIZING,
40 : STATE_RUNNING,
41 : STATE_FAILED
42 : };
43 :
44 : class Channel
45 : {
46 : public:
47 811 : Channel()
48 : : state( STATE_STOPPED )
49 : , initialSize( Vector2i::ZERO )
50 : #ifdef EQUALIZER_USE_DEFLECT
51 : , _deflectProxy( 0 )
52 : #endif
53 811 : , _updateFrameBuffer( false )
54 : {
55 811 : lunchbox::RNG rng;
56 811 : color.r() = rng.get< uint8_t >();
57 811 : color.g() = rng.get< uint8_t >();
58 811 : color.b() = rng.get< uint8_t >();
59 811 : }
60 :
61 1 : ~Channel()
62 1 : {
63 1 : statistics->clear();
64 1 : }
65 :
66 0 : void addResultImageListener( ResultImageListener* listener )
67 : {
68 0 : LBASSERT( std::find( resultImageListeners.begin(),
69 : resultImageListeners.end(), listener ) ==
70 : resultImageListeners.end( ));
71 :
72 0 : resultImageListeners.push_back( listener );
73 0 : }
74 :
75 0 : void removeResultImageListener( ResultImageListener* listener )
76 : {
77 : ResultImageListeners::iterator i =
78 : std::find( resultImageListeners.begin(),
79 0 : resultImageListeners.end(), listener );
80 0 : if( i != resultImageListeners.end( ))
81 0 : resultImageListeners.erase( i );
82 0 : }
83 :
84 0 : void frameViewFinish( eq::Channel& channel )
85 : {
86 0 : if( channel.getSAttribute( channel.SATTR_DUMP_IMAGE ).empty( ))
87 0 : removeResultImageListener( &frameWriter );
88 : else
89 : {
90 : ResultImageListeners::iterator i =
91 : std::find( resultImageListeners.begin(),
92 0 : resultImageListeners.end(), &frameWriter );
93 0 : if( i == resultImageListeners.end( ))
94 0 : addResultImageListener( &frameWriter );
95 : }
96 :
97 : #ifdef EQUALIZER_USE_DEFLECT
98 0 : if( _deflectProxy && !_deflectProxy->isRunning( ))
99 : {
100 0 : delete _deflectProxy;
101 0 : _deflectProxy = 0;
102 : }
103 : #endif
104 :
105 0 : if( resultImageListeners.empty( ))
106 0 : return;
107 :
108 0 : downloadFramebuffer( channel );
109 0 : BOOST_FOREACH( ResultImageListener* listener, resultImageListeners )
110 0 : listener->notifyNewImage( channel, framebufferImage );
111 : }
112 :
113 0 : void downloadFramebuffer( eq::Channel& channel )
114 : {
115 0 : framebufferImage.setAlphaUsage( true );
116 0 : framebufferImage.setQuality( eq::Frame::BUFFER_COLOR, 1.0f );
117 0 : framebufferImage.setStorageType( eq::Frame::TYPE_MEMORY );
118 0 : framebufferImage.setInternalFormat( eq::Frame::BUFFER_COLOR, GL_RGBA );
119 :
120 0 : if( framebufferImage.startReadback( eq::Frame::BUFFER_COLOR,
121 0 : channel.getPixelViewport(),
122 0 : channel.getContext(),
123 0 : channel.getZoom(),
124 0 : channel.getObjectManager( )))
125 : {
126 0 : framebufferImage.finishReadback( channel.glewGetContext( ));
127 : }
128 0 : }
129 :
130 : /** The configInit/configExit state. */
131 : State state;
132 :
133 : /** A random, unique color for this channel. */
134 : Vector3ub color;
135 :
136 : typedef std::vector< Statistic > Statistics;
137 4 : struct FrameStatistics
138 : {
139 : Statistics data; //!< all events for one frame
140 : eq::Viewport region; //!< from draw for equalizers
141 : /** reference count by pipe and transmit thread */
142 : lunchbox::a_int32_t used;
143 : };
144 :
145 : typedef std::vector< FrameStatistics > StatisticsRB;
146 : typedef StatisticsRB::const_iterator StatisticsRBCIter;
147 :
148 : /** Global statistics events, index per frame and channel. */
149 : lunchbox::Lockable< StatisticsRB, lunchbox::SpinLock > statistics;
150 :
151 : /** The initial channel size, used for view resize events. */
152 : Vector2i initialSize;
153 :
154 : /** The application-declared regions of interest, merged if
155 : necessary to be non overlapping. */
156 : PixelViewports regions;
157 :
158 : /** The number of the last finished frame. */
159 : lunchbox::Monitor< uint32_t > finishedFrame;
160 :
161 : /** Listeners that get notified on each new rendered image */
162 : typedef std::vector< ResultImageListener* > ResultImageListeners;
163 : ResultImageListeners resultImageListeners;
164 :
165 : /** Image of the current framebuffer if result listeners are present */
166 : eq::Image framebufferImage;
167 :
168 : #ifdef EQUALIZER_USE_DEFLECT
169 : deflect::Proxy* _deflectProxy;
170 : #endif
171 :
172 : /** Dumps images when the channel is configured to do so */
173 : FileFrameWriter frameWriter;
174 :
175 : bool _updateFrameBuffer;
176 : };
177 :
178 : }
179 : }
|