Line data Source code
1 :
2 : /* Copyright (C) 2013-2014, Stefan.Eilemann@epfl.ch
3 : *
4 : * This file is part of Pression <https://github.com/Eyescale/Pression>
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 "uploader.h"
21 :
22 : #include "log.h"
23 : #include "plugin.h"
24 : #include "pluginInstance.h"
25 : #include "pluginRegistry.h"
26 : #include "pluginVisitor.h"
27 :
28 : namespace pression
29 : {
30 : namespace detail
31 : {
32 : class Uploader : public PluginInstance
33 : {
34 : public:
35 0 : Uploader() {}
36 :
37 0 : Uploader( pression::PluginRegistry& registry, const uint32_t name )
38 0 : {
39 0 : setup( registry, name );
40 0 : }
41 :
42 0 : ~Uploader()
43 0 : {
44 0 : clear();
45 0 : }
46 :
47 0 : void clear()
48 : {
49 0 : if( plugin && instance )
50 0 : plugin->deleteDecompressor( instance );
51 0 : PluginInstance::clear();
52 0 : }
53 :
54 0 : bool setup( pression::PluginRegistry& registry, const uint32_t name )
55 : {
56 0 : if( instance && name == info.name )
57 0 : return true;
58 :
59 0 : clear();
60 :
61 0 : if( name <= EQ_COMPRESSOR_NONE )
62 0 : return true;
63 :
64 0 : plugin = registry.findPlugin( name );
65 0 : LBASSERT( plugin );
66 0 : if( !plugin )
67 0 : return false;
68 :
69 0 : instance = plugin->newCompressor( name );
70 0 : info = plugin->findInfo( name );
71 0 : LBASSERT( instance );
72 0 : LBASSERT( info.name == name );
73 0 : LBASSERT( info.capabilities & EQ_COMPRESSOR_TRANSFER );
74 0 : LBLOG( LOG_PLUGIN ) << "Instantiated uploader of type 0x" << std::hex
75 0 : << name << std::dec << std::endl;
76 0 : return instance;
77 : }
78 : };
79 : }
80 :
81 0 : Uploader::Uploader()
82 0 : : impl_( new detail::Uploader )
83 : {
84 0 : LB_TS_THREAD( _thread );
85 0 : }
86 :
87 0 : Uploader::Uploader( PluginRegistry& registry, const uint32_t name )
88 0 : : impl_( new detail::Uploader( registry, name ))
89 : {
90 0 : LB_TS_THREAD( _thread );
91 0 : }
92 :
93 0 : Uploader::~Uploader()
94 : {
95 0 : LBASSERTINFO( impl_->plugin == 0,
96 : "Clear uploader while GL context is still active" );
97 0 : delete impl_;
98 0 : }
99 :
100 0 : bool Uploader::isGood( const GLEWContext* gl ) const
101 : {
102 0 : LB_TS_SCOPED( _thread );
103 0 : return impl_->isGood() && impl_->instance &&
104 0 : impl_->plugin->isCompatible( impl_->info.name, gl );
105 : }
106 :
107 0 : bool Uploader::uses( const uint32_t name ) const
108 : {
109 0 : return impl_->isGood() && impl_->instance && impl_->info.name == name;
110 : }
111 :
112 0 : bool Uploader::supports( const uint32_t externalFormat,
113 : const uint32_t internalFormat,
114 : const uint64_t capabilities,
115 : const GLEWContext* gl ) const
116 : {
117 0 : return isGood( gl ) && impl_->info.outputTokenType == externalFormat &&
118 0 : (impl_->info.capabilities & capabilities) == capabilities &&
119 0 : impl_->info.tokenType == internalFormat;
120 : }
121 :
122 : namespace
123 : {
124 0 : class Finder : public ConstPluginVisitor
125 : {
126 : public:
127 0 : Finder( const uint32_t externalFormat, const uint32_t internalFormat,
128 : const uint64_t capabilities, const GLEWContext* gl )
129 0 : : externalFormat_( externalFormat )
130 : , internalFormat_( internalFormat )
131 : , capabilities_( capabilities )
132 0 : , gl_( gl )
133 : {
134 0 : current.name = EQ_COMPRESSOR_NONE;
135 0 : current.speed = 0.f;
136 0 : }
137 :
138 0 : virtual VisitorResult visit( const Plugin& plugin,
139 : const EqCompressorInfo& info )
140 : {
141 0 : if( (info.capabilities & capabilities_) == capabilities_ &&
142 0 : info.outputTokenType == externalFormat_ &&
143 0 : info.tokenType == internalFormat_ &&
144 0 : plugin.isCompatible( info.name, gl_ ) &&
145 0 : current.speed < info.speed )
146 : {
147 0 : current = info;
148 : }
149 0 : return TRAVERSE_CONTINUE;
150 : }
151 :
152 : EqCompressorInfo current;
153 :
154 : private:
155 : const uint32_t externalFormat_;
156 : const uint32_t internalFormat_;
157 : const uint64_t capabilities_;
158 : const GLEWContext* gl_;
159 : };
160 : }
161 :
162 0 : uint32_t Uploader::choose( const PluginRegistry& registry,
163 : const uint32_t externalFormat,
164 : const uint32_t internalFormat,
165 : const uint64_t capabilities, const GLEWContext* gl )
166 : {
167 0 : Finder finder( externalFormat, internalFormat, capabilities, gl );
168 0 : registry.accept( finder );
169 0 : return finder.current.name;
170 : }
171 :
172 0 : const EqCompressorInfo& Uploader::getInfo() const
173 : {
174 0 : return impl_->info;
175 : }
176 :
177 0 : bool Uploader::setup( PluginRegistry& from, const uint32_t name )
178 : {
179 0 : return impl_->setup( from, name );
180 : }
181 :
182 0 : bool Uploader::setup( PluginRegistry& from, const uint32_t externalFormat,
183 : const uint32_t internalFormat,
184 : const uint64_t capabilities, const GLEWContext* gl )
185 : {
186 0 : return impl_->setup( from, choose( from, externalFormat, internalFormat,
187 0 : capabilities, gl ));
188 : }
189 :
190 0 : void Uploader::clear()
191 : {
192 0 : impl_->clear();
193 0 : }
194 :
195 0 : void Uploader::upload( const void* buffer, const uint64_t inDims[4],
196 : const uint64_t flags, const uint64_t outDims[4],
197 : const unsigned destination, const GLEWContext* gl )
198 : {
199 0 : LBASSERT( isGood( gl ));
200 0 : impl_->plugin->upload( impl_->instance, impl_->info.name, gl, buffer,
201 0 : inDims, flags, outDims, destination );
202 0 : }
203 :
204 3 : }
|