Line data Source code
1 :
2 : /* Copyright (c) 2010, Cedric Stalder <cedric.stalder@gmail.com>
3 : * 2010-2014, Stefan Eilemann <eile@eyescale.ch>
4 : *
5 : * This file is part of Lunchbox <https://github.com/Eyescale/Lunchbox>
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 "compressor.h"
22 :
23 : #include "compressorInfo.h"
24 : #include "compressorResult.h"
25 : #include "plugin.h"
26 : #include "pluginInstance.h"
27 : #include "pluginRegistry.h"
28 :
29 : #include <algorithm>
30 :
31 : namespace lunchbox
32 : {
33 : namespace detail
34 : {
35 : class Compressor : public PluginInstance
36 : {
37 : public:
38 1 : Compressor() {}
39 :
40 152 : Compressor( lunchbox::PluginRegistry& registry, const uint32_t name )
41 152 : {
42 152 : setup( registry, name );
43 152 : }
44 :
45 153 : ~Compressor()
46 153 : {
47 153 : clear();
48 153 : }
49 :
50 305 : void clear()
51 : {
52 305 : if( instance )
53 152 : plugin->deleteCompressor( instance );
54 305 : PluginInstance::clear();
55 305 : }
56 :
57 152 : bool setup( lunchbox::PluginRegistry& registry, const uint32_t name )
58 : {
59 152 : if( instance && info.name == name )
60 0 : return true;
61 :
62 152 : clear();
63 :
64 152 : if( name <= EQ_COMPRESSOR_NONE )
65 0 : return true;
66 :
67 152 : plugin = registry.findPlugin( name );
68 152 : LBASSERT( plugin );
69 152 : if( !plugin )
70 0 : return false;
71 :
72 152 : instance = plugin->newCompressor( name );
73 152 : info = plugin->findInfo( name );
74 152 : LBASSERT( instance );
75 152 : LBASSERT( info.name == name );
76 152 : LBLOG( LOG_PLUGIN ) << "Instantiated compressor of type 0x" << std::hex
77 152 : << name << std::dec << std::endl;
78 152 : return instance;
79 : }
80 : };
81 : }
82 :
83 1 : Compressor::Compressor()
84 1 : : impl_( new detail::Compressor )
85 : {
86 1 : LB_TS_THREAD( _thread );
87 1 : }
88 :
89 152 : Compressor::Compressor( PluginRegistry& registry, const uint32_t name )
90 152 : : impl_( new detail::Compressor( registry, name ))
91 : {
92 152 : LB_TS_THREAD( _thread );
93 152 : }
94 :
95 306 : Compressor::~Compressor()
96 : {
97 153 : delete impl_;
98 153 : }
99 :
100 762 : bool Compressor::isGood() const
101 : {
102 762 : LB_TS_SCOPED( _thread );
103 762 : return impl_->isGood() && impl_->instance;
104 : }
105 :
106 0 : bool Compressor::uses( const uint32_t name ) const
107 : {
108 0 : return isGood() && impl_->info.name == name;
109 : }
110 :
111 0 : const EqCompressorInfo& Compressor::getInfo() const
112 : {
113 0 : return impl_->info;
114 : }
115 :
116 0 : uint32_t Compressor::choose( const PluginRegistry& registry,
117 : const uint32_t tokenType, const float minQuality,
118 : const bool ignoreAlpha )
119 : {
120 0 : LBASSERT( tokenType != EQ_COMPRESSOR_DATATYPE_NONE );
121 0 : CompressorInfo candidate;
122 0 : candidate.name = EQ_COMPRESSOR_NONE;
123 0 : candidate.ratingAlpha = 1.0f;
124 0 : candidate.quality = 1.0f;
125 0 : candidate.speed = 1.0f;
126 :
127 0 : const Plugins& plugins = registry.getPlugins();
128 0 : for( Plugins::const_iterator i = plugins.begin(); i != plugins.end(); ++i )
129 : {
130 0 : const Plugin* plugin = *i;
131 0 : const CompressorInfos& infos = plugin->getInfos();
132 :
133 0 : for( CompressorInfosCIter j = infos.begin(); j != infos.end(); ++j )
134 : {
135 0 : const CompressorInfo& info = *j;
136 0 : if( info.tokenType != tokenType || info.quality < minQuality ||
137 0 : ( info.capabilities & EQ_COMPRESSOR_TRANSFER ))
138 : {
139 0 : continue;
140 : }
141 :
142 : const float rating = ignoreAlpha ? info.ratingNoAlpha :
143 0 : info.ratingAlpha;
144 0 : if( rating > candidate.ratingAlpha )
145 : {
146 0 : candidate = info;
147 0 : candidate.ratingAlpha = rating;
148 : }
149 : }
150 : }
151 :
152 0 : return candidate.name;
153 : }
154 :
155 0 : bool Compressor::setup( PluginRegistry& registry, const uint32_t name )
156 : {
157 0 : return impl_->setup( registry, name );
158 : }
159 :
160 0 : bool Compressor::setup( PluginRegistry& registry, const uint32_t tokenType,
161 : const float minQuality, const bool ignoreMSE )
162 : {
163 : return impl_->setup( registry,
164 0 : choose( registry, tokenType, minQuality, ignoreMSE ));
165 : }
166 :
167 0 : bool Compressor::realloc()
168 : {
169 0 : if( !isGood( ))
170 0 : return false;
171 :
172 0 : impl_->plugin->deleteCompressor( impl_->instance );
173 0 : impl_->instance = impl_->plugin->newCompressor( impl_->info.name );
174 :
175 0 : LBASSERT( impl_->instance );
176 0 : return impl_->instance;
177 : }
178 :
179 0 : void Compressor::clear()
180 : {
181 0 : impl_->clear();
182 0 : }
183 :
184 304 : void Compressor::compress( void* const in, const uint64_t pvpIn[4],
185 : const uint64_t flags )
186 : {
187 304 : LBASSERT( impl_->plugin );
188 304 : LBASSERT( impl_->instance );
189 304 : LBASSERT( in );
190 304 : if( !isGood( ))
191 304 : return;
192 :
193 : impl_->plugin->compress( impl_->instance, impl_->info.name, in, pvpIn,
194 304 : flags );
195 : }
196 :
197 0 : void Compressor::compress( void* const in, const uint64_t inDims[2] )
198 : {
199 0 : LBASSERT( impl_->plugin );
200 0 : LBASSERT( impl_->instance );
201 0 : LBASSERT( in );
202 0 : if( !isGood( ))
203 0 : return;
204 :
205 : impl_->plugin->compress( impl_->instance, impl_->info.name, in, inDims,
206 0 : EQ_COMPRESSOR_DATA_1D );
207 : }
208 :
209 0 : unsigned Compressor::getNumResults() const
210 : {
211 0 : LBASSERT( impl_->plugin );
212 0 : LBASSERT( impl_->instance );
213 0 : if( !isGood( ))
214 0 : return 0;
215 :
216 0 : return impl_->plugin->getNumResults( impl_->instance, impl_->info.name );
217 : }
218 :
219 0 : void Compressor::getResult( const unsigned i, void** const out,
220 : uint64_t* const outSize ) const
221 : {
222 0 : LBASSERT( impl_->plugin );
223 0 : LBASSERT( impl_->instance );
224 0 : if( !isGood( ))
225 0 : return;
226 :
227 : impl_->plugin->getResult( impl_->instance, impl_->info.name, i,
228 0 : out, outSize );
229 : }
230 :
231 152 : CompressorResult Compressor::getResult() const
232 : {
233 152 : LBASSERT( impl_->plugin );
234 152 : LBASSERT( impl_->instance );
235 152 : if( !isGood( ))
236 0 : return CompressorResult();
237 :
238 : const unsigned num = impl_->plugin->getNumResults( impl_->instance,
239 152 : impl_->info.name );
240 152 : CompressorChunks chunks;
241 152 : chunks.reserve( num );
242 :
243 718 : for( unsigned i = 0; i < num; ++i )
244 : {
245 : void* data;
246 : uint64_t size;
247 : impl_->plugin->getResult( impl_->instance, impl_->info.name, i,
248 566 : &data, &size );
249 566 : chunks.push_back( CompressorChunk( data, size ));
250 : }
251 :
252 152 : return CompressorResult( impl_->info.name, chunks );
253 : }
254 :
255 90 : }
|