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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.