LCOV - code coverage report
Current view: top level - eq/compressor - compressorReadDrawPixels.cpp (source / functions) Hit Total Coverage
Test: Equalizer Lines: 31 293 10.6 %
Date: 2016-07-30 05:04:55 Functions: 60 77 77.9 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c)      2010, Cedric Stalder <cedric.stalder@eyescale.ch>
       3             :  *               2010-2014, Stefan Eilemann <eile@eyescale.ch>
       4             :  *               2010-2011, 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             : #include "compressorReadDrawPixels.h"
      21             : 
      22             : #include <eq/fabric/pixelViewport.h>
      23             : #include <eq/util/texture.h>
      24             : #include <eq/util/pixelBufferObject.h>
      25             : #include <lunchbox/buffer.h>
      26             : 
      27             : #define glewGetContext() glewContext
      28             : 
      29             : namespace eq
      30             : {
      31             : namespace plugin
      32             : {
      33             : 
      34             : namespace
      35             : {
      36             : int _warned = 0;
      37          14 : static stde::hash_map< unsigned, unsigned > _depths;
      38             : 
      39             : #define REGISTER_TRANSFER( in, out, size, quality_, ratio_, speed_, alpha ) \
      40             :     static void _getInfo ## in ## out( EqCompressorInfo* const info )   \
      41             :     {                                                                   \
      42             :         info->version = EQ_COMPRESSOR_VERSION;                          \
      43             :         info->capabilities = EQ_COMPRESSOR_TRANSFER |                   \
      44             :                              EQ_COMPRESSOR_DATA_2D |                    \
      45             :                              EQ_COMPRESSOR_USE_TEXTURE_RECT |           \
      46             :                              EQ_COMPRESSOR_USE_TEXTURE_2D |             \
      47             :                              EQ_COMPRESSOR_USE_ASYNC_DOWNLOAD |         \
      48             :                              EQ_COMPRESSOR_USE_FRAMEBUFFER;             \
      49             :         if( alpha )                                                     \
      50             :             info->capabilities |= EQ_COMPRESSOR_IGNORE_ALPHA;           \
      51             :         info->quality = quality_ ## f;                                  \
      52             :         info->ratio   = ratio_ ## f;                                    \
      53             :         info->speed   = speed_ ## f;                                    \
      54             :         info->name = EQ_COMPRESSOR_TRANSFER_ ## in ## _TO_ ## out;      \
      55             :         info->tokenType = EQ_COMPRESSOR_DATATYPE_ ## in;                \
      56             :         info->outputTokenType = EQ_COMPRESSOR_DATATYPE_ ## out;         \
      57             :         info->outputTokenSize = size;                                   \
      58             :     }                                                                   \
      59             :                                                                         \
      60             :     static bool _register ## in ## out()                                \
      61             :     {                                                                   \
      62             :         const unsigned name = EQ_COMPRESSOR_TRANSFER_ ## in ## _TO_ ## out; \
      63             :         Compressor::registerEngine(                                     \
      64             :             Compressor::Functions(                                      \
      65             :                 name,                                                   \
      66             :                 _getInfo ## in ## out,                                  \
      67             :                 CompressorReadDrawPixels::getNewCompressor,             \
      68             :                 CompressorReadDrawPixels::getNewDecompressor,           \
      69             :                 0,                                                      \
      70             :                 CompressorReadDrawPixels::isCompatible ));              \
      71             :         _depths[ name ] = size;                                         \
      72             :         return true;                                                    \
      73             :     }                                                                   \
      74             :                                                                         \
      75             : static bool _initialized ## in ## out LB_UNUSED = _register ## in ## out();
      76             : 
      77          33 : REGISTER_TRANSFER( RGBA, RGBA, 4, 1., 1., 1., false );
      78          33 : REGISTER_TRANSFER( RGBA, BGRA, 4, 1., 1., 2., false );
      79          33 : REGISTER_TRANSFER( RGBA, RGBA_UINT_8_8_8_8_REV, 4, 1., 1., 1., false );
      80          33 : REGISTER_TRANSFER( RGBA, BGRA_UINT_8_8_8_8_REV, 4, 1., 1., 2., false );
      81          33 : REGISTER_TRANSFER( RGBA, RGB, 3, 1., 1., .7, true );
      82          33 : REGISTER_TRANSFER( RGBA, BGR, 3, 1., 1., .7, true );
      83             : 
      84          33 : REGISTER_TRANSFER( RGB10_A2, BGR10_A2, 4, 1., 1., 1.1, false );
      85          33 : REGISTER_TRANSFER( RGB10_A2, RGB10_A2, 4, 1., 1., 1., false );
      86             : 
      87          33 : REGISTER_TRANSFER( RGBA16F, RGBA16F, 8, 1., 1., 1., false );
      88          33 : REGISTER_TRANSFER( RGBA16F, BGRA16F, 8, 1., 1., 1.1, false );
      89          33 : REGISTER_TRANSFER( RGBA16F, RGB16F, 6, 1., 1., 1., true );
      90          33 : REGISTER_TRANSFER( RGBA16F, BGR16F, 6, 1., 1., 1.1, true );
      91          33 : REGISTER_TRANSFER( RGBA16F, RGBA, 4, .5, .5, 1., false );
      92          33 : REGISTER_TRANSFER( RGBA16F, BGRA, 4, .5, .5, 1.1, false );
      93          33 : REGISTER_TRANSFER( RGBA16F, RGB, 3, .5, .5, 1., true );
      94          33 : REGISTER_TRANSFER( RGBA16F, BGR, 3, .5, .5, 1.1, true );
      95             : 
      96          33 : REGISTER_TRANSFER( RGBA32F, RGBA32F, 16, 1., 1., 1.1, false );
      97          33 : REGISTER_TRANSFER( RGBA32F, BGRA32F, 16, 1., 1., 1., false );
      98          33 : REGISTER_TRANSFER( RGBA32F, RGB32F, 12, 1., 1., 1., true );
      99          33 : REGISTER_TRANSFER( RGBA32F, BGR32F, 12, 1., 1., 1.1, true );
     100          33 : REGISTER_TRANSFER( RGBA32F, RGBA16F, 8, .5, .5, 1., false );
     101          33 : REGISTER_TRANSFER( RGBA32F, BGRA16F, 8,.5, .5, 1.1, false );
     102          33 : REGISTER_TRANSFER( RGBA32F, RGB16F, 6, .5, .5, 1., true );
     103          33 : REGISTER_TRANSFER( RGBA32F, BGR16F, 6, .5, .5, 1.1, true );
     104          33 : REGISTER_TRANSFER( RGBA32F, RGBA, 4, .25, .25, 1., false );
     105          33 : REGISTER_TRANSFER( RGBA32F, BGRA, 4, .25, .25, 1.1, false );
     106          33 : REGISTER_TRANSFER( RGBA32F, RGB, 3, .25, .25, 1., true );
     107          33 : REGISTER_TRANSFER( RGBA32F, BGR, 3, .25, .25, 1.1, true );
     108             : 
     109          33 : REGISTER_TRANSFER( DEPTH, DEPTH_UNSIGNED_INT, 4, 1., 1., 1., false );
     110             : }
     111             : 
     112           0 : CompressorReadDrawPixels::CompressorReadDrawPixels( const unsigned name )
     113             :         : Compressor()
     114             :         , _texture( 0 )
     115             :         , _pbo( 0 )
     116             :         , _internalFormat( 0 )
     117             :         , _format( 0 )
     118             :         , _type( 0 )
     119           0 :         , _depth( _depths[ name ] )
     120             : {
     121           0 :     LBASSERT( _depth > 0 );
     122           0 :     switch( name )
     123             :     {
     124             :         case EQ_COMPRESSOR_TRANSFER_RGBA_TO_RGBA:
     125           0 :             _format = GL_RGBA;
     126           0 :             _type = GL_UNSIGNED_BYTE;
     127           0 :             _internalFormat = GL_RGBA;
     128           0 :             break;
     129             :         case EQ_COMPRESSOR_TRANSFER_RGBA_TO_RGBA_UINT_8_8_8_8_REV:
     130           0 :             _format = GL_RGBA;
     131           0 :             _type = GL_UNSIGNED_BYTE;
     132           0 :             _internalFormat = GL_RGBA;
     133           0 :             break;
     134             :         case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_RGBA:
     135           0 :             _format = GL_RGBA;
     136           0 :             _type = GL_UNSIGNED_BYTE;
     137           0 :             _internalFormat = GL_RGBA16F;
     138           0 :             break;
     139             :         case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_RGBA16F:
     140           0 :             _format = GL_RGBA;
     141           0 :             _type = GL_HALF_FLOAT;
     142           0 :             _internalFormat = GL_RGBA16F;
     143           0 :             break;
     144             :         case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_RGBA:
     145           0 :             _format = GL_RGBA;
     146           0 :             _type = GL_UNSIGNED_BYTE;
     147           0 :             _internalFormat = GL_RGBA32F;
     148           0 :             break;
     149             :         case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_RGBA16F:
     150           0 :             _format = GL_RGBA;
     151           0 :             _type = GL_HALF_FLOAT;
     152           0 :             _internalFormat = GL_RGBA32F;
     153           0 :             break;
     154             :         case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_RGBA32F:
     155           0 :             _format = GL_RGBA;
     156           0 :             _type = GL_FLOAT;
     157           0 :             _internalFormat = GL_RGBA32F;
     158           0 :             break;
     159             : 
     160             :         case EQ_COMPRESSOR_TRANSFER_RGBA_TO_BGRA:
     161           0 :             _format = GL_BGRA;
     162           0 :             _type = GL_UNSIGNED_BYTE;
     163           0 :             _internalFormat = GL_RGBA;
     164           0 :             break;
     165             :         case EQ_COMPRESSOR_TRANSFER_RGBA_TO_BGRA_UINT_8_8_8_8_REV:
     166           0 :             _format = GL_BGRA;
     167           0 :             _type = GL_UNSIGNED_BYTE;
     168           0 :             _internalFormat = GL_RGBA;
     169           0 :             break;
     170             :         case EQ_COMPRESSOR_TRANSFER_RGB10_A2_TO_BGR10_A2:
     171           0 :             _format = GL_BGRA;
     172           0 :             _type = GL_UNSIGNED_INT_10_10_10_2;
     173           0 :             _internalFormat = GL_RGB10_A2;
     174           0 :             break;
     175             :         case EQ_COMPRESSOR_TRANSFER_RGB10_A2_TO_RGB10_A2:
     176           0 :             _format = GL_RGBA;
     177           0 :             _type = GL_UNSIGNED_INT_10_10_10_2;
     178           0 :             _internalFormat = GL_RGB10_A2;
     179           0 :             break;
     180             :         case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_BGRA:
     181           0 :             _format = GL_BGRA;
     182           0 :             _type = GL_UNSIGNED_BYTE;
     183           0 :             _internalFormat = GL_RGBA16F;
     184           0 :             break;
     185             :         case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_BGRA16F:
     186           0 :             _format = GL_BGRA;
     187           0 :             _type = GL_HALF_FLOAT;
     188           0 :             _internalFormat = GL_RGBA16F;
     189           0 :             break;
     190             :         case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_BGRA:
     191           0 :             _format = GL_BGRA;
     192           0 :             _type = GL_UNSIGNED_BYTE;
     193           0 :             _internalFormat = GL_RGBA32F;
     194           0 :             break;
     195             :         case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_BGRA16F:
     196           0 :             _format = GL_BGRA;
     197           0 :             _type = GL_HALF_FLOAT;
     198           0 :             _internalFormat = GL_RGBA32F;
     199           0 :             break;
     200             :         case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_BGRA32F:
     201           0 :             _format = GL_BGRA;
     202           0 :             _type = GL_FLOAT;
     203           0 :             _internalFormat = GL_RGBA32F;
     204           0 :             break;
     205             :         case EQ_COMPRESSOR_TRANSFER_RGBA_TO_RGB:
     206           0 :             _format = GL_RGB;
     207           0 :             _type = GL_UNSIGNED_BYTE;
     208           0 :             _internalFormat = GL_RGBA;
     209           0 :             break;
     210             :         case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_RGB:
     211           0 :             _format = GL_RGB;
     212           0 :             _type = GL_UNSIGNED_BYTE;
     213           0 :             _internalFormat = GL_RGBA16F;
     214           0 :             break;
     215             :         case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_RGB16F:
     216           0 :             _format = GL_RGB;
     217           0 :             _type = GL_HALF_FLOAT;
     218           0 :             _internalFormat = GL_RGBA16F;
     219           0 :             break;
     220             :         case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_RGB:
     221           0 :             _format = GL_RGB;
     222           0 :             _type = GL_UNSIGNED_BYTE;
     223           0 :             _internalFormat = GL_RGBA32F;
     224           0 :             break;
     225             :         case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_RGB32F:
     226           0 :             _format = GL_RGB;
     227           0 :             _type = GL_FLOAT;
     228           0 :             _internalFormat = GL_RGBA32F;
     229           0 :             break;
     230             :         case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_RGB16F:
     231           0 :             _format = GL_RGB;
     232           0 :             _type = GL_HALF_FLOAT;
     233           0 :             _internalFormat = GL_RGBA32F;
     234           0 :             break;
     235             :         case EQ_COMPRESSOR_TRANSFER_RGBA_TO_BGR:
     236           0 :             _format = GL_BGR;
     237           0 :             _type = GL_UNSIGNED_BYTE;
     238           0 :             _internalFormat = GL_RGBA;
     239           0 :             break;
     240             :         case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_BGR:
     241           0 :             _format = GL_BGR;
     242           0 :             _type = GL_UNSIGNED_BYTE;
     243           0 :             _internalFormat = GL_RGBA16F;
     244           0 :             break;
     245             :         case EQ_COMPRESSOR_TRANSFER_RGBA16F_TO_BGR16F:
     246           0 :             _format = GL_BGR;
     247           0 :             _type = GL_HALF_FLOAT;
     248           0 :             _internalFormat = GL_RGBA16F;
     249           0 :             break;
     250             :         case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_BGR:
     251           0 :             _format = GL_BGR;
     252           0 :             _type = GL_UNSIGNED_BYTE;
     253           0 :             _internalFormat = GL_RGBA32F;
     254           0 :             break;
     255             :         case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_BGR32F:
     256           0 :             _format = GL_BGR;
     257           0 :             _type = GL_FLOAT;
     258           0 :             _internalFormat = GL_RGBA32F;
     259           0 :             break;
     260             :         case EQ_COMPRESSOR_TRANSFER_RGBA32F_TO_BGR16F:
     261           0 :             _format = GL_BGR;
     262           0 :             _type = GL_HALF_FLOAT;
     263           0 :             _internalFormat = GL_RGBA32F;
     264           0 :             break;
     265             :         case EQ_COMPRESSOR_TRANSFER_DEPTH_TO_DEPTH_UNSIGNED_INT:
     266           0 :             _format = GL_DEPTH_COMPONENT;
     267           0 :             _type = GL_UNSIGNED_INT;
     268           0 :             _internalFormat = GL_DEPTH_COMPONENT;
     269           0 :             break;
     270             : 
     271           0 :         default: LBASSERT( false );
     272             :     }
     273           0 : }
     274             : 
     275           0 : CompressorReadDrawPixels::~CompressorReadDrawPixels( )
     276             : {
     277           0 :     delete _texture;
     278           0 :     _texture = 0;
     279             : 
     280           0 :     if( _pbo )
     281             :     {
     282           0 :         _pbo->destroy();
     283           0 :         delete _pbo;
     284           0 :         _pbo = 0;
     285             :     }
     286           0 : }
     287             : 
     288           0 : bool CompressorReadDrawPixels::isCompatible( const GLEWContext* )
     289             : {
     290           0 :     return true;
     291             : }
     292             : 
     293             : namespace
     294             : {
     295           0 : void _copy4( eq_uint64_t dst[4], const eq_uint64_t src[4] )
     296             : {
     297           0 :     memcpy( &dst[0], &src[0], sizeof(eq_uint64_t)*4 );
     298           0 : }
     299             : 
     300           0 : void _initPackAlignment( const eq_uint64_t width )
     301             : {
     302           0 :     if( (width % 4) == 0 )
     303             :     {
     304           0 :         EQ_GL_CALL( glPixelStorei( GL_PACK_ALIGNMENT, 4 ));
     305             :     }
     306           0 :     else if( (width % 2) == 0 )
     307             :     {
     308           0 :         EQ_GL_CALL( glPixelStorei( GL_PACK_ALIGNMENT, 2 ));
     309             :     }
     310             :     else
     311             :     {
     312           0 :         EQ_GL_CALL( glPixelStorei( GL_PACK_ALIGNMENT, 1 ));
     313             :     }
     314           0 : }
     315             : 
     316           0 : void _initUnpackAlignment( const eq_uint64_t width )
     317             : {
     318           0 :     if( (width % 4) == 0 )
     319             :     {
     320           0 :         EQ_GL_CALL( glPixelStorei( GL_UNPACK_ALIGNMENT, 4 ));
     321             :     }
     322           0 :     else if( (width % 2) == 0 )
     323             :     {
     324           0 :         EQ_GL_CALL( glPixelStorei( GL_UNPACK_ALIGNMENT, 2 ));
     325             :     }
     326             :     else
     327             :     {
     328           0 :         EQ_GL_CALL( glPixelStorei( GL_UNPACK_ALIGNMENT, 1 ));
     329             :     }
     330           0 : }
     331             : }
     332             : 
     333           0 : void CompressorReadDrawPixels::_resizeBuffer( const eq_uint64_t size )
     334             : {
     335             :     // eile: The code path using realloc creates visual artefacts on my MacBook
     336             :     //       The other crashes occasionally with KERN_BAD_ADDRESS
     337             :     //       Seems to be only with GL_RGB. Radar #8261726.
     338             : #if 1
     339           0 :     _buffer.reserve( size );
     340           0 :     _buffer.setSize( size );
     341             : #else
     342             :     // eile: This code path using realloc creates visual artefacts on my MacBook
     343             :     _buffer.resize( size );
     344             : #endif
     345           0 : }
     346             : 
     347           0 : void CompressorReadDrawPixels::_initDownload( const GLEWContext*,
     348             :                                               const eq_uint64_t inDims[4],
     349             :                                               eq_uint64_t outDims[4] )
     350             : {
     351           0 :     _copy4( outDims, inDims );
     352           0 :     const size_t size = inDims[1] * inDims[3] * _depth;
     353           0 :     _resizeBuffer( size );
     354           0 :     _initPackAlignment( outDims[1] );
     355           0 : }
     356             : 
     357           0 : void CompressorReadDrawPixels::_initTexture( const GLEWContext* glewContext,
     358             :                                              const eq_uint64_t flags )
     359             : {
     360           0 :     GLenum target = 0;
     361           0 :     if( flags & EQ_COMPRESSOR_USE_TEXTURE_2D )
     362           0 :         target = GL_TEXTURE_2D;
     363           0 :     else if( flags & EQ_COMPRESSOR_USE_TEXTURE_RECT )
     364           0 :         target = GL_TEXTURE_RECTANGLE_ARB;
     365             :     else
     366             :     {
     367           0 :         LBUNREACHABLE;
     368             :     }
     369             : 
     370           0 :     if ( !_texture || _texture->getTarget() != target )
     371             :     {
     372           0 :         delete _texture;
     373           0 :         _texture = new util::Texture( target, glewContext );
     374             :     }
     375           0 : }
     376             : 
     377           0 : void CompressorReadDrawPixels::_initAsyncTexture(const GLEWContext* glewContext,
     378             :                                                  const eq_uint64_t w,
     379             :                                                  const eq_uint64_t h )
     380             : {
     381           0 :     if( !_texture || _texture->getTarget() != GL_TEXTURE_RECTANGLE_ARB ||
     382           0 :         !_texture->isValid( ))
     383             :     {
     384           0 :         delete _texture;
     385           0 :         _texture = new util::Texture( GL_TEXTURE_RECTANGLE_ARB, glewContext );
     386             :     }
     387             : 
     388           0 :     _texture->setGLEWContext( glewContext );
     389           0 :     _texture->init( _internalFormat, w, h );
     390             : 
     391             :     // ensure texture exists in tfer thread, might need fence for Tesla GPUs
     392           0 :     glFlush();
     393           0 : }
     394             : 
     395           0 : void CompressorReadDrawPixels::download( const GLEWContext* glewContext,
     396             :                                          const eq_uint64_t  inDims[4],
     397             :                                          const unsigned     source,
     398             :                                          const eq_uint64_t  flags,
     399             :                                                eq_uint64_t  outDims[4],
     400             :                                          void**             out )
     401             : {
     402           0 :     _initDownload( glewContext, inDims, outDims );
     403             : 
     404           0 :     if( flags & EQ_COMPRESSOR_USE_FRAMEBUFFER )
     405             :     {
     406           0 :         EQ_GL_CALL( glReadPixels( inDims[0], inDims[2], inDims[1], inDims[3],
     407             :                                   _format, _type, _buffer.getData( )));
     408           0 :         *out = _buffer.getData();
     409             :     }
     410             :     else
     411             :     {
     412           0 :         _initTexture( glewContext, flags );
     413           0 :         _texture->setGLData( source, _internalFormat, inDims[1], inDims[3] );
     414           0 :         _texture->setExternalFormat( _format, _type );
     415           0 :         *out = _downloadTexture( glewContext, FLUSH_TEXTURE );
     416             :     }
     417           0 : }
     418             : 
     419           0 : void CompressorReadDrawPixels::upload( const GLEWContext* glewContext,
     420             :                                        const void*        buffer,
     421             :                                        const eq_uint64_t  inDims[4],
     422             :                                        const eq_uint64_t  flags,
     423             :                                        const eq_uint64_t  outDims[4],
     424             :                                        const unsigned     destination )
     425             : {
     426           0 :     _initUnpackAlignment( inDims[1] );
     427             : 
     428           0 :     if( flags & EQ_COMPRESSOR_USE_FRAMEBUFFER )
     429             :     {
     430           0 :         EQ_GL_CALL( glRasterPos2i( outDims[0], outDims[2] ));
     431           0 :         EQ_GL_CALL( glDrawPixels( outDims[1], outDims[3], _format, _type,
     432             :                     buffer ));
     433             :     }
     434             :     else
     435             :     {
     436           0 :         LBASSERT( outDims[0] == 0 && outDims[2]==0 ); // Implement me
     437           0 :         _initTexture( glewContext, flags );
     438             :         _texture->setGLData( destination, _internalFormat,
     439           0 :                              outDims[1], outDims[3] );
     440           0 :         _texture->setExternalFormat( _format, _type );
     441           0 :         _texture->upload( outDims[1], outDims[3], buffer );
     442           0 :         _texture->flushNoDelete();
     443             :     }
     444           0 : }
     445             : 
     446           0 : bool CompressorReadDrawPixels::_initPBO( const GLEWContext* glewContext,
     447             :                                          const eq_uint64_t size )
     448             : {
     449             :     // create thread-safe PBO
     450           0 :     if( !_pbo )
     451           0 :         _pbo = new util::PixelBufferObject( glewContext, true );
     452             : 
     453           0 :     const Error error = _pbo->setup( size, GL_READ_ONLY_ARB );
     454           0 :     if( !error )
     455           0 :         return true;
     456             : 
     457           0 :     if( _warned < 10 )
     458             :     {
     459           0 :         LBWARN << "Can't initialize PBO for async readback: " << error
     460           0 :                << std::endl;
     461           0 :         ++_warned;
     462             :     }
     463           0 :     return false;
     464             : }
     465             : 
     466           0 : void CompressorReadDrawPixels::startDownload( const GLEWContext* glewContext,
     467             :                                               const eq_uint64_t dims[4],
     468             :                                               const unsigned source,
     469             :                                               const eq_uint64_t flags )
     470             : {
     471           0 :     _initPackAlignment( dims[1] );
     472             : 
     473           0 :     const eq_uint64_t size = dims[1] * dims[3] * _depth;
     474           0 :     if( flags & EQ_COMPRESSOR_USE_FRAMEBUFFER )
     475             :     {
     476             :         // async RB through texture
     477           0 :         if( !GLEW_ARB_pixel_buffer_object )
     478             :         {
     479           0 :             const PixelViewport pvp( dims[0], dims[2], dims[1], dims[3] );
     480           0 :             _initAsyncTexture( glewContext, pvp.w, pvp.h );
     481           0 :             _texture->setExternalFormat( _format, _type );
     482           0 :             _texture->copyFromFrameBuffer( _internalFormat, pvp );
     483           0 :             _resizeBuffer( size );
     484           0 :             return;
     485             :         }
     486             : 
     487           0 :         if( _initPBO( glewContext, size ))
     488             :         {
     489           0 :             EQ_GL_CALL( glReadPixels( dims[0], dims[2], dims[1], dims[3],
     490             :                                       _format, _type, 0 ));
     491           0 :             _pbo->unbind();
     492           0 :             glFlush(); // Fixes https://github.com/Eyescale/Equalizer/issues/118
     493           0 :             return;
     494             :         }
     495             :         // else
     496           0 :         _resizeBuffer( size );
     497           0 :         EQ_GL_CALL( glReadPixels( dims[0], dims[2], dims[1], dims[3],
     498             :                                   _format, _type, _buffer.getData( )));
     499             :     }
     500             :     else
     501             :     {
     502           0 :         _resizeBuffer( size );
     503           0 :         _initTexture( glewContext, flags );
     504           0 :         _texture->setGLData( source, _internalFormat, dims[1], dims[3] );
     505           0 :         _texture->setExternalFormat( _format, _type );
     506           0 :         glFlush(); // Enough?
     507             :     }
     508             : }
     509             : 
     510           0 : void* CompressorReadDrawPixels::_downloadTexture(
     511             :     const GLEWContext* glewContext, const FlushMode mode )
     512             : {
     513           0 :     LBASSERT( _texture );
     514           0 :     _texture->setGLEWContext( glewContext );
     515           0 :     _texture->download( _buffer.getData( ));
     516           0 :     if( mode == FLUSH_TEXTURE )
     517           0 :         _texture->flushNoDelete();
     518             : 
     519           0 :     return _buffer.getData();
     520             : }
     521             : 
     522           0 : void CompressorReadDrawPixels::finishDownload(
     523             :     const GLEWContext* glewContext, const eq_uint64_t inDims[4],
     524             :     const eq_uint64_t flags, eq_uint64_t outDims[4], void** out )
     525             : {
     526           0 :     _copy4( outDims, inDims );
     527           0 :     _initPackAlignment( inDims[1] );
     528             : 
     529           0 :     if( flags & (EQ_COMPRESSOR_USE_TEXTURE_RECT|EQ_COMPRESSOR_USE_TEXTURE_2D) )
     530             :     {
     531           0 :         *out = _downloadTexture( glewContext, FLUSH_TEXTURE );
     532           0 :         return;
     533             :     }
     534             : 
     535           0 :     LBASSERT( flags & EQ_COMPRESSOR_USE_FRAMEBUFFER );
     536             : 
     537             :     // async RB through texture
     538           0 :     if( !GLEW_ARB_pixel_buffer_object )
     539             :     {
     540           0 :         *out = _downloadTexture( glewContext, KEEP_TEXTURE );
     541           0 :         return;
     542             :     }
     543             : 
     544           0 :     if( _pbo && _pbo->isInitialized( ))
     545             :     {
     546           0 :         const eq_uint64_t size = inDims[1] * inDims[3] * _depth;
     547           0 :         _resizeBuffer( size );
     548             : 
     549           0 :         const void* ptr = _pbo->mapRead();
     550           0 :         if( ptr )
     551             :         {
     552           0 :             memcpy( _buffer.getData(), ptr, size );
     553           0 :             _pbo->unmap();
     554             :         }
     555             :         else
     556             :         {
     557           0 :             LBERROR << "Can't map PBO" << std::endl;
     558           0 :             EQ_GL_ERROR( "PixelBufferObject::mapRead()" );
     559             :         }
     560             :     }
     561           0 :     *out = _buffer.getData();
     562             : }
     563             : 
     564             : }
     565          42 : }

Generated by: LCOV version 1.11