1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
41 //---------------------------------------------------------------------------
46 #include "OSGConfig.h"
48 #include "OSGBinarySwapComposer.h"
53 /*! \class OSG::BinarySwapComposer
55 This composer implements the binary swap composition.
58 void BinarySwapComposer::initMethod(InitPhase ePhase
)
60 Inherited::initMethod(ePhase
);
64 /*----------------------- constructors & destructors ----------------------*/
66 BinarySwapComposer::BinarySwapComposer(void) :
72 _swapConnection(NULL
),
84 _intDepthMax (0xffffffff),
85 _shortDepthMax (0xffff )
89 BinarySwapComposer::BinarySwapComposer(const BinarySwapComposer
&source
) :
95 _swapConnection(NULL
),
107 _intDepthMax (0xffffffff),
108 _shortDepthMax (0xffff )
112 BinarySwapComposer::~BinarySwapComposer(void)
116 /*----------------------------- class specific ----------------------------*/
118 void BinarySwapComposer::changed(ConstFieldMaskArg whichField
,
122 Inherited::changed(whichField
, origin
, details
);
125 void BinarySwapComposer::dump( UInt32
,
126 const BitVector
) const
128 SLOG
<< "Dump BinarySwapComposer NI" << std::endl
;
131 /*----------------------------- features ---------------------------------*/
133 /*! Currently it is not possible to do rendering on the client
135 bool BinarySwapComposer::clientRendering()
140 /*----------------------------- composition -------------------------------*/
142 void BinarySwapComposer::open()
144 // determine usable servers
145 if(osgIsPower2(serverCount()))
146 _usableServers
= serverCount();
148 _usableServers
= osgNextPower2(serverCount()) / 2;
150 // _usableServers = 1;
152 // create server cross connection
153 _clusterWindow
->getNetwork()->connectAllPointToPoint(clusterId(),
155 // do not buffer any data
156 for(UInt32 i
=0 ; i
<= serverCount() ; ++i
)
157 clusterWindow()->getNetwork()->getConnection(i
)->forceDirectIO();
161 _barrier = Barrier::get(NULL);
162 // create writer thread
163 _writer = BaseThread::get(NULL);
167 if(!_isClient
&& clusterId() < _usableServers
)
170 _barrier
= Barrier::get(NULL
, false);
171 // create writer thread
172 _writer
= BaseThread::get(NULL
, false);
173 // start writer thread
174 _writer
->runFunction( writeProc
, this );
182 void BinarySwapComposer::composeViewport(Viewport
*port
)
186 pl
=port
->calcPixelLeft(),
187 pr
=port
->calcPixelRight(),
188 pb
=port
->calcPixelBottom(),
189 pt
=port
->calcPixelTop();
190 GLint pw
=pr
-pl
+1,ph
=pt
-pb
+1;
191 bool full
= port
->calcIsFullWindow();
192 glViewport(pl
, pb
, pw
, ph
);
193 glScissor(pl
, pb
, pw
, ph
);
195 glEnable(GL_SCISSOR_TEST
);
197 GLboolean depth
= glIsEnabled(GL_DEPTH_TEST
);
198 GLboolean blend
= glIsEnabled(GL_BLEND
);
200 glDisable(GL_DEPTH_TEST
);
203 glMatrixMode(GL_PROJECTION
);
206 glOrtho(0, port
->calcPixelWidth(),
207 0, port
->calcPixelHeight(),-1,1);
209 // printf("max %x,%x\n",_intDepthMax,_shortDepthMax);
214 glBlendFunc(GL_SRC_ALPHA
, GL_ONE_MINUS_SRC_ALPHA
);
216 _tilesX
= port
->calcPixelWidth() / getTileSize() + 1;
217 _tilesY
= port
->calcPixelHeight() / getTileSize() + 1;
219 _tileBufferSize
= getTileSize()*getTileSize()*8+sizeof(TileBuffer
);
220 _readTile
.resize(_tileBufferSize
);
222 _statistics
.bytesIn
= 0;
223 _statistics
.bytesOut
= 0;
231 recvFromServers(depthDummy
,colorDummy
,
233 GL_UNSIGNED_SHORT_5_6_5
,
242 recvFromServers(depthDummy
,colorDummy
,
251 recvFromServers(depthDummy
,colorDummy
,
259 UInt32 maxIn
= _statistics
.bytesIn
;
260 UInt32 maxOut
= _statistics
.bytesOut
;
261 UInt32 maxIO
= maxIn
+ maxOut
;
262 UInt32 sumOut
= _statistics
.bytesOut
;
263 UInt32 missing
= _usableServers
;
264 double composeTime
= 1e32
;
267 Statistics statistics
;
268 for(UInt32 i
=0 ; i
<_usableServers
;++i
)
270 server
= clusterWindow()->getNetwork()->getConnection(i
);
271 server
->selectChannel();
272 server
->get(&statistics
,sizeof(Statistics
));
273 sumOut
+= statistics
.bytesOut
;
274 if(statistics
.composeTime
< composeTime
)
275 composeTime
= statistics
.composeTime
;
276 if(statistics
.bytesOut
> maxOut
)
277 maxOut
= statistics
.bytesOut
;
278 if(statistics
.bytesIn
> maxIn
)
279 maxIn
= statistics
.bytesIn
;
280 if(statistics
.bytesIn
+ statistics
.bytesOut
> maxIO
)
281 maxIO
= statistics
.bytesIn
+ statistics
.bytesOut
;
284 printf("compose Time : %1.5lf\n",composeTime
);
285 printf("Transfered bytes : %10d\n",sumOut
);
286 printf("Max out : %10d\n",maxOut
);
287 printf("Max in : %10d\n",maxIn
);
288 printf("Max io : %10d\n",maxIO
);
293 if(clusterId() < _usableServers
)
295 _statistics
.composeTime
= -getSystemTime();
296 _tile
.resize(_tileBufferSize
* _tilesX
* _tilesY
);
300 UInt32 depthDummy
=_shortDepthMax
;
301 // UInt32 depthDummy=_intDepthMax;
302 startReader(depthDummy
,colorDummy
,
303 // GL_UNSIGNED_SHORT,
306 GL_UNSIGNED_SHORT_5_6_5
,
314 UInt32 depthDummy
=_intDepthMax
;
315 startReader(depthDummy
,colorDummy
,
324 UInt32 depthDummy
=_intDepthMax
;
325 startReader(depthDummy
,colorDummy
,
332 _statistics
.composeTime
+= getSystemTime();
335 Connection
*client
= clusterWindow()->getNetwork()->getConnection(serverCount());
336 client
->put(&_statistics
,sizeof(Statistics
));
341 // max depth value !! find a better way
342 glClear(GL_DEPTH_BUFFER_BIT);
343 glReadPixels(0, 0, 1, 1,
344 GL_DEPTH_COMPONENT, GL_UNSIGNED_INT,
346 glReadPixels(0, 0, 1, 1,
347 GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT,
353 glMatrixMode(GL_MODELVIEW
);
355 glEnable(GL_DEPTH_TEST
);
358 if(depth
&& !glIsEnabled(GL_DEPTH_TEST
))
359 glEnable(GL_DEPTH_TEST
);
360 if(!blend
&& glIsEnabled(GL_BLEND
))
364 void BinarySwapComposer::close(void)
366 if(!isClient() && _writer
)
370 BaseThread::join(_writer
);
376 /*----------------------------- features ---------------------------------*/
378 /*! it is not possible to do rendering on the client with binary swap
381 bool BinarySwapComposer::getClientRendering()
386 /*! use only 2^n servers
388 UInt32
BinarySwapComposer::getUsableServers()
390 return _usableServers
;
393 /*----------------------------- helper ------------------------------------*/
395 BinarySwapComposer::TileBuffer
*BinarySwapComposer::getTileBuffer(UInt32 x
,UInt32 y
)
397 return reinterpret_cast<TileBuffer
*>(
398 &_tile
[(y
*_tilesX
+ x
)*_tileBufferSize
]);
401 BinarySwapComposer::TileBuffer
*BinarySwapComposer::getTileReadBuffer(void)
403 return reinterpret_cast<TileBuffer
*>(&_readTile
[0]);
406 /*----------------------------- thread proc -------------------------------*/
409 void BinarySwapComposer::writeProc(void *arg
)
411 BinarySwapComposer
*the
=static_cast<BinarySwapComposer
*>(arg
);
414 the
->_barrier
->enter(2);
421 the
->writeCombine(depthDummy
,colorDummy
);
429 the
->writeCombine(depthDummy
,colorDummy
);
435 the
->writeCombine(depthDummy
,colorDummy
);