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