Update the the eglfs-kms QPA enhancements for
- multiple-display support
- user-interface enhancements

This is the final version for QT5.7.1 and significant changes may be
required for QT5.9 at rocko. Therefore, upstream will not be considered
until then.


Signed-off-by: Eric Ruei <e-ru...@ti.com>
---
 ...nhance-the-QPA-for-multiple-display-and-u.patch | 1380 ++++++++++++++++++++
 recipes-qt/qt5/qtbase_%.bbappend                   |    4 +-
 2 files changed, 1382 insertions(+), 2 deletions(-)
 create mode 100644 
recipes-qt/qt5/qtbase/0001-eglfs_kms-enhance-the-QPA-for-multiple-display-and-u.patch

diff --git 
a/recipes-qt/qt5/qtbase/0001-eglfs_kms-enhance-the-QPA-for-multiple-display-and-u.patch
 
b/recipes-qt/qt5/qtbase/0001-eglfs_kms-enhance-the-QPA-for-multiple-display-and-u.patch
new file mode 100644
index 0000000..2784906
--- /dev/null
+++ 
b/recipes-qt/qt5/qtbase/0001-eglfs_kms-enhance-the-QPA-for-multiple-display-and-u.patch
@@ -0,0 +1,1380 @@
+From 038932af411049c1dc6cbe0dc3f963b9b539efa8 Mon Sep 17 00:00:00 2001
+From: Manisha Agrawal <manisha.agra...@ti.com>
+Date: Tue, 13 Feb 2018 16:36:38 -0600
+Subject: [PATCH] eglfs_kms: enhance the QPA for multiple display and user
+ buffer
+
+Enhance the QPA to support multiple screens and to accept the buffers
+from user application to overlay on QT drawn surface utilizing the
+underneath display IP scaling, overlaying and alphablending feature.
+
+This QPA has following limitations -
+1. It only supports importing user overlay buffer. It doesn't
+suport allocating the buffer for overlay plane inside QPA and exporting to user
+application.
+2. Dynamic creation and destruction of user plane (createPlane,
+distroyPlane) is not supported. Meaning you can create the plane once
+at the start of application and destroy it before exiting the
+application.
+3. There is an API called startDispPlane which will trigger displaying
+of user/overlay plane. There is no corresponding API as stopDispPlane to
+stop displaying of user/overlay plane.
+
+Signed-off-by: Manisha Agrawal <manisha.agra...@ti.com>
+---
+ .../eglfs_kms/qeglfskmsgbmdevice.cpp               |  63 ++++-
+ .../eglfs_kms/qeglfskmsgbmdevice.h                 |  15 +-
+ .../eglfs_kms/qeglfskmsgbmintegration.cpp          | 105 +++++++-
+ .../eglfs_kms/qeglfskmsgbmintegration.h            |  14 +-
+ .../eglfs_kms/qeglfskmsgbmscreen.cpp               | 272 ++++++++++++++++++++-
+ .../eglfs_kms/qeglfskmsgbmscreen.h                 |  38 ++-
+ .../eglfs_kms_support/qeglfskmsdevice.cpp          | 211 +++++++++++++++-
+ .../eglfs_kms_support/qeglfskmsdevice.h            |  16 +-
+ .../eglfs_kms_support/qeglfskmsscreen.h            |   2 +
+ .../platforms/eglfs/qeglfsdeviceintegration.cpp    |  88 +++++++
+ .../platforms/eglfs/qeglfsdeviceintegration.h      |  15 +-
+ src/plugins/platforms/eglfs/qeglfsintegration.cpp  | 106 +++++++-
+ 12 files changed, 895 insertions(+), 50 deletions(-)
+
+diff --git 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
+index 278752bddf..63de320c0f 100644
+--- 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
++++ 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.cpp
+@@ -54,6 +54,31 @@ QT_BEGIN_NAMESPACE
+ 
+ Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
+ 
++class DrmPageFlipHandler : public QThread
++{
++public:
++    DrmPageFlipHandler(QEglFSKmsGbmDevice *gbm_device)
++        : m_abort(false), m_gbm_device(gbm_device)  {}
++    bool m_abort;
++    void run();
++
++private:
++    QEglFSKmsGbmDevice *m_gbm_device;
++};
++
++void DrmPageFlipHandler::run()
++{
++    drmEventContext drmEvent = {
++        DRM_EVENT_CONTEXT_VERSION,
++        Q_NULLPTR,      // vblank handler
++        QEglFSKmsGbmDevice::pageFlipHandler // page flip handler
++    };
++
++    while(m_abort == false){
++        drmHandleEvent(m_gbm_device->fd(), &drmEvent);
++    }
++}
++
+ void QEglFSKmsGbmDevice::pageFlipHandler(int fd, unsigned int sequence, 
unsigned int tv_sec, unsigned int tv_usec, void *user_data)
+ {
+     Q_UNUSED(fd);
+@@ -61,8 +86,17 @@ void QEglFSKmsGbmDevice::pageFlipHandler(int fd, unsigned 
int sequence, unsigned
+     Q_UNUSED(tv_sec);
+     Q_UNUSED(tv_usec);
+ 
+-    QEglFSKmsScreen *screen = static_cast<QEglFSKmsScreen *>(user_data);
+-    screen->flipFinished();
++    QEglFSKmsGbmScreen *screen = static_cast<QEglFSKmsGbmScreen *>(user_data);
++
++    if(screen->m_qpa_flip_call == true){
++        screen->flipFinished();
++    }
++
++    if(screen->m_user_flip_call == true){
++        screen->m_hndl_user_callback(screen->m_user_data);
++    }
++
++    screen->m_flip_event.release(1);
+ }
+ 
+ QEglFSKmsGbmDevice::QEglFSKmsGbmDevice(QEglFSKmsIntegration *integration, 
const QString &path)
+@@ -94,26 +128,40 @@ bool QEglFSKmsGbmDevice::open()
+         return false;
+     }
+ 
++    drmSetClientCap(fd, DRM_CLIENT_CAP_UNIVERSAL_PLANES, 1);
++    drmSetClientCap(fd, DRM_CLIENT_CAP_ATOMIC, 1);
+     setFd(fd);
+ 
++    m_drm_page_flip_handler = new DrmPageFlipHandler(this);
++    m_drm_page_flip_handler->start();
+     return true;
+ }
+ 
+ void QEglFSKmsGbmDevice::close()
+ {
++    // Terminate the device thread
+     if (m_gbm_device) {
+         gbm_device_destroy(m_gbm_device);
+         m_gbm_device = Q_NULLPTR;
+     }
++    m_drm_page_flip_handler->m_abort = true;
++    m_drm_page_flip_handler->wait();
++    delete m_drm_page_flip_handler;
++    m_drm_page_flip_handler = 0;
+ 
+     if (fd() != -1) {
++        drmSetClientCap(fd(), DRM_CLIENT_CAP_UNIVERSAL_PLANES, 0);
++        drmSetClientCap(fd(), DRM_CLIENT_CAP_ATOMIC, 0);
+         qt_safe_close(fd());
++        qWarning("QEglFSKmsGBmDevice::close(): close DRM %d", fd());
+         setFd(-1);
+     }
+ 
+     if (m_globalCursor)
+         m_globalCursor->deleteLater();
+     m_globalCursor = Q_NULLPTR;
++    qWarning("QEglFSKmsGbmDevice::close(): delete global cursor");
++
+ }
+ 
+ EGLNativeDisplayType QEglFSKmsGbmDevice::nativeDisplay() const
+@@ -131,17 +179,6 @@ QPlatformCursor *QEglFSKmsGbmDevice::globalCursor() const
+     return m_globalCursor;
+ }
+ 
+-void QEglFSKmsGbmDevice::handleDrmEvent()
+-{
+-    drmEventContext drmEvent = {
+-        DRM_EVENT_CONTEXT_VERSION,
+-        Q_NULLPTR,      // vblank handler
+-        pageFlipHandler // page flip handler
+-    };
+-
+-    drmHandleEvent(fd(), &drmEvent);
+-}
+-
+ QEglFSKmsScreen *QEglFSKmsGbmDevice::createScreen(QEglFSKmsIntegration 
*integration, QEglFSKmsDevice *device, QEglFSKmsOutput output, QPoint position)
+ {
+     static bool firstScreen = true;
+diff --git 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
+index 6a45f9ffa0..30411dfa9e 100644
+--- 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
++++ 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmdevice.h
+@@ -50,7 +50,7 @@
+ QT_BEGIN_NAMESPACE
+ 
+ class QEglFSKmsScreen;
+-
++class DrmPageFlipHandler;
+ class QEglFSKmsGbmDevice: public QEglFSKmsDevice
+ {
+ public:
+@@ -64,12 +64,15 @@ public:
+ 
+     QPlatformCursor *globalCursor() const;
+ 
+-    void handleDrmEvent();
+-
+     virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration,
+                                           QEglFSKmsDevice *device,
+                                           QEglFSKmsOutput output,
+                                           QPoint position) Q_DECL_OVERRIDE;
++    static void pageFlipHandler(int fd,
++                                unsigned int sequence,
++                                unsigned int tv_sec,
++                                unsigned int tv_usec,
++                                void *user_data);
+ 
+ private:
+     Q_DISABLE_COPY(QEglFSKmsGbmDevice)
+@@ -78,11 +81,7 @@ private:
+ 
+     QEglFSKmsGbmCursor *m_globalCursor;
+ 
+-    static void pageFlipHandler(int fd,
+-                                unsigned int sequence,
+-                                unsigned int tv_sec,
+-                                unsigned int tv_usec,
+-                                void *user_data);
++    DrmPageFlipHandler *m_drm_page_flip_handler;
+ };
+ 
+ QT_END_NAMESPACE
+diff --git 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
+index 1c0a8e1b5f..b1f64c2992 100644
+--- 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
++++ 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.cpp
+@@ -59,7 +59,7 @@
+ #include <gbm.h>
+ 
+ QT_BEGIN_NAMESPACE
+-
++Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
+ QMutex QEglFSKmsGbmScreen::m_waitForFlipMutex;
+ 
+ QEglFSKmsGbmIntegration::QEglFSKmsGbmIntegration()
+@@ -140,4 +140,107 @@ QEglFSKmsDevice 
*QEglFSKmsGbmIntegration::createDevice(const QString &devicePath
+     return new QEglFSKmsGbmDevice(this, path);
+ }
+ 
++int QEglFSKmsGbmIntegration::exportBuffer(const QScreen *screen, uint32_t 
width, uint32_t height,
++                                          uint32_t pixel_format, uint32_t 
*strides, uint32_t *offsets, 
++                                          uint32_t buf_fd, uint32_t *buf_id)
++{
++    if(device())
++    {
++        QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen 
*>(screen->handle());
++        return (gbmScreen->addOverlayBuffer(width, 
++            height, pixel_format, strides, offsets, buf_fd, buf_id));
++    }
++
++    return -1;
++}
++
++int QEglFSKmsGbmIntegration::distroyBuffer(const QScreen *screen, uint32_t 
buf_id)
++{
++    if(device())
++    {
++        QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen 
*>(screen->handle());
++        return (gbmScreen->removeOverlayBuffer(buf_id));
++    }
++
++    return -1;
++}
++
++int QEglFSKmsGbmIntegration::setPlaneProperties(const QScreen *screen, 
++                                                uint8_t planeType, uint8_t 
idx, uint8_t num_prop, 
++                                                const char **propName, 
uint32_t *propVal)
++{
++    if(device())
++    {
++        QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen 
*>(screen->handle());
++        return(gbmScreen->setPlaneProperties(planeType, idx, num_prop, 
propName, propVal));
++    }
++
++    return -1;
++}
++
++int QEglFSKmsGbmIntegration::getPlaneProperty(const QScreen *screen, 
++                                              uint8_t planeType, uint8_t idx, 
const char *propName)
++{
++    if(device())
++    {
++        QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen 
*>(screen->handle());
++        return(gbmScreen->getPlaneProperty(planeType, idx, propName));
++    }
++
++    return -1;
++}
++
++int QEglFSKmsGbmIntegration::createPlane(const QScreen *screen)
++{
++    if(device())
++    {
++        QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen 
*>(screen->handle());
++        return(gbmScreen->createOverlayPlane());              
++    }
++    return -1;
++}
++
++int QEglFSKmsGbmIntegration::distroyPlane(const QScreen *screen, int planeId)
++{
++    if(device())
++    {
++        QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen 
*>(screen->handle());
++        return(gbmScreen->distroyOverlayPlane(planeId));              
++    }
++    return -1;
++}
++
++int QEglFSKmsGbmIntegration::queuePlane(QScreen *screen,
++                                        uint32_t idx, uint32_t fbId)
++{
++    if(device())
++    {
++        QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen 
*>(screen->handle());
++        return(gbmScreen->queueOverlayPlane(idx, fbId));
++    }
++    return -1;
++}
++
++int QEglFSKmsGbmIntegration::startDispPlane(QScreen *screen)
++{
++    if(device())
++    {
++        QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen 
*>(screen->handle());
++        return(gbmScreen->startDispOverlayPlane());
++    }
++    return -1;
++}
++
++int QEglFSKmsGbmIntegration::userCallBackHandle(QScreen *screen,  void 
(*hndlUserCallBack)(void *), void *userData)
++{
++    if(device())
++    {
++        QEglFSKmsGbmScreen *gbmScreen = static_cast<QEglFSKmsGbmScreen 
*>(screen->handle());
++              gbmScreen->m_hndl_user_callback = hndlUserCallBack;
++              gbmScreen->m_user_data = userData;
++        return 0;
++    }
++    return -1;
++}
++
+ QT_END_NAMESPACE
+diff --git 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h
 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h
