1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
7 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
9 \*---------------------------------------------------------------------------*/
10 /*---------------------------------------------------------------------------*\
13 * This library is free software; you can redistribute it and/or modify it *
14 * under the terms of the GNU Library General Public License as published *
15 * by the Free Software Foundation, version 2. *
17 * This library is distributed in the hope that it will be useful, but *
18 * WITHOUT ANY WARRANTY; without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
20 * Library General Public License for more details. *
22 * You should have received a copy of the GNU Library General Public *
23 * License along with this library; if not, write to the Free Software *
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
26 \*---------------------------------------------------------------------------*/
27 /*---------------------------------------------------------------------------*\
35 \*---------------------------------------------------------------------------*/
37 //---------------------------------------------------------------------------
39 //---------------------------------------------------------------------------
43 template<class DepthT,class ColorT>
44 void BinarySwapComposer::sendToClient(DepthT &depth,
51 // send the resulting tile to the client
53 clusterWindow()->getNetwork()->getConnection(clusterId());
57 UInt32 lastx = right + 1;
58 UInt32 lasty = top + 1;
60 for(ty = bottom; ty <= top ; ++ty)
62 for(tx = left; tx <= right ; ++tx)
64 if(!getTileBuffer(tx,ty)->empty)
72 for(ty = bottom; ty <= top ; ++ty)
74 for(tx = left; tx <= right ; ++tx)
76 tile = getTileBuffer(tx,ty);
80 if(ty == lasty && tx == lastx)
81 tile->header.x^=0x8000;
83 client->put(&(tile->header),
85 sizeof(tile->header));
89 _statistics.bytesOut +=
90 tile->colorSize + sizeof(tile->header);
95 if(lastx == right + 1)
102 client->put(&(t.header),
107 _statistics.bytesOut += sizeof(t.header);
111 template<class DepthT,class ColorT>
112 void BinarySwapComposer::recvFromServers(DepthT &depth,
118 UInt32 missing = _usableServers;
119 TileBuffer *readTile = getTileReadBuffer();
120 GroupConnection *servers =
121 clusterWindow()->getNetwork()->getGroupConnection(clusterId());
123 Connection::Channel channel;
127 channel = servers->selectChannel();
129 servers->get(&(readTile->header),
130 sizeof(readTile->header));
132 _statistics.bytesIn += sizeof(readTile->header);
134 if(readTile->header.x & 0x8000)
136 readTile->header.x ^= 0x8000;
137 servers->subSelection(channel);
141 if(!(readTile->header.y & 0x8000))
143 servers->get(readTile->data,
144 readTile->header.w*readTile->header.h*
147 _statistics.bytesIn +=
148 readTile->header.w * readTile->header.h * sizeof(ColorT);
150 glRasterPos2f(readTile->header.x * getTileSize(),
151 readTile->header.y * getTileSize());
152 glDrawPixels(readTile->header.w,
154 colorType, colorFormat,readTile->data);
158 servers->resetSelection();
161 template<class DepthT,class ColorT>
162 void BinarySwapComposer::writeCombine(DepthT &depthDummy,ColorT &colorDummy)
173 if(_swapWith >= _usableServers)
176 lastx = _writeRight + 1;
177 lasty = _writeTop + 1;
179 for(ty = _writeBottom; ty <= _writeTop ; ++ty)
181 for(tx = _writeLeft; tx <= _writeRight ; ++tx)
183 if(!getTileBuffer(tx,ty)->empty)
191 for(ty = _writeBottom; ty <= _writeTop ; ++ty)
193 for(tx = _writeLeft; tx <= _writeRight ; ++tx)
195 tile = getTileBuffer(tx,ty);
201 tile->header.x^=0x8000;
203 _swapConnection->put(&(tile->header),
205 sizeof(tile->header));
207 _swapConnection->flush();
209 _statistics.bytesOut +=
210 tile->dataSize + sizeof(tile->header);
212 if(ty == lasty && tx == lastx)
213 tile->header.x^=0x8000;
217 // no data, write single header
218 if(lastx == _writeRight + 1)
223 _swapConnection->put(&(t.header),
225 _statistics.bytesOut += sizeof(t.header);
230 template<class DepthT,class ColorT>
231 void BinarySwapComposer::readCombine(DepthT &depth,
242 UInt32 aRight,bLeft,aTop,bBottom;
243 UInt32 readLeft,readRight,readTop,readBottom;
245 TileBuffer *readTile=getTileReadBuffer();
246 DepthT *srcDepth,*dstDepth,*srcDepthEnd;
247 ColorT *srcColor,*dstColor;
251 memset(&nullColor,0,sizeof(ColorT));
253 _swapWith = clusterId() ^ level;
255 if(_swapWith >= _usableServers)
258 // send the resulting tile to the client
259 sendToClient(depth,color,
260 left,bottom,right,top);
263 _swapConnection = clusterWindow()->getNetwork()->getConnection(_swapWith);
265 w = right - left + 1;
266 h = top - bottom + 1;
270 aRight = left + (w/2);
278 aTop = bottom + (h/2);
282 if(clusterId() > _swapWith)
285 _writeBottom = bottom;
286 _writeRight = aRight;
290 readBottom = bBottom;
297 _writeBottom = bBottom;
308 _swapConnection->selectChannel();
311 _swapConnection->get(&(readTile->header),
312 sizeof(readTile->header));
313 _statistics.bytesIn += sizeof(readTile->header);
314 if(readTile->header.x&0x8000)
317 readTile->header.x^=0x8000;
319 if(!(readTile->header.y & 0x8000))
321 tile = getTileBuffer(readTile->header.x,
325 // dest is empty, overwrite
326 _swapConnection->get(tile->data,
328 _statistics.bytesIn += tile->dataSize;
329 if(sizeof(ColorT) == 4)
331 glRasterPos2f(tile->header.x * getTileSize(),
332 tile->header.y * getTileSize());
333 glDrawPixels(tile->header.w,tile->header.h,
334 colorType, colorFormat,
342 _swapConnection->get(readTile->data,
344 _statistics.bytesIn += tile->dataSize;
347 reinterpret_cast<DepthT*>(readTile->data + tile->colorSize);
349 srcDepthEnd = reinterpret_cast<DepthT*>(readTile->data +
351 srcColor = reinterpret_cast<ColorT*>(readTile->data);
353 reinterpret_cast<DepthT*>(tile->data + tile->colorSize);
354 dstColor = reinterpret_cast<ColorT*>(tile->data);
356 if(sizeof(ColorT) == 4)
359 while(srcDepth < srcDepthEnd)
361 if(*srcDepth <= *dstDepth)
362 *dstDepth = *srcDepth;
364 *srcColor = nullColor;
369 // hardware alpha combine
370 glRasterPos2f(tile->header.x * getTileSize(),
371 tile->header.y * getTileSize());
372 glDrawPixels(tile->header.w,tile->header.h,
373 colorType, colorFormat,
375 glReadPixels(tile->header.x * getTileSize(),
376 tile->header.y * getTileSize(),
377 tile->header.w,tile->header.h,
378 colorType, colorFormat,
384 while(srcDepth < srcDepthEnd)
386 if(*srcDepth < *dstDepth)
388 *dstColor = *srcColor;
389 *dstDepth = *srcDepth;
401 readCombine(depth,color,
402 colorType,colorFormat,
403 readLeft,readBottom,readRight,readTop,level<<1);
406 template<class DepthT,class ColorT>
407 void BinarySwapComposer::startReader(DepthT &depthMax,
414 UInt32 tx,ty,x,y,w,h;
416 UInt32 left,bottom,top,right,front,back;
417 #ifdef OPTIMIZED_BINARY_SWAP
418 DepthT *depthStart,*depthEnd;
422 if(!getScreenAlignedBBox(port->getRoot(),
424 left,bottom,right,top,front,back))
426 left=right=clusterWindow()->getWidth();
427 top=bottom=clusterWindow()->getHeight();
428 front=back=UInt32(-1);
431 for(ty = 0; ty < _tilesY ; ++ty)
433 for(tx = 0; tx < _tilesX ; ++tx)
435 x = tx * getTileSize();
436 y = ty * getTileSize();
437 w = osgMin(getTileSize(),port->calcPixelWidth() - x);
438 h = osgMin(getTileSize(),port->calcPixelHeight() - y);
439 tile = getTileBuffer(tx,ty);
444 tile->colorSize = sizeof(ColorT)*w*h;
445 tile->depthSize = sizeof(DepthT)*w*h;
446 tile->dataSize = tile->colorSize + tile->depthSize;
456 glReadPixels(x, y, w, h,
457 GL_DEPTH_COMPONENT, depthFormat,
458 tile->data+tile->colorSize);
459 #ifdef OPTIMIZED_BINARY_SWAP
460 if(sizeof(ColorT) != 4)
462 depthStart = (DepthT*)(tile->data + tile->colorSize);
463 depthEnd = (DepthT*)(tile->data +
467 while(depthStart < depthEnd &&
468 *depthStart == (DepthT)depthMax)
470 if(depthStart == depthEnd)
476 glReadPixels(x, y, w, h,
477 colorType, colorFormat,
479 if(sizeof(ColorT) == 4)
481 // in alpha mode, only empty if alpha is 0
483 cEnd = tile->data + 3 + w * h * 4;
484 while(c != cEnd && *c == 0)
494 readCombine(depthMax,color,
495 colorType,colorFormat,
496 0,0,_tilesX-1,_tilesY-1,1);