LCOV - code coverage report
Current view: top level - eq - window.h (source / functions) Hit Total Coverage
Test: Equalizer Lines: 6 8 75.0 %
Date: 2017-12-16 05:07:20 Functions: 7 9 77.8 %

          Line data    Source code
       1             : /* Copyright (c) 2005-2017, Stefan Eilemann <eile@equalizergraphics.com>
       2             :  *                          Cedric Stalder <cedric.stalder@gmail.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             : #ifndef EQ_WINDOW_H
      20             : #define EQ_WINDOW_H
      21             : 
      22             : #include <eq/notifierInterface.h> // base class
      23             : #include <eq/types.h>
      24             : #include <eq/visitorResult.h>  // enum
      25             : #include <eq/windowSettings.h> // template param
      26             : 
      27             : #include <eq/fabric/renderContext.h> // member
      28             : #include <eq/fabric/window.h>        // base class
      29             : #include <eq/util/bitmapFont.h>      // member
      30             : #include <eq/util/objectManager.h>   // member
      31             : 
      32             : /** @file eq/window.h */
      33             : 
      34             : namespace eq
      35             : {
      36             : /**
      37             :  * A Window represents an on-screen or off-screen drawable.
      38             :  *
      39             :  * A drawable is a 2D rendering surface, typically attached to an OpenGL
      40             :  * context. A window uses an SystemWindow implementation to manage the operating
      41             :  * system specific handling of window and context creation.
      42             :  *
      43             :  * A Window is a child of a Pipe. The task methods for all windows of a pipe are
      44             :  * executed in the same pipe thread. All window and subsequent channel task
      45             :  * methods are executed in the order the windows are defined on the pipe, with
      46             :  * the exception of the swap and finish tasks, which are executed after all
      47             :  * windows have been updated. This ensures that all windows of a given pipe swap
      48             :  * at the same time.
      49             :  *
      50             :  * The default window initialization methods initialize all windows of the same
      51             :  * pipe with a shared context, so that OpenGL objects can be reused between them
      52             :  * for optimal GPU memory usage. The window facilitates OpenGL object management
      53             :  * by providing an ObjectManager for allocating and sharing OpenGL objects.
      54             :  *
      55             :  * Please note that each window potentially has its own OpenGL command buffer,
      56             :  * thus glFlush is needed to synchronize the state of OpenGL objects between
      57             :  * windows. Therefore, Equalizer calls flush() at the end of each frame for each
      58             :  * window.
      59             :  *
      60             :  * @sa fabric::Window
      61             :  */
      62             : class Window : public fabric::Window<Pipe, Window, Channel, WindowSettings>,
      63             :                public NotifierInterface
      64             : {
      65             : public:
      66             :     /** Construct a new window. @version 1.0 */
      67             :     EQ_API explicit Window(Pipe* parent);
      68             : 
      69             :     /** Destruct the window. @version 1.0 */
      70             :     EQ_API virtual ~Window();
      71             : 
      72             :     /** @name Data Access */
      73             :     //@{
      74             :     EQ_API co::CommandQueue* getPipeThreadQueue();    //!< @internal
      75             :     EQ_API co::CommandQueue* getCommandThreadQueue(); //!< @internal
      76             :     EQ_API uint32_t getCurrentFrame() const; //!< @internal render thr only
      77             : 
      78             :     /** @return the Node of this window. @version 1.0 */
      79             :     EQ_API const Node* getNode() const;
      80             : 
      81             :     /** @return the Node of this window. @version 1.0 */
      82             :     EQ_API Node* getNode();
      83             : 
      84             :     /** @return the Config of this window. @version 1.0 */
      85             :     EQ_API const Config* getConfig() const;
      86             : 
      87             :     /** @return the Config of this window. @version 1.0 */
      88             :     EQ_API Config* getConfig();
      89             : 
      90             :     /** @return the Client of this window. @version 1.0 */
      91             :     EQ_API ClientPtr getClient();
      92             : 
      93             :     /** @return the Server of this window. @version 1.0 */
      94             :     EQ_API ServerPtr getServer();
      95             : 
      96             :     /**
      97             :      * @return true if this window is running, false otherwise.
      98             :      * @version 1.0
      99             :      */
     100           7 :     bool isRunning() const { return (_state == STATE_RUNNING); }
     101             :     /**
     102             :      * @return true if this window is stopped, false otherwise.
     103             :      * @version 1.0
     104             :      */
     105           2 :     bool isStopped() const { return (_state == STATE_STOPPED); }
     106             :     /**
     107             :      * Get the last rendering context at the x, y position.
     108             :      *
     109             :      * If no render context is found on the given position, false is returned
     110             :      * and context is not modified.
     111             :      *
     112             :      * @return true if a render context was found, false otherwise.
     113             :      * @warning experimental - may not be supported in the future.
     114             :      */
     115             :     EQ_API bool getRenderContext(const int32_t x, const int32_t y,
     116             :                                  RenderContext& context) const;
     117             :     //@}
     118             : 
     119             :     /** @name OpenGL context handling and sharing */
     120             :     //@{
     121             :     /**
     122             :      * Set the window with which this window shares the OpenGL context.
     123             :      *
     124             :      * By default it is set to the first window of the pipe in the window's
     125             :      * constructor. The shared context window is used during initialization to
     126             :      * setup the OpenGL context and util::ObjectManager. The default
     127             :      * implementation of configInitSystemWindow() will use this to call
     128             :      * WindowSettings::setSharedContextWindow() using the corresponding
     129             :      * SystemWindow.
     130             :      * @version 1.0
     131             :      */
     132             :     EQ_API void setSharedContextWindow(const Window* sharedContextWindow);
     133             : 
     134             :     /**
     135             :      * @return the window with which this window shares the GL context.
     136             :      * @version 1.0
     137             :      */
     138             :     EQ_API const Window* getSharedContextWindow() const;
     139             : 
     140             :     /** @return the window's object manager instance. @version 1.0 */
     141           6 :     util::ObjectManager& getObjectManager() { return _objectManager; }
     142             :     /** @return the window's object manager instance. @version 1.0 */
     143             :     const util::ObjectManager& getObjectManager() const
     144             :     {
     145             :         return _objectManager;
     146             :     }
     147             : 
     148             :     /**
     149             :      * @return a small bitmap font used for overlays.
     150             :      * @warning experimental - may not be supported in the future.
     151             :      */
     152             :     EQ_API const util::BitmapFont* getSmallFont();
     153             : 
     154             :     /**
     155             :      * @return a medium bitmap font used for overlays.
     156             :      * @warning experimental - may not be supported in the future.
     157             :      */
     158             :     EQ_API const util::BitmapFont* getMediumFont();
     159             : 
     160             :     /**
     161             :      * Get the GLEW context for this window.
     162             :      *
     163             :      * The glew context is provided and initialized by the SystemWindow, and
     164             :      * provides access to OpenGL extensions. This function does not follow the
     165             :      * Equalizer naming conventions, since GLEW uses a function of this name to
     166             :      * automatically resolve OpenGL function entry points. Therefore, any OpenGL
     167             :      * function support by the driver can be directly called from any method of
     168             :      * an initialized window.
     169             :      *
     170             :      * @return the extended OpenGL function table for the window's OpenGL
     171             :      *         context.
     172             :      * @version 1.0
     173             :      */
     174             :     EQ_API const GLEWContext* glewGetContext() const;
     175             : 
     176             :     /** @internal @return shared context for used by the transfer thread. */
     177             :     EQ_API const GLEWContext* getTransferGlewContext() const;
     178             : 
     179             :     /**
     180             :      * @internal
     181             :      * @return the OpenGL texture format corresponding to the window's color
     182             :      *         drawable configuration
     183             :      */
     184             :     EQ_API uint32_t getColorFormat() const;
     185             :     //@}
     186             : 
     187             :     /** @name Actions */
     188             :     //@{
     189             :     /**
     190             :      * Flush outstanding rendering requests.
     191             :      *
     192             :      * Called at the end of each frame from frameFinish() to ensure timely
     193             :      * execution of pending rendering requests.
     194             :      * @version 1.0
     195             :      */
     196             :     EQ_API virtual void flush() const;
     197             : 
     198             :     /**
     199             :      * Finish outstanding rendering requests.
     200             :      *
     201             :      * Called before a software swap barrier to ensure that the window will
     202             :      * swap directly after the barrier is left.
     203             :      * @version 1.0
     204             :      */
     205             :     EQ_API virtual void finish() const;
     206             : 
     207             :     /** Swap the front and back buffer of the window. @version 1.0 */
     208             :     EQ_API virtual void swapBuffers();
     209             : 
     210             :     /** Render the current framerate as on overlay. @version 1.0 */
     211             :     EQ_API virtual void drawFPS();
     212             : 
     213             :     /** @return the window's average framerate. @version 1.0 */
     214           0 :     float getFPS() const { return _avgFPS; }
     215             :     /**
     216             :      * Make the window's drawable and context current.
     217             :      *
     218             :      * GL drivers tend to behave sub-optimally if too many makeCurrent calls
     219             :      * happen in a multi-threaded program. When caching is enabled, this method
     220             :      * will only call SystemWindow::makeCurrent if it has not been done before
     221             :      * for this window on this thread.
     222             :      * @version 1.3.2
     223             :      */
     224             :     EQ_API virtual void makeCurrent(const bool cache = true) const;
     225             : 
     226             :     /**
     227             :      * This results in no context being current in the current thread.
     228             :      * @version 1.10
     229             :      */
     230             :     EQ_API virtual void doneCurrent() const;
     231             : 
     232             :     /** @internal Bind the window's FBO, if it uses one. */
     233             :     EQ_API virtual void bindFrameBuffer() const;
     234             : 
     235             :     /** @internal Bind the window's draw (aka multisampled) FBO, if it uses one.
     236             :      */
     237             :     EQ_API virtual void bindDrawFrameBuffer() const;
     238             : 
     239             :     /** @internal Blit from multisampled FBO to window FBO */
     240             :     EQ_API virtual void updateFrameBuffer() const;
     241             : 
     242             :     /** @internal Notify this window that the viewport has changed. */
     243             :     EQ_API void notifyViewportChanged() override;
     244             :     //@}
     245             : 
     246             :     /**  @name SystemWindow interface */
     247             :     //@{
     248             :     /**
     249             :      * Set the OS-specific window.
     250             :      *
     251             :      * The SystemWindow implements the window-system-dependent part, e.g., the
     252             :      * drawable creation. This window forwards certain calls, e.g.,
     253             :      * swapBuffers(), to the SystemWindow. The system window has to be
     254             :      * initialized.
     255             :      * @version 1.0
     256             :      */
     257             :     EQ_API void setSystemWindow(SystemWindow* window);
     258             : 
     259             :     /** @return the OS-specific window implementation. @version 1.0 */
     260          24 :     const SystemWindow* getSystemWindow() const { return _systemWindow; }
     261             :     /** @return the OS-specific window implementation. @version 1.0 */
     262           0 :     SystemWindow* getSystemWindow() { return _systemWindow; }
     263             :     /** @return the OS-specific pipe implementation. @version 1.0 */
     264             :     const SystemPipe* getSystemPipe() const;
     265             : 
     266             :     /** @return the OS-specific pipe implementation. @version 1.0 */
     267             :     SystemPipe* getSystemPipe();
     268             : 
     269             :     /** @internal Create shared context window for asynchronuous usage. */
     270             :     bool createTransferWindow();
     271             : 
     272             :     /** @internal delete the shared context window. */
     273             :     void deleteTransferWindow();
     274             : 
     275             :     /** @internal @return the transfer window, or 0 if not created yet. */
     276             :     SystemWindow* getTransferWindow();
     277             :     const SystemWindow* getTransferWindow() const; //!< @internal
     278             :                                                    //@}
     279             : 
     280             :     /** @name Events */
     281             :     //@{
     282             :     /**
     283             :      * Send a window error event to the application node.
     284             :      *
     285             :      * @param error the error code.
     286             :      * @version 1.7.1
     287             :      */
     288             :     EQ_API EventOCommand sendError(const uint32_t error) final;
     289             : 
     290             :     /** @sa NotifierInterface::processEvent(). */
     291             :     EQ_API bool processEvent(EventType type) override;
     292             : 
     293             :     /** @sa NotifierInterface::processEvent(). */
     294             :     EQ_API bool processEvent(EventType type, SizeEvent& event) override;
     295             : 
     296             :     /** @sa NotifierInterface::processEvent(). */
     297             :     EQ_API bool processEvent(EventType type, PointerEvent& event) override;
     298             : 
     299             :     /** @sa NotifierInterface::processEvent(). */
     300             :     EQ_API bool processEvent(EventType type, KeyEvent& event) override;
     301             : 
     302             :     /** @sa NotifierInterface::processEvent(). */
     303             :     EQ_API bool processEvent(AxisEvent& event) override;
     304             : 
     305             :     /** @sa NotifierInterface::processEvent(). */
     306             :     EQ_API bool processEvent(ButtonEvent& event) override;
     307             : 
     308             :     EQ_API bool processEvent(Statistic& event);
     309             :     //@}
     310             : 
     311             : protected:
     312             :     friend class Pipe;
     313             : 
     314             :     /** @internal */
     315             :     EQ_API
     316             :     void attach(const uint128_t& id, const uint32_t instanceID) override;
     317             : 
     318             :     /** @name Actions */
     319             :     //@{
     320             :     /**
     321             :      * Start a frame by unlocking all child resources.
     322             :      *
     323             :      * @param frameNumber the frame to start.
     324             :      * @version 1.0
     325             :      */
     326             :     EQ_API void startFrame(const uint32_t frameNumber);
     327             : 
     328             :     /**
     329             :      * Signal the completion of a frame to the parent.
     330             :      *
     331             :      * @param frameNumber the frame to end.
     332             :      * @version 1.0
     333             :      */
     334             :     EQ_API void releaseFrame(const uint32_t frameNumber);
     335             : 
     336             :     /**
     337             :      * Signal the release of the local synchronization to the parent.
     338             :      *
     339             :      * @param frameNumber the frame to release.
     340             :      * @version 1.0
     341             :      */
     342             :     EQ_API void releaseFrameLocal(const uint32_t frameNumber);
     343             :     //@}
     344             : 
     345             :     /**
     346             :      * @name Callbacks
     347             :      *
     348             :      * The callbacks are called by Equalizer during rendering to execute
     349             :      * various actions.
     350             :      */
     351             :     //@{
     352             :     /**
     353             :      * Initialize this window.
     354             :      *
     355             :      * @param initID the init identifier.
     356             :      * @version 1.0
     357             :      */
     358             :     EQ_API virtual bool configInit(const uint128_t& initID);
     359             : 
     360             :     /**
     361             :      * Initialize the OS-specific window.
     362             :      *
     363             :      * @sa setSystemWindow()
     364             :      * @version 1.0
     365             :      */
     366             :     EQ_API virtual bool configInitSystemWindow(const uint128_t& initID);
     367             : 
     368             :     /**
     369             :      * Initialize the OpenGL state for this window.
     370             :      *
     371             :      * Called from configInit(), after the system window has been successfully
     372             :      * initialized.
     373             :      *
     374             :      * @param initID the init identifier.
     375             :      * @return true if the initialization was successful, false if not.
     376             :      * @version 1.0
     377             :      */
     378             :     EQ_API virtual bool configInitGL(const uint128_t& initID);
     379             : 
     380             :     /** Exit this window. @version 1.0 */
     381             :     EQ_API virtual bool configExit();
     382             : 
     383             :     /** De-initialize the OS-specific window. @version 1.0 */
     384             :     EQ_API virtual bool configExitSystemWindow();
     385             : 
     386             :     /** De-initialize the OpenGL state for this window. @version 1.0 */
     387           2 :     virtual bool configExitGL() { return true; }
     388             :     /**
     389             :      * Start rendering a frame.
     390             :      *
     391             :      * Called once at the beginning of each frame, to do per-frame updates
     392             :      * of window-specific data. This method has to call startFrame().
     393             :      *
     394             :      * @param frameID the per-frame identifier.
     395             :      * @param frameNumber the frame to start.
     396             :      * @version 1.0
     397             :      */
     398             :     EQ_API virtual void frameStart(const uint128_t& frameID,
     399             :                                    const uint32_t frameNumber);
     400             : 
     401             :     /**
     402             :      * Finish rendering a frame.
     403             :      *
     404             :      * Called once at the end of each frame, to do per-frame updates of
     405             :      * window-specific data. This method has to call releaseFrame(). The
     406             :      * default implementation also flushes all rendering commands. This
     407             :      * light-weight call ensures that all outstanding rendering commands for
     408             :      * the window's context are being executed in a timely fashion.
     409             :      *
     410             :      * @param frameID the per-frame identifier.
     411             :      * @param frameNumber the frame to finish.
     412             :      * @version 1.0
     413             :      */
     414             :     EQ_API virtual void frameFinish(const uint128_t& frameID,
     415             :                                     const uint32_t frameNumber);
     416             : 
     417             :     /**
     418             :      * Finish drawing.
     419             :      *
     420             :      * Called once per frame after the last draw operation. Typically
     421             :      * releases the local node thread synchronization for this frame.
     422             :      *
     423             :      * @param frameID the per-frame identifier.
     424             :      * @param frameNumber the frame to finished with draw.
     425             :      * @version 1.0
     426             :      */
     427             :     EQ_API virtual void frameDrawFinish(const uint128_t& frameID,
     428             :                                         const uint32_t frameNumber);
     429             :     //@}
     430             : 
     431             : private:
     432             :     enum State
     433             :     {
     434             :         STATE_STOPPED,
     435             :         STATE_INITIALIZING,
     436             :         STATE_RUNNING,
     437             :         STATE_FAILED
     438             :     };
     439             : 
     440             :     /** The window sharing the OpenGL context. */
     441             :     const Window* _sharedContextWindow;
     442             : 
     443             :     /** Transfer window */
     444             :     SystemWindow* _transferWindow;
     445             : 
     446             :     /** Window-system specific functions class */
     447             :     SystemWindow* _systemWindow;
     448             : 
     449             :     /** The configInit/configExit state. */
     450             :     State _state;
     451             : 
     452             :     /** OpenGL object management. */
     453             :     util::ObjectManager _objectManager;
     454             : 
     455             :     /** Used to calculate time of last frame rendering */
     456             :     float _lastTime;
     457             : 
     458             :     /** averaged FPS value, to prevent FPS counter flickering */
     459             :     float _avgFPS;
     460             : 
     461             :     /** The list of render context used since the last frame start. */
     462             :     std::vector<RenderContext> _renderContexts[2];
     463             :     enum
     464             :     {
     465             :         FRONT = 0,
     466             :         BACK = 1
     467             :     };
     468             : 
     469             :     /** The time of the last swap command. */
     470             :     int64_t _lastSwapTime;
     471             : 
     472             :     /** List of channels that have grabbed the mouse. */
     473             :     Channels _grabbedChannels;
     474             : 
     475             :     struct Private;
     476             :     Private* _private; // placeholder for binary-compatible changes
     477             : 
     478             :     /** Add a channel's rendering context to the current frame's list */
     479             :     void _addRenderContext(const RenderContext& context);
     480             :     friend class Channel;
     481             : 
     482             :     /** @return the channels concerned by the given mouse event. */
     483             :     Channels _getEventChannels(const PointerEvent& event);
     484             : 
     485             :     /** Set up object manager during initialization. */
     486             :     void _setupObjectManager();
     487             :     /** Release object manager. */
     488             :     void _releaseObjectManager();
     489             : 
     490             :     /** Calculates per-window frame rate */
     491             :     void _updateFPS();
     492             : 
     493             :     /** Enter the given barrier. */
     494             :     void _enterBarrier(co::ObjectVersion barrier);
     495             : 
     496             :     /* The command functions. */
     497             :     bool _cmdCreateChannel(co::ICommand& command);
     498             :     bool _cmdDestroyChannel(co::ICommand& command);
     499             :     bool _cmdConfigInit(co::ICommand& command);
     500             :     bool _cmdConfigExit(co::ICommand& command);
     501             :     bool _cmdFrameStart(co::ICommand& command);
     502             :     bool _cmdFrameFinish(co::ICommand& command);
     503             :     bool _cmdThrottleFramerate(co::ICommand& command);
     504             :     bool _cmdFlush(co::ICommand& command);
     505             :     bool _cmdFinish(co::ICommand& command);
     506             :     bool _cmdBarrier(co::ICommand& command);
     507             :     bool _cmdNVBarrier(co::ICommand& command);
     508             :     bool _cmdSwap(co::ICommand& command);
     509             :     bool _cmdFrameDrawFinish(co::ICommand& command);
     510             :     bool _cmdResize(co::ICommand& command);
     511             : 
     512           4 :     LB_TS_VAR(_pipeThread)
     513             : };
     514             : }
     515             : 
     516             : #endif // EQ_WINDOW_H

Generated by: LCOV version 1.11