From e69edc6e097629552b83e028c7af99b62429a333 Mon Sep 17 00:00:00 2001 From: Linas Beresna Date: Tue, 3 Dec 2024 13:43:41 -0800 Subject: [PATCH] Update DisplayDriverServer and ClientDisplayDriver Adds option to server and client driver to allow a 'merge' driver that shares a display driver to write to. --- src/IECoreImage/ClientDisplayDriver.cpp | 13 ++++++- src/IECoreImage/DisplayDriverServer.cpp | 50 +++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/src/IECoreImage/ClientDisplayDriver.cpp b/src/IECoreImage/ClientDisplayDriver.cpp index 6358c0ff3f..585c61046c 100644 --- a/src/IECoreImage/ClientDisplayDriver.cpp +++ b/src/IECoreImage/ClientDisplayDriver.cpp @@ -92,6 +92,7 @@ ClientDisplayDriver::ClientDisplayDriver( const Imath::Box2i &displayWindow, con // expects three custom StringData parameters : displayHost, displayPort and displayType const StringData *displayHostData = parameters->member( "displayHost", true /* throw if missing */ ); const StringData *displayPortData = parameters->member( "displayPort", true /* throw if missing */ ); + const BoolData *mergeDriverData = parameters->member( "mergeDriver", false /* throw if missing */ ); m_data->m_host = displayHostData->readable(); m_data->m_port = displayPortData->readable(); @@ -122,11 +123,19 @@ ClientDisplayDriver::ClientDisplayDriver( const Imath::Box2i &displayWindow, con StringVectorDataPtr channelNamesData = new StringVectorData( channelNames ); IECore::CompoundDataPtr tmpParameters = parameters->copy(); + if (mergeDriverData && mergeDriverData->readable()) + { + const IntData *sessionIdData = parameters->member( "sessionId", true /* throw if missing */ ); + tmpParameters->writable()[ "clientPID" ] = new IntData( sessionIdData->readable() ); + } + else + { #ifndef _MSC_VER - tmpParameters->writable()[ "clientPID" ] = new IntData( getpid() ); + tmpParameters->writable()[ "clientPID" ] = new IntData( getpid() ); #else - tmpParameters->writable()[ "clientPID" ] = new IntData( _getpid() ); + tmpParameters->writable()[ "clientPID" ] = new IntData( _getpid() ); #endif + } // build the data block io = new MemoryIndexedIO( ConstCharVectorDataPtr(), IndexedIO::rootPath, IndexedIO::Exclusive | IndexedIO::Write ); diff --git a/src/IECoreImage/DisplayDriverServer.cpp b/src/IECoreImage/DisplayDriverServer.cpp index c337225b76..3562d5d680 100644 --- a/src/IECoreImage/DisplayDriverServer.cpp +++ b/src/IECoreImage/DisplayDriverServer.cpp @@ -53,6 +53,8 @@ #include "boost/bind/bind.hpp" #include +#include +#include #include #ifndef _MSC_VER @@ -70,6 +72,8 @@ IE_CORE_DEFINERUNTIMETYPED( DisplayDriverServer ); namespace { +std::map> mergeMap; + /* Set the FD_CLOEXEC flag for the given socket descriptor, so that it will not exist on child processes.*/ static void fixSocketFlags( int socketDesc ) { @@ -114,6 +118,8 @@ class DisplayDriverServer::Session : public RefCounted DisplayDriverPtr m_displayDriver; DisplayDriverServerHeader m_header; CharVectorDataPtr m_buffer; + bool m_mergeSession; + int m_mergeId; }; class DisplayDriverServer::PrivateData : public RefCounted @@ -293,7 +299,7 @@ void DisplayDriverServer::handleAccept( DisplayDriverServer::SessionPtr session, */ DisplayDriverServer::Session::Session( boost::asio::io_service& io_service ) : - m_socket( io_service ), m_displayDriver(nullptr), m_buffer( new CharVectorData( ) ) + m_socket( io_service ), m_displayDriver(nullptr), m_buffer( new CharVectorData( ) ), m_mergeSession(false), m_mergeId(-1) { } @@ -363,7 +369,15 @@ void DisplayDriverServer::Session::handleReadHeader( const boost::system::error_ { try { - m_displayDriver->imageClose(); + if ( !m_mergeSession ) + { + m_displayDriver->imageClose(); + } + else if ( auto search = mergeMap.find(m_mergeId); search != mergeMap.end() && --mergeMap[m_mergeId].second <= 0 ) + { + mergeMap.erase(m_mergeId); + m_displayDriver->imageClose(); + } } catch ( std::exception &e ) { @@ -423,9 +437,39 @@ void DisplayDriverServer::Session::handleReadOpenParameters( const boost::system const StringData *displayType = parameters->member( "remoteDisplayType", true /* throw if missing */ ); + const BoolData *mergeDriverData = parameters->member( "mergeDriver", false); + m_mergeSession = mergeDriverData && mergeDriverData->readable(); + // create a displayDriver using the factory function. - m_displayDriver = DisplayDriver::create( displayType->readable(), displayWindow->readable(), dataWindow->readable(), channelNames->readable(), parameters ); + if (!m_mergeSession) + { + m_displayDriver = DisplayDriver::create( displayType->readable(), displayWindow->readable(), dataWindow->readable(), channelNames->readable(), parameters ); + } + else + { + m_mergeId = parameters->member( "sessionId", true /* throw if missing */ )->readable(); + // Check if merge ID in map, if not then create display driver and session count pair with merge ID. + if (const auto search = mergeMap.find(m_mergeId); search == mergeMap.end()) + { + const IntData *sessionClientsData = parameters->member( "sessionClients", true /* throw if missing */ ); + mergeMap.emplace( + m_mergeId, + std::make_pair( + DisplayDriver::create( + displayType->readable(), + displayWindow->readable(), + displayWindow->readable(), // For merge we want dataWindow = displayWindow + channelNames->readable(), + parameters + ), + sessionClientsData->readable() + ) + ); + } + // Merge ID is now in map, so load the display driver. + m_displayDriver = mergeMap[m_mergeId].first; + } scanLineOrder = m_displayDriver->scanLineOrderOnly(); acceptsRepeatedData = m_displayDriver->acceptsRepeatedData(); }