highgui: update backends handling, fix WITH_OPENGL=ON build
authorAlexander Alekhin <alexander.a.alekhin@gmail.com>
Fri, 4 Jun 2021 17:15:07 +0000 (17:15 +0000)
committerAlexander Alekhin <alexander.a.alekhin@gmail.com>
Mon, 7 Jun 2021 11:28:05 +0000 (11:28 +0000)
modules/highgui/CMakeLists.txt
modules/highgui/cmake/detect_gtk.cmake
modules/highgui/cmake/init.cmake
modules/highgui/misc/plugins/build_plugins.sh
modules/highgui/misc/plugins/plugin_gtk/CMakeLists.txt
modules/highgui/misc/plugins/plugin_gtk/Dockerfile-ubuntu-gtk2
modules/highgui/misc/plugins/plugin_gtk/build.sh
modules/highgui/src/backend.cpp
modules/highgui/src/registry.impl.hpp
modules/highgui/src/window_gtk.cpp

index 9b68b4672e0419f208263d556523b905e490b276..a0f444fd524cb2ea9b2911b3325656cb80150463 100644 (file)
@@ -1,26 +1,5 @@
 set(the_description "High-level GUI")
 
-set(ENABLE_PLUGINS_DEFAULT ON)
-if(EMSCRIPTEN OR IOS OR WINRT)
-  set(ENABLE_PLUGINS_DEFAULT OFF)
-endif()
-set(HIGHGUI_PLUGIN_LIST "" CACHE STRING "List of GUI backends to be compiled as plugins (gtk, gtk2/gtk3, qt, win32 or special value 'all')")
-set(HIGHGUI_ENABLE_PLUGINS "${ENABLE_PLUGINS_DEFAULT}" CACHE BOOL "Allow building and using of GUI plugins")
-mark_as_advanced(HIGHGUI_PLUGIN_LIST HIGHGUI_ENABLE_PLUGINS)
-
-string(REPLACE "," ";" HIGHGUI_PLUGIN_LIST "${HIGHGUI_PLUGIN_LIST}")  # support comma-separated list (,) too
-if(NOT HIGHGUI_ENABLE_PLUGINS)
-  if(HIGHGUI_PLUGIN_LIST)
-    message(WARNING "HighGUI: plugins are disabled through HIGHGUI_ENABLE_PLUGINS, so HIGHGUI_PLUGIN_LIST='${HIGHGUI_PLUGIN_LIST}' is ignored")
-    set(HIGHGUI_PLUGIN_LIST "")
-  endif()
-else()
-  # Make virtual plugins target
-  if(NOT TARGET opencv_highgui_plugins)
-    add_custom_target(opencv_highgui_plugins ALL)
-  endif()
-endif()
-
 if(ANDROID)
   ocv_add_module(highgui opencv_imgproc opencv_imgcodecs OPTIONAL opencv_videoio WRAP python)
 else()
@@ -68,7 +47,10 @@ file(GLOB highgui_ext_hdrs
 # Removing WinRT API headers by default
 list(REMOVE_ITEM highgui_ext_hdrs "${CMAKE_CURRENT_LIST_DIR}/include/opencv2/${name}/highgui_winrt.hpp")
 
+set(OPENCV_HIGHGUI_BUILTIN_BACKEND "")
+
 if(HAVE_QT5)
+  set(OPENCV_HIGHGUI_BUILTIN_BACKEND "QT5")
   add_definitions(-DHAVE_QT)
 
   # "Automoc" doesn't work properly with opencv_world build, use QT5_WRAP_CPP() directly
@@ -96,8 +78,8 @@ if(HAVE_QT5)
     include_directories(${Qt5OpenGL_INCLUDE_DIRS})
     list(APPEND HIGHGUI_LIBRARIES ${Qt5OpenGL_LIBRARIES})
   endif()
-
 elseif(HAVE_QT)
+  set(OPENCV_HIGHGUI_BUILTIN_BACKEND "QT4")
   add_definitions(-DHAVE_QT)
   if(HAVE_QT_OPENGL)
     add_definitions(-DHAVE_QT_OPENGL)
@@ -115,6 +97,7 @@ elseif(HAVE_QT)
     set_source_files_properties(${_RCC_OUTFILES} PROPERTIES COMPILE_FLAGS -Wno-missing-declarations)
   endif()
 elseif(WINRT)
+  set(OPENCV_HIGHGUI_BUILTIN_BACKEND "WINRT")
   if(NOT WINRT_8_0)
     # Dependencies used by the implementation referenced
     # below are not available on WinRT 8.0.
@@ -149,11 +132,13 @@ elseif(WINRT)
     message(STATUS "  ${name}:   Leaving '${HIGHGUI_LIBRARIES}'")
   endif()
 elseif(HAVE_WIN32UI)
+  set(OPENCV_HIGHGUI_BUILTIN_BACKEND "WIN32UI")
   list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_w32.cpp)
   if(OpenCV_ARCH STREQUAL "ARM64")
     list(APPEND HIGHGUI_LIBRARIES "comdlg32" "advapi32")
   endif()
 elseif(HAVE_COCOA)
