Equalizer  1.6.1
asyncFetcher.cpp
1 
2 /* Copyright (c) 2009-2011, Maxim Makhinya <maxmah@gmail.com>
3  * 2012, Stefan Eilemann <eile@eyescale.ch>
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * - Redistributions of source code must retain the above copyright notice, this
9  * list of conditions and the following disclaimer.
10  * - Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13  * - Neither the name of Eyescale Software GmbH nor the names of its
14  * contributors may be used to endorse or promote products derived from this
15  * software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  *
29  */
30 
31 #include "asyncFetcher.h"
32 #include "eqAsync.h"
33 
34 #include <eq/eq.h>
35 #include <eq/client/system.h>
36 
37 namespace eqAsync
38 {
40 
41 AsyncFetcher::AsyncFetcher()
42  : lunchbox::Thread()
43  , _sharedWindow( 0 )
44 {
45 }
46 
47 AsyncFetcher::~AsyncFetcher()
48 {
49  stop();
50 }
51 
52 const GLEWContext* AsyncFetcher::glewGetContext() const
53 {
54  return _sharedWindow->glewGetContext();
55 }
56 
57 static eq::SystemWindow* initSharedContextWindow( eq::Window* window )
58 {
59  LBASSERT( window );
60 
61  // store old drawable of window and set window's drawable to OFF,
62  // create another (shared) osWindow and restore original drawable
63  const int32_t drawable =
66 
67  const eq::Pipe* pipe = window->getPipe();
68  LBASSERT( pipe );
69 
70  eq::SystemWindow* sharedWindow =
71  pipe->getWindowSystem().createWindow( window );
72 
73  if( sharedWindow )
74  {
75  if( sharedWindow->configInit( ))
76  sharedWindow->makeCurrent();
77  else
78  {
79  LBWARN << "OS Window initialization failed: " << std::endl;
80  delete sharedWindow;
81  sharedWindow = 0;
82  }
83  }
84  else
85  {
86  LBERROR << "Failed to create shared context window for "
87  << pipe->getWindowSystem() << std::endl;
88  }
89 
91  window->makeCurrent();
92 
93  LBINFO << "Async fetcher initialization finished" << std::endl;
94  return sharedWindow;
95 }
96 
97 void AsyncFetcher::setup( Window* window )
98 {
99  _sharedWindow = initSharedContextWindow( window );
100  start();
101 }
102 
103 void AsyncFetcher::stop()
104 {
105  if( !_sharedWindow )
106  return;
107 
108  deleteTexture( 0 ); // exit async thread
109  join();
110 
111  _sharedWindow->configExit();
112  delete _sharedWindow;
113  _sharedWindow = 0;
114 }
115 
120 void AsyncFetcher::run()
121 {
122  LBASSERT( _sharedWindow );
123  if( !_sharedWindow )
124  return;
125 
126  _sharedWindow->makeCurrent();
127  eq::ObjectManager objects( glewGetContext( ));
128  lunchbox::Bufferb textureData( 64*64*4 );
129  LBINFO << "async fetcher initialized" << std::endl;
130 
131  bool running = true;
132  lunchbox::sleep( 1000 ); // imitate loading of the first texture
133  for( uint8_t* i = 0; running; ++i )
134  {
135  // generate new texture
136  eq::util::Texture* tx = objects.newEqTexture( i, GL_TEXTURE_2D );
137  tx->init( GL_RGBA8, 64, 64 );
138 
139  int j = 0;
140  lunchbox::RNG rng;
141  for( int y = 0; y < 64; ++y )
142  {
143  for( int x = 0; x < 64; ++x )
144  {
145  const GLbyte rnd = rng.get< uint8_t >() % 127;
146  const GLbyte val = (x / 8) % 2 == (y / 8) % 2 ? rnd : 0;
147  textureData[ j++ ] = val;
148  textureData[ j++ ] = val;
149  textureData[ j++ ] = val;
150  textureData[ j++ ] = val;
151  }
152  }
153  tx->upload( 64, 64, textureData.getData( ));
154  EQ_GL_CALL( glFinish( ));
155 
156  // add new texture to the pool
157  _outQueue.push( TextureId( tx->getName(), i ));
158 
159  // imitate hard work of loading something else
160  lunchbox::sleep( rng.get< uint32_t >() % 5000u );
161 
162  // clean unused textures
163  const void* keyToDelete = 0;
164  while( _inQueue.tryPop( keyToDelete ))
165  {
166  if( keyToDelete )
167  {
168  LBWARN << "Deleting eq texture " << keyToDelete << std::endl;
169  objects.deleteEqTexture( keyToDelete );
170  }
171  else
172  running = false;
173  }
174  }
175  objects.deleteAll();
176 }
177 
178 } //namespace eqAsync
void upload(const int32_t width, const int32_t height, const void *ptr)
Copy the specified buffer to the texture at 0,0.
virtual void makeCurrent(const bool cache=true) const =0
Make the system window rendering context and drawable current.
A Window represents an on-screen or off-screen drawable.
const P * getPipe() const
A facility class to manage OpenGL objects across shared contexts.
A Pipe represents a graphics card (GPU) on a Node.
void deleteAll()
Delete all managed objects and associated GL objects.
unsigned getName() const
Structure to associate OpenGL texture ids with an external key.
Definition: asyncFetcher.h:42
The interface definition for system-specific windowing code.
Definition: systemWindow.h:35
virtual void makeCurrent(const bool cache=true) const
Make the window&#39;s drawable and context current.
void setIAttribute(const IAttribute attr, const int32_t value)
Set a window attribute.
A wrapper around OpenGL textures.
Definition: texture.h:38
int32_t getIAttribute(const IAttribute attr) const
WindowSystem getWindowSystem() const
Return the window system used by this pipe.
util::ObjectManager< const void * > ObjectManager
The OpenGL object manager used in the client library.
virtual bool configInit()=0
Initialize this system window.
void init(const unsigned internalFormat, const int32_t width, const int32_t height)
Initialize an OpenGL texture.