Implemented optional EGL based GL/CL interop#22704
Implemented optional EGL based GL/CL interop#22704kallaballa wants to merge 21 commits intoopencv:4.xfrom
Conversation
|
OpenCV may use GLX for several purposes:
|
But why would you use GLX if you already have EGL (e.g. for android CL/GL interop). Could you please explain a use case where having EGL & GLX provides a benefit? Because all of those things (and more... e.g. offscreen rendering) can be done with EGL. |
|
Let's say, historical reason. Some code was contributed long time ago and not developed actively. I'm not against of EGL, but prefer safe way - not destroy existing features. |
|
I see now what you mean. There is another place where GLX is used: opencv/modules/core/src/gl_core_3_1.cpp Line 131 in 778fadd Anyway, I understand your point but on the other hand I wouldn't mind also replacing the CV_GL_GET_PROC_ADDRESS implementation and be done with GLX. :) |
|
Anyway... even if you don't want to replace GLX completely, this pull request still makes sense. Replacing GLX with EGL for OpenGL interop brings many advantages, like:
|
I understand now. and will implement it like that. |
|
Done de6bb16 |
|
I improved the implementation by defining a proper OCV_OPTION |
|
I thought about it and maybe it would be a good idea to infer which window-system API (GLX or EGL) to use by probing |
|
I tried both branches on my Ubuntu 18.04 host. Both implementations work, but final executable has significantly different dependencies. I do not think that dependency from both libEGL and libGLX is good idea. |
|
Also not all Linux systems provide EGL support. Please check |
Alright!
I understand your intuition in this (I had the same) but since i really want this feature i went to find evidence. ;) First i tried to find examples of libraries on my system linking to both find /usr/lib64/ -maxdepth 1 -name "*.so" | while read lib; do
deps="$(sudo ldd "$lib" 2>/dev/null | tr -d '\n')";
echo "$deps" | grep -q -E "libGLX.so.*libEGL.so|libEGL.so.*libGLX.so";
if [ $? -eq 0 ]; then
echo "$lib";
fi;
doneAnd i found the following files: So at least somebody is actively linking EGL and GLX at the same time. But what struck my eye quickly is that it's mostly GTK stack.... So i went to search in their repo and found this: https://gitlab.gnome.org/GNOME/gtk/-/merge_requests/3540 They are basically using GLX as a fallback to EGL. |
|
Half a year later firefox did the same: https://mozillagfx.wordpress.com/2021/10/30/switching-the-linux-graphics-stack-from-glx-to-egl/ Btw. I just realized I left |
|
Thanks a lot for the research! Could you check if the GTK stack does lazy linkage with EGL and GLX? |
|
I am on it :) |
|
I have following statement from a GTK developer: "EGL has issues with properly reporting the RGBA VIsual, which is why GTK defaults to GLX. You can often just force the RGBA Visual and it'll work, but GTK isn't doing that yet (Firefox and Chrome switched recently I think, maybe it got fixed or there's a an official way, didn't investigate yet) About the exact circumstances of linking i still have to investigate and I am also going to branch out to the Firefox community and see if they have advice. |
|
GTK doesn't do any special linking but has routines for probing the subsystems and only uses one at the time: |
|
Statement from a Firefox dev: "Hi! So unfortunately Mesas X11 EGL implementation still has some open issues (e.g. https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9989 ....) which is why GTK4 still falls back to GLX. Generally GTK4 and OBS-Studio might be simpler examples than FF." |
There is no check for GLX in place either (as far as i can see). Can't hurt to add that too? |
Done 735a0f2
Done 49f64dd |
| endif() | ||
| endmacro() | ||
|
|
||
| add_backend("gtk" WITH_GTK) |
There was a problem hiding this comment.
Need to recover GTK plugins support.
There was a problem hiding this comment.
Yes. I need to push my latest changes. They include working GTK.
There was a problem hiding this comment.
Sorry. needed quite some to come back to this, but now i pushed the latest changes :)
modules/core/CMakeLists.txt
Outdated
| ocv_append_source_file_compile_definitions("${CMAKE_CURRENT_LIST_DIR}/src/va_intel.cpp" "OPENCV_LIBVA_LINK=1") | ||
| endif() | ||
| if(OPENCV_ENABLE_EGL_INTEROP) | ||
| ocv_append_source_file_compile_definitions("${CMAKE_CURRENT_LIST_DIR}/src/opengl.cpp" "HAVE_EGL_INTEROP") |
There was a problem hiding this comment.
Perhaps HAVE_EGL and HAVE_OPENGL should be checked too.
There was a problem hiding this comment.
Not really.
User could specify WITH_OPENGL=ON but there could be no OpenCL dev packages on build system (or for build target platform in case of cross-compiling).
WITH_ / OPENCV_ENABLE_ is a user intention (lets enable this if available).
Next, find_package() should be executed.
Preferable try_compile() should be run to validate dependency configuration.
After checks above HAVE_ variable is set to ON / 1.
Feature usage should be guarded by HAVE_ checks.
All dependencies should be properly detected on configuration (cmake) stage.
Build stage (make) should not fail due to dependency misusing.
There was a problem hiding this comment.
I see now. Will probably create a PR today.
modules/core/CMakeLists.txt
Outdated
| "${ZLIB_LIBRARIES}" "${OPENCL_LIBRARIES}" "${VA_LIBRARIES}" | ||
| "${OPENGL_LIBRARIES}" | ||
| "${GLX_LIBRARIES}" | ||
| "${OPENGL_LIBRARIES}" "${OPENGL_egl_LIBRARY}" |
There was a problem hiding this comment.
@asmorkalov Does OpenGL subsystem in OpenCV uses dynamic loading? or direct linkage?
There was a problem hiding this comment.
In a way it does both and with libGLVND the situation is a bit more complex. But anyway, it is directly linked but the function pointers are loaded a runtime.
There was a problem hiding this comment.
No, linkage is static for now:
opencv-build/lib$ readelf -d ./libopencv_core.so
Dynamic section at offset 0xe7d750 contains 31 entries:
Tag Type Name/Value
0x0000000000000001 (NEEDED) Shared library: [libz.so.1]
0x0000000000000001 (NEEDED) Shared library: [libGL.so.1]
0x0000000000000001 (NEEDED) Shared library: [libstdc++.so.6]
0x0000000000000001 (NEEDED) Shared library: [libm.so.6]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]
0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
0x000000000000000e (SONAME) Library soname: [libopencv_core.so.412]
0x000000000000001d (RUNPATH) Library runpath: [::::::::::::::]
0x000000000000000c (INIT) 0x7c000
0x000000000000000d (FINI) 0xbd84cc
0x0000000000000019 (INIT_ARRAY) 0xe65860
0x000000000000001b (INIT_ARRAYSZ) 120 (bytes)
0x000000000000001a (FINI_ARRAY) 0xe658d8
0x000000000000001c (FINI_ARRAYSZ) 8 (bytes)
0x000000006ffffef5 (GNU_HASH) 0x2f0
0x0000000000000005 (STRTAB) 0x14608
0x0000000000000006 (SYMTAB) 0x4fd8
0x000000000000000a (STRSZ) 101596 (bytes)
0x000000000000000b (SYMENT) 24 (bytes)
0x0000000000000003 (PLTGOT) 0xe7efe8
0x0000000000000002 (PLTRELSZ) 26304 (bytes)
0x0000000000000014 (PLTREL) RELA
0x0000000000000017 (JMPREL) 0x75800
0x0000000000000007 (RELA) 0x2e9b8
0x0000000000000008 (RELASZ) 290376 (bytes)
0x0000000000000009 (RELAENT) 24 (bytes)
0x000000006ffffffe (VERNEED) 0x2e768
0x000000006fffffff (VERNEEDNUM) 4
0x000000006ffffff0 (VERSYM) 0x2d2e4
0x000000006ffffff9 (RELACOUNT) 11124
0x0000000000000000 (NULL) 0x0
|
I have this in use on a couple of Linux systems (OpenSuSe, Debian, Ubuntu) mostly Intel iGPU systems but also one with Nvidia GPU. Intel requires EGL while Nvidia requires GLX. On the NVidia system the Intel iGPU is available as well and works - so i can switch between them with the same binary due to the GLX fallback mechanism. |
|
Tested using an Intel A770 and Mesa 24.3.1 as well |
|
Resolved merge conflict. testing. |
|
Tested. Still works as expected. |
d243a30 to
3b3f415
Compare
cmake/OpenCVFindLibsGUI.cmake
Outdated
| if(WITH_WIN32UI OR (HAVE_QT AND QT_QTOPENGL_FOUND) OR HAVE_GTK3 OR (HAVE_GTK AND NOT HAVE_GTK3 AND HAVE_GTKGLEXT)) | ||
| find_package (OpenGL QUIET) | ||
| if(OpenGL_EGL_FOUND) | ||
| set(HAVE_EGL TRUE AND OPENCV_ENABLE_EGL) |
There was a problem hiding this comment.
CMake's set doesn't support complex boolean values.
modules/core/src/opengl.cpp
Outdated
| # if defined(OPENCV_ENABLE_EGL) | ||
| # include <EGL/egl.h> | ||
| # endif | ||
| # if defined(OPENCV_ENABLE_GLX) |
There was a problem hiding this comment.
Where are these vars defined?
| if(OPENCV_LIBVA_LINK) | ||
| ocv_append_source_file_compile_definitions("${CMAKE_CURRENT_LIST_DIR}/src/va_intel.cpp" "OPENCV_LIBVA_LINK=1") | ||
| endif() | ||
| if(OPENCV_ENABLE_EGL_INTEROP) |
There was a problem hiding this comment.
Where do we define this flag?
|
i fixed the issues |
The pertaining issue: #22703
Pull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.