53
53
#include " boost/bind/bind.hpp"
54
54
55
55
#include < thread>
56
+ #include < map>
57
+ #include < utility>
56
58
57
59
#include < fcntl.h>
58
60
#ifndef _MSC_VER
@@ -70,6 +72,8 @@ IE_CORE_DEFINERUNTIMETYPED( DisplayDriverServer );
70
72
namespace
71
73
{
72
74
75
+ std::map<int , std::pair<DisplayDriverPtr, int >> mergeMap;
76
+
73
77
/* Set the FD_CLOEXEC flag for the given socket descriptor, so that it will not exist on child processes.*/
74
78
static void fixSocketFlags ( int socketDesc )
75
79
{
@@ -114,6 +118,8 @@ class DisplayDriverServer::Session : public RefCounted
114
118
DisplayDriverPtr m_displayDriver;
115
119
DisplayDriverServerHeader m_header;
116
120
CharVectorDataPtr m_buffer;
121
+ bool m_mergeSession;
122
+ int m_mergeId;
117
123
};
118
124
119
125
class DisplayDriverServer ::PrivateData : public RefCounted
@@ -293,7 +299,7 @@ void DisplayDriverServer::handleAccept( DisplayDriverServer::SessionPtr session,
293
299
*/
294
300
295
301
DisplayDriverServer::Session::Session ( boost::asio::io_service& io_service ) :
296
- m_socket( io_service ), m_displayDriver(nullptr ), m_buffer( new CharVectorData( ) )
302
+ m_socket( io_service ), m_displayDriver(nullptr ), m_buffer( new CharVectorData( ) ), m_mergeSession( false ), m_mergeId(- 1 )
297
303
{
298
304
}
299
305
@@ -363,7 +369,15 @@ void DisplayDriverServer::Session::handleReadHeader( const boost::system::error_
363
369
{
364
370
try
365
371
{
366
- m_displayDriver->imageClose ();
372
+ if ( !m_mergeSession )
373
+ {
374
+ m_displayDriver->imageClose ();
375
+ }
376
+ else if ( auto search = mergeMap.find (m_mergeId); search != mergeMap.end () && --mergeMap[m_mergeId].second <= 0 )
377
+ {
378
+ mergeMap.erase (m_mergeId);
379
+ m_displayDriver->imageClose ();
380
+ }
367
381
}
368
382
catch ( std::exception &e )
369
383
{
@@ -423,9 +437,39 @@ void DisplayDriverServer::Session::handleReadOpenParameters( const boost::system
423
437
424
438
const StringData *displayType = parameters->member <StringData>( " remoteDisplayType" , true /* throw if missing */ );
425
439
440
+ const BoolData *mergeDriverData = parameters->member <BoolData>( " mergeDriver" , false );
441
+ m_mergeSession = mergeDriverData && mergeDriverData->readable ();
442
+
426
443
// create a displayDriver using the factory function.
427
- m_displayDriver = DisplayDriver::create ( displayType->readable (), displayWindow->readable (), dataWindow->readable (), channelNames->readable (), parameters );
444
+ if (!m_mergeSession)
445
+ {
446
+ m_displayDriver = DisplayDriver::create ( displayType->readable (), displayWindow->readable (), dataWindow->readable (), channelNames->readable (), parameters );
447
+ }
448
+ else
449
+ {
450
+ m_mergeId = parameters->member <IntData>( " sessionId" , true /* throw if missing */ )->readable ();
428
451
452
+ // Check if merge ID in map, if not then create display driver and session count pair with merge ID.
453
+ if (const auto search = mergeMap.find (m_mergeId); search == mergeMap.end ())
454
+ {
455
+ const IntData *sessionClientsData = parameters->member <IntData>( " sessionClients" , true /* throw if missing */ );
456
+ mergeMap.emplace (
457
+ m_mergeId,
458
+ std::make_pair (
459
+ DisplayDriver::create (
460
+ displayType->readable (),
461
+ displayWindow->readable (),
462
+ displayWindow->readable (), // For merge we want dataWindow = displayWindow
463
+ channelNames->readable (),
464
+ parameters
465
+ ),
466
+ sessionClientsData->readable ()
467
+ )
468
+ );
469
+ }
470
+ // Merge ID is now in map, so load the display driver.
471
+ m_displayDriver = mergeMap[m_mergeId].first ;
472
+ }
429
473
scanLineOrder = m_displayDriver->scanLineOrderOnly ();
430
474
acceptsRepeatedData = m_displayDriver->acceptsRepeatedData ();
431
475
}
0 commit comments