LCOV - code coverage report
Current view: top level - eq/detail - channel.ipp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 27 60 45.0 %
Date: 2017-12-16 05:07:20 Functions: 7 10 70.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2012-2017, 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             : #ifdef EQUALIZER_USE_DEFLECT
      26             : #include "../deflect/proxy.h"
      27             : #endif
      28             : 
      29             : namespace eq
      30             : {
      31             : namespace detail
      32             : {
      33             : enum State
      34             : {
      35             :     STATE_STOPPED,
      36             :     STATE_INITIALIZING,
      37             :     STATE_RUNNING,
      38             :     STATE_FAILED
      39             : };
      40             : 
      41             : class Channel
      42             : {
      43             : public:
      44           2 :     Channel()
      45           2 :         : state(STATE_STOPPED)
      46             : #ifdef EQUALIZER_USE_DEFLECT
      47             :         , _deflectProxy(0)
      48             : #endif
      49           2 :         , _updateFrameBuffer(false)
      50             :     {
      51           4 :         lunchbox::RNG rng;
      52           1 :         color.r() = rng.get<uint8_t>();
      53           2 :         color.g() = rng.get<uint8_t>();
      54           2 :         color.b() = rng.get<uint8_t>();
      55           1 :     }
      56             : 
      57           2 :     ~Channel() { statistics->clear(); }
      58           0 :     void addResultImageListener(ResultImageListener* listener)
      59             :     {
      60           0 :         LBASSERT(std::find(resultImageListeners.begin(),
      61             :                            resultImageListeners.end(),
      62             :                            listener) == resultImageListeners.end());
      63             : 
      64           0 :         resultImageListeners.push_back(listener);
      65           0 :     }
      66             : 
      67           1 :     void removeResultImageListener(ResultImageListener* listener)
      68             :     {
      69             :         ResultImageListeners::iterator i =
      70             :             std::find(resultImageListeners.begin(), resultImageListeners.end(),
      71           1 :                       listener);
      72           1 :         if (i != resultImageListeners.end())
      73           0 :             resultImageListeners.erase(i);
      74           1 :     }
      75             : 
      76           1 :     void frameViewFinish(eq::Channel& channel)
      77             :     {
      78           1 :         if (channel.getSAttribute(channel.SATTR_DUMP_IMAGE).empty())
      79           1 :             removeResultImageListener(&frameWriter);
      80             :         else
      81             :         {
      82             :             ResultImageListeners::iterator i =
      83             :                 std::find(resultImageListeners.begin(),
      84           0 :                           resultImageListeners.end(), &frameWriter);
      85           0 :             if (i == resultImageListeners.end())
      86           0 :                 addResultImageListener(&frameWriter);
      87             :         }
      88             : 
      89             : #ifdef EQUALIZER_USE_DEFLECT
      90           1 :         if (_deflectProxy && !_deflectProxy->isRunning())
      91             :         {
      92           0 :             delete _deflectProxy;
      93           0 :             _deflectProxy = 0;
      94             :         }
      95             : #endif
      96             : 
      97           1 :         eq::View* view = channel.getView();
      98           1 :         eq::Frame::Buffer buffers = view->getScreenshotBuffers();
      99           1 :         if (!resultImageListeners.empty())
     100           0 :             buffers |= eq::Frame::Buffer::color;
     101             : 
     102           1 :         if (buffers == eq::Frame::Buffer::none)
     103           1 :             return;
     104             : 
     105           0 :         downloadFramebuffer(channel, buffers);
     106           0 :         for (ResultImageListener* listener : resultImageListeners)
     107           0 :             listener->notifyNewImage(channel, framebufferImage);
     108           0 :         _finishImageListeners = true;
     109             : 
     110           0 :         if (view->getScreenshotBuffers() != eq::Frame::Buffer::none)
     111             :         {
     112           0 :             view->sendScreenshotEvent(channel.getViewport(),
     113             :                                       channel.getPipe()->getCurrentFrame(),
     114           0 :                                       framebufferImage);
     115             :         }
     116             :     }
     117             : 
     118           2 :     void frameFinish()
     119             :     {
     120           2 :         if (_finishImageListeners)
     121           0 :             for (ResultImageListener* listener : resultImageListeners)
     122           0 :                 listener->notifyFinishFrame();
     123           2 :         _finishImageListeners = false;
     124           2 :     }
     125             : 
     126           0 :     void downloadFramebuffer(eq::Channel& channel,
     127             :                              const eq::Frame::Buffer buffers)
     128             :     {
     129           0 :         framebufferImage.setAlphaUsage(true);
     130           0 :         framebufferImage.setQuality(eq::Frame::Buffer::color, 1.0f);
     131           0 :         framebufferImage.setStorageType(eq::Frame::TYPE_MEMORY);
     132           0 :         framebufferImage.setInternalFormat(eq::Frame::Buffer::color, GL_RGBA);
     133             : 
     134           0 :         if (buffers & eq::Frame::Buffer::color)
     135           0 :             framebufferImage.startReadback(eq::Frame::Buffer::color,
     136             :                                            channel.getPixelViewport(),
     137             :                                            channel.getContext(),
     138             :                                            channel.getZoom(),
     139           0 :                                            channel.getObjectManager());
     140             : 
     141           0 :         if (buffers & eq::Frame::Buffer::depth)
     142           0 :             framebufferImage.startReadback(eq::Frame::Buffer::depth,
     143             :                                            channel.getPixelViewport(),
     144             :                                            channel.getContext(),
     145             :                                            channel.getZoom(),
     146           0 :                                            channel.getObjectManager());
     147             : 
     148           0 :         framebufferImage.finishReadback(channel.glewGetContext());
     149           0 :     }
     150             : 
     151             :     /** The configInit/configExit state. */
     152             :     State state;
     153             : 
     154             :     /** A random, unique color for this channel. */
     155             :     Vector3ub color;
     156             : 
     157             :     typedef std::vector<Statistic> Statistics;
     158           8 :     struct FrameStatistics
     159             :     {
     160             :         Statistics data;     //!< all events for one frame
     161             :         eq::Viewport region; //!< from draw for equalizers
     162             :         /** reference count by pipe and transmit thread */
     163             :         lunchbox::a_int32_t used;
     164             :     };
     165             : 
     166             :     typedef std::vector<FrameStatistics> StatisticsRB;
     167             :     typedef StatisticsRB::const_iterator StatisticsRBCIter;
     168             : 
     169             :     /** Global statistics events, index per frame and channel. */
     170             :     lunchbox::Lockable<StatisticsRB, lunchbox::SpinLock> statistics;
     171             : 
     172             :     /** The initial channel size, used for view resize events. */
     173             :     Vector2i initialSize;
     174             : 
     175             :     /** The application-declared regions of interest, merged if
     176             :         necessary to be non overlapping. */
     177             :     PixelViewports regions;
     178             : 
     179             :     /** The number of the last finished frame. */
     180             :     lunchbox::Monitor<uint32_t> finishedFrame;
     181             : 
     182             :     /** Listeners that get notified on each new rendered image */
     183             :     typedef std::vector<ResultImageListener*> ResultImageListeners;
     184             :     ResultImageListeners resultImageListeners;
     185             : 
     186             :     /** Image of the current framebuffer if result listeners are present */
     187             :     eq::Image framebufferImage;
     188             : 
     189             : #ifdef EQUALIZER_USE_DEFLECT
     190             :     deflect::Proxy* _deflectProxy;
     191             : #endif
     192             : 
     193             :     /** Dumps images when the channel is configured to do so */
     194             :     FileFrameWriter frameWriter;
     195             : 
     196             :     bool _updateFrameBuffer;
     197             :     bool _finishImageListeners = false;
     198             : };
     199             : }
     200             : }

Generated by: LCOV version 1.11