LCOV - code coverage report
Current view: top level - eq/qt/detail - window.h (source / functions) Hit Total Coverage
Test: Equalizer Lines: 0 115 0.0 %
Date: 2017-12-16 05:07:20 Functions: 0 25 0.0 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2014-2017, Daniel Nachbaur <danielnachbaur@gmail.com>
       3             :  *                          Juan Hernando <jhernando@fi.upm.es>
       4             :  *                          Stefan.Eilemann@epfl.ch
       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             : #ifndef EQ_QT_WINDOWIMPL_H
      21             : #define EQ_QT_WINDOWIMPL_H
      22             : 
      23             : #include "../eventHandler.h"
      24             : 
      25             : #include <eq/util/frameBufferObject.h>
      26             : #include <lunchbox/monitor.h>
      27             : 
      28             : #include <QApplication>
      29             : #include <QExposeEvent>
      30             : #include <QOffscreenSurface>
      31             : #include <QOpenGLContext>
      32             : #include <QWindow>
      33             : 
      34             : namespace eq
      35             : {
      36             : namespace qt
      37             : {
      38             : namespace detail
      39             : {
      40             : namespace
      41             : {
      42             : #define getAttribute(attr) settings.getIAttribute(WindowSettings::attr)
      43             : 
      44           0 : QSurfaceFormat _createFormat(const WindowSettings& settings)
      45             : {
      46             :     // defaults: http://doc.qt.io/qt-5/qsurfaceformat.html
      47           0 :     QSurfaceFormat format;
      48             : 
      49           0 :     const int coreProfile = getAttribute(IATTR_HINT_CORE_PROFILE);
      50           0 :     if (coreProfile == ON)
      51             :     {
      52           0 :         format.setMajorVersion(getAttribute(IATTR_HINT_OPENGL_MAJOR));
      53           0 :         format.setMinorVersion(getAttribute(IATTR_HINT_OPENGL_MINOR));
      54           0 :         format.setProfile(QSurfaceFormat::CoreProfile);
      55             :     }
      56             : 
      57           0 :     const int colorSize = getAttribute(IATTR_PLANES_COLOR);
      58           0 :     if (colorSize > 0 || colorSize == eq::AUTO)
      59             :     {
      60           0 :         const int colorBits = (colorSize > 0 ? colorSize : 8);
      61           0 :         format.setRedBufferSize(colorBits);
      62           0 :         format.setGreenBufferSize(colorBits);
      63           0 :         format.setBlueBufferSize(colorBits);
      64             :     }
      65             : 
      66           0 :     const int alphaPlanes = getAttribute(IATTR_PLANES_ALPHA);
      67           0 :     if (alphaPlanes > 0 || alphaPlanes == eq::AUTO)
      68             :     {
      69           0 :         const int alphaBits = (alphaPlanes > 0 ? alphaPlanes : 8);
      70           0 :         format.setAlphaBufferSize(alphaBits);
      71             :     }
      72             : 
      73           0 :     const int depthPlanes = getAttribute(IATTR_PLANES_DEPTH);
      74           0 :     if (depthPlanes > 0 || depthPlanes == eq::AUTO)
      75             :     {
      76           0 :         const int depthBits = (depthPlanes > 0 ? depthPlanes : 8);
      77           0 :         format.setDepthBufferSize(depthBits);
      78             :     }
      79             :     else
      80           0 :         format.setDepthBufferSize(0);
      81             : 
      82           0 :     const int stencilPlanes = getAttribute(IATTR_PLANES_STENCIL);
      83           0 :     if (stencilPlanes > 0 || stencilPlanes == eq::AUTO)
      84             :     {
      85           0 :         const int stencilBits = (stencilPlanes > 0 ? stencilPlanes : 8);
      86           0 :         format.setStencilBufferSize(stencilBits);
      87             :     }
      88             :     else
      89           0 :         format.setStencilBufferSize(0);
      90             : 
      91           0 :     const int samplesPlanes = getAttribute(IATTR_PLANES_SAMPLES);
      92           0 :     if (samplesPlanes >= 0)
      93             :     {
      94           0 :         format.setSamples(samplesPlanes);
      95             :     }
      96             : 
      97           0 :     if (getAttribute(IATTR_HINT_STEREO) == eq::ON)
      98             :     {
      99           0 :         format.setStereo(true);
     100             :     }
     101             : 
     102           0 :     if (getAttribute(IATTR_HINT_DOUBLEBUFFER) == eq::ON ||
     103           0 :         (getAttribute(IATTR_HINT_DOUBLEBUFFER) == eq::AUTO &&
     104           0 :          getAttribute(IATTR_HINT_DRAWABLE) == eq::WINDOW))
     105             :     {
     106           0 :         format.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
     107             :     }
     108             :     else
     109           0 :         format.setSwapBehavior(QSurfaceFormat::SingleBuffer);
     110             : 
     111           0 :     return format;
     112             : }
     113             : #undef getAttribute
     114             : }
     115             : 
     116             : class Window
     117             : {
     118             : public:
     119           0 :     Window(WindowIF& window, QThread* qThread)
     120           0 :         : _eventHandler(window)
     121             :     {
     122           0 :         if (qThread)
     123           0 :             _eventHandler.moveToThread(qThread);
     124           0 :     }
     125             : 
     126           0 :     virtual ~Window() {}
     127             :     virtual QOpenGLContext* getContext() const = 0;
     128             :     virtual bool configInit() = 0;
     129             :     virtual void makeCurrent() = 0;
     130             :     virtual void doneCurrent() = 0;
     131             :     virtual void swapBuffers() = 0;
     132           0 :     virtual void resize(const PixelViewport&){};
     133           0 :     virtual QObject* getEventProcessor() { return &_eventHandler; }
     134             : protected:
     135             :     EventHandler _eventHandler;
     136             : };
     137             : 
     138           0 : class QWindowWrapper : public Window, public QWindow
     139             : {
     140             : public:
     141           0 :     QWindowWrapper(WindowIF& window, QThread* qThread,
     142             :                    const WindowSettings& settings, QScreen* screen_,
     143             :                    QOpenGLContext* shareContext)
     144           0 :         : detail::Window(window, qThread)
     145           0 :         , _context(new QOpenGLContext)
     146           0 :         , _realized(false)
     147             :     {
     148           0 :         setScreen(screen_);
     149           0 :         const QSurfaceFormat& format_ = _createFormat(settings);
     150           0 :         setFormat(format_);
     151           0 :         const PixelViewport& pvp = settings.getPixelViewport();
     152           0 :         setGeometry(pvp.x, pvp.y, pvp.w, pvp.h);
     153           0 :         setSurfaceType(QSurface::OpenGLSurface);
     154             : 
     155           0 :         _context->setFormat(format());
     156           0 :         _context->setShareContext(shareContext);
     157             : 
     158           0 :         if (settings.getIAttribute(WindowSettings::IATTR_HINT_FULLSCREEN) ==
     159             :             eq::ON)
     160             :         {
     161           0 :             showFullScreen();
     162             :         }
     163             :         else
     164           0 :             show();
     165           0 :     }
     166             : 
     167           0 :     QOpenGLContext* getContext() const final { return _context.data(); }
     168           0 :     void makeCurrent() final
     169             :     {
     170           0 :         if (!_context->makeCurrent(this))
     171           0 :             LBWARN << "QOpenGLContext::makeCurrent failed: " << _context.data()
     172           0 :                    << std::endl;
     173           0 :     }
     174             : 
     175           0 :     void doneCurrent() final { _context->doneCurrent(); }
     176           0 :     void swapBuffers() final
     177             :     {
     178           0 :         if (isExposed())
     179           0 :             _context->swapBuffers(this);
     180           0 :     }
     181             : 
     182           0 :     void resize(const PixelViewport& pvp) final
     183             :     {
     184           0 :         setPosition(pvp.x, pvp.y);
     185           0 :         QWindow::resize(pvp.w, pvp.h);
     186           0 :     }
     187             : 
     188           0 :     bool configInit() final
     189             :     {
     190             :         // The application thread must be running the event loop somewhere
     191             :         // else. Otherwise this code will wait forever.
     192           0 :         _realized.waitEQ(true);
     193             : 
     194           0 :         if (!_context->create())
     195           0 :             return false;
     196             : 
     197             :         // Adjusting the actual window viewport in case the window manager
     198             :         // disobeyed the requested geometry.
     199           0 :         WindowIF& window = _eventHandler.getWindow();
     200           0 :         window.setPixelViewport(PixelViewport(x(), y(), width(), height()));
     201           0 :         return true;
     202             :     }
     203             : 
     204           0 :     QObject* getEventProcessor() final { return this; }
     205             : protected:
     206           0 :     bool event(QEvent* qevent) final
     207             :     {
     208           0 :         if (qevent->type() == QEvent::Expose)
     209             :         {
     210           0 :             const QExposeEvent* expose = static_cast<QExposeEvent*>(qevent);
     211           0 :             _realized = !expose->region().isEmpty();
     212             :         }
     213             : 
     214           0 :         QApplication::sendEvent(&_eventHandler, qevent);
     215           0 :         return true;
     216             :     }
     217             : 
     218             : private:
     219             :     QScopedPointer<QOpenGLContext> _context;
     220             : 
     221             :     lunchbox::Monitorb _realized;
     222             : };
     223             : 
     224           0 : class QOffscreenSurfaceWrapper : public Window, public QOffscreenSurface
     225             : {
     226             : public:
     227           0 :     QOffscreenSurfaceWrapper(WindowIF& window, QThread* qThread,
     228             :                              const WindowSettings& settings, QScreen* screen_,
     229             :                              QOpenGLContext* shareContext)
     230           0 :         : detail::Window(window, qThread)
     231           0 :         , _context(new QOpenGLContext)
     232             :     {
     233           0 :         setScreen(screen_);
     234           0 :         const QSurfaceFormat& format_ = _createFormat(settings);
     235           0 :         setFormat(format_);
     236             : 
     237           0 :         _context->setFormat(format());
     238           0 :         _context->setShareContext(shareContext);
     239           0 :         create();
     240           0 :     }
     241             : 
     242           0 :     QOpenGLContext* getContext() const final { return _context.data(); }
     243           0 :     void makeCurrent() final
     244             :     {
     245           0 :         if (!_context->makeCurrent(this))
     246           0 :             LBWARN << "QOpenGLContext::makeCurrent failed: " << _context.data()
     247           0 :                    << std::endl;
     248           0 :     }
     249             : 
     250           0 :     void doneCurrent() final { _context->doneCurrent(); }
     251           0 :     void swapBuffers() final
     252             :     {
     253           0 :         if (isValid())
     254           0 :             _context->swapBuffers(this);
     255           0 :     }
     256             : 
     257           0 :     bool configInit() final { return isValid() && _context->create(); }
     258             : private:
     259             :     QScopedPointer<QOpenGLContext> _context;
     260             : };
     261             : }
     262             : }
     263             : }
     264             : 
     265             : #endif

Generated by: LCOV version 1.11