Equalizer  1.2.1
asyncFetcher.cpp
00001 
00002 /* Copyright (c) 2009-2011, Maxim Makhinya <maxmah@gmail.com>
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions are met:
00006  *
00007  * - Redistributions of source code must retain the above copyright notice, this
00008  *   list of conditions and the following disclaimer.
00009  * - Redistributions in binary form must reproduce the above copyright notice,
00010  *   this list of conditions and the following disclaimer in the documentation
00011  *   and/or other materials provided with the distribution.
00012  * - Neither the name of Eyescale Software GmbH nor the names of its
00013  *   contributors may be used to endorse or promote products derived from this
00014  *   software without specific prior written permission.
00015  *
00016  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00017  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00018  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00019  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
00020  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00021  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00022  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00023  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00024  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00025  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00026  * POSSIBILITY OF SUCH DAMAGE.
00027  *
00028  */
00029 
00030 #include "asyncFetcher.h"
00031 #include "eqAsync.h"
00032 
00033 #include <eq/eq.h>
00034 #include <eq/client/system.h>
00035 #ifdef AGL
00036 #  include "aglWindowShared.h"
00037 #endif
00038 #ifdef GLX
00039 #  include "glXWindowShared.h"
00040 #endif
00041 
00042 namespace eqAsync
00043 {
00044 
00045 static eq::SystemWindow* initSharedContextWindow( eq::Window* wnd )
00046 {
00047     EQASSERT( wnd );
00048 
00049     // store old drawable of window and set window's drawable to FBO,
00050     // create another (shared) osWindow and restore original drowable
00051     const int32_t drawable =
00052         wnd->getIAttribute( eq::Window::IATTR_HINT_DRAWABLE );
00053     wnd->setIAttribute( eq::Window::IATTR_HINT_DRAWABLE, eq::FBO );
00054 
00055     const int32_t stencil =
00056         wnd->getIAttribute( eq::Window::IATTR_PLANES_STENCIL );
00057     wnd->setIAttribute( eq::Window::IATTR_PLANES_STENCIL, eq::OFF );
00058 
00059     const eq::Pipe* pipe = wnd->getPipe();
00060     EQASSERT( pipe );
00061 
00062     eq::SystemWindow* sharedContextWindow = 0;
00063 
00064     const std::string& ws = pipe->getWindowSystem().getName();
00065 
00066 #ifdef GLX
00067     if( ws == "GLX" )
00068     {
00069         EQINFO << "Using GLXWindow" << std::endl;
00070         sharedContextWindow = new GLXWindowShared( wnd );
00071     }
00072 #endif
00073 #ifdef AGL
00074     if( ws == "AGL" )
00075     {
00076         EQINFO << "Using AGLWindow" << std::endl;
00077         sharedContextWindow = new AGLWindowShared( wnd );
00078     }
00079 #endif
00080 #ifdef WGL
00081     if( ws == "WGL" )
00082     {
00083         EQINFO << "Using WGLWindow" << std::endl;
00084         sharedContextWindow = new eq::wgl::Window( wnd );
00085     }
00086 #endif
00087     if( !sharedContextWindow )
00088     {
00089         EQERROR << "Window system " << pipe->getWindowSystem()
00090                 << " not implemented or supported" << std::endl;
00091         return 0;
00092     }
00093 
00094     if( !sharedContextWindow->configInit( ))
00095     {
00096         EQWARN << "OS Window initialization failed: " << std::endl;
00097         delete sharedContextWindow;
00098         return 0;
00099     }
00100 
00101     wnd->setIAttribute( eq::Window::IATTR_HINT_DRAWABLE, drawable );
00102     wnd->setIAttribute( eq::Window::IATTR_PLANES_STENCIL, stencil );
00103 
00104     sharedContextWindow->makeCurrent();
00105 
00106     EQWARN << "Async fetcher initialization finished" << std::endl;
00107     return sharedContextWindow;
00108 }
00109 
00110 
00111 static void deleteSharedContextWindow( eq::Window* wnd,
00112                                        eq::SystemWindow** sharedContextWindow,
00113                                        eq::ObjectManager** objectManager )
00114 {
00115     EQWARN << "Deleting shared context" << std::endl;
00116     if( !sharedContextWindow || !*sharedContextWindow )
00117         return;
00118 
00119     if( *objectManager )
00120     {
00121         (*objectManager)->deleteAll();
00122         delete *objectManager;
00123         *objectManager = 0;
00124     }
00125 
00126     const int32_t drawable =
00127         wnd->getIAttribute( eq::Window::IATTR_HINT_DRAWABLE );
00128     wnd->setIAttribute( eq::Window::IATTR_HINT_DRAWABLE, eq::FBO );
00129 
00130     (*sharedContextWindow)->configExit(); // mb set window to 0 before that?
00131 
00132     delete *sharedContextWindow;
00133     *sharedContextWindow = 0;
00134 
00135     wnd->setIAttribute( eq::Window::IATTR_HINT_DRAWABLE, drawable );
00136 }
00137 
00138 
00139 AsyncFetcher::AsyncFetcher()
00140     : co::base::Thread()
00141     , _wnd( 0 )
00142     , _objectManager( 0 )
00143     , _sharedContextWindow( 0 )
00144 {
00145     _tmpTexture = new GLbyte[ 64*64*4 ];
00146 }
00147 
00148 
00149 AsyncFetcher::~AsyncFetcher()
00150 {
00151     if( _wnd && _sharedContextWindow )
00152         deleteSharedContextWindow( _wnd, &_sharedContextWindow,
00153                                    &_objectManager );
00154 
00155     delete [] _tmpTexture;
00156 }
00157 
00158 
00159 const GLEWContext* AsyncFetcher::glewGetContext() const
00160 {
00161     return _sharedContextWindow->glewGetContext();
00162 }
00163 
00164 
00169 void AsyncFetcher::run()
00170 {
00171     EQASSERT( !_sharedContextWindow );
00172     _sharedContextWindow = initSharedContextWindow( _wnd );
00173     _outQueue.push( TextureId( )); // unlock pipe thread
00174     if( !_sharedContextWindow )
00175         return;
00176 
00177     _objectManager = new eq::ObjectManager( glewGetContext( ));
00178     EQINFO << "async fetcher initialized: " << _wnd << std::endl;
00179 
00180     uint8_t* i = 0;
00181     bool running = true;
00182     co::base::sleep( 1000 ); // imitate loading of the first texture
00183     while( running )
00184     {
00185         // generate new texture
00186         eq::util::Texture* tx = _objectManager->newEqTexture( ++i,
00187                                                               GL_TEXTURE_2D );
00188         tx->init( GL_RGBA8, 64, 64 );
00189 
00190         int j = 0;
00191         co::base::RNG rng;
00192         for( int y = 0; y < 64; ++y )
00193         {
00194             for( int x = 0; x < 64; ++x )
00195             {
00196                 const GLbyte rnd = rng.get< uint8_t >() % 127;
00197                 const GLbyte val = (x / 8) % 2 == (y / 8) % 2 ? rnd : 0;
00198                 _tmpTexture[ j++ ] = val;
00199                 _tmpTexture[ j++ ] = val;
00200                 _tmpTexture[ j++ ] = val;
00201                 _tmpTexture[ j++ ] = val;
00202             }
00203         }
00204         tx->upload( 64, 64, _tmpTexture );
00205         EQ_GL_CALL( glFinish( ));
00206 
00207         // add new texture to the pool
00208         _outQueue.push( TextureId( tx->getName(), i ));
00209 
00210         // imitate hard work of loading something else
00211         co::base::sleep( rng.get< uint32_t >() % 5000u );
00212 
00213         // clean unused textures
00214         const void* keyToDelete = 0;
00215         while( _inQueue.tryPop( keyToDelete ))
00216         {
00217             if( keyToDelete )
00218             {
00219                 EQWARN << "Deleting eq texture " << keyToDelete << std::endl;
00220                 _objectManager->deleteEqTexture( keyToDelete );
00221             }
00222             else
00223                 running = false;
00224         }
00225     }
00226     deleteSharedContextWindow( _wnd, &_sharedContextWindow, &_objectManager );
00227 }
00228 
00229 } //namespace eqAsync
Generated on Fri Jun 8 2012 15:44:29 for Equalizer 1.2.1 by  doxygen 1.8.0