So we stripped down the code and can provide a minimal viable example for our approach to share an egl stream above process borders.
To be clear - we know how to use EGLStream consumer/producer in the same executable, but want to share the stream between two separate binaries for consumer and producer now. According to the EGL extension EGL_KHR_stream_cross_process_fd this should be possible by using “eglGetStreamFileDescriptorKHR” and “eglCreateStreamFromFileDescriptorKHR”.
From my understanding the cuda sample does not use this inter process approach, which we need for our application.
btw: i am working on the same project as bodo.pfeifer
consumer:
int main() {
initEGLfunctions();
std::cout << "Getting device ...\n";
EGLBoolean eglStatus;
#define MAX_EGL_DEVICES 4
EGLint numDevices = 0;
EGLDeviceEXT devices[MAX_EGL_DEVICES];
eglStatus = eglQueryDevicesEXT(MAX_EGL_DEVICES, devices, &numDevices);
if (eglStatus != EGL_TRUE) {
printf("Error querying EGL devices\n");
exit(EXIT_FAILURE);
}
EGLAttrib cudaIndex;
int cuda_device;
int egl_device_id = 0;
for (egl_device_id = 0; egl_device_id < numDevices; egl_device_id++) {
eglStatus = eglQueryDeviceAttribEXT(devices[egl_device_id],
EGL_CUDA_DEVICE_NV, &cudaIndex);
if (eglStatus == EGL_TRUE) {
cuda_device = cudaIndex; // We select first EGL-CUDA Capable device.
printf("Found EGL-CUDA Capable device with CUDA Device id = %d\n",
(int) cudaIndex);
break;
}
}
if (numDevices == 0) {
printf("No EGL devices found.. Waiving\n");
eglStatus = EGL_FALSE;
exit(1);
}
std::cout << "Creating display ...\n";
EGLDisplay eglDpy = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT,
(void *) devices[cuda_device], NULL);
if (eglDpy == EGL_NO_DISPLAY) {
printf("Could not get EGL display from device. \n");
eglStatus = EGL_FALSE;
exit(EXIT_FAILURE);
}
std::cout << "egl display: " << eglDpy << "\n";
EGLint major = 0;
EGLint minor = 0;
eglInitialize(eglDpy, &major, &minor);
EGLint streamAttrMailboxMode[] = {EGL_NONE};
std::cout << "Creating stream ...\n";
EGLStreamKHR eglstream =
eglCreateStreamKHR(eglDpy, streamAttrMailboxMode);
if (EGL_NO_STREAM_KHR == eglstream) {
std::cout << "\t!! Unable to create EGL stream (eglError: " << eglGetError()
<< ")";
return EXIT_FAILURE;
}
std::cout << "egl stream: " << eglstream << "\n";
EGLint streamState;
eglQueryStreamKHR(eglDpy, eglstream, EGL_STREAM_STATE_KHR,
&streamState);
EGLNativeFileDescriptorKHR fd = -1;
if (EGL_STREAM_STATE_CREATED_KHR == streamState) {
fd = eglGetStreamFileDescriptorKHR(eglDpy, eglstream);
}
if (fd <= 0) {
std::cout << "\t!! Unable to eglGetStreamFileDescriptorKHR (eglError: " <<
eglGetError() << ")";
}
std::cout << "egl stream fd: " << fd << "\n";
std::cout << "\nStart producer and enter fd value manually. Press [Enter] when "
"prompted by producer.\n";
std::cin.get();
return 0;
}
producer:
int main() {
initEGLfunctions();
std::cout << "Getting device ...\n";
EGLBoolean eglStatus;
#define MAX_EGL_DEVICES 4
EGLint numDevices = 0;
EGLDeviceEXT devices[MAX_EGL_DEVICES];
eglStatus = eglQueryDevicesEXT(MAX_EGL_DEVICES, devices, &numDevices);
if (eglStatus != EGL_TRUE) {
printf("Error querying EGL devices\n");
exit(EXIT_FAILURE);
}
EGLAttrib cudaIndex;
int cuda_device;
int egl_device_id = 0;
for (egl_device_id = 0; egl_device_id < numDevices; egl_device_id++) {
eglStatus = eglQueryDeviceAttribEXT(devices[egl_device_id],
EGL_CUDA_DEVICE_NV, &cudaIndex);
if (eglStatus == EGL_TRUE) {
cuda_device = cudaIndex; // We select first EGL-CUDA Capable device.
printf("Found EGL-CUDA Capable device with CUDA Device id = %d\n",
(int) cudaIndex);
break;
}
}
if (numDevices == 0) {
printf("No EGL devices found.. Waiving\n");
eglStatus = EGL_FALSE;
exit(1);
}
std::cout << "Creating display ...\n";
EGLDisplay eglDpy = eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT,
(void *) devices[cuda_device], NULL);
if (eglDpy == EGL_NO_DISPLAY) {
printf("Could not get EGL display from device. \n");
eglStatus = EGL_FALSE;
exit(EXIT_FAILURE);
}
std::cout << "egl display: " << eglDpy << "\n";
EGLint major = 0;
EGLint minor = 0;
eglInitialize(eglDpy, &major, &minor);
EGLint EGLfd;
std::cin >> EGLfd;
std::cout << "egl stream fd: " << EGLfd << "\n";
EGLStreamKHR eglstream =
eglCreateStreamFromFileDescriptorKHR(eglDpy, EGLfd);
if (eglstream == nullptr) {
std::cout << "Error: Invalid EGL Stream (" << std::hex << std::showbase <<
eglGetError
() << ")\n";
}
std::cout << "egl stream: " << eglstream << "\n";
std::cin.get();
return 0;
}