fixed: auto_ptr -> unique_ptr
[opensg.git] / Source / System / Cluster / Window / SortLast / OSGPipelineComposer.cpp
blobc34ba59ce6e71b213d24ff6160c74d5d7be3c375
1 /*---------------------------------------------------------------------------*\
2 * OpenSG *
3 * *
4 * *
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
6 * *
7 * www.opensg.org *
8 * *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
10 * *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
13 * License *
14 * *
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. *
18 * *
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. *
23 * *
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. *
27 * *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
30 * Changes *
31 * *
32 * *
33 * *
34 * *
35 * *
36 * *
37 \*---------------------------------------------------------------------------*/
39 //---------------------------------------------------------------------------
40 // Includes
41 //---------------------------------------------------------------------------
43 #include <stdlib.h>
44 #include <stdio.h>
46 #define GL_GLEXT_PROTOTYPES 1
48 #include "OSGConfig.h"
49 #include "OSGConnection.h"
50 #include "OSGGLEXT.h"
52 #include "OSGPipelineComposer.h"
54 OSG_USING_NAMESPACE
56 /***************************************************************************\
57 * Description *
58 \***************************************************************************/
60 /*! \class OSG::PipelineComposer
64 /***************************************************************************\
65 * Class variables *
66 \***************************************************************************/
68 /***************************************************************************\
69 * Class methods *
70 \***************************************************************************/
72 void PipelineComposer::initMethod(InitPhase ePhase)
77 /***************************************************************************\
78 * Instance methods *
79 \***************************************************************************/
81 /*-------------------------------------------------------------------------*\
82 - private -
83 \*-------------------------------------------------------------------------*/
85 /*----------------------- constructors & destructors ----------------------*/
87 PipelineComposer::PipelineComposer(void) :
88 Inherited ( ),
89 _tileBufferSize (0 ),
90 _tileA ( ),
91 _tileB ( ),
92 _workingTile ( ),
93 _readTilePtr (&_tileA),
94 _composeTilePtr (&_tileB),
95 _readTilesX (0 ),
96 _readTilesY (0 ),
97 _composeTilesX (0 ),
98 _composeTilesY (0 ),
100 _transInfo ( ),
101 _groupInfoPool ( ),
102 _groupInfo ( ),
104 _colorFormat (GL_NONE),
105 _colorType (GL_NONE),
106 _depthType (GL_NONE),
108 _statistics ( ),
110 _writer (NULL ),
111 _composer (NULL ),
112 _barrier (NULL ),
113 _composeBarrier (NULL ),
114 _frameEndBarrier(NULL ),
115 _lock (NULL ),
116 _queue ( ),
117 _waiting (false ),
118 _occlusionQuery (0 ),
119 _firstFrame (true )
123 PipelineComposer::PipelineComposer(const PipelineComposer &source) :
124 Inherited (source ),
125 _tileBufferSize (0 ),
126 _tileA ( ),
127 _tileB ( ),
128 _workingTile ( ),
129 _readTilePtr (&_tileA),
130 _composeTilePtr (&_tileB),
131 _readTilesX (0 ),
132 _readTilesY (0 ),
133 _composeTilesX (0 ),
134 _composeTilesY (0 ),
136 _transInfo ( ),
137 _groupInfoPool ( ),
138 _groupInfo ( ),
140 _colorFormat (GL_NONE),
141 _colorType (GL_NONE),
142 _depthType (GL_NONE),
144 _statistics ( ),
146 _writer (NULL ),
147 _composer (NULL ),
148 _barrier (NULL ),
149 _composeBarrier (NULL ),
150 _frameEndBarrier(NULL ),
151 _lock (NULL ),
152 _queue ( ),
153 _waiting (false ),
154 _occlusionQuery (0 ),
155 _firstFrame (true )
159 PipelineComposer::~PipelineComposer(void)
163 /*----------------------------- class specific ----------------------------*/
165 void PipelineComposer::changed(ConstFieldMaskArg whichField,
166 UInt32 origin,
167 BitVector details)
169 Inherited::changed(whichField, origin, details);
172 void PipelineComposer::dump( UInt32 ,
173 const BitVector ) const
175 SLOG << "Dump PipelineComposer NI" << std::endl;
178 /*----------------------------- composition -------------------------------*/
180 void PipelineComposer::open()
182 setShort(true);
184 // create server cross connection
185 _clusterWindow->getNetwork()->connectAllGroupToPoint(clusterId(),
186 "StreamSock");
187 // do not buffer any data
188 for(UInt32 i=0 ; i <= serverCount() ; ++i)
189 clusterWindow()->getNetwork()->getConnection(i)->forceDirectIO();
190 if(!_isClient)
192 // create barrier
193 _lock = Lock::get("PipelineComposer", false);
194 // create barrier
195 _barrier = Barrier::get("PipelineComposer", false);
196 _frameEndBarrier = Barrier::get("PipelineComposerFrameEnd", false);
197 // create writer thread
198 _writer = BaseThread::get("PipelineComposer", false);
199 // start writer thread
200 _writer->runFunction( writeProc, this );
202 if(!_isClient && getPipelined())
204 _composeBarrier = Barrier::get("PipelineComposerCompose", false);
205 // _composer = BaseThread::get("PipelineComposerCompose");
206 _composer = dynamic_pointer_cast<Thread>(
207 ThreadManager::the()->getThread(NULL, false));
209 _composer->runFunction( composeProc,0, this );
212 #ifdef USE_NV_OCCLUSION
213 glGenOcclusionQueriesNV(1, &_occlusionQuery);
214 #endif
217 void PipelineComposer::startViewport(Viewport *)
219 if(getPipelined())
221 if(!isClient())
223 _composeBarrier->enter(2);
225 else
227 // transfer tile size
228 _composeTilesX = _readTilesX;
229 _composeTilesY = _readTilesY;
234 void PipelineComposer::composeViewport(Viewport *port)
236 // setup viewport
237 GLint
238 pl=port->calcPixelLeft(),
239 pr=port->calcPixelRight(),
240 pb=port->calcPixelBottom(),
241 pt=port->calcPixelTop();
242 GLint pw=pr-pl+1,ph=pt-pb+1;
243 bool full = port->calcIsFullWindow();
244 glViewport(pl, pb, pw, ph);
245 glScissor(pl, pb, pw, ph);
246 if(! full)
247 glEnable(GL_SCISSOR_TEST);
249 GLboolean depth = glIsEnabled(GL_DEPTH_TEST);
250 GLboolean blend = glIsEnabled(GL_BLEND);
252 // glDisable(GL_DEPTH_TEST);
253 glPushMatrix();
254 glLoadIdentity();
255 glMatrixMode(GL_PROJECTION);
256 glPushMatrix();
257 glLoadIdentity();
258 glOrtho(0, port->calcPixelWidth(),
259 0, port->calcPixelHeight(),-1,1);
260 if(getAlpha())
262 glEnable(GL_BLEND);
263 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
266 // only one buffer for the client
267 if(isClient())
268 _composeTilePtr = _readTilePtr;
270 _readTilesX = (port->calcPixelWidth() - 1) / getTileSize() + 1;
271 _readTilesY = (port->calcPixelHeight() - 1) / getTileSize() + 1;
273 _tileBufferSize = getTileSize()*getTileSize()*8+sizeof(TileBuffer);
274 _workingTile.resize(_tileBufferSize);
276 // resize
277 _readTilePtr->resize(_tileBufferSize * _readTilesX * _readTilesY);
279 if(isClient())
281 while(_groupInfo.size() < serverCount())
283 _groupInfoPool.push_back(GroupInfo());
284 _groupInfo.push_back(&(*_groupInfoPool.rbegin()));
286 _groupInfo.resize(serverCount());
289 _statistics.bytesIn = 0;
290 _statistics.bytesOut = 0;
291 _statistics.occluded = 0;
292 _statistics.noDepth = 0;
293 _statistics.noGeo = 0;
294 _statistics.clipped = 0;
296 if(!getPipelined())
298 _composeTilesX = _readTilesX;
299 _composeTilesY = _readTilesY;
301 if(getShort())
303 UInt16 colorDummy;
304 // UInt16 depthDummy;
305 UInt32 depthDummy;
306 // _depthType = GL_UNSIGNED_SHORT;
307 _depthType = GL_UNSIGNED_INT;
308 _colorFormat = GL_RGB;
309 _colorType = GL_UNSIGNED_SHORT_5_6_5;
311 readBuffer(depthDummy,colorDummy,port);
312 if(!getPipelined() || isClient())
313 composeBuffer(depthDummy,colorDummy);
315 else
317 if(getAlpha())
319 UInt32 colorDummy;
320 UInt32 depthDummy;
321 _depthType = GL_UNSIGNED_INT;
322 _colorFormat = GL_RGBA;
323 _colorType = GL_UNSIGNED_BYTE;
324 readBuffer(depthDummy,colorDummy,port);
325 if(!getPipelined() || isClient())
326 composeBuffer(depthDummy,colorDummy);
328 else
330 RGBValue colorDummy;
331 UInt32 depthDummy;
332 _depthType = GL_UNSIGNED_INT;
333 _colorFormat = GL_RGB;
334 _colorType = GL_UNSIGNED_BYTE;
335 readBuffer(depthDummy,colorDummy,port);
336 if(!getPipelined() || isClient())
337 composeBuffer(depthDummy,colorDummy);
341 if(getStatistics())
343 if(isClient())
345 double pixelReadTime = 0;
346 double sortTime = 0;
347 UInt32 maxIn = _statistics.bytesIn;
348 UInt32 maxOut = _statistics.bytesOut;
349 UInt32 maxIO = maxIn + maxOut;
350 UInt32 sumOut = _statistics.bytesOut;
351 UInt32 clipped = 0;
352 Connection::Channel channel;
353 GroupConnection *server;
354 Statistics statistics;
355 server = clusterWindow()->getNetwork()->getMainGroupConnection();
356 for(UInt32 i=0 ; i<serverCount() ;++i)
358 channel = server->selectChannel();
359 server->subSelection(channel);
360 server->get(&statistics,sizeof(Statistics));
361 sumOut += statistics.bytesOut;
362 if(statistics.pixelReadTime > pixelReadTime) {
363 pixelReadTime = statistics.pixelReadTime;
364 sortTime = statistics.sortTime;
366 if(statistics.bytesOut > maxOut)
367 maxOut = statistics.bytesOut;
368 if(statistics.bytesIn > maxIn)
369 maxIn = statistics.bytesIn;
370 if(statistics.bytesIn + statistics.bytesOut > maxIO)
371 maxIO = statistics.bytesIn + statistics.bytesOut;
372 clipped += statistics.clipped;
374 server->resetSelection();
375 printf("pixel read time : %1.5lf\n",pixelReadTime);
376 printf("sort Time : %1.5lf\n",sortTime);
377 printf("compose Time : %1.5lf\n",_statistics.composeTime);
378 printf("Transfered bytes : %10d\n",sumOut);
379 printf("Max out : %10d\n",maxOut);
380 printf("Max in : %10d\n",maxIn);
381 printf("Max io : %10d\n",maxIO);
382 printf("occluded : %10d\n",_statistics.occluded);
383 printf("Layerd : %10d\n",_statistics.noDepth);
384 printf("Empty : %10d\n",_statistics.noGeo-clipped);
385 printf("Clipped : %10d\n",clipped);
386 printf("DepthAndColor : %10d\n",serverCount()*_composeTilesX*_composeTilesY-
387 _statistics.occluded-
388 _statistics.noDepth-
389 _statistics.noGeo);
391 else
393 Connection *client = clusterWindow()->getNetwork()->getMainConnection();
394 client->put(&_statistics,sizeof(Statistics));
395 client->flush();
399 glPopMatrix();
400 glMatrixMode(GL_MODELVIEW);
401 glPopMatrix();
402 glEnable(GL_DEPTH_TEST);
404 // reset state
405 if(depth && !glIsEnabled(GL_DEPTH_TEST))
406 glEnable(GL_DEPTH_TEST);
407 if(!blend && glIsEnabled(GL_BLEND))
408 glDisable(GL_BLEND);
411 void PipelineComposer::close(void)
413 if(!isClient() && _writer)
415 _lock->acquire();
416 _queue.push_back(NULL);
417 if(_waiting)
419 _lock ->release( );
420 _barrier->enter (2);
422 else
424 _lock->release();
426 BaseThread::join(_writer);
428 _writer = NULL;
429 _composer = NULL;
430 _barrier = NULL;
431 _composeBarrier = NULL;
432 _frameEndBarrier = NULL;
433 _lock = NULL;
437 /*----------------------------- features ---------------------------------*/
439 /*!
441 bool PipelineComposer::getClientRendering()
443 return false;
446 /*----------------------------- helper ------------------------------------*/
448 PipelineComposer::TileBuffer *PipelineComposer::getComposeTileBuffer(UInt32 x,UInt32 y)
450 return reinterpret_cast<TileBuffer*>(&(*_composeTilePtr)[(y*_composeTilesX + x)*_tileBufferSize]);
453 PipelineComposer::TileBuffer *PipelineComposer::getReadTileBuffer(UInt32 x,UInt32 y)
455 return reinterpret_cast<TileBuffer*>(&(*_readTilePtr)[(y*_readTilesX + x)*_tileBufferSize]);
458 PipelineComposer::TileBuffer *PipelineComposer::getWorkingTileBuffer(void)
460 return reinterpret_cast<TileBuffer*>(&_workingTile[0]);
463 /*! Depth order for pipe sort
465 bool PipelineComposer::GroupInfoOrder::operator()
466 (const GroupInfo *a, const GroupInfo *b)
468 if( a->depth.max > b->depth.max ||
469 ( a->depth.max == b->depth.max &&
470 a->id > b->id ))
471 return true;
472 else
473 return false;
476 UInt32 PipelineComposer::compressTransInfo(std::vector<TransInfo> &transInfo)
478 TransInfo *src = &transInfo[0];
479 TransInfo *srcEnd = src + _composeTilesX*_composeTilesY*serverCount();
480 TransInfo *dst = &transInfo[0];
481 TransInfo *empty = NULL;
482 while(src != srcEnd) {
483 if(src->empty) {
484 if(!empty) {
485 empty = dst++;
486 empty->sendTo=1;
487 empty->empty=true;
488 } else {
489 empty->sendTo++;
490 if(empty->sendTo == 0) {
491 empty->sendTo--;
492 empty = dst++;
493 empty->sendTo=1;
494 empty->empty=true;
497 } else {
498 empty = NULL;
499 *dst=*src;
500 dst++;
502 src++;
504 // printf("Compress %f\n",(dst - &transInfo[0])*100.0/transInfo.size());
505 return dst - &transInfo[0];
508 void PipelineComposer::uncompressTransInfo(std::vector<TransInfo> &transInfo,UInt32 infoCount)
510 transInfo.resize(_composeTilesX*_composeTilesY*serverCount());
512 TransInfo *src = &transInfo[infoCount-1];
513 TransInfo *srcEnd = &transInfo[0] - 1;
514 TransInfo *dst = &transInfo[_composeTilesX*_composeTilesY*serverCount()-1];
515 while(src != srcEnd) {
516 if(src->empty) {
517 while(src->sendTo) {
518 dst->empty = true;
519 dst--;
520 src->sendTo--;
522 } else {
523 *dst=*src;
524 dst--;
526 src--;
530 /*----------------------------- thread proc -------------------------------*/
532 void PipelineComposer::writeProc(void *arg)
534 PipelineComposer *the=static_cast<PipelineComposer*>(arg);
535 if(the->getShort())
537 UInt16 colorDummy;
538 UInt16 depthDummy;
539 the->writeResult(depthDummy,colorDummy);
541 else
543 if(the->getAlpha())
545 RGBValue colorDummy;
546 UInt32 depthDummy;
547 the->writeResult(depthDummy,colorDummy);
549 else
551 UInt32 colorDummy;
552 UInt32 depthDummy;
553 the->writeResult(depthDummy,colorDummy);
558 void PipelineComposer::composeProc(void *arg)
560 PipelineComposer *the=static_cast<PipelineComposer*>(arg);
562 // TODO stop compose thread
563 for(;;)
565 if(the->getShort())
567 UInt16 colorDummy;
568 UInt32 depthDummy;
569 the->composeBuffer(depthDummy,colorDummy);
571 else
573 if(the->getAlpha())
575 RGBValue colorDummy;
576 UInt32 depthDummy;
577 the->composeBuffer(depthDummy,colorDummy);
579 else
581 UInt32 colorDummy;
582 UInt32 depthDummy;
583 the->composeBuffer(depthDummy,colorDummy);