LCOV - code coverage report
Current view: top level - eq - view.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 27 106 25.5 %
Date: 2017-12-16 05:07:20 Functions: 10 23 43.5 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2008-2017, Stefan Eilemann <eile@equalizergraphics.com>
       3             :  *                          Daniel Nachbaur <danielnachbaur@gmail.com>
       4             :  *
       5             :  * This library is free software; you can redistribute it and/or modify it under
       6             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       7             :  * by the Free Software Foundation.
       8             :  *
       9             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      10             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      11             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      12             :  * details.
      13             :  *
      14             :  * You should have received a copy of the GNU Lesser General Public License
      15             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      16             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      17             :  */
      18             : 
      19             : #include "view.h"
      20             : 
      21             : #include "compositor.h"
      22             : #include "config.h"
      23             : #include "eventICommand.h"
      24             : #include "image.h"
      25             : #include "imageOp.h"
      26             : #include "layout.h"
      27             : #include "observer.h"
      28             : #include "pipe.h"
      29             : #include "server.h"
      30             : 
      31             : #include <eq/fabric/commands.h>
      32             : #include <eq/fabric/sizeEvent.h>
      33             : 
      34             : #include <co/dataIStream.h>
      35             : #include <co/dataOStream.h>
      36             : #include <lunchbox/scopedMutex.h>
      37             : #include <lunchbox/spinLock.h>
      38             : 
      39             : namespace eq
      40             : {
      41             : namespace detail
      42             : {
      43          16 : class View
      44             : {
      45             : public:
      46             :     lunchbox::SpinLock eventLock; //!< event-handling resize synchronizer
      47             : 
      48             :     /** Unmodified, baseline view frustum data, used for resizing. */
      49             :     Frustum baseFrustum;
      50             : 
      51           0 :     struct Screenshot
      52             :     {
      53             :         std::unique_ptr<eq::Image> _image;
      54             :         Viewport _viewport;
      55             : 
      56           0 :         bool isComplete() const { return _viewport == Viewport::FULL; }
      57           0 :         void composite(const Viewport& viewport, const eq::Image& image)
      58             :         {
      59           0 :             if (!_image)
      60             :             {
      61           0 :                 _viewport = viewport;
      62           0 :                 _image.reset(new eq::Image(image));
      63           0 :                 return;
      64             :             }
      65             : 
      66           0 :             ImageOps ops;
      67           0 :             ImageOp current;
      68           0 :             current.image = _image.get();
      69           0 :             ImageOp newImage;
      70           0 :             newImage.image = &image;
      71             : 
      72           0 :             ops.push_back(current);
      73           0 :             ops.push_back(newImage);
      74           0 :             _image.reset(
      75           0 :                 new eq::Image(*Compositor::mergeImagesCPU(ops, false)));
      76           0 :             _viewport.unite(viewport);
      77             :         }
      78             :     };
      79             : 
      80             :     std::map<uint32_t, Screenshot> screenshot;
      81             :     eq::View::ScreenshotFunc screenshotFunc;
      82             : };
      83             : }
      84             : 
      85             : typedef fabric::View<Layout, View, Observer> Super;
      86             : 
      87           8 : View::View(Layout* parent)
      88             :     : Super(parent)
      89           8 :     , _impl(new detail::View)
      90          16 :     , _pipe(0)
      91             : {
      92           8 : }
      93             : 
      94          16 : View::~View()
      95             : {
      96           8 :     delete _impl;
      97           8 : }
      98             : 
      99          28 : void View::deserialize(co::DataIStream& is, const uint64_t dirtyBits)
     100             : {
     101          28 :     Super::deserialize(is, dirtyBits);
     102          36 :     if (_impl->baseFrustum.getCurrentType() == TYPE_NONE &&
     103           8 :         (dirtyBits & DIRTY_FRUSTUM))
     104             :     {
     105           8 :         _impl->baseFrustum = *this; // save baseline data for resizing
     106             :     }
     107          28 : }
     108             : 
     109           8 : void View::detach()
     110             : {
     111             :     // if pipe is not running, detach comes from _flushViews in state stopping
     112             :     //  Don't send command to stopping pipe (see issue #11)
     113           8 :     if (_pipe && _pipe->isRunning())
     114             :     {
     115             :         // local command dispatching
     116           0 :         co::ObjectOCommand(_pipe, getLocalNode(), fabric::CMD_PIPE_DETACH_VIEW,
     117           0 :                            co::COMMANDTYPE_OBJECT, _pipe->getID(),
     118             :                            CO_INSTANCE_ALL)
     119           0 :             << getID();
     120             :     }
     121           8 :     Super::detach();
     122           8 : }
     123             : 
     124          14 : Config* View::getConfig()
     125             : {
     126          14 :     Layout* layout = getLayout();
     127          14 :     if (layout)
     128          14 :         return layout->getConfig();
     129             : 
     130           0 :     if (_pipe)
     131           0 :         return _pipe->getConfig();
     132             : 
     133           0 :     LBUNREACHABLE;
     134           0 :     return 0;
     135             : }
     136             : 
     137           7 : const Config* View::getConfig() const
     138             : {
     139           7 :     const Layout* layout = getLayout();
     140           7 :     if (layout)
     141           7 :         return layout->getConfig();
     142             : 
     143           0 :     if (_pipe)
     144           0 :         return _pipe->getConfig();
     145             : 
     146           0 :     LBUNREACHABLE;
     147           0 :     return 0;
     148             : }
     149             : 
     150           0 : ServerPtr View::getServer()
     151             : {
     152           0 :     Config* config = getConfig();
     153           0 :     LBASSERT(config);
     154           0 :     return (config ? config->getServer() : 0);
     155             : }
     156             : 
     157           0 : const Frustum& View::getBaseFrustum() const
     158             : {
     159           0 :     return _impl->baseFrustum;
     160             : }
     161             : 
     162           0 : bool View::handleEvent(const EventType type, const SizeEvent& event)
     163             : {
     164           0 :     if (type != EVENT_VIEW_RESIZE)
     165           0 :         return false;
     166             : 
     167           0 :     if (event.dw == 0.f || event.dh == 0.f)
     168           0 :         return true;
     169             : 
     170           0 :     switch (getCurrentType())
     171             :     {
     172             :     case TYPE_WALL:
     173             :     {
     174           0 :         const float ratio(event.dw / event.dh);
     175           0 :         Wall wall(_impl->baseFrustum.getWall());
     176           0 :         wall.resizeHorizontal(ratio);
     177             : 
     178           0 :         lunchbox::ScopedFastWrite mutex(_impl->eventLock);
     179           0 :         setWall(wall);
     180           0 :         return true;
     181             :     }
     182             : 
     183             :     case View::TYPE_PROJECTION:
     184             :     {
     185           0 :         const float ratio(event.dw / event.dh);
     186           0 :         eq::Projection projection(_impl->baseFrustum.getProjection());
     187           0 :         projection.resizeHorizontal(ratio);
     188             : 
     189           0 :         lunchbox::ScopedFastWrite mutex(_impl->eventLock);
     190           0 :         setProjection(projection);
     191           0 :         return true;
     192             :     }
     193             : 
     194             :     default:
     195           0 :         LBUNIMPLEMENTED;
     196             :     case eq::View::TYPE_NONE:
     197           0 :         return false;
     198             :     }
     199             : }
     200             : 
     201           0 : void View::enableScreenshot(Frame::Buffer buffers, const ScreenshotFunc& func)
     202             : {
     203           0 :     Super::_setScreenshotBuffers(buffers);
     204           0 :     _impl->screenshotFunc = func;
     205           0 : }
     206             : 
     207           0 : void View::disableScreenshot()
     208             : {
     209           0 :     Super::_setScreenshotBuffers(Frame::Buffer::none);
     210           0 : }
     211             : 
     212           0 : void View::sendScreenshotEvent(const Viewport& viewport,
     213             :                                const uint32_t frameNumber, const Image& image)
     214             : {
     215           0 :     getConfig()->sendEvent(EVENT_VIEW_SCREENSHOT) << getID() << viewport
     216           0 :                                                   << frameNumber << image;
     217           0 : }
     218             : 
     219           0 : bool View::handleEvent(EventICommand& command)
     220             : {
     221           0 :     switch (command.getEventType())
     222             :     {
     223             :     case EVENT_VIEW_SCREENSHOT:
     224           0 :         return _handleScreenshot(command);
     225             :     }
     226           0 :     return false;
     227             : }
     228             : 
     229           0 : bool View::_handleScreenshot(EventICommand& command)
     230             : {
     231           0 :     const auto& vp = command.read<Viewport>();
     232           0 :     const auto frameNumber = command.read<uint32_t>();
     233           0 :     const auto& newImage = command.read<Image>();
     234             : 
     235           0 :     auto& screenshot = _impl->screenshot[frameNumber];
     236           0 :     screenshot.composite(vp, newImage);
     237             : 
     238           0 :     if (screenshot.isComplete())
     239             :     {
     240           0 :         _impl->screenshotFunc(frameNumber, *screenshot._image);
     241           0 :         _impl->screenshot.erase(frameNumber);
     242             :     }
     243             : 
     244           0 :     return true;
     245             : }
     246             : }
     247             : 
     248             : #include <eq/fabric/view.ipp>
     249             : template class eq::fabric::View<eq::Layout, eq::View, eq::Observer>;
     250             : 
     251             : /** @cond IGNORE */
     252             : template EQFABRIC_API std::ostream& eq::fabric::operator<<(std::ostream&,
     253          30 :                                                            const eq::Super&);
     254             : /** @endcond */

Generated by: LCOV version 1.11