+index 727571d3e3..86cf16c6f5 100644
+--- 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h
++++ 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmintegration.h
+@@ -45,7 +45,6 @@
+ #include "qeglfskmsintegration.h"
+ #include <QtCore/QMap>
+ #include <QtCore/QVariant>
+-
+ QT_BEGIN_NAMESPACE
+ 
+ class QEglFSKmsDevice;
+@@ -63,6 +62,19 @@ public:
+ 
+     QPlatformCursor *createCursor(QPlatformScreen *screen) const 
Q_DECL_OVERRIDE;
+     void presentBuffer(QPlatformSurface *surface) Q_DECL_OVERRIDE;
++    int exportBuffer(const QScreen *screen, uint32_t width,
++        uint32_t height, uint32_t pixel_format,       uint32_t *strides,
++        uint32_t *offsets, uint32_t buf_fd, uint32_t *buf_id) Q_DECL_OVERRIDE;
++    int distroyBuffer(const QScreen *screen,uint32_t buf_id) Q_DECL_OVERRIDE;
++    int setPlaneProperties(const QScreen *screen, uint8_t planeType,
++        uint8_t idx, uint8_t numProp, const char **propName, uint32_t 
*propVal) Q_DECL_OVERRIDE;
++    int getPlaneProperty(const QScreen *screen, uint8_t planeType,
++        uint8_t idx, const char *propName) Q_DECL_OVERRIDE;
++    int createPlane(const QScreen *screen) Q_DECL_OVERRIDE;
++    int distroyPlane(const QScreen *screen, int planeId) Q_DECL_OVERRIDE;
++    int queuePlane(QScreen *screen, uint32_t idx, uint32_t fbId) 
Q_DECL_OVERRIDE;
++    int startDispPlane(QScreen *screen) Q_DECL_OVERRIDE;
++    int userCallBackHandle(QScreen *screen, void (*fnPtr)(void *), void 
*data) Q_DECL_OVERRIDE;
+ 
+ protected:
+     QEglFSKmsDevice *createDevice(const QString &devicePath) Q_DECL_OVERRIDE;
+diff --git 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
+index 7a17b60a5e..25ed63f4a8 100644
+--- 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
++++ 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.cpp
+@@ -49,10 +49,26 @@
+ #include <QtGui/private/qguiapplication_p.h>
+ #include <QtPlatformSupport/private/qfbvthandler_p.h>
+ 
++#include <QMutex>
++#include <string.h>
++
+ QT_BEGIN_NAMESPACE
+ 
+ Q_DECLARE_LOGGING_CATEGORY(qLcEglfsKmsDebug)
+ 
++class DrmPageFlip : public QThread
++{
++
++public:
++    DrmPageFlip(QEglFSKmsGbmScreen *screen)
++        : m_abort(false), m_gbm_screen(screen) {}
++    bool m_abort;
++    void run();
++
++private:
++    QEglFSKmsGbmScreen *m_gbm_screen;
++};
++
+ void QEglFSKmsGbmScreen::bufferDestroyedHandler(gbm_bo *bo, void *data)
+ {
+     FrameBuffer *fb = static_cast<FrameBuffer *>(data);
+@@ -97,15 +113,118 @@ 
QEglFSKmsGbmScreen::QEglFSKmsGbmScreen(QEglFSKmsIntegration *integration,
+                                  QEglFSKmsOutput output,
+                                  QPoint position)
+     : QEglFSKmsScreen(integration, device, output, position)
++    , m_qpa_flip_call(false)
++    , m_user_flip_call(false)
++      , m_start_flip_overlay_plane(false)
+     , m_gbm_surface(Q_NULLPTR)
+     , m_gbm_bo_current(Q_NULLPTR)
+     , m_gbm_bo_next(Q_NULLPTR)
+     , m_cursor(Q_NULLPTR)
++    , m_flip_primary_plane(false)
++    , m_plane_id{0}
++    , m_plane_idx(0)
++    , m_primary_plane_fb(0)
+ {
++    m_drm_page_flip = new DrmPageFlip(this);
++    m_drm_page_flip->start();
+ }
+ 
+ QEglFSKmsGbmScreen::~QEglFSKmsGbmScreen()
+ {
++    m_drm_page_flip->m_abort = true;
++    m_drm_page_flip->wait();
++    delete m_drm_page_flip;
++    m_drm_page_flip = 0;
++}
++
++/* This thread periodically cheks if there is any user submitted buffer for 
++overlay with primary plane or if QT has drawn new surface (primary plane)
++to be displayed. In any or both of the case, this thread will do atomic 
++submission of the new framebuffer id to the DRM device for display.
++Access to overlay plane queue and primary plane resources are Mutex protected
++with respective threads. 
++*/
++void DrmPageFlip::run(){
++    while(m_abort == false){
++        drmModeAtomicReqPtr req = drmModeAtomicAlloc();
++        bool commit_overlay_plane = false;
++        bool commit_primary_plane = false;
++        uint32_t primary_plane_fb_id;
++        int ret = -1;
++
++        m_gbm_screen->m_primary_mutex.lock();
++        commit_primary_plane = m_gbm_screen->m_flip_primary_plane;
++        primary_plane_fb_id = m_gbm_screen->m_primary_plane_fb; 
++        m_gbm_screen->m_flip_primary_plane = false;
++        m_gbm_screen->m_primary_mutex.unlock();
++
++        if(commit_primary_plane == true){
++            if((ret = drmModeAtomicAddProperty(req, 
m_gbm_screen->m_output.primary_plane_id,
++                m_gbm_screen->device()->m_prop_fbId, primary_plane_fb_id)) < 
0){
++                    qWarning("failed to add property with error code = %d\n", 
ret);
++            }
++        }
++
++        //Check for any new buffer queued by user application
++        if(m_gbm_screen->m_start_flip_overlay_plane == true){
++            m_gbm_screen->m_overlay_mutex.lock();
++            for(uint32_t i = 0 ; i < m_gbm_screen->m_plane_idx; i++){
++                if (!m_gbm_screen->overlayPlaneFbIdQueue[i].isEmpty()){
++                    uint32_t planeId = m_gbm_screen->m_plane_id[i];
++                    uint32_t fbId = 
m_gbm_screen->overlayPlaneFbIdQueue[i].dequeue();
++                    if((ret = drmModeAtomicAddProperty(req, planeId, 
m_gbm_screen->device()->m_prop_fbId, fbId)) < 0){
++                        qWarning("failed to add property with error code = 
%d\n", ret);
++                    }
++                    commit_overlay_plane = true;
++                }
++            }
++            m_gbm_screen->m_overlay_mutex.unlock();
++        }
++
++        if((commit_primary_plane == true) ||  (commit_overlay_plane == 
true)){            
++            ret = drmModeAtomicCommit(m_gbm_screen->device()->fd(), req,
++                DRM_MODE_ATOMIC_TEST_ONLY, 0);
++
++            if(!ret){
++                if(commit_overlay_plane == true){
++                    m_gbm_screen->m_user_flip_call = true;
++                }
++
++                if(commit_primary_plane == true){
++                    m_gbm_screen->m_qpa_flip_call = true;
++                }                
++
++                drmModeAtomicCommit(m_gbm_screen->device()->fd(), req,
++                    DRM_MODE_PAGE_FLIP_EVENT | DRM_MODE_ATOMIC_NONBLOCK, 
m_gbm_screen);
++
++                //sleeping for 5 msec, assuming that display is not running 
at more than 120 fps
++                msleep(5);
++                while(m_gbm_screen->m_flip_event.tryAcquire(1) == false){
++                    usleep(500);
++                }
++                m_gbm_screen->m_qpa_flip_call = false;
++                m_gbm_screen->m_user_flip_call = false;
++
++                msleep(1);
++            }
++            else {
++                if(m_gbm_screen->m_qpa_flip_call == true){
++                    qErrnoWarning("Could not queue DRM page flip!");
++                    gbm_surface_release_buffer(m_gbm_screen->m_gbm_surface, 
m_gbm_screen->m_gbm_bo_next);
++                    m_gbm_screen->m_gbm_bo_next = Q_NULLPTR;
++                }
++
++                if(commit_overlay_plane == true){
++                    qErrnoWarning("Could not page flip user overlay plane!");
++                    
m_gbm_screen->m_hndl_user_callback(m_gbm_screen->m_user_data);
++                }
++            }
++        }
++        else{
++            msleep(1);
++        }
++        drmModeAtomicFree(req);
++    }
+ }
+ 
+ QPlatformCursor *QEglFSKmsGbmScreen::cursor() const
+@@ -159,12 +278,15 @@ void QEglFSKmsGbmScreen::destroySurface()
+ void QEglFSKmsGbmScreen::waitForFlip()
+ {
+     // Don't lock the mutex unless we actually need to
++
+     if (!m_gbm_bo_next)
+         return;
+ 
+     QMutexLocker lock(&m_waitForFlipMutex);
+-    while (m_gbm_bo_next)
+-        static_cast<QEglFSKmsGbmDevice *>(device())->handleDrmEvent();
++    while (m_gbm_bo_next){
++        usleep(200);
++    }
++
+ }
+ 
+ void QEglFSKmsGbmScreen::flip()
+@@ -175,6 +297,7 @@ void QEglFSKmsGbmScreen::flip()
+     }
+ 
+     m_gbm_bo_next = gbm_surface_lock_front_buffer(m_gbm_surface);
++
+     if (!m_gbm_bo_next) {
+         qWarning("Could not lock GBM surface front buffer!");
+         return;
+@@ -191,23 +314,18 @@ void QEglFSKmsGbmScreen::flip()
+                                  &output().modes[output().mode]);
+ 
+         if (ret) {
+-            qErrnoWarning("Could not set DRM mode!");
++            qErrnoWarning("Could not set DRM (%d) CRTC (%d) mode!", 
device()->fd(), output().crtc_id);
++
+         } else {
+             output().mode_set = true;
+             setPowerState(PowerStateOn);
+         }
+     }
+ 
+-    int ret = drmModePageFlip(device()->fd(),
+-                              output().crtc_id,
+-                              fb->fb,
+-                              DRM_MODE_PAGE_FLIP_EVENT,
+-                              this);
+-    if (ret) {
+-        qErrnoWarning("Could not queue DRM page flip!");
+-        gbm_surface_release_buffer(m_gbm_surface, m_gbm_bo_next);
+-        m_gbm_bo_next = Q_NULLPTR;
+-    }
++    m_primary_mutex.lock();
++    m_primary_plane_fb = fb->fb;
++    m_flip_primary_plane = true;
++    m_primary_mutex.unlock();
+ }
+ 
+ void QEglFSKmsGbmScreen::flipFinished()
+@@ -220,4 +338,132 @@ void QEglFSKmsGbmScreen::flipFinished()
+     m_gbm_bo_next = Q_NULLPTR;
+ }
+ 
++int QEglFSKmsGbmScreen::addOverlayBuffer(uint32_t width, 
++                                         uint32_t height,
++                                         uint32_t pixel_format,
++                                         uint32_t *strides,
++                                         uint32_t *offsets,
++                                         uint32_t buf_fd,
++                                         uint32_t *buf_id)
++{
++    /* Get the buffer handle from the exported buffer fd */
++    uint32_t bo_handle;
++    drmPrimeFDToHandle(m_device->fd(), buf_fd, &bo_handle);
++    int ret = drmModeAddFB2(m_device->fd(), width, height, pixel_format, 
&bo_handle,\
++        strides, offsets, buf_id, 0);
++
++    if (ret) {
++              qWarning() << "addOverlayBuffer: drmModeAddFB2 failed:" << 
strerror(errno) << ret;
++        return -1;
++    }
++    return ret;
++}
++
++int QEglFSKmsGbmScreen::removeOverlayBuffer(uint32_t buf_id)
++{
++    int ret = drmModeRmFB(m_device->fd(), buf_id);
++
++    if (ret) {
++              qWarning() << "removeOverlayBuffer: drmModeRmFB failed:" << 
strerror(errno) << ret;
++        return -1;
++    }
++    return ret;
++}
++
++int QEglFSKmsGbmScreen::setPlaneProperties(uint8_t planeType, uint8_t idx,
++                                           uint8_t numProp, const char 
**propName, uint32_t *propVal)
++{
++    uint32_t planeId, crtcId;
++    uint32_t objectType;
++    crtcId = m_output.crtc_id;
++    
++      if (idx > MAX_NUM_PLANES){
++              qWarning("queueOverlayPlane: invalid plane index\n");
++              return -1;
++    }
++
++    if(planeType == DRM_PLANE_TYPE_OVERLAY){
++        planeId = m_plane_id[idx];
++        objectType = DRM_MODE_OBJECT_PLANE;
++    }
++    else if(planeType == DRM_PLANE_TYPE_PRIMARY){
++        objectType = DRM_MODE_OBJECT_CRTC;
++        planeId = crtcId;
++    }
++    else{
++              qWarning() << "setPlaneProperties: invalid plane type";
++        return -1;
++    }
++    return m_device->setPlaneProperties(objectType, crtcId, planeId, numProp, 
propName, propVal);
++}
++
++int QEglFSKmsGbmScreen::getPlaneProperty(uint8_t planeType, uint8_t idx, 
const char *propName)
++{
++    uint32_t planeId, crtcId;
++    uint32_t objectType;
++    crtcId = m_output.crtc_id;
++    
++      if (idx > MAX_NUM_PLANES){
++              qWarning("queueOverlayPlane: invalid plane index\n");
++              return -1;
++    }
++
++    if(planeType == DRM_PLANE_TYPE_OVERLAY){
++        planeId = m_plane_id[idx];
++        objectType = DRM_MODE_OBJECT_PLANE;
++    }
++    else if(planeType == DRM_PLANE_TYPE_PRIMARY){
++        objectType = DRM_MODE_OBJECT_CRTC;
++        planeId = crtcId;
++    }
++    else{
++              qWarning() << "getPlaneProperty: invalid plane type";
++        return -1;
++    }
++    return m_device->getPlaneProperty(objectType, planeId, propName);
++}
++
++int QEglFSKmsGbmScreen::createOverlayPlane()
++{
++    int planeId = m_device->getPlane(0, DRM_PLANE_TYPE_OVERLAY);
++    if (planeId > 0){
++        uint8_t pcnt = m_plane_idx++;
++        if(pcnt > MAX_NUM_PLANES){
++                      qWarning() << "createOverlayPlane: Don't support number 
of planes greater then" <<  MAX_NUM_PLANES;
++        }
++        m_plane_id[pcnt] = planeId;
++        return pcnt;
++    }
++    else {
++        qWarning() << "createOverlayPlane: cannot find free plane";
++        return -1;
++    }
++}
++
++int QEglFSKmsGbmScreen::distroyOverlayPlane(int pcnt)
++{
++    int planeId = m_plane_id[pcnt];
++    Q_UNUSED(planeId);
++    //nothing to be done to distroy the plane
++    return 0;
++}
++
++int QEglFSKmsGbmScreen::queueOverlayPlane(uint32_t idx, uint32_t fbId)
++{
++    if (idx > MAX_NUM_PLANES){
++        qWarning("queueOverlayPlane: invalid plane index\n");
++        return -1;
++    }
++    m_overlay_mutex.lock();
++    overlayPlaneFbIdQueue[idx].enqueue(fbId);
++    m_overlay_mutex.unlock();
++    return 0;
++}
++
++int QEglFSKmsGbmScreen::startDispOverlayPlane()
++{
++    m_start_flip_overlay_plane = true;
++    return 0;
++}
++
+ QT_END_NAMESPACE
+diff --git 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
+index 3381bbfdbb..d2915c40a7 100644
+--- 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
++++ 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsgbmscreen.h
+@@ -44,12 +44,15 @@
+ 
+ #include "qeglfskmsscreen.h"
+ #include <QtCore/QMutex>
++#include <QtCore/QSemaphore>
++#include <QtCore/QQueue>
+ 
+ #include <gbm.h>
+-
+ QT_BEGIN_NAMESPACE
+ 
+ class QEglFSKmsGbmCursor;
++class DrmPageFlip;
++typedef void (*m_fnptr_user_callback)(void *data);
+ 
+ class QEglFSKmsGbmScreen : public QEglFSKmsScreen
+ {
+@@ -70,6 +73,30 @@ public:
+     void flip() Q_DECL_OVERRIDE;
+     void flipFinished() Q_DECL_OVERRIDE;
+ 
++    int addOverlayBuffer(uint32_t width,
++        uint32_t height,
++        uint32_t pixel_format,
++        uint32_t *strides,
++        uint32_t *offsets,
++        uint32_t buf_fd,
++        uint32_t *buf_id);
++    int removeOverlayBuffer(uint32_t buf_id);
++    int setPlaneProperties(uint8_t planeType, uint8_t idx,
++        uint8_t numProp, const char **propName, uint32_t *propVal);
++    int getPlaneProperty(uint8_t planeType, uint8_t idx, const char 
*propName);
++    int createOverlayPlane();
++    int distroyOverlayPlane(int pcnt);
++    int queueOverlayPlane(uint32_t idx, uint32_t fbId);
++    int startDispOverlayPlane();
++    m_fnptr_user_callback m_hndl_user_callback;
++    void *m_user_data;
++    bool m_qpa_flip_call;
++    bool m_user_flip_call;
++    bool m_start_flip_overlay_plane;
++    QMutex m_flip_mutex;
++    QSemaphore m_flip_event;
++    friend class DrmPageFlip;
++
+ private:
+     gbm_surface *m_gbm_surface;
+ 
+@@ -86,6 +113,15 @@ private:
+     FrameBuffer *framebufferForBufferObject(gbm_bo *bo);
+ 
+     static QMutex m_waitForFlipMutex;
++
++    bool m_flip_primary_plane;
++    QMutex m_overlay_mutex;
++    QMutex m_primary_mutex;
++    QQueue<uint32_t> overlayPlaneFbIdQueue[MAX_NUM_PLANES];
++    uint32_t m_plane_id[MAX_NUM_PLANES];
++    uint8_t m_plane_idx;
++    uint32_t m_primary_plane_fb;
++    DrmPageFlip *m_drm_page_flip;
+ };
+ 
+ QT_END_NAMESPACE
+diff --git 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp
 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp
