55                   serialization::EnumAsIntegerTag<OSVR_ImagingValueType,
 
   74             void allocateBuffer(T &, 
size_t bytes, std::true_type 
const &) {
 
   75                 m_imgBuf = util::makeAlignedImageBuffer(bytes);
 
   79             void allocateBuffer(T &, 
size_t, std::false_type 
const &) {
 
   85                 auto bytes = getBufferSize(m_meta);
 
   89                 allocateBuffer(p, bytes, p.isDeserialize());
 
   95                 ret.sensor = m_sensor;
 
   96                 ret.metadata = m_meta;
 
   97                 ret.buffer = m_imgBuf;
 
  103             ImageBufferPtr m_imgBuf;
 
  106         const char *ImageRegion::identifier() {
 
  107             return "com.osvr.imaging.imageregion";
 
  110 #ifdef OSVR_COMMON_IN_PROCESS_IMAGING 
  112             struct InProcessMemoryMessage {
 
  117             template <
typename T>
 
  118             void process(InProcessMemoryMessage &ipmmMsg, T &p) {
 
  119                 process(ipmmMsg.metadata, p);
 
  125         const char *ImagePlacedInProcessMemory::identifier() {
 
  126             return "com.osvr.imaging.imageplacedinprocessmemory";
 
  129         class ImagePlacedInProcessMemory::MessageSerialization {
 
  131             MessageSerialization() {}
 
  132             explicit MessageSerialization(InProcessMemoryMessage &&msg)
 
  133                 : m_msgData(
std::move(msg)) {}
 
  135 #if defined(_MSC_VER) && defined(_PREFAST_) 
  137             explicit MessageSerialization(InProcessMemoryMessage 
const &msg)
 
  140             template <
typename T> 
void processMessage(T &p) {
 
  141                 process(m_msgData, p);
 
  144             InProcessMemoryMessage 
const &getMessage() { 
return m_msgData; }
 
  147             InProcessMemoryMessage m_msgData;
 
  152             struct SharedMemoryMessage {
 
  156                 IPCRingBuffer::abi_level_type abiLevel;
 
  157                 IPCRingBuffer::BackendType backend;
 
  160             template <
typename T>
 
  161             void process(SharedMemoryMessage &shmMsg, T &p) {
 
  162                 process(shmMsg.metadata, p);
 
  175                 : m_msgData(std::move(msg)) {}
 
  177 #if defined(_MSC_VER) && defined(_PREFAST_) 
  183             template <
typename T> 
void processMessage(T &p) {
 
  184                 process(m_msgData, p);
 
  187             SharedMemoryMessage 
const &getMessage() { 
return m_msgData; }
 
  190             SharedMemoryMessage m_msgData;
 
  193         const char *ImagePlacedInSharedMemory::identifier() {
 
  194             return "com.osvr.imaging.imageplacedinsharedmemory";
 
  198     shared_ptr<ImagingComponent>
 
  204         : m_numSensor(numChan) {}
 
  213 #ifdef OSVR_COMMON_IN_PROCESS_IMAGING 
  214         dataSent += m_sendImageDataViaInProcessMemory(metadata, imageData,
 
  217         dataSent += m_sendImageDataViaSharedMemory(metadata, imageData, sensor,
 
  221             m_sendImageDataOnTheWire(metadata, imageData, sensor, timestamp);
 
  223             m_checkFirst(metadata);
 
  227 #ifdef OSVR_COMMON_IN_PROCESS_IMAGING 
  228     bool ImagingComponent::m_sendImageDataViaInProcessMemory(
 
  232         auto imageBufferSize = getBufferSize(metadata);
 
  233         auto imageBufferCopy = util::makeAlignedImageBuffer(imageBufferSize);
 
  234         memcpy(imageBufferCopy.get(), imageData, imageBufferSize);
 
  237         messages::ImagePlacedInProcessMemory::MessageSerialization
 
  238             serialization(messages::InProcessMemoryMessage{
 
  240                 reinterpret_cast<intptr_t
>(imageBufferCopy.release())});
 
  244             buf, imagePlacedInProcessMemory.getMessageType(), timestamp);
 
  250     bool ImagingComponent::m_sendImageDataViaSharedMemory(
 
  254         m_growShmVecIfRequired(sensor);
 
  255         uint32_t imageBufferSize = getBufferSize(metadata);
 
  256         if (!m_shmBuf[sensor] ||
 
  257             m_shmBuf[sensor]->getEntrySize() != imageBufferSize) {
 
  260                                std::string 
const &devName) {
 
  261                 std::ostringstream os;
 
  262                 os << 
"com.osvr.imaging/" << devName << 
"/" << int(sensor);
 
  266                 IPCRingBuffer::Options(
 
  268                     .setEntrySize(imageBufferSize));
 
  270         if (!m_shmBuf[sensor]) {
 
  272                 "Some issue creating shared memory for imaging, skipping out.");
 
  275         auto &shm = *(m_shmBuf[sensor]);
 
  276         auto seq = shm.put(imageData, imageBufferSize);
 
  279         messages::ImagePlacedInSharedMemory::MessageSerialization serialization(
 
  280             messages::SharedMemoryMessage{metadata, seq, sensor,
 
  282                                           shm.getBackend(), shm.getName()});
 
  290     bool ImagingComponent::m_sendImageDataOnTheWire(
 
  294         if (metadata.
depth != 1) {
 
  298         messages::ImageRegion::MessageSerialization msg(metadata, imageData,
 
  301         if (buf.size() > vrpn_CONNECTION_TCP_BUFLEN) {
 
  303             OSVR_DEV_VERBOSE(
"Skipping imaging message: size is " 
  304                              << buf.size() << 
" vs the maximum of " 
  305                              << vrpn_CONNECTION_TCP_BUFLEN);
 
  315     ImagingComponent::m_handleImageRegion(
void *userdata, vrpn_HANDLERPARAM p) {
 
  316         auto self = 
static_cast<ImagingComponent *
>(userdata);
 
  319         messages::ImageRegion::MessageSerialization msg;
 
  321         auto data = msg.getData();
 
  324         self->m_checkFirst(data.metadata);
 
  325         for (
auto const &cb : self->m_cb) {
 
  331 #ifdef OSVR_COMMON_IN_PROCESS_IMAGING 
  332     int VRPN_CALLBACK ImagingComponent::m_handleImagePlacedInProcessMemory(
 
  333         void *userdata, vrpn_HANDLERPARAM p) {
 
  334         auto self = 
static_cast<ImagingComponent *
>(userdata);
 
  337         messages::ImagePlacedInProcessMemory::MessageSerialization msgSerialize;
 
  339         auto msg = msgSerialize.getMessage();
 
  341         data.sensor = msg.sensor;
 
  342         data.metadata = msg.metadata;
 
  344             reinterpret_cast<OSVR_ImageBufferElement *>(msg.buffer),
 
  348         self->m_checkFirst(msg.metadata);
 
  349         for (
auto const &cb : self->m_cb) {
 
  356     int VRPN_CALLBACK ImagingComponent::m_handleImagePlacedInSharedMemory(
 
  357         void *userdata, vrpn_HANDLERPARAM p) {
 
  358         auto self = 
static_cast<ImagingComponent *
>(userdata);
 
  361         messages::ImagePlacedInSharedMemory::MessageSerialization msgSerialize;
 
  363         auto &msg = msgSerialize.getMessage();
 
  368             OSVR_DEV_VERBOSE(
"Can't handle SHM ABI level " << msg.abiLevel);
 
  371         self->m_growShmVecIfRequired(msg.sensor);
 
  372         auto checkSameRingBuf = [](messages::SharedMemoryMessage 
const &msg,
 
  374             return (msg.backend == ringbuf->getBackend()) &&
 
  375                    (ringbuf->getEntrySize() == getBufferSize(msg.metadata)) &&
 
  376                    (ringbuf->getName() == msg.shmName);
 
  378         if (!self->m_shmBuf[msg.sensor] ||
 
  379             !checkSameRingBuf(msg, self->m_shmBuf[msg.sensor])) {
 
  381                 IPCRingBuffer::Options(msg.shmName, msg.backend));
 
  383         if (!self->m_shmBuf[msg.sensor]) {
 
  386             OSVR_DEV_VERBOSE(
"Can't find desired IPC ring buffer " 
  391         auto &shm = 
self->m_shmBuf[msg.sensor];
 
  392         auto getResult = shm->get(msg.seqNum);
 
  394             auto bufptr = getResult.getBufferSmartPointer();
 
  395             self->m_checkFirst(msg.metadata);
 
  396             auto data = ImageData{msg.sensor, msg.metadata, bufptr};
 
  398             for (
auto const &cb : self->m_cb) {
 
  405     void ImagingComponent::registerImageHandler(ImageHandler handler) {
 
  411                 &ImagingComponent::m_handleImagePlacedInSharedMemory, 
this,
 
  414 #ifdef OSVR_COMMON_IN_PROCESS_IMAGING 
  416                 &ImagingComponent::m_handleImagePlacedInProcessMemory, 
this,
 
  417                 imagePlacedInProcessMemory.getMessageType());
 
  420         m_cb.push_back(handler);
 
  422     void ImagingComponent::m_parentSet() {
 
  425 #ifdef OSVR_COMMON_IN_PROCESS_IMAGING 
  436         OSVR_DEV_VERBOSE(
"Sending/receiving first frame: width=" 
  437                          << metadata.
width << 
" height=" << metadata.
height);
 
  440         if (m_shmBuf.size() <= sensor) {
 
  441             m_shmBuf.resize(sensor + 1);
 
uint32_t OSVR_ChannelCount
The integer type specifying a number of channels/sensors or a channel/sensor index. 
A tag for use for raw data (bytestream), optionally aligned. 
void deserialize(BufferReaderType &reader, MessageClass &msg)
Deserializes a message from a buffer, using a MessageClass 
void serialize(BufferType &buf, MessageClass &msg)
Serializes a message into a buffer, using a MessageClass 
shared_ptr< IPCRingBuffer > IPCRingBufferPtr
Pointer type for holding a shared memory ring buffer. 
static IPCRingBufferPtr find(Options const &opts)
Named constructor, for use by client processes: accesses an IPC ring buffer using the options structu...
static shared_ptr< ImagingComponent > create(OSVR_ChannelCount numSensor=0)
Factory method. 
void m_registerHandler(vrpn_MESSAGEHANDLER handler, void *userdata, RawMessageType const &msgType)
Registers a handler whose lifetime is tied to the lifetime of the component. 
void processMessage(T &p)
void fromStructTimeval(TimeValue &dest, struct timeval const &src)
Convert a struct timeval to a TimeValue. 
static abi_level_type getABILevel()
Gets an integer representing a unique arrangement of the internal shared memory layout, such that if two processes try to communicate with different ABI levels, they will (likely) not succeed and thus should not try. 
uint32_t sequence_type
The sequence number is automatically incremented with each "put" into the buffer. Note that...
void sendPending()
Called from a component to send pending messages instead of waiting for next time. 
Parent & m_getParent()
Gets the parent - only call if m_hasParent() is true. 
messages::ImageRegion imageRegion
Message from server to client, containing some image data. 
Internal, configured header file for verbosity macros. 
messages::ImagePlacedInSharedMemory imagePlacedInSharedMemory
Message from server to client, notifying of image data in the shared memory ring buffer. 
Standardized, portable parallel to struct timeval for representing both absolute times and time inter...
Header defining buffer types, with optional alignment dependent on Boost version. ...
unsigned char OSVR_ImageBufferElement
Type for raw buffer access to image data. 
BufferReader< ExternalBufferReadingWrapper< CharType > > readExternalBuffer(const CharType *buf, size_t len)
Constructs and returns a buffer reader for an externally-allocated buffer: it's on you to supply a va...
void registerMessageType(MessageRegistration< T > &messageReg)
Call with a MessageRegistration object, and the message type will be registered and stored in the typ...
void alignedFree(void *p)
Aligned deallocation function, uses the pointer to the original memory block to deallocate it...
A class that lightly wraps a bool, in order to provide easier maintenance of a "dirty" flag...
static IPCRingBufferPtr create(Options const &opts)
Named constructor, for use by server processes: creates a shared memory ring buffer given the options...