diff --git a/Dockerfile b/Dockerfile index 21902d197..10b280172 100644 --- a/Dockerfile +++ b/Dockerfile @@ -25,6 +25,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ make \ ocl-icd-opencl-dev \ opencl-headers \ + libegl-dev \ python-openssl \ tk-dev \ wget \ diff --git a/SConscript b/SConscript index e40d3ba1a..4d9fb38bc 100644 --- a/SConscript +++ b/SConscript @@ -64,6 +64,7 @@ if arch == "Darwin": vipc_frameworks.append('OpenCL') else: vipc_libs.append('OpenCL') + vipc_libs.append('EGL') envCython.Program('visionipc/visionipc_pyx.so', 'visionipc/visionipc_pyx.pyx', LIBS=vipc_libs, FRAMEWORKS=vipc_frameworks) diff --git a/visionipc/visionbuf.h b/visionipc/visionbuf.h index fe546a64e..e3872ca02 100644 --- a/visionipc/visionbuf.h +++ b/visionipc/visionbuf.h @@ -8,6 +8,12 @@ #include #endif +#define EGL_EGLEXT_PROTOTYPES +#define EGL_NO_X11 +#include +#include +#include + #define VISIONBUF_SYNC_FROM_DEVICE 0 #define VISIONBUF_SYNC_TO_DEVICE 1 @@ -51,12 +57,16 @@ class VisionBuf { cl_mem buf_cl = nullptr; cl_command_queue copy_q = nullptr; + // OpenGL + EGLImageKHR egl_image = EGL_NO_IMAGE_KHR; + // ion int handle = 0; void allocate(size_t len); void import(); void init_cl(cl_device_id device_id, cl_context ctx); + void init_gl(); void init_rgb(size_t width, size_t height, size_t stride); void init_yuv(size_t width, size_t height, size_t stride, size_t uv_offset); int sync(int dir); diff --git a/visionipc/visionbuf_cl.cc b/visionipc/visionbuf_cl.cc index 0286d28fd..08d768df7 100644 --- a/visionipc/visionbuf_cl.cc +++ b/visionipc/visionbuf_cl.cc @@ -49,6 +49,9 @@ void VisionBuf::init_cl(cl_device_id device_id, cl_context ctx){ assert(err == 0); } +void VisionBuf::init_gl() { + assert(false); // only used for visionbuf_ion +}; void VisionBuf::import(){ assert(this->fd >= 0); diff --git a/visionipc/visionbuf_ion.cc b/visionipc/visionbuf_ion.cc index c66b668c6..157ed8901 100644 --- a/visionipc/visionbuf_ion.cc +++ b/visionipc/visionbuf_ion.cc @@ -117,6 +117,24 @@ void VisionBuf::init_cl(cl_device_id device_id, cl_context ctx) { assert(err == 0); } +void VisionBuf::init_gl() { + EGLDisplay display = eglGetCurrentDisplay(); + + EGLint img_attrs[] = { + EGL_WIDTH, (int)this->width, + EGL_HEIGHT, (int)this->height, + EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_NV12, + EGL_DMA_BUF_PLANE0_FD_EXT, this->fd, + EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, + EGL_DMA_BUF_PLANE0_PITCH_EXT, (int)this->stride, + EGL_DMA_BUF_PLANE1_FD_EXT, this->fd, + EGL_DMA_BUF_PLANE1_OFFSET_EXT, (int)this->uv_offset, + EGL_DMA_BUF_PLANE1_PITCH_EXT, (int)this->stride, + EGL_NONE + }; + this->egl_image = eglCreateImageKHR(display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, 0, img_attrs); + assert(eglGetError() == EGL_SUCCESS); +} int VisionBuf::sync(int dir) { struct ion_flush_data flush_data = {0}; @@ -142,6 +160,11 @@ int VisionBuf::sync(int dir) { int VisionBuf::free() { int err = 0; + if (this->egl_image) { + EGLDisplay display = eglGetCurrentDisplay(); + eglDestroyImageKHR(display, this->egl_image); + } + if (this->buf_cl){ err = clReleaseMemObject(this->buf_cl); if (err != 0) return err;