+  set(OPENCV_HIGHGUI_BUILTIN_BACKEND "COCOA")
   add_definitions(-DHAVE_COCOA)
   list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_cocoa.mm)
   list(APPEND HIGHGUI_LIBRARIES "-framework Cocoa")
@@ -170,16 +155,31 @@ if(TARGET ocv.3rdparty.gtk3 OR TARGET ocv.3rdparty.gtk2)
     AND NOT "gtk" IN_LIST HIGHGUI_PLUGIN_LIST
     AND NOT "gtk2" IN_LIST HIGHGUI_PLUGIN_LIST
     AND NOT "gtk3" IN_LIST HIGHGUI_PLUGIN_LIST
+    AND NOT OPENCV_HIGHGUI_BUILTIN_BACKEND
   )
+    if(__gtk_dependency STREQUAL "ocv.3rdparty.gtk3")
+      set(OPENCV_HIGHGUI_BUILTIN_BACKEND "GTK3")
+    elseif(__gtk_dependency STREQUAL "ocv.3rdparty.gtk2")
+      set(OPENCV_HIGHGUI_BUILTIN_BACKEND "GTK2")
+    else()
+      set(OPENCV_HIGHGUI_BUILTIN_BACKEND "GTK")
+    endif()
     list(APPEND highgui_srcs ${CMAKE_CURRENT_LIST_DIR}/src/window_gtk.cpp)
     list(APPEND tgts ${__gtk_dependency})
     if(TARGET ocv.3rdparty.gthread)
       list(APPEND tgts ocv.3rdparty.gthread)
     endif()
     if(TARGET ocv.3rdparty.gtkglext
+        AND __gtk_dependency STREQUAL "ocv.3rdparty.gtk2"
         AND NOT OPENCV_GTK_DISABLE_GTKGLEXT
     )
       list(APPEND tgts ocv.3rdparty.gtkglext)
+      if(TARGET ocv.3rdparty.gtk_opengl
+          AND __gtk_dependency STREQUAL "ocv.3rdparty.gtk2"
+          AND NOT OPENCV_GTK_DISABLE_OPENGL
+      )
+        list(APPEND tgts ocv.3rdparty.gtk_opengl)
+      endif()
     endif()
   elseif("gtk" IN_LIST HIGHGUI_PLUGIN_LIST)
     ocv_create_builtin_highgui_plugin(opencv_highgui_gtk ${__gtk_dependency} "window_gtk.cpp")
@@ -211,6 +211,11 @@ if(TARGET ocv.3rdparty.gtk3 OR TARGET ocv.3rdparty.gtk2)
   endif()
 endif()
 
+if(NOT OPENCV_HIGHGUI_BUILTIN_BACKEND)
+  set(OPENCV_HIGHGUI_BUILTIN_BACKEND "NONE")
+endif()
+message(STATUS "highgui: using builtin backend: ${OPENCV_HIGHGUI_BUILTIN_BACKEND}")  # FIXIT: propagate to root CMake
+
 if(TRUE)
   # these variables are set by 'ocv_append_build_options(HIGHGUI ...)'
   foreach(P ${HIGHGUI_INCLUDE_DIRS})
@@ -271,3 +276,10 @@ if(HIGHGUI_ENABLE_PLUGINS)
 endif()
 
 ocv_target_link_libraries(${the_module} LINK_PRIVATE ${tgts})
+
+# generate module configuration
+set(CONFIG_STR "// Auto-generated file
+#define OPENCV_HIGHGUI_BUILTIN_BACKEND_STR \"${OPENCV_HIGHGUI_BUILTIN_BACKEND}\"
+")
+
+ocv_update_file("${CMAKE_CURRENT_BINARY_DIR}/opencv_highgui_config.hpp" "${CONFIG_STR}")
index 1f919860202956696108bbc491cb28333dca44cf..cdc054fad0c54becd8a3d3f125c3d14813da935a 100644 (file)
@@ -1,5 +1,5 @@
 # --- GTK ---
-ocv_clear_vars(HAVE_GTK HAVE_GTK3 HAVE_GTHREAD HAVE_GTKGLEXT)
+ocv_clear_vars(HAVE_GTK HAVE_GTK2 HAVE_GTK3 HAVE_GTHREAD HAVE_GTKGLEXT)
 if(WITH_GTK)
   if(NOT WITH_GTK_2_X)
     ocv_check_modules(GTK3 gtk+-3.0)
@@ -32,7 +32,7 @@ if(WITH_GTK)
     set(HAVE_GTHREAD "${HAVE_GTHREAD}" PARENT_SCOPE) # informational
     set(GTHREAD_VERSION "${GTHREAD_VERSION}" PARENT_SCOPE) # informational
   endif()
-  if(WITH_OPENGL AND NOT HAVE_GTK3)
+  if((WITH_OPENGL OR HAVE_OPENGL) AND HAVE_GTK2)
     ocv_check_modules(GTKGLEXT gtkglext-1.0)
     if(HAVE_GTKGLEXT)
       ocv_add_external_target(gtkglext "${GTKGLEXT_INCLUDE_DIRS}" "${GTKGLEXT_LIBRARIES}" "HAVE_GTKGLEXT")
@@ -44,4 +44,13 @@ elseif(HAVE_GTK)
   ocv_add_external_target(gtk "${GTK_INCLUDE_DIRS}" "${GTK_LIBRARIES}" "${GTK_DEFINES};HAVE_GTK")
 endif()
 
+if(WITH_OPENGL AND HAVE_GTKGLEXT)
+  find_package(OpenGL QUIET)
+  if(OPENGL_FOUND)
+    set(HAVE_OPENGL TRUE)
+    #set(HAVE_OPENGL ${HAVE_OPENGL} PARENT_SCOPE)
+    ocv_add_external_target(gtk_opengl "${OPENGL_INCLUDE_DIRS}" "${OPENGL_LIBRARIES}" "HAVE_OPENGL")
+  endif()
+endif()
+
 set(HAVE_GTK ${HAVE_GTK} PARENT_SCOPE)
index 1a115f22edd80426483fb8b6fdc2b7dc1a54e69f..3b766b3758c02d0714c0c1a371d48fbbc74a5fc2 100644 (file)
@@ -1,3 +1,30 @@
+if(PROJECT_NAME STREQUAL "OpenCV")
+  set(ENABLE_PLUGINS_DEFAULT ON)
+  if(EMSCRIPTEN OR IOS OR WINRT)
+    set(ENABLE_PLUGINS_DEFAULT OFF)
+  endif()
+  set(HIGHGUI_PLUGIN_LIST "" CACHE STRING "List of GUI backends to be compiled as plugins (gtk, gtk2/gtk3, qt, win32 or special value 'all')")
+  set(HIGHGUI_ENABLE_PLUGINS "${ENABLE_PLUGINS_DEFAULT}" CACHE BOOL "Allow building and using of GUI plugins")
+  mark_as_advanced(HIGHGUI_PLUGIN_LIST HIGHGUI_ENABLE_PLUGINS)
+
+  string(REPLACE "," ";" HIGHGUI_PLUGIN_LIST "${HIGHGUI_PLUGIN_LIST}")  # support comma-separated list (,) too
+  if(NOT HIGHGUI_ENABLE_PLUGINS)
+    if(HIGHGUI_PLUGIN_LIST)
+      message(WARNING "HighGUI: plugins are disabled through HIGHGUI_ENABLE_PLUGINS, so HIGHGUI_PLUGIN_LIST='${HIGHGUI_PLUGIN_LIST}' is ignored")
+      set(HIGHGUI_PLUGIN_LIST "")
+    endif()
+  else()
+    # Make virtual plugins target
+    if(NOT TARGET opencv_highgui_plugins)
+      add_custom_target(opencv_highgui_plugins ALL)
+    endif()
+  endif()
+endif()
+
+#
+# Detect available dependencies
+#
+
 include(FindPkgConfig)
 
 # FIXIT: stop using PARENT_SCOPE in dependencies
index a27f4a0ecaeef26e9e0208d23acfba3c5cae0a34..0018eef3ba14db1d9fd554410cfb4f98597b18c5 100755 (executable)
@@ -11,7 +11,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
 OCV="$( cd "${DIR}/../../../.." >/dev/null 2>&1 && pwd )"
 mkdir -p "${1}"  # Docker creates non-existed mounts with 'root' owner, lets ensure that dir exists under the current user to avoid "Permission denied" problem
 DST="$( cd "$1" >/dev/null 2>&1 && pwd )"
-CFG=$2
+CFG=${2:-Release}
 
 do_build()
 {
@@ -40,30 +40,33 @@ docker run \
     -e CFG=$CFG \
     --user $(id -u):$(id -g) \
     $TAG \
-    $@
+    "$@"
 }
 
 build_gtk2_ubuntu()
 {
 VER=$1
+shift 1
 TAG=opencv_highgui_ubuntu_gtk2_builder:${VER}
 do_build $TAG "${DIR}/plugin_gtk" Dockerfile-ubuntu-gtk2 --build-arg VER=${VER}
-do_run $TAG /opencv/modules/highgui/misc/plugins/plugin_gtk/build.sh /dst gtk2_ubuntu${VER} ${CFG}
+do_run $TAG /opencv/modules/highgui/misc/plugins/plugin_gtk/build.sh /dst gtk2_ubuntu${VER} ${CFG} "$@"
 
 }
 
 build_gtk3_ubuntu()
 {
 VER=$1
+shift 1
 TAG=opencv_highgui_ubuntu_gtk3_builder:${VER}
 do_build $TAG "${DIR}/plugin_gtk" Dockerfile-ubuntu-gtk3 --build-arg VER=${VER}
-do_run $TAG /opencv/modules/highgui/misc/plugins/plugin_gtk/build.sh /dst gtk3_ubuntu${VER} ${CFG}
+do_run $TAG /opencv/modules/highgui/misc/plugins/plugin_gtk/build.sh /dst gtk3_ubuntu${VER} ${CFG} "$@"
 }
 
 echo "OpenCV: ${OCV}"
 echo "Destination: ${DST}"
 
 build_gtk2_ubuntu 16.04
+build_gtk2_ubuntu 16.04 -DOPENCV_PLUGIN_NAME=opencv_highgui_gtk2-opengl_ubuntu16.04 -DWITH_OPENGL=ON -DWITH_GTK_2_X=ON
 build_gtk2_ubuntu 18.04
 build_gtk3_ubuntu 18.04
 build_gtk3_ubuntu 20.04
index 22462900f1963f36a7444c97ce5a82f0de9d3bfb..6a2da0c9c329a8f0a97e1b1f1181f928e734e50f 100644 (file)
@@ -25,6 +25,21 @@ else()
   message(FATAL_ERROR "Missing dependency target for GTK libraries")
 endif()
 ocv_create_plugin(highgui "opencv_highgui_gtk" "${__deps}" "GTK" "src/window_gtk.cpp")
+if(WITH_OPENGL)
+  if(HAVE_GTK2
+      AND TARGET ocv.3rdparty.gtkglext
+      AND TARGET ocv.3rdparty.gtk_opengl
+      AND NOT OPENCV_GTK_DISABLE_GTKGLEXT
+      AND NOT OPENCV_GTK_DISABLE_OPENGL
+  )
+    message(STATUS "OpenGL: YES")
+    target_link_libraries(${OPENCV_PLUGIN_NAME} PRIVATE
+        ocv.3rdparty.gtkglext ocv.3rdparty.gtk_opengl
+    )
+  else()
+    message(WARNING "OpenGL dependencies are not available!")
+  endif()
+endif()
 
 if(HAVE_GTK3)
   message(STATUS "GTK3+: ver ${GTK3_VERSION}")
@@ -41,8 +56,3 @@ if(HAVE_GTHREAD)
 else()
   message(STATUS "GThread : NO")
 endif()
-if(HAVE_GTKGLEXT)
-  message(STATUS "GtkGlExt: YES (ver ${GTKGLEXT_VERSION})")
-else()
-  message(STATUS "GtkGlExt: NO")
-endif()
index 81836cb384119cadf0c99586b07e8c02dbd6b4fe..fefa0ba339b16f03e5a707581b881a828cfedf9a 100644 (file)
@@ -18,4 +18,11 @@ RUN \
   && \
   rm -rf /var/lib/apt/lists/*
 
+RUN \
+  apt-get update && \
+  DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
+    libgtkglext1-dev \
+  && \
+  rm -rf /var/lib/apt/lists/*
+
 WORKDIR /tmp
index 58048698db80aed2c54cc461ec95592d310edd96..4383016910e87197b270a1b80ce3b33b23a73d0d 100755 (executable)
@@ -4,10 +4,18 @@ set -e
 
 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
 
+OPENCV_PLUGIN_DESTINATION=$1
+OPENCV_PLUGIN_NAME=opencv_highgui_$2
+CMAKE_BUILD_TYPE=${3:-Release}
+
+shift 3 || true
+
+set -x
 cmake -GNinja \
-    -DOPENCV_PLUGIN_NAME=opencv_highgui_$2 \
-    -DOPENCV_PLUGIN_DESTINATION=$1 \
-    -DCMAKE_BUILD_TYPE=$3 \
+    -DOPENCV_PLUGIN_NAME=${OPENCV_PLUGIN_NAME} \
+    -DOPENCV_PLUGIN_DESTINATION=${OPENCV_PLUGIN_DESTINATION} \
+    -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} \
+    "$@" \
     $DIR
 
 ninja -v
index 4c0de0584ea724d5db49ba3b455f31a086719086..7c241ea90775b564d0a043d34a5b4eefca2b4b72 100644 (file)
@@ -2,6 +2,7 @@
 // It is subject to the license terms in the LICENSE file found in the top-level directory
 // of this distribution and at http://opencv.org/license.html.
 #include "precomp.hpp"
+#include "opencv_highgui_config.hpp"  // generated by CMake
 #include "backend.hpp"
 
 #include <opencv2/core/utils/configuration.private.hpp>
@@ -103,7 +104,7 @@ std::shared_ptr<UIBackend> createUIBackend()
     }
     if (name.empty())
     {
-        CV_LOG_DEBUG(NULL, "UI: fallback on builtin code");
+        CV_LOG_DEBUG(NULL, "UI: fallback on builtin code: " OPENCV_HIGHGUI_BUILTIN_BACKEND_STR);
     }
     else
     {
index a2e4dbea47e735eca0f652fadf2d990a4f2484a1..9c50986a69a6170ae414d56c174762509fa9a160 100644 (file)
@@ -162,6 +162,7 @@ public:
             const BackendInfo& info = enabledBackends[i];
             os << info.name << '(' << info.priority << ')';
         }
+        os << " + BUILTIN(" OPENCV_HIGHGUI_BUILTIN_BACKEND_STR ")";
         return os.str();
     }
 
index f2d02d66b03dc6432043ad82023c6bedd5698d93..f7570f42c7f41aa717e5824cffc936e4e3f9bb8f 100644 (file)
 #if defined (HAVE_GTK)
 
 #include <gtk/gtk.h>
+
+#if (GTK_MAJOR_VERSION == 3) && defined(HAVE_OPENGL)
+  #undef HAVE_OPENGL  // no support with GTK3
+#endif
+#if defined(HAVE_OPENGL) && !defined(HAVE_GTKGLEXT)
+  #undef HAVE_OPENGL  // gtkglext is required
+#endif
+
 #include <gdk/gdkkeysyms.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <stdio.h>
@@ -1187,7 +1195,7 @@ static std::shared_ptr<CvWindow> namedWindow_(const std::string& name, int flags
 
 #ifdef HAVE_OPENGL
     if (window->useGl)
-        cvSetOpenGlContext(name);
+        cvSetOpenGlContext(name.c_str());
 #endif
 
     return window_ptr;
@@ -1205,7 +1213,7 @@ CV_IMPL void cvSetOpenGlContext(const char* name)
 
     CV_LOCK_MUTEX();
 
-    CvWindow* window = icvFindWindowByName(name);
+    auto window = icvFindWindowByName(name);
     if (!window)
         CV_Error( CV_StsNullPtr, "NULL window" );
 
@@ -1225,7 +1233,7 @@ CV_IMPL void cvUpdateWindow(const char* name)
 
     CV_LOCK_MUTEX();
 
-    CvWindow* window = icvFindWindowByName(name);
+    auto window = icvFindWindowByName(name);
     if (!window)
         return;
 
@@ -1239,7 +1247,7 @@ CV_IMPL void cvSetOpenGlDrawCallback(const char* name, CvOpenGlDrawCallback call
 
     CV_LOCK_MUTEX();
 
-    CvWindow* window = icvFindWindowByName(name);
+    auto window = icvFindWindowByName(name);
     if( !window )
         return;