summaryrefslogtreecommitdiffstats
path: root/src/plugins/qnx/common/windowgrabber.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/qnx/common/windowgrabber.cpp')
-rw-r--r--src/plugins/qnx/common/windowgrabber.cpp419
1 files changed, 0 insertions, 419 deletions
diff --git a/src/plugins/qnx/common/windowgrabber.cpp b/src/plugins/qnx/common/windowgrabber.cpp
deleted file mode 100644
index 65037fcce..000000000
--- a/src/plugins/qnx/common/windowgrabber.cpp
+++ /dev/null
@@ -1,419 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 Research In Motion
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "windowgrabber.h"
-
-#include <QAbstractEventDispatcher>
-#include <QDebug>
-#include <QGuiApplication>
-#include <QImage>
-#include <QThread>
-#include <qpa/qplatformnativeinterface.h>
-
-#include <QOpenGLContext>
-#include <QOpenGLFunctions>
-
-#include <errno.h>
-
-QT_BEGIN_NAMESPACE
-
-static PFNEGLCREATEIMAGEKHRPROC s_eglCreateImageKHR;
-static PFNEGLDESTROYIMAGEKHRPROC s_eglDestroyImageKHR;
-
-WindowGrabber::WindowGrabber(QObject *parent)
- : QObject(parent),
- m_windowParent(nullptr),
- m_screenContext(0),
- m_active(false),
- m_currentFrame(0),
- m_eglImageSupported(false),
- m_eglImageCheck(false)
-{
- // grab the window frame with 60 frames per second
- m_timer.setInterval(1000/60);
-
- connect(&m_timer, SIGNAL(timeout()), SLOT(triggerUpdate()));
-
- QCoreApplication::eventDispatcher()->installNativeEventFilter(this);
-
- for ( int i = 0; i < 2; ++i )
- m_images[i] = 0;
-
- // Use of EGL images can be disabled by setting QQNX_MM_DISABLE_EGLIMAGE_SUPPORT to something
- // non-zero. This is probably useful only to test that this path still works since it results
- // in a high CPU load.
- if (!s_eglCreateImageKHR && qgetenv("QQNX_MM_DISABLE_EGLIMAGE_SUPPORT").toInt() == 0) {
- s_eglCreateImageKHR = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
- s_eglDestroyImageKHR = reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress("eglDestroyImageKHR"));
- }
-
- QPlatformNativeInterface *const nativeInterface = QGuiApplication::platformNativeInterface();
- if (nativeInterface) {
- m_screenContext = static_cast<screen_context_t>(
- nativeInterface->nativeResourceForIntegration("screenContext"));
- }
-
- // Create a parent window for the window whose content will be grabbed. Since the
- // window is only a buffer conduit, the characteristics of the parent window are
- // irrelevant. The contents of the window can be grabbed so long as the window
- // joins the parent window's group and the parent window is in this process.
- // Using the window that displays this content isn't possible because there's no
- // way to reliably retrieve it from this code or any calling code.
- screen_create_window(&m_windowParent, m_screenContext);
- screen_create_window_group(m_windowParent, nullptr);
-}
-
-WindowGrabber::~WindowGrabber()
-{
- screen_destroy_window(m_windowParent);
- QCoreApplication::eventDispatcher()->removeNativeEventFilter(this);
- cleanup();
-}
-
-void WindowGrabber::setFrameRate(int frameRate)
-{
- m_timer.setInterval(1000/frameRate);
-}
-
-
-void WindowGrabber::setWindowId(const QByteArray &windowId)
-{
- m_windowId = windowId;
-}
-
-void WindowGrabber::start()
-{
- if (m_active)
- return;
-
- if (!m_screenContext)
- screen_get_window_property_pv(m_window, SCREEN_PROPERTY_CONTEXT, reinterpret_cast<void**>(&m_screenContext));
-
- m_timer.start();
-
- m_active = true;
-}
-
-void WindowGrabber::stop()
-{
- if (!m_active)
- return;
-
- cleanup();
-
- m_timer.stop();
-
- m_active = false;
-}
-
-void WindowGrabber::pause()
-{
- m_timer.stop();
-}
-
-void WindowGrabber::resume()
-{
- if (!m_active)
- return;
-
- m_timer.start();
-}
-
-bool WindowGrabber::handleScreenEvent(screen_event_t screen_event)
-{
-
- int eventType;
- if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) {
- qWarning() << "WindowGrabber: Failed to query screen event type";
- return false;
- }
-
- if (eventType != SCREEN_EVENT_CREATE)
- return false;
-
- screen_window_t window = 0;
- if (screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_WINDOW, (void**)&window) != 0) {
- qWarning() << "WindowGrabber: Failed to query window property";
- return false;
- }
-
- const int maxIdStrLength = 128;
- char idString[maxIdStrLength];
- if (screen_get_window_property_cv(window, SCREEN_PROPERTY_ID_STRING, maxIdStrLength, idString) != 0) {
- qWarning() << "WindowGrabber: Failed to query window ID string";
- return false;
- }
-
- // Grab windows that have a non-empty ID string and a matching window id to grab
- if (idString[0] != '\0' && m_windowId == idString) {
- m_window = window;
- start();
- }
-
- return false;
-}
-
-bool WindowGrabber::nativeEventFilter(const QByteArray &eventType, void *message, qintptr *)
-{
- if (eventType == "screen_event_t") {
- const screen_event_t event = static_cast<screen_event_t>(message);
- return handleScreenEvent(event);
- }
-
- return false;
-}
-
-QByteArray WindowGrabber::windowGroupId() const
-{
- char groupName[256];
- memset(groupName, 0, sizeof(groupName));
- screen_get_window_property_cv(m_windowParent,
- SCREEN_PROPERTY_GROUP,
- sizeof(groupName) - 1,
- groupName);
- return QByteArray(groupName);
-}
-
-bool WindowGrabber::eglImageSupported()
-{
- return m_eglImageSupported;
-}
-
-void WindowGrabber::checkForEglImageExtension()
-{
- QOpenGLContext *m_context = QOpenGLContext::currentContext();
- if (!m_context) //Should not happen, because we are called from the render thread
- return;
-
- QByteArray eglExtensions = QByteArray(eglQueryString(eglGetDisplay(EGL_DEFAULT_DISPLAY),
- EGL_EXTENSIONS));
- m_eglImageSupported = m_context->hasExtension(QByteArrayLiteral("GL_OES_EGL_image"))
- && eglExtensions.contains(QByteArrayLiteral("EGL_KHR_image"))
- && s_eglCreateImageKHR && s_eglDestroyImageKHR;
-
- if (strstr(reinterpret_cast<const char*>(glGetString(GL_VENDOR)), "VMware"))
- m_eglImageSupported = false;
-
- m_eglImageCheck = true;
-}
-
-void WindowGrabber::triggerUpdate()
-{
- if (!m_eglImageCheck) // We did not check for egl images yet
- return;
-
- int size[2] = { 0, 0 };
-
- int result = screen_get_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, size);
- if (result != 0) {
- cleanup();
- qWarning() << "WindowGrabber: cannot get window size:" << strerror(errno);
- return;
- }
-
- if (m_size.width() != size[0] || m_size.height() != size[1])
- m_size = QSize(size[0], size[1]);
-
- emit updateScene(m_size);
-}
-
-bool WindowGrabber::selectBuffer()
-{
- // If we're using egl images we need to double buffer since the gpu may still be using the last
- // video frame. If we're not, it doesn't matter since the data is immediately copied.
- if (eglImageSupported())
- m_currentFrame = (m_currentFrame + 1) % 2;
-
- if (!m_images[m_currentFrame]) {
- m_images[m_currentFrame] = new WindowGrabberImage();
- if (!m_images[m_currentFrame]->initialize(m_screenContext)) {
- delete m_images[m_currentFrame];
- m_images[m_currentFrame] = 0;
- return false;
- }
- }
- return true;
-}
-
-int WindowGrabber::getNextTextureId()
-{
- if (!selectBuffer())
- return 0;
- return m_images[m_currentFrame]->getTexture(m_window, m_size);
-}
-
-QImage WindowGrabber::getNextImage()
-{
- if (!selectBuffer())
- return QImage();
-
- return m_images[m_currentFrame]->getImage(m_window, m_size);
-}
-
-void WindowGrabber::cleanup()
-{
- for ( int i = 0; i < 2; ++i ) {
- if (m_images[i]) {
- m_images[i]->destroy();
- m_images[i] = 0;
- }
- }
-}
-
-
-WindowGrabberImage::WindowGrabberImage()
- : m_pixmap(0), m_pixmapBuffer(0), m_eglImage(0), m_glTexture(0), m_bufferAddress(0), m_bufferStride(0)
-{
-}
-
-WindowGrabberImage::~WindowGrabberImage()
-{
- if (m_glTexture)
- glDeleteTextures(1, &m_glTexture);
- if (m_eglImage)
- s_eglDestroyImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), m_eglImage);
- if (m_pixmap)
- screen_destroy_pixmap(m_pixmap);
-}
-
-bool
-WindowGrabberImage::initialize(screen_context_t screenContext)
-{
- if (screen_create_pixmap(&m_pixmap, screenContext) != 0) {
- qWarning() << "WindowGrabber: cannot create pixmap:" << strerror(errno);
- return false;
- }
- const int usage = SCREEN_USAGE_WRITE | SCREEN_USAGE_READ | SCREEN_USAGE_NATIVE;
- screen_set_pixmap_property_iv(m_pixmap, SCREEN_PROPERTY_USAGE, &usage);
-
- const int format = SCREEN_FORMAT_RGBX8888;
- screen_set_pixmap_property_iv(m_pixmap, SCREEN_PROPERTY_FORMAT, &format);
-
- return true;
-}
-
-void
-WindowGrabberImage::destroy()
-{
- // We want to delete in the thread we were created in since we need the thread that
- // has called eglMakeCurrent on the right EGL context. This doesn't actually guarantee
- // this but that would be hard to achieve and in practice it works.
- if (QThread::currentThread() == thread())
- delete this;
- else
- deleteLater();
-}
-
-bool
-WindowGrabberImage::resize(const QSize &newSize)
-{
- if (m_pixmapBuffer) {
- screen_destroy_pixmap_buffer(m_pixmap);
- m_pixmapBuffer = 0;
- m_bufferAddress = 0;
- m_bufferStride = 0;
- }
-
- int size[2] = { newSize.width(), newSize.height() };
-
- screen_set_pixmap_property_iv(m_pixmap, SCREEN_PROPERTY_BUFFER_SIZE, size);
-
- if (screen_create_pixmap_buffer(m_pixmap) == 0) {
- screen_get_pixmap_property_pv(m_pixmap, SCREEN_PROPERTY_RENDER_BUFFERS,
- reinterpret_cast<void**>(&m_pixmapBuffer));
- screen_get_buffer_property_pv(m_pixmapBuffer, SCREEN_PROPERTY_POINTER,
- reinterpret_cast<void**>(&m_bufferAddress));
- screen_get_buffer_property_iv(m_pixmapBuffer, SCREEN_PROPERTY_STRIDE, &m_bufferStride);
- m_size = newSize;
-
- return true;
- } else {
- m_size = QSize();
- return false;
- }
-}
-
-bool
-WindowGrabberImage::grab(screen_window_t window)
-{
- const int rect[] = { 0, 0, m_size.width(), m_size.height() };
- return screen_read_window(window, m_pixmapBuffer, 1, rect, 0) == 0;
-}
-
-QImage
-WindowGrabberImage::getImage(screen_window_t window, const QSize &size)
-{
- if (size != m_size) {
- if (!resize(size))
- return QImage();
- }
- if (!m_bufferAddress || !grab(window))
- return QImage();
-
- return QImage(m_bufferAddress, m_size.width(), m_size.height(), m_bufferStride, QImage::Format_ARGB32);
-}
-
-GLuint
-WindowGrabberImage::getTexture(screen_window_t window, const QSize &size)
-{
- if (size != m_size) {
- if (!m_glTexture)
- glGenTextures(1, &m_glTexture);
- glBindTexture(GL_TEXTURE_2D, m_glTexture);
- if (m_eglImage) {
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, 0);
- s_eglDestroyImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), m_eglImage);
- m_eglImage = 0;
- }
- if (!resize(size))
- return 0;
- m_eglImage = s_eglCreateImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT,
- EGL_NATIVE_PIXMAP_KHR, m_pixmap, 0);
- glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage);
- }
-
- if (!m_pixmap || !grab(window))
- return 0;
-
- return m_glTexture;
-}
-
-
-
-QT_END_NAMESPACE