Skip to content

Commit

Permalink
Update DisplayDriverServer and ClientDisplayDriver
Browse files Browse the repository at this point in the history
Adds option to server and client driver to allow a 'merge' driver
that shares a display driver to write to.
  • Loading branch information
Linas Beresna committed Dec 3, 2024
1 parent e8bc39a commit e69edc6
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
13 changes: 11 additions & 2 deletions src/IECoreImage/ClientDisplayDriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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<StringData>( "displayHost", true /* throw if missing */ );
const StringData *displayPortData = parameters->member<StringData>( "displayPort", true /* throw if missing */ );
const BoolData *mergeDriverData = parameters->member<BoolData>( "mergeDriver", false /* throw if missing */ );

m_data->m_host = displayHostData->readable();
m_data->m_port = displayPortData->readable();
Expand Down Expand Up @@ -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<IntData>( "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 );
Expand Down
50 changes: 47 additions & 3 deletions src/IECoreImage/DisplayDriverServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@
#include "boost/bind/bind.hpp"

#include <thread>
#include <map>
#include <utility>

#include <fcntl.h>
#ifndef _MSC_VER
Expand All @@ -70,6 +72,8 @@ IE_CORE_DEFINERUNTIMETYPED( DisplayDriverServer );
namespace
{

std::map<int, std::pair<DisplayDriverPtr, int>> 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 )
{
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
{
}

Expand Down Expand Up @@ -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 )
{
Expand Down Expand Up @@ -423,9 +437,39 @@ void DisplayDriverServer::Session::handleReadOpenParameters( const boost::system

const StringData *displayType = parameters->member<StringData>( "remoteDisplayType", true /* throw if missing */ );

const BoolData *mergeDriverData = parameters->member<BoolData>( "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<IntData>( "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<IntData>( "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();
}
Expand Down

0 comments on commit e69edc6

Please sign in to comment.