Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QInteropWindow with QPA



  • Quite a while ago I created a class called QInteropWindow which was inspired by QOpenGLWindow, but the class takes care of setting up OpenCL-GL interop. Because it has a few extra behaviors QOpenGLWindow does not, it inherits from QWindow.

    class InteropWindow : public QWindow
    {
        Q_OBJECT
    
    public:
    
    #ifdef _WIN32
        typedef QPair<HDC, HGLRC> gl_device;           // Windows-specific OpenGL device handles
    #endif
    #ifdef __linux__
        typedef QPair<Display*, GLXContext> gl_device; // Linux-specific OpenGL device handles
    #endif
    
       ...
    };
    

    This is how the class starts because, I will need these two handles so I can pass them over to OpenCL when I create the context.

    QVector<cl_context_properties> InteropWindow::interopCLcontextProps(const cl::Platform& plat)
    {
        QVector<cl_context_properties> result;
    
        result.append(CL_CONTEXT_PLATFORM);
        result.append(reinterpret_cast<cl_context_properties>(plat()));
    #ifdef _WIN32
        result.append(CL_WGL_HDC_KHR);
        result.append(reinterpret_cast<cl_context_properties>(m_gl_device.first));
        result.append(CL_GL_CONTEXT_KHR);
        result.append(reinterpret_cast<cl_context_properties>(m_gl_device.second));
    #endif
    #ifdef __linux__
        result.append(CL_GLX_DISPLAY_KHR);
        result.append(reinterpret_cast<cl_context_properties>(m_gl_device.first));
        result.append(CL_GL_CONTEXT_KHR);
        result.append(reinterpret_cast<cl_context_properties>(m_gl_device.second));
    #endif
        result.append(0);
    
       return result;
    }
    

    My questions are:

    • How can I get the include files for QPlatformOpenGLContext that does not have the Qt version in its path? It is really annoying to have to update the source files when I revisit a project with a different Qt version.
    // Qt5 includes
    #include <QtGui>
    #include <QtGui/5.7.0/QtGui/qpa/qplatformnativeinterface.h>
    #include <QtGui/5.7.0/QtGui/qpa/qplatformopenglcontext.h>
    
    • How can I omit the platform native handle types? This would be the very reason I am using Qt in the first place? Ultimately I saw that Qt does not provide any typedefs for these entities. Is there a solution other than me doing it by hand?

    • Can QPA provide the implementations to all of its internals? What module do I have to use? QPA is highly underdocumented. I get linker errors like the following when linking against Qt libs only. If even in the build scripts I have to take of platform specific linkage, plus have to take care of platform specific OpenGL usage, what is the purpose of QPlatformOpenGLContext really?

    InteropWindow.cpp.obj : error LNK2019: unresolved external symbol __imp_wglGetCurrentContext referenced in function "private: struct QPair<struct HDC__ *,struct HGLRC__ *> __cdecl InteropWindow::nativeGLdevice(void)" (?nativeGLdevice@InteropWindow@@AEAA?AU?$QPair@PEAUHDC__@@PEAUHGLRC__@@@@XZ)
    InteropWindow.cpp.obj : error LNK2019: unresolved external symbol __imp_wglGetCurrentDC referenced in function "private: struct QPair<struct HDC__ *,struct HGLRC__ *> __cdecl InteropWindow::nativeGLdevice(void)" (?nativeGLdevice@InteropWindow@@AEAA?AU?$QPair@PEAUHDC__@@PEAUHGLRC__@@@@XZ)
    

    This is how my build script currently looks like:

    cmake_minimum_required (VERSION 3.1)
    
    project (Interop)
    
    set (CMAKE_CXX_STANDARD 11)
    set (CMAKE_AUTOMOC ON)
    
    find_package (Qt5 5.7 CONFIG REQUIRED Gui OpenGL)
    find_package (OpenCL 1.2 REQUIRED)
    
    set (Sources)
    set (Headers)
    set (Kernels)
    set (Shaders)
    
    list (APPEND Sources src/Application.cpp src/InteropWindow.cpp)
    list (APPEND Headers inc/Application.hpp inc/InteropWindow.hpp)
    list (APPEND Kernels src/Interop_kernel.cl)
    list (APPEND Shaders src/Interop_vertex.glsl src/Interop_fragment.glsl)
    
    add_executable(${PROJECT_NAME} ${Sources} ${Headers} ${Kernels} ${Shaders})
    
    target_include_directories (${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR}/inc)
    target_include_directories (${PROJECT_NAME} PUBLIC ${OpenCL_INCLUDE_DIRS})
    
    target_link_libraries (${PROJECT_NAME} ${OpenCL_LIBRARIES})
    
    qt5_use_modules (${PROJECT_NAME} Gui)
    qt5_use_modules (${PROJECT_NAME} OpenGL)
    
    if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
    
    #  target_compile_definitions (${PROJECT_NAME} PUBLIC "/EHsc")
    
      set (MSVC_CXX_COMPILER_FLAGS)
      set (MSVC_CXX_LINKER_FLAGS)
      
        # Enable C++ exception handler unwind semantics
        set (MSVC_CXX_COMPILER_FLAGS "${MSVC_CXX_COMPILER_FLAGS} /EHsc")
        # Disable warnings of having to use dllspec(__import) when using user libraries
        set (MSVC_CXX_COMPILER_FLAGS "${MSVC_CXX_COMPILER_FLAGS} /wd4251")
        # Disable warnings of cl.hpp for finding deprecated OpenCL 1.1 functions, even though they are never used
        set (MSVC_CXX_COMPILER_FLAGS "${MSVC_CXX_COMPILER_FLAGS} /wd4996")
      
        # Disable incremental linking and manifest files for annoying command line errors
        set (MSVC_CXX_LINKER_FLAGS " /INCREMENTAL:NO /MANIFEST:NO /NOLOGO ")
      
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${MSVC_CXX_COMPILER_FLAGS}")
    	
      endif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
    
    

  • Lifetime Qt Champion

    Hi,

    I don't know if there are cmake files for that but IIRC qmake provides the private-qtmodulename to use private headers.

    Note that I'm not sure that the qpa headers are provided through them.

    Hope it helps


Log in to reply