LCOV - code coverage report
Current view: top level - lunchbox - plugin.cpp (source / functions) Hit Total Coverage
Test: lcov2.info Lines: 74 112 66.1 %
Date: 2014-10-01 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 "debug.h"
      25             : #include "log.h"
      26             : #include "os.h"
      27             : #include "pluginRegistry.h"
      28             : #include "pluginVisitor.h"
      29             : #include <cmath>
      30             : 
      31             : namespace lunchbox
      32             : {
      33             : typedef void ( *GetInfo_t ) ( const size_t, EqCompressorInfo* const );
      34             : namespace detail
      35             : {
      36           2 : class Plugin
      37             : {
      38             : public:
      39             :     CompressorInfos infos;
      40             : };
      41             : }
      42             : 
      43           1 : Plugin::Plugin( const std::string& libraryName )
      44             :     : DSO( libraryName )
      45             :     , getNumCompressors( getFunctionPointer< GetNumCompressors_t >(
      46           2 :                              "EqCompressorGetNumCompressors" ))
      47             :     , newCompressor( getFunctionPointer< NewCompressor_t >(
      48           2 :                          "EqCompressorNewCompressor" ))
      49             :     , newDecompressor( getFunctionPointer< NewDecompressor_t >(
      50           2 :                            "EqCompressorNewDecompressor" ))
      51             :     , deleteCompressor( getFunctionPointer< DeleteCompressor_t >(
      52           2 :                             "EqCompressorDeleteCompressor" ))
      53             :     , deleteDecompressor( getFunctionPointer< DeleteDecompressor_t >(
      54           2 :                               "EqCompressorDeleteDecompressor" ))
      55           2 :     , compress( getFunctionPointer< Compress_t >( "EqCompressorCompress" ))
      56           2 :     , decompress( getFunctionPointer< Decompress_t >( "EqCompressorDecompress"))
      57             :     , getNumResults( getFunctionPointer< GetNumResults_t >(
      58           2 :                          "EqCompressorGetNumResults" ))
      59           2 :     , getResult( getFunctionPointer< GetResult_t >( "EqCompressorGetResult" ))
      60             :     , isCompatible( getFunctionPointer< IsCompatible_t >(
      61           2 :                         "EqCompressorIsCompatible" ))
      62           2 :     , download( getFunctionPointer< Download_t >( "EqCompressorDownload" ))
      63           2 :     , upload( getFunctionPointer< Upload_t >( "EqCompressorUpload" ))
      64             :     , startDownload( getFunctionPointer< StartDownload_t >(
      65           2 :                          "EqCompressorStartDownload" ))
      66             :     , finishDownload( getFunctionPointer< FinishDownload_t >(
      67           2 :                           "EqCompressorFinishDownload" ))
      68          16 :     , impl_( new detail::Plugin )
      69             : {
      70           1 :     if( !isOpen( ))
      71           0 :         return;
      72             : 
      73             :     const GetInfo_t getInfo =
      74           1 :         getFunctionPointer< GetInfo_t >( "EqCompressorGetInfo" );
      75             : 
      76           1 :     const bool hasBase = newDecompressor && newCompressor && deleteCompressor &&
      77           2 :                          deleteDecompressor && getInfo && getNumCompressors;
      78           1 :     const bool hasCPU = getResult && getNumResults && decompress && compress;
      79           1 :     const bool hasGPU = isCompatible && download && upload;
      80           1 :     if( !hasBase || ( !hasCPU && !hasGPU ))
      81             :     {
      82           0 :         LBWARN << "Initializing compression DSO " << libraryName
      83           0 :                << " failed, at least one entry point missing" << std::endl;
      84           0 :         return;
      85             :     }
      86             : 
      87           1 :     const size_t nCompressors = getNumCompressors();
      88           1 :     if( nCompressors == 0 )
      89             :     {
      90           0 :         LBWARN << "Initializing compression DSO " << libraryName
      91           0 :                << " failed, 0 compression engines reported" << std::endl;
      92           0 :         return;
      93             :     }
      94             : 
      95           1 :     impl_->infos.resize( nCompressors );
      96          40 :     for( size_t i = 0; i < nCompressors; ++i )
      97             :     {
      98          39 :         CompressorInfo& info = impl_->infos[ i ];
      99          39 :         info.version = EQ_COMPRESSOR_VERSION;
     100          39 :         info.outputTokenType = EQ_COMPRESSOR_DATATYPE_NONE;
     101          39 :         info.outputTokenSize = 0;
     102          39 :         getInfo( i, &info );
     103             : 
     104          39 :         if(( info.capabilities & EQ_COMPRESSOR_USE_ASYNC_DOWNLOAD ) &&
     105           0 :             ( !startDownload || !finishDownload ))
     106             :         {
     107           0 :             LBWARN << "Download plugin claims to support async readback " <<
     108           0 :                       "but corresponding functions are missing" << std::endl;
     109           0 :             impl_->infos.clear();
     110           0 :             return;
     111             :         }
     112          39 :         info.ratingAlpha = powf( info.speed, .3f ) / info.ratio;
     113          39 :         info.ratingNoAlpha = info.ratingAlpha;
     114             : 
     115          39 :         if( info.capabilities & EQ_COMPRESSOR_IGNORE_ALPHA )
     116             :         {
     117          28 :             switch( info.tokenType )
     118             :             {
     119             :               case EQ_COMPRESSOR_DATATYPE_4_BYTE:
     120             :               case EQ_COMPRESSOR_DATATYPE_4_HALF_FLOAT:
     121             :               case EQ_COMPRESSOR_DATATYPE_4_FLOAT:
     122           9 :                   info.ratingNoAlpha /= .75f;
     123           9 :                   break;
     124             : 
     125             :               case EQ_COMPRESSOR_DATATYPE_RGB10_A2:
     126           1 :                   info.ratingNoAlpha /= .9375f; // 30/32
     127           1 :                   break;
     128             : 
     129             :               default:
     130          18 :                   break;
     131             :             }
     132             :         }
     133             : 
     134          39 :         if( !( info.capabilities & EQ_COMPRESSOR_TRANSFER ))
     135             :         {
     136          39 :             if( info.outputTokenType == EQ_COMPRESSOR_DATATYPE_NONE )
     137             :             {
     138             :                 // Set up CPU compressor output to be input type
     139          33 :                 info.outputTokenType = info.tokenType;
     140          33 :                 LBASSERT( info.outputTokenSize == 0 );
     141             :             }
     142             :             else
     143             :             {
     144           6 :                 LBASSERT( info.outputTokenSize != 0 );
     145             :             }
     146             :         }
     147             : #ifndef NDEBUG // Check that each compressor exist once
     148         780 :         for( size_t j = 0; j < i; ++j )
     149             :         {
     150         741 :             LBASSERTINFO( info.name != impl_->infos[j].name,
     151             :                           "Compressors " << i << " and " << j << " in '" <<
     152             :                           libraryName << "' use the same name" );
     153             :         }
     154             : #endif
     155             :     }
     156             : 
     157           3 :     LBINFO << "Loaded " << nCompressors << " plugins from " << libraryName
     158           3 :            << std::endl;
     159             : }
     160             : 
     161           3 : Plugin::~Plugin()
     162             : {
     163           1 :     delete impl_;
     164           2 : }
     165             : 
     166           1 : bool Plugin::isGood() const
     167             : {
     168           1 :     return !impl_->infos.empty();
     169             : }
     170             : 
     171         304 : VisitorResult Plugin::accept( PluginVisitor& visitor )
     172             : {
     173         304 :     switch( visitor.visit( *this ))
     174             :     {
     175             :     case TRAVERSE_TERMINATE:
     176           0 :         return TRAVERSE_TERMINATE;
     177             :     case TRAVERSE_PRUNE:
     178           0 :         return TRAVERSE_PRUNE;
     179             :     case TRAVERSE_CONTINUE:
     180         304 :         break;
     181             :     }
     182             : 
     183         304 :     VisitorResult result = TRAVERSE_CONTINUE;
     184       12312 :     for( CompressorInfosIter i = impl_->infos.begin();
     185        8208 :          i != impl_->infos.end(); ++i )
     186             :     {
     187        4104 :         switch( visitor.visit( *this, *i ))
     188             :         {
     189             :         case TRAVERSE_TERMINATE:
     190         304 :             return TRAVERSE_TERMINATE;
     191             :         case TRAVERSE_PRUNE:
     192           0 :             result = TRAVERSE_PRUNE;
     193             :         case TRAVERSE_CONTINUE:
     194        3800 :             break;
     195             :         }
     196             :     }
     197           0 :     return result;
     198             : }
     199             : 
     200           0 : VisitorResult Plugin::accept( ConstPluginVisitor& visitor ) const
     201             : {
     202           0 :     switch( visitor.visit( *this ))
     203             :     {
     204             :     case TRAVERSE_TERMINATE:
     205           0 :         return TRAVERSE_TERMINATE;
     206             :     case TRAVERSE_PRUNE:
     207           0 :         return TRAVERSE_PRUNE;
     208             :     case TRAVERSE_CONTINUE:
     209           0 :         break;
     210             :     }
     211             : 
     212           0 :     VisitorResult result = TRAVERSE_CONTINUE;
     213           0 :     for( CompressorInfosIter i = impl_->infos.begin();
     214           0 :          i != impl_->infos.end(); ++i )
     215             :     {
     216           0 :         switch( visitor.visit( *this, *i ))
     217             :         {
     218             :         case TRAVERSE_TERMINATE:
     219           0 :             return TRAVERSE_TERMINATE;
     220             :         case TRAVERSE_PRUNE:
     221           0 :             result = TRAVERSE_PRUNE;
     222             :         case TRAVERSE_CONTINUE:
     223           0 :             break;
     224             :         }
     225             :     }
     226           0 :     return result;
     227             : }
     228             : 
     229           0 : bool Plugin::implementsType( const uint32_t name ) const
     230             : {
     231           0 :     for( CompressorInfos::const_iterator i = impl_->infos.begin();
     232           0 :          i != impl_->infos.end(); ++i )
     233             :     {
     234           0 :         if ( i->name == name )
     235           0 :             return true;
     236             :     }
     237             : 
     238           0 :     return false;
     239             : }
     240             : 
     241         304 : EqCompressorInfo Plugin::findInfo( const uint32_t name ) const
     242             : {
     243       12312 :     for( CompressorInfos::const_iterator i = impl_->infos.begin();
     244        8208 :          i != impl_->infos.end(); ++i )
     245             :     {
     246        4104 :         if( i->name == name )
     247         304 :             return (*i);
     248             :     }
     249             : 
     250           0 :     LBUNREACHABLE;
     251             :     EqCompressorInfo info;
     252           0 :     setZero( &info, sizeof( info ));
     253           0 :     return info;
     254             : }
     255             : 
     256           3 : const CompressorInfos& Plugin::getInfos() const
     257             : {
     258           3 :     return impl_->infos;
     259             : }
     260          90 : }

Generated by: LCOV version 1.10