+index f4ffee569d..6dbe84202b 100644
+--- 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp
++++ 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.cpp
+@@ -62,6 +62,180 @@ enum OutputConfiguration {
+     OutputConfigModeline
+ };
+ 
++
++int QEglFSKmsDevice::getDrmPropId(drmModeObjectPropertiesPtr props,
++                                  const char *name, uint32_t *propId)
++{
++    drmModePropertyPtr p;
++    unsigned int i;
++    *propId = 0;/* Property ID should always be > 0 */
++
++    for (i = 0; i < props->count_props; i++) {
++        p = drmModeGetProperty(m_dri_fd, props->props[i]);
++        if (!strcmp(p->name, name)){
++            *propId = p->prop_id;
++            break;
++        }
++        drmModeFreeProperty(p);
++    }
++    if (!*propId) {
++        qWarning() << "getDrmPropId: Could not find" <<  name << "property";
++        return(-1);
++    }
++
++    return i;
++}
++
++int QEglFSKmsDevice::setPlaneProperties(uint32_t objectType, uint32_t crtcId, 
++                                        uint32_t planeId, uint8_t num_prop, 
const char **propName,
++                                        uint32_t *propVal)
++{
++    int ret, i;
++    uint32_t objectId;
++    if(objectType == DRM_MODE_OBJECT_PLANE){
++        objectId = planeId;
++    }
++    else{
++        objectId = crtcId;
++    }
++    drmModeObjectProperties   *props = drmModeObjectGetProperties(m_dri_fd, 
objectId,
++        objectType);
++
++    if(props == NULL){
++        qWarning() << "setPlaneProperties: drm object properties for 
objectId" << objectId << "is NULL";
++        return (-1);
++    }
++
++    drmModeAtomicReqPtr req = drmModeAtomicAlloc();
++    uint32_t propId;
++
++    for(i = 0; i < num_prop; i++)
++    {
++        if (getDrmPropId(props, propName[i], &propId) < 0){
++            qWarning() << "setPlaneProperties: failed to get the DRM property 
id for " <<  propName[i];
++            goto error_exit;
++        }
++        if(drmModeAtomicAddProperty(req, objectId, propId, propVal[i]) < 0){
++            qWarning() << "setPlaneProperties: failed to add DRM property 
for" << propName[i];
++            goto error_exit;
++        }
++    }
++
++    if(objectType == DRM_MODE_OBJECT_PLANE){
++        if(getDrmPropId(props, "CRTC_ID", &propId) < 0){
++            qWarning() << "setPlaneProperties: failed to get the DRM property 
id for CRTC_ID";
++            goto error_exit;
++        }
++        if(drmModeAtomicAddProperty(req, planeId, propId, crtcId) < 0){
++            qWarning() << "setPlaneProperties: failed to add DRM property for 
CRTC_ID";
++            goto error_exit;
++        }
++    }
++
++    ret = drmModeAtomicCommit(m_dri_fd, req, DRM_MODE_ATOMIC_TEST_ONLY, 0);
++
++    if(!ret){
++        drmModeAtomicCommit(m_dri_fd, req, 0, 0);
++    }
++    else{
++        qWarning() << "setPlaneProperties: ret from drmModeAtomicCommit = " 
<<  ret;
++        goto error_exit;
++    }
++
++    drmModeAtomicFree(req);
++    drmModeFreeObjectProperties(props);
++    return 0;
++
++error_exit:
++    drmModeAtomicFree(req);
++    drmModeFreeObjectProperties(props);
++    return -1;
++}
++
++int QEglFSKmsDevice::getPlaneProperty(uint32_t objectType, uint32_t planeId, 
++                                      const char *propName)
++{
++    uint32_t propId;
++    int propVal = -1, propIndx;
++
++    drmModeObjectProperties   *props = drmModeObjectGetProperties(m_dri_fd, 
planeId,
++        objectType);
++
++    if(props == NULL){
++        qWarning() << "getPlaneProperty: drm obeject properties for plane 
type is NULL\n";
++        return (-1);
++    }
++
++    propIndx = getDrmPropId(props, propName, &propId);
++
++    if(propIndx >= 0){
++        propVal = props->prop_values[propIndx];
++    }
++    else{
++        qWarning() << "getPlaneProperty: Couldn't get DRM plane property for" 
<< *propName;
++        return -1;
++    }
++    drmModeFreeObjectProperties(props);
++
++    return propVal;
++}
++
++int QEglFSKmsDevice::getPlane(uint32_t crtc_id, uint8_t planeType)
++{
++    uint32_t i;
++    drmModeObjectProperties *props;
++    drmModePlaneRes *res = drmModeGetPlaneResources(m_dri_fd);
++
++    if(res == NULL){
++        qWarning() << "plane resources not found\n";
++        return -1;
++    }
++
++    for (i = 0; i < res->count_planes; i++) {
++        uint32_t planeId = res->planes[i];
++        unsigned int typeVal;
++
++        drmModePlane *plane = drmModeGetPlane(m_dri_fd, planeId);
++        if(plane == NULL){
++            qWarning() << "getPlane: Plane not found";
++            goto error_exit;
++        }
++
++        props = drmModeObjectGetProperties(m_dri_fd, plane->plane_id, 
DRM_MODE_OBJECT_PLANE);
++
++        if(props == NULL){
++            qWarning() << "getPlane: plane (%d) properties not found\n" << 
plane->plane_id;
++            drmModeFreePlane(plane);
++            goto error_exit;
++        }
++
++        typeVal = getPlaneProperty(DRM_MODE_OBJECT_PLANE, plane->plane_id, 
"type");
++
++        drmModeFreeObjectProperties(props);
++        drmModeFreePlane(plane);
++
++        if(typeVal == planeType){
++            if(planeType == DRM_PLANE_TYPE_PRIMARY){
++                if((plane->crtc_id == crtc_id) || (!plane->crtc_id)){
++                    plane->crtc_id = crtc_id;
++                    drmModeFreePlaneResources(res);
++                    return planeId;
++                }
++            }
++            else if (!(m_plane_allocator & ((quint64)1<<planeId))){
++                m_plane_allocator |= ((quint64)1 << planeId);
++                drmModeFreePlaneResources(res);
++                return planeId;
++            }
++        }
++    }
++
++    qWarning("getPlane: Plane for crtc %d not found", crtc_id);
++error_exit:
++    drmModeFreePlaneResources(res);
++    return -1;
++}
++
+ int QEglFSKmsDevice::crtcForConnector(drmModeResPtr resources, 
drmModeConnectorPtr connector)
+ {
+     for (int i = 0; i < connector->count_encoders; i++) {
+@@ -159,6 +333,7 @@ static bool parseModeline(const QByteArray &text, 
drmModeModeInfoPtr mode)
+     return true;
+ }
+ 
++
+ QEglFSKmsScreen *QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, 
drmModeConnectorPtr connector, QPoint pos)
+ {
+     const QByteArray connectorName = nameForConnector(connector);
+@@ -172,6 +347,7 @@ QEglFSKmsScreen 
*QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr
+     OutputConfiguration configuration;
+     QSize configurationSize;
+     drmModeModeInfo configurationModeline;
++    int plane_id;
+ 
+     const QByteArray mode = 
m_integration->outputSettings().value(QString::fromUtf8(connectorName))
+             .value(QStringLiteral("mode"), 
QStringLiteral("preferred")).toByteArray().toLower();
+@@ -268,14 +444,14 @@ QEglFSKmsScreen 
*QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr
+ 
+     int selected_mode = -1;
+ 
+-    if (configured >= 0)
+-        selected_mode = configured;
++    if (current >= 0)
++        selected_mode = current;
+     else if (preferred >= 0)
+         selected_mode = preferred;
+-    else if (current >= 0)
+-        selected_mode = current;
+     else if (best >= 0)
+         selected_mode = best;
++    else if (configured >= 0)
++        selected_mode = configured;
+ 
+     if (selected_mode < 0) {
+         qWarning() << "No modes available for output" << connectorName;
+@@ -287,6 +463,13 @@ QEglFSKmsScreen 
*QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr
+         qCDebug(qLcEglfsKmsDebug) << "Selected mode" << selected_mode << ":" 
<< width << "x" << height
+                                   << '@' << refresh << "hz for output" << 
connectorName;
+     }
++    
++    plane_id = getPlane(crtc_id, DRM_PLANE_TYPE_PRIMARY);
++
++    if(plane_id < 0){
++        return Q_NULLPTR;
++    }
++
+     static const int width = 
qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_WIDTH");
+     static const int height = 
qEnvironmentVariableIntValue("QT_QPA_EGLFS_PHYSICAL_HEIGHT");
+     QSizeF size(width, height);
+@@ -304,12 +487,26 @@ QEglFSKmsScreen 
*QEglFSKmsDevice::screenForConnector(drmModeResPtr resources, dr
+         drmModeGetCrtc(m_dri_fd, crtc_id),
+         modes,
+         connector->subpixel,
+-        connectorProperty(connector, QByteArrayLiteral("DPMS"))
++        connectorProperty(connector, QByteArrayLiteral("DPMS")),
++        plane_id
+     };
+ 
+     m_crtc_allocator |= (1 << output.crtc_id);
+     m_connector_allocator |= (1 << output.connector_id);
+ 
++    drmModeObjectProperties   *props = drmModeObjectGetProperties(m_dri_fd, 
plane_id,
++        DRM_MODE_OBJECT_PLANE);
++    if(props == NULL){
++              qWarning() << "drm object properties for planeId:" << plane_id 
<< "is NULL";
++        return NULL;
++    }
++
++    if(getDrmPropId(props, "FB_ID", &m_prop_fbId) < 0){
++        drmModeFreeObjectProperties(props);
++        qWarning() << "Couldn't get DRM property id for FB_ID";
++        return NULL;
++    }
++    drmModeFreeObjectProperties(props);
+     return createScreen(m_integration, this, output, pos);
+ }
+ 
+@@ -330,11 +527,13 @@ drmModePropertyPtr 
QEglFSKmsDevice::connectorProperty(drmModeConnectorPtr connec
+ }
+ 
+ QEglFSKmsDevice::QEglFSKmsDevice(QEglFSKmsIntegration *integration, const 
QString &path)
+-    : m_integration(integration)
++    : m_prop_fbId(0)
++    , m_integration(integration)
+     , m_path(path)
+     , m_dri_fd(-1)
+     , m_crtc_allocator(0)
+     , m_connector_allocator(0)
++    , m_plane_allocator(0)
+ {
+ }
+ 
+diff --git 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
+index 041c063695..d0e52b8476 100644
+--- 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
++++ 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsdevice.h
+@@ -47,7 +47,6 @@
+ 
+ #include <xf86drm.h>
+ #include <xf86drmMode.h>
+-
+ QT_BEGIN_NAMESPACE
+ 
+ class Q_EGLFS_EXPORT QEglFSKmsDevice
+@@ -65,6 +64,13 @@ public:
+     int fd() const;
+     QString devicePath() const;
+ 
++    int setPlaneProperties(uint32_t objectType, uint32_t crtcId, uint32_t 
planeId, 
++        uint8_t numProp, const char **propName, uint32_t *propVal);
++    int getPlaneProperty(uint32_t objectType, uint32_t planeId, 
++        const char *propName);
++    int getPlane(uint32_t crtcId, uint8_t planeType);
++    uint32_t m_prop_fbId;
++
+ protected:
+     virtual QEglFSKmsScreen *createScreen(QEglFSKmsIntegration *integration,
+                                           QEglFSKmsDevice *device,
+@@ -76,9 +82,9 @@ protected:
+     QString m_path;
+     int m_dri_fd;
+ 
+-    quint32 m_crtc_allocator;
+-    quint32 m_connector_allocator;
+-
++    quint64 m_crtc_allocator;
++    quint64 m_connector_allocator;
++    quint64 m_plane_allocator;
+     int crtcForConnector(drmModeResPtr resources, drmModeConnectorPtr 
connector);
+     QEglFSKmsScreen *screenForConnector(drmModeResPtr resources, 
drmModeConnectorPtr connector, QPoint pos);
+     drmModePropertyPtr connectorProperty(drmModeConnectorPtr connector, const 
QByteArray &name);
+@@ -90,6 +96,8 @@ protected:
+                                 void *user_data);
+ 
+ private:
++    int getDrmPropId(drmModeObjectPropertiesPtr props,
++        const char *name, unsigned int *propId);
+     Q_DISABLE_COPY(QEglFSKmsDevice)
+ };
+ 
+diff --git 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
+index aa698e1b5d..d75b06945e 100644
+--- 
a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
++++ 
b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms_support/qeglfskmsscreen.h
+@@ -55,6 +55,7 @@ QT_BEGIN_NAMESPACE
+ class QEglFSKmsDevice;
+ class QEglFSKmsInterruptHandler;
+ 
++#define MAX_NUM_PLANES 10
+ struct QEglFSKmsOutput
+ {
+     QString name;
+@@ -67,6 +68,7 @@ struct QEglFSKmsOutput
+     QList<drmModeModeInfo> modes;
+     int subpixel;
+     drmModePropertyPtr dpms_prop;
++    uint32_t primary_plane_id;
+ };
+ 
+ class Q_EGLFS_EXPORT QEglFSKmsScreen : public QEglFSScreen
+diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp 
b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp
+index fc41dc5643..3c2ee3db5a 100644
+--- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp
++++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp
+@@ -345,4 +345,92 @@ void *QEGLDeviceIntegration::wlDisplay() const
+     return Q_NULLPTR;
+ }
+ 
++
++int QEGLDeviceIntegration::exportBuffer(const QScreen *screen, uint32_t 
width, uint32_t height,
++                                        uint32_t pixel_format, uint32_t 
*strides, uint32_t *offsets,
++                                        uint32_t buf_fd, uint32_t *bufId)
++{
++    Q_UNUSED(screen);
++    Q_UNUSED(width);
++    Q_UNUSED(height);
++    Q_UNUSED(pixel_format);
++    Q_UNUSED(strides);
++    Q_UNUSED(offsets);
++    Q_UNUSED(buf_fd);
++    Q_UNUSED(bufId);
++
++    return -1;
++}
++
++int QEGLDeviceIntegration::distroyBuffer(const QScreen *screen, uint32_t 
bufId)
++{
++    Q_UNUSED(screen)
++        Q_UNUSED(bufId);
++
++    return -1;
++}
++
++int QEGLDeviceIntegration::setPlaneProperties(const QScreen *screen, 
++                                              uint8_t planeType, uint8_t idx, 
uint8_t numProp,
++                                              const char **propName, uint32_t 
*propVal)
++{
++    Q_UNUSED(screen);
++    Q_UNUSED(planeType);
++    Q_UNUSED(idx);
++    Q_UNUSED(numProp);
++    Q_UNUSED(propName);
++    Q_UNUSED(propVal);
++
++    return -1;
++}
++
++int QEGLDeviceIntegration::getPlaneProperty(const QScreen *screen, 
++                                            uint8_t planeType, uint8_t idx, 
++                                            const char *propName)
++{
++    Q_UNUSED(screen);
++    Q_UNUSED(planeType);
++    Q_UNUSED(idx);
++    Q_UNUSED(propName);
++
++    return -1;
++}
++
++int QEGLDeviceIntegration::createPlane(const QScreen *screen)
++{
++    Q_UNUSED(screen);
++    return -1;
++}
++
++int QEGLDeviceIntegration::distroyPlane(const QScreen *screen, int planeId)
++{
++    Q_UNUSED(screen);
++    Q_UNUSED(planeId);
++    return -1;
++}
++
++int QEGLDeviceIntegration::queuePlane(QScreen *screen,
++                                      uint32_t idx, uint32_t fbId)
++{
++    Q_UNUSED(screen);
++    Q_UNUSED(idx);
++    Q_UNUSED(fbId);
++
++    return -1;
++}
++
++int QEGLDeviceIntegration::startDispPlane(QScreen *screen)
++{
++    Q_UNUSED(screen);
++      return -1;
++}
++
++int QEGLDeviceIntegration::userCallBackHandle(QScreen *screen, void 
(*fnPtr)(void *), void *data)
++{
++    Q_UNUSED(screen);
++    Q_UNUSED(fnPtr);
++    Q_UNUSED(data);
++    return -1;
++}
++
+ QT_END_NAMESPACE
+diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h 
b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h
+index f1a5bde331..36fe3d2556 100644
+--- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h
++++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h
+@@ -57,7 +57,6 @@
+ #include <QtCore/QString>
+ #include <QtGui/QSurfaceFormat>
+ #include <QtGui/QImage>
+-
+ QT_BEGIN_NAMESPACE
+ 
+ class QPlatformSurface;
+@@ -105,6 +104,20 @@ public:
+     virtual bool supportsSurfacelessContexts() const;
+ 
+     virtual void *wlDisplay() const;
++    virtual int exportBuffer(const QScreen *screen, uint32_t width, 
++        uint32_t height, uint32_t pixel_format,       uint32_t *strides, 
++        uint32_t *offsets, uint32_t buf_fd, uint32_t *buf_id);
++    virtual int distroyBuffer(const QScreen *screen, uint32_t buf_id);
++    virtual int setPlaneProperties(const QScreen *screen, uint8_t planeType,
++        uint8_t idx, uint8_t numProp, const char **propName,
++        uint32_t *propVal);
++    virtual int getPlaneProperty(const QScreen *screen, uint8_t planeType,
++        uint8_t idx, const char *propName);
++    virtual int createPlane(const QScreen *screen);
++    virtual int distroyPlane(const QScreen *screen, int plane_id);
++    virtual int queuePlane(QScreen *screen, uint32_t idx, uint32_t fb_id);
++    virtual int startDispPlane(QScreen *screen);
++    virtual int userCallBackHandle(QScreen *screen, void (*fnPtr)(void *), 
void *data);
+ };
+ 
+ class Q_EGLFS_EXPORT QEGLDeviceIntegrationPlugin : public QObject
+diff --git a/src/plugins/platforms/eglfs/qeglfsintegration.cpp 
b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+index 6f38a96f45..6120af3f59 100644
+--- a/src/plugins/platforms/eglfs/qeglfsintegration.cpp
++++ b/src/plugins/platforms/eglfs/qeglfsintegration.cpp
+@@ -93,6 +93,8 @@ static void initResources()
+ #endif
+ }
+ 
++Q_DECLARE_LOGGING_CATEGORY(qLcEglDevDebug)
++
+ QT_BEGIN_NAMESPACE
+ 
+ QEglFSIntegration::QEglFSIntegration()
+@@ -259,7 +261,16 @@ enum ResourceType {
+     EglConfig,
+     NativeDisplay,
+     XlibDisplay,
+-    WaylandDisplay
++    WaylandDisplay,
++    ExportBuffer,
++    DistroyBuffer,
++    SetPlaneProperties,
++    GetPlaneProperty,
++    CreatePlane,
++    DistroyPlane,
++    QueuePlane,
++    StartDispPlane,
++    UserCallBackHandl,
+ };
+ 
+ static int resourceType(const QByteArray &key)
+@@ -271,7 +282,16 @@ static int resourceType(const QByteArray &key)
+         QByteArrayLiteral("eglconfig"),
+         QByteArrayLiteral("nativedisplay"),
+         QByteArrayLiteral("display"),
+-        QByteArrayLiteral("server_wl_display")
++        QByteArrayLiteral("server_wl_display"),
++        QByteArrayLiteral("export_buffer"),
++        QByteArrayLiteral("distroy_buffer"),
++        QByteArrayLiteral("set_plane_properties"),
++        QByteArrayLiteral("get_plane_property"),
++        QByteArrayLiteral("create_plane"),
++        QByteArrayLiteral("distroy_plane"),
++        QByteArrayLiteral("queue_plane"),
++        QByteArrayLiteral("start_disp_plane"),
++        QByteArrayLiteral("user_call_back_handle"),
+     };
+     const QByteArray *end = names + sizeof(names) / sizeof(names[0]);
+     const QByteArray *result = std::find(names, end, key);
+@@ -280,6 +300,61 @@ static int resourceType(const QByteArray &key)
+     return int(result - names);
+ }
+ 
++static int exportBuffer(const QScreen *screen, uint32_t width, uint32_t 
height,
++                        uint32_t pixel_format, uint32_t *strides, uint32_t 
*offsets, 
++                        uint32_t buf_fd, uint32_t *buf_id)
++{
++    return(qt_egl_device_integration()->exportBuffer(screen, width, 
++        height, pixel_format, strides, offsets, buf_fd, buf_id));
++}
++
++static int distroyBuffer(const QScreen *screen, uint32_t buf_id)
++{
++    return(qt_egl_device_integration()->distroyBuffer(screen, buf_id));
++}
++
++static int setPlaneProperties(const QScreen *screen, uint8_t planeType,
++                              uint32_t idx, uint8_t num_prop, const char 
**prop_name, uint32_t *prop_val)
++{
++    return (qt_egl_device_integration()->setPlaneProperties(
++        screen, planeType, idx, num_prop, prop_name, prop_val));
++}
++
++static int getPlaneProperty(const QScreen *screen, uint8_t planeType, 
uint32_t idx, 
++                            const char *propName)
++{
++    return (qt_egl_device_integration()->getPlaneProperty(
++        screen, planeType, idx, propName));
++}
++
++static int createPlane(QScreen *screen)
++{
++    return(qt_egl_device_integration()->createPlane(screen));
++}
++
++static int distroyPlane(QScreen *screen, int plane_id)
++{
++    return (qt_egl_device_integration()->distroyPlane(screen, plane_id));
++}
++
++static int queuePlane(QScreen *screen,
++                      uint32_t idx, uint32_t fb_id)
++{
++    return (qt_egl_device_integration()->queuePlane(screen,
++        idx, fb_id));
++}
++
++static int startDispPlane(QScreen *screen)
++{
++    return (qt_egl_device_integration()->startDispPlane(screen));
++}
++
++static int userCallBackHandle(QScreen *screen,  void (*funPtr)(void *), void 
*data)
++{
++    return (qt_egl_device_integration()->userCallBackHandle(screen,
++        funPtr, data));
++}
++
+ void *QEglFSIntegration::nativeResourceForIntegration(const QByteArray 
&resource)
+ {
+     void *result = 0;
+@@ -294,6 +369,33 @@ void 
*QEglFSIntegration::nativeResourceForIntegration(const QByteArray &resource
+     case WaylandDisplay:
+         result = qt_egl_device_integration()->wlDisplay();
+         break;
++    case ExportBuffer:
++        result = reinterpret_cast<void *>(exportBuffer);
++        break;
++    case DistroyBuffer:
++        result = reinterpret_cast<void *>(distroyBuffer);
++        break;
++    case CreatePlane:
++        result = reinterpret_cast<void *>(createPlane);
++        break;
++    case DistroyPlane:
++        result = reinterpret_cast<void *>(distroyPlane);
++        break;
++    case SetPlaneProperties:
++        result = reinterpret_cast<void *>(setPlaneProperties);
++        break;
++    case GetPlaneProperty:
++        result = reinterpret_cast<void *>(getPlaneProperty);
++        break;
++    case QueuePlane:
++        result = reinterpret_cast<void *>(queuePlane);
++        break;
++    case StartDispPlane:
++        result = reinterpret_cast<void *>(startDispPlane);
++        break;
++    case UserCallBackHandl:
++        result = reinterpret_cast<void *>(userCallBackHandle);
++        break;
+     default:
+         break;
+     }
+-- 
+2.13.0
+
diff --git a/recipes-qt/qt5/qtbase_%.bbappend b/recipes-qt/qt5/qtbase_%.bbappend
index 98710f3..14c505b 100644
--- a/recipes-qt/qt5/qtbase_%.bbappend
+++ b/recipes-qt/qt5/qtbase_%.bbappend
@@ -1,4 +1,4 @@
-PR_append = ".tisdk4"
+PR_append = ".tisdk5"
 
 FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:"
 
@@ -21,7 +21,7 @@ QT_NOSGX_PATCHES = "\
 
 SRC_URI += "\
     ${@bb.utils.contains('MACHINE_FEATURES', 'sgx', '', "${QT_NOSGX_PATCHES}", 
d)}\
-    file://0001-qtbase-enhance-eglfs_kms-to-handle-DRM-plane-set-req.patch     
   \
+    file://0001-eglfs_kms-enhance-the-QPA-for-multiple-display-and-u.patch     
   \
 "
 
 python do_patch_append() {
-- 
1.9.1

_______________________________________________
meta-arago mailing list
meta-arago@arago-project.org
http://arago-project.org/cgi-bin/mailman/listinfo/meta-arago

Reply via email to