LCOV - code coverage report
Current view: top level - pression - plugin.cpp (source / functions) Hit Total Coverage
Test: Pression Lines: 75 114 65.8 %
Date: 2016-12-06 05:44:58 Functions: 11 13 84.6 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2009-2010, Cedric Stalder <cedric.stalder@gmail.com>
       3             :  *               2009-2014, Stefan Eilemann <eile@equalizergraphics.com>
       4             :  *
       5             :  * This file is part of Collage <https://github.com/Eyescale/Collage>
       6             :  *
       7             :  * This library is free software; you can redistribute it and/or modify it under
       8             :  * the terms of the GNU Lesser General Public License version 2.1 as published
       9             :  * by the Free Software Foundation.
      10             :  *
      11             :  * This library is distributed in the hope that it will be useful, but WITHOUT
      12             :  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
      13             :  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
      14             :  * details.
      15             :  *
      16             :  * You should have received a copy of the GNU Lesser General Public License
      17             :  * along with this library; if not, write to the Free Software Foundation, Inc.,
      18             :  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
      19             :  */
      20             : 
      21             : #include "plugin.h"
      22             : 
      23             : #include "compressorInfo.h"
      24             : #include "pluginRegistry.h"
      25             : #include "pluginVisitor.h"
      26             : 
      27             : #include <cmath>
      28             : #include <lunchbox/debug.h>
      29             : #include <lunchbox/log.h>
      30             : #include <lunchbox/os.h>
      31             : 
      32             : namespace pression
      33             : {
      34             : typedef void ( *GetInfo_t ) ( const size_t, EqCompressorInfo* const );
      35             : namespace detail
      36             : {
      37           2 : class Plugin
      38             : {
      39             : public:
      40             :     CompressorInfos infos;
      41             : };
      42             : }
      43             : 
      44           1 : Plugin::Plugin( const std::string& libraryName )
      45             :     : DSO( libraryName )
      46           2 :     , getNumCompressors( getFunctionPointer< GetNumCompressors_t >(
      47             :                              "EqCompressorGetNumCompressors" ))
      48           2 :     , newCompressor( getFunctionPointer< NewCompressor_t >(
      49             :                          "EqCompressorNewCompressor" ))
      50           2 :     , newDecompressor( getFunctionPointer< NewDecompressor_t >(
      51             :                            "EqCompressorNewDecompressor" ))
      52           2 :     , deleteCompressor( getFunctionPointer< DeleteCompressor_t >(
      53             :                             "EqCompressorDeleteCompressor" ))
      54           2 :     , deleteDecompressor( getFunctionPointer< DeleteDecompressor_t >(
      55             :                               "EqCompressorDeleteDecompressor" ))
      56           2 :     , compress( getFunctionPointer< Compress_t >( "EqCompressorCompress" ))
      57           2 :     , decompress( getFunctionPointer< Decompress_t >( "EqCompressorDecompress"))
      58           2 :     , getNumResults( getFunctionPointer< GetNumResults_t >(
      59             :                          "EqCompressorGetNumResults" ))
      60           2 :     , getResult( getFunctionPointer< GetResult_t >( "EqCompressorGetResult" ))
      61           2 :     , isCompatible( getFunctionPointer< IsCompatible_t >(
      62             :                         "EqCompressorIsCompatible" ))
      63           2 :     , download( getFunctionPointer< Download_t >( "EqCompressorDownload" ))
      64           2 :     , upload( getFunctionPointer< Upload_t >( "EqCompressorUpload" ))
      65           2 :     , startDownload( getFunctionPointer< StartDownload_t >(
      66             :                          "EqCompressorStartDownload" ))
      67           2 :     , finishDownload( getFunctionPointer< FinishDownload_t >(
      68             :                           "EqCompressorFinishDownload" ))
      69          16 :     , impl_( new detail::Plugin )
      70             : {
      71           1 :     if( !isOpen( ))
      72           0 :         return;
      73             : 
      74             :     const GetInfo_t getInfo =
      75           1 :         getFunctionPointer< GetInfo_t >( "EqCompressorGetInfo" );
      76             : 
      77           3 :     const bool hasBase = newDecompressor && newCompressor && deleteCompressor &&
      78           3 :                          deleteDecompressor && getInfo && getNumCompressors;
      79           1 :     const bool hasCPU = getResult && getNumResults && decompress && compress;
      80           1 :     const bool hasGPU = isCompatible && download && upload;
      81           1 :     if( !hasBase || ( !hasCPU && !hasGPU ))
      82             :     {
      83           0 :         LBWARN << "Initializing compression DSO " << libraryName
      84           0 :                << " failed, at least one entry point missing" << std::endl;
      85           0 :         return;
      86             :     }
      87             : 
      88           1 :     const size_t nCompressors = getNumCompressors();
      89           1 :     if( nCompressors == 0 )
      90             :     {
      91           0 :         LBWARN << "Initializing compression DSO " << libraryName
      92           0 :                << " failed, 0 compression engines reported" << std::endl;
      93           0 :         return;
      94             :     }
      95             : 
      96           1 :     impl_->infos.resize( nCompressors );
      97          41 :     for( size_t i = 0; i < nCompressors; ++i )
      98             :     {
      99          40 :         CompressorInfo& info = impl_->infos[ i ];
     100          40 :         info.version = EQ_COMPRESSOR_VERSION;
     101          40 :         info.outputTokenType = EQ_COMPRESSOR_DATATYPE_NONE;
     102          40 :         info.outputTokenSize = 0;
     103          40 :         getInfo( i, &info );
     104             : 
     105          40 :         if(( info.capabilities & EQ_COMPRESSOR_USE_ASYNC_DOWNLOAD ) &&
     106           0 :             ( !startDownload || !finishDownload ))
     107             :         {
     108           0 :             LBWARN << "Download plugin claims to support async readback " <<
     109           0 :                       "but corresponding functions are missing" << std::endl;
     110           0 :             impl_->infos.clear();
     111           0 :             return;
     112             :         }
     113          40 :         info.ratingAlpha = powf( info.speed, .3f ) / info.ratio;
     114          40 :         info.ratingNoAlpha = info.ratingAlpha;
     115             : 
     116          40 :         if( info.capabilities & EQ_COMPRESSOR_IGNORE_ALPHA )
     117             :         {
     118          28 :             switch( info.tokenType )
     119             :             {
     120             :               case EQ_COMPRESSOR_DATATYPE_4_BYTE:
     121             :               case EQ_COMPRESSOR_DATATYPE_4_HALF_FLOAT:
     122             :               case EQ_COMPRESSOR_DATATYPE_4_FLOAT:
     123           9 :                   info.ratingNoAlpha /= .75f;
     124           9 :                   break;
     125             : 
     126             :               case EQ_COMPRESSOR_DATATYPE_RGB10_A2:
     127           1 :                   info.ratingNoAlpha /= .9375f; // 30/32
     128           1 :                   break;
     129             : 
     130             :               default:
     131          18 :                   break;
     132             :             }
     133             :         }
     134             : 
     135          40 :         if( !( info.capabilities & EQ_COMPRESSOR_TRANSFER ))
     136             :         {
     137          40 :             if( info.outputTokenType == EQ_COMPRESSOR_DATATYPE_NONE )
     138             :             {
     139             :                 // Set up CPU compressor output to be input type
     140          34 :                 info.outputTokenType = info.tokenType;
     141          34 :                 LBASSERT( info.outputTokenSize == 0 );
     142             :             }
     143             :             else
     144             :             {
     145           6 :                 LBASSERT( info.outputTokenSize != 0 );
     146             :             }
     147             :         }
     148             : #ifndef NDEBUG // Check that each compressor exist once
     149         820 :         for( size_t j = 0; j < i; ++j )
     150             :         {
     151         780 :             LBASSERTINFO( info.name != impl_->infos[j].name,
     152             :                           "Compressors " << i << " and " << j << " in '" <<
     153             :                           libraryName << "' use the same name" );
     154             :         }
     155             : #endif
     156             :     }
     157             : 
     158           1 :     if( nCompressors == 0 )
     159           0 :         LBERROR << "No plugins found in  " << libraryName << std::endl;
     160             :     else
     161           3 :         LBDEBUG << "Loaded " << nCompressors << " plugins from " << libraryName
     162           3 :                 << std::endl;
     163             : }
     164             : 
     165           3 : Plugin::~Plugin()
     166             : {
     167           1 :     delete impl_;
     168           2 : }
     169             : 
     170           1 : bool Plugin::isGood() const
     171             : {
     172           1 :     return !impl_->infos.empty();
     173             : }
     174             : 
     175         370 : VisitorResult Plugin::accept( PluginVisitor& visitor )
     176             : {
     177         370 :     switch( visitor.visit( *this ))
     178             :     {
     179             :     case TRAVERSE_TERMINATE:
     180           0 :         return TRAVERSE_TERMINATE;
     181             :     case TRAVERSE_PRUNE:
     182           0 :         return TRAVERSE_PRUNE;
     183             :     case TRAVERSE_CONTINUE:
     184         370 :         break;
     185             :     }
     186             : 
     187         370 :     VisitorResult result = TRAVERSE_CONTINUE;
     188       20868 :     for( CompressorInfosIter i = impl_->infos.begin();
     189       13912 :          i != impl_->infos.end(); ++i )
     190             :     {
     191        6956 :         switch( visitor.visit( *this, *i ))
     192             :         {
     193             :         case TRAVERSE_TERMINATE:
     194         370 :             return TRAVERSE_TERMINATE;
     195             :         case TRAVERSE_PRUNE:
     196           0 :             result = TRAVERSE_PRUNE;
     197             :         case TRAVERSE_CONTINUE:
     198        6586 :             break;
     199             :         }
     200             :     }
     201           0 :     return result;
     202             : }
     203             : 
     204           0 : VisitorResult Plugin::accept( ConstPluginVisitor& visitor ) const
     205             : {
     206           0 :     switch( visitor.visit( *this ))
     207             :     {
     208             :     case TRAVERSE_TERMINATE:
     209           0 :         return TRAVERSE_TERMINATE;
     210             :     case TRAVERSE_PRUNE:
     211           0 :         return TRAVERSE_PRUNE;
     212             :     case TRAVERSE_CONTINUE:
     213           0 :         break;
     214             :     }
     215             : 
     216           0 :     VisitorResult result = TRAVERSE_CONTINUE;
     217           0 :     for( CompressorInfosIter i = impl_->infos.begin();
     218           0 :          i != impl_->infos.end(); ++i )
     219             :     {
     220           0 :         switch( visitor.visit( *this, *i ))
     221             :         {
     222             :         case TRAVERSE_TERMINATE:
     223           0 :             return TRAVERSE_TERMINATE;
     224             :         case TRAVERSE_PRUNE:
     225           0 :             result = TRAVERSE_PRUNE;
     226             :         case TRAVERSE_CONTINUE:
     227           0 :             break;
     228             :         }
     229             :     }
     230           0 :     return result;
     231             : }
     232             : 
     233           0 : bool Plugin::implementsType( const uint32_t name ) const
     234             : {
     235           0 :     for( CompressorInfos::const_iterator i = impl_->infos.begin();
     236           0 :          i != impl_->infos.end(); ++i )
     237             :     {
     238           0 :         if ( i->name == name )
     239           0 :             return true;
     240             :     }
     241             : 
     242           0 :     return false;
     243             : }
     244             : 
     245         370 : EqCompressorInfo Plugin::findInfo( const uint32_t name ) const
     246             : {
     247       20868 :     for( CompressorInfos::const_iterator i = impl_->infos.begin();
     248       13912 :          i != impl_->infos.end(); ++i )
     249             :     {
     250        6956 :         if( i->name == name )
     251         370 :             return (*i);
     252             :     }
     253             : 
     254           0 :     LBUNREACHABLE;
     255             :     EqCompressorInfo info;
     256           0 :     lunchbox::setZero( &info, sizeof( info ));
     257           0 :     return info;
     258             : }
     259             : 
     260           3 : const CompressorInfos& Plugin::getInfos() const
     261             : {
     262           3 :     return impl_->infos;
     263             : }
     264           3 : }

Generated by: LCOV version 1.11