LCOV - code coverage report
Current view: top level - eq/util - pixelBufferObject.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 81 110 73.6 %
Date: 2017-12-16 05:07:20 Functions: 22 27 81.5 %

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

Generated by: LCOV version 1.11