LCOV - code coverage report
Current view: top level - eq/util - pixelBufferObject.cpp (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 38 114 33.3 %
Date: 2014-06-18 Functions: 14 30 46.7 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c)      2012, Maxim Makhinya <maxmah@gmail.com>
       3             :  *               2012-2013, Stefan Eilemann <eile@eyescale.ch>
       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 "pixelBufferObject.h"
      20             : 
      21             : #include <eq/client/gl.h>
      22             : #include <lunchbox/debug.h>
      23             : #include <lunchbox/scopedMutex.h>
      24             : 
      25             : namespace eq
      26             : {
      27             : namespace util
      28             : {
      29             : namespace detail
      30             : {
      31             : class PixelBufferObject
      32             : {
      33             : public:
      34           3 :     PixelBufferObject( const GLEWContext* glewContext,
      35             :                        const bool threadSafe )
      36           3 :         : lock_( threadSafe ? new lunchbox::Lock : 0 )
      37             :         , pboID( 0 )
      38             :         , size( 0 )
      39             :         , _glewContext( glewContext )
      40           6 :         , _type( 0 )
      41             :     {
      42           3 :         LBVERB << (void*)this << backtrace << std::endl;
      43           3 :     }
      44             : 
      45           3 :     ~PixelBufferObject()
      46             :     {
      47           3 :         LBASSERTINFO( !isInitialized(), (void*)this << backtrace );
      48           3 :         if( isInitialized( ))
      49           0 :             LBWARN << "PBO was not freed" << std::endl;
      50             : 
      51           3 :         delete lock_;
      52           3 :     }
      53             : 
      54           3 :     const GLEWContext* glewGetContext() const { return _glewContext; }
      55             : 
      56           9 :     bool isInitialized() const { return pboID != 0; }
      57             : 
      58           3 :     Error setup( const size_t newSize, const GLuint type )
      59             :     {
      60           3 :         LBASSERT( _glewContext );
      61             : 
      62           3 :         if( !GLEW_ARB_pixel_buffer_object )
      63           3 :             return Error( ERROR_PBO_UNSUPPORTED );
      64             : 
      65           0 :         if( newSize == 0 )
      66             :         {
      67           0 :             destroy();
      68           0 :             return Error( ERROR_PBO_SIZE_TOO_SMALL );
      69             :         }
      70             : 
      71           0 :         if( pboID == 0 )
      72             :         {
      73           0 :             EQ_GL_CALL( glGenBuffersARB( 1, &pboID ));
      74             :         }
      75           0 :         if( pboID == 0 )
      76           0 :             return Error( ERROR_PBO_NOT_INITIALIZED );
      77             : 
      78           0 :         if( _type == type && size >= newSize )
      79             :         {
      80           0 :             bind();
      81           0 :             return Error( ERROR_NONE );
      82             :         }
      83             : 
      84           0 :         _type = type;
      85           0 :         size = newSize;
      86           0 :         bind();
      87             : 
      88           0 :         switch( type )
      89             :         {
      90             :         case GL_READ_ONLY_ARB:
      91           0 :             EQ_GL_CALL(
      92             :                 glBufferDataARB( GL_PIXEL_PACK_BUFFER_ARB, newSize, 0,
      93             :                                  GL_STREAM_READ_ARB ));
      94           0 :             return Error( ERROR_NONE );
      95             : 
      96             :         case GL_WRITE_ONLY_ARB:
      97           0 :             EQ_GL_CALL(
      98             :                 glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB, newSize, 0,
      99             :                                  GL_STREAM_DRAW_ARB ));
     100           0 :             return Error( ERROR_NONE );
     101             : 
     102             :         default:
     103           0 :             destroy();
     104           0 :             return Error( ERROR_PBO_TYPE_UNSUPPORTED );
     105             :         }
     106             :     }
     107             : 
     108           3 :     void destroy()
     109             :     {
     110           3 :         if( pboID != 0 )
     111             :         {
     112           0 :             unbind();
     113           0 :             EQ_GL_CALL( glDeleteBuffersARB( 1, &pboID ));
     114             :         }
     115           3 :         pboID = 0;
     116           3 :         size = 0;
     117           3 :         _type = 0;
     118           3 :     }
     119             : 
     120           0 :     const void* mapRead() const
     121             :     {
     122           0 :         if( !isInitialized() || _type != GL_READ_ONLY_ARB )
     123           0 :             return 0;
     124             : 
     125           0 :         bind();
     126           0 :         return glMapBufferARB( _getName(), GL_READ_ONLY_ARB );
     127             :     }
     128             : 
     129           0 :     void* mapWrite()
     130             :     {
     131           0 :         if( !isInitialized() || _type != GL_WRITE_ONLY_ARB )
     132           0 :             return 0;
     133             : 
     134           0 :         bind();
     135             :         // cancel all draw operations on this buffer to prevent stalling
     136           0 :         EQ_GL_CALL( glBufferDataARB( _getName(), size, 0, GL_STREAM_DRAW_ARB ));
     137           0 :         return glMapBufferARB( _getName(), GL_WRITE_ONLY_ARB );
     138             :     }
     139             : 
     140           0 :     void unmap() const
     141             :     {
     142           0 :         LBASSERT( isInitialized( ));
     143           0 :         EQ_GL_CALL( glUnmapBufferARB( _getName( )));
     144           0 :         unbind();
     145           0 :     }
     146             : 
     147           0 :     bool bind() const
     148             :     {
     149           0 :         if( !isInitialized( ))
     150           0 :             return false;
     151             : 
     152           0 :         EQ_GL_CALL( glBindBufferARB( _getName(), pboID ));
     153           0 :         return true;
     154             :     }
     155             : 
     156           0 :     void unbind() const
     157             :     {
     158           0 :         LBASSERT( isInitialized( ));
     159           0 :         EQ_GL_CALL( glBindBufferARB( _getName(), 0 ));
     160           0 :     }
     161             : 
     162           0 :     void lock()   const { if( lock_ ) lock_->set();   }
     163           0 :     void unlock() const { if( lock_ ) lock_->unset(); }
     164             : 
     165             :     mutable lunchbox::Lock* lock_;
     166             :     GLuint  pboID; //!< the PBO GL name
     167             :     size_t size;  //!< size of the allocated PBO buffer
     168             : 
     169             : private:
     170             :     const GLEWContext* const _glewContext;
     171             :     GLuint _type; //!< GL_READ_ONLY_ARB or GL_WRITE_ONLY_ARB
     172             : 
     173           0 :     GLuint _getName() const
     174             :     {
     175           0 :         return _type == GL_READ_ONLY_ARB ? GL_PIXEL_PACK_BUFFER_ARB :
     176           0 :                                            GL_PIXEL_UNPACK_BUFFER_ARB;
     177             :     }
     178             : };
     179             : }
     180             : 
     181           3 : PixelBufferObject::PixelBufferObject( const GLEWContext* glewContext,
     182             :                                       const bool threadSafe )
     183           3 :     : _impl( new detail::PixelBufferObject( glewContext, threadSafe ))
     184             : {
     185           3 : }
     186             : 
     187           6 : PixelBufferObject::~PixelBufferObject()
     188             : {
     189           3 :     delete _impl;
     190           6 : }
     191             : 
     192           3 : Error PixelBufferObject::setup( const size_t size, const unsigned type )
     193             : {
     194           3 :     lunchbox::ScopedWrite mutex( _impl->lock_ );
     195           3 :     return _impl->setup( size, type );
     196             : }
     197             : 
     198           3 : void PixelBufferObject::destroy()
     199             : {
     200           3 :     lunchbox::ScopedWrite mutex( _impl->lock_ );
     201           3 :     _impl->destroy();
     202           3 : }
     203             : 
     204           0 : const void* PixelBufferObject::mapRead() const
     205             : {
     206           0 :     _impl->lock();
     207           0 :     return _impl->mapRead();
     208             : }
     209             : 
     210           0 : void* PixelBufferObject::mapWrite()
     211             : {
     212           0 :     _impl->lock();
     213           0 :     return _impl->mapWrite();
     214             : }
     215             : 
     216           0 : void PixelBufferObject::unmap() const
     217             : {
     218           0 :     _impl->unmap();
     219           0 :     _impl->unlock();
     220           0 : }
     221             : 
     222           0 : bool PixelBufferObject::bind() const
     223             : {
     224           0 :     _impl->lock();
     225           0 :     return _impl->bind();
     226             : }
     227             : 
     228           0 : void PixelBufferObject::unbind() const
     229             : {
     230           0 :     _impl->unbind();
     231           0 :     _impl->unlock();
     232           0 : }
     233             : 
     234           0 : size_t PixelBufferObject::getSize() const
     235             : {
     236           0 :     return _impl->size;
     237             : }
     238             : 
     239           3 : bool PixelBufferObject::isInitialized() const
     240             : {
     241           3 :     return _impl->isInitialized();
     242             : }
     243             : 
     244           0 : bool PixelBufferObject::isThreadSafe() const
     245             : {
     246           0 :     return _impl->lock_ != 0;
     247             : }
     248             : 
     249           0 : GLuint PixelBufferObject::getID() const
     250             : {
     251           0 :     return _impl->pboID;
     252             : }
     253             : 
     254             : }
     255          36 : }

Generated by: LCOV version 1.10