LCOV - code coverage report
Current view: top level - eq/client - window.h (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 6 7 85.7 %
Date: 2014-06-18 Functions: 7 8 87.5 %

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

Generated by: LCOV version 1.10