5353#include " boost/bind/bind.hpp"
5454
5555#include < thread>
56+ #include < map>
57+ #include < utility>
5658
5759#include < fcntl.h>
5860#ifndef _MSC_VER
@@ -70,6 +72,8 @@ IE_CORE_DEFINERUNTIMETYPED( DisplayDriverServer );
7072namespace
7173{
7274
75+ std::map<int , std::pair<DisplayDriverPtr, int >> mergeMap;
76+
7377/* Set the FD_CLOEXEC flag for the given socket descriptor, so that it will not exist on child processes.*/
7478static void fixSocketFlags ( int socketDesc )
7579{
@@ -114,6 +118,8 @@ class DisplayDriverServer::Session : public RefCounted
114118 DisplayDriverPtr m_displayDriver;
115119 DisplayDriverServerHeader m_header;
116120 CharVectorDataPtr m_buffer;
121+ bool m_mergeSession;
122+ int m_mergeId;
117123};
118124
119125class DisplayDriverServer ::PrivateData : public RefCounted
@@ -293,7 +299,7 @@ void DisplayDriverServer::handleAccept( DisplayDriverServer::SessionPtr session,
293299 */
294300
295301DisplayDriverServer::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 )
297303{
298304}
299305
@@ -363,7 +369,15 @@ void DisplayDriverServer::Session::handleReadHeader( const boost::system::error_
363369 {
364370 try
365371 {
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+ }
367381 }
368382 catch ( std::exception &e )
369383 {
@@ -423,9 +437,39 @@ void DisplayDriverServer::Session::handleReadOpenParameters( const boost::system
423437
424438 const StringData *displayType = parameters->member <StringData>( " remoteDisplayType" , true /* throw if missing */ );
425439
440+ const BoolData *mergeDriverData = parameters->member <BoolData>( " mergeDriver" , false );
441+ m_mergeSession = mergeDriverData && mergeDriverData->readable ();
442+
426443 // 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 ();
428451
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+ }
429473 scanLineOrder = m_displayDriver->scanLineOrderOnly ();
430474 acceptsRepeatedData = m_displayDriver->acceptsRepeatedData ();
431475 }
0 commit comments