summaryrefslogtreecommitdiffstats
path: root/src/plugins/qnx/common/windowgrabber.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-01-12 14:22:08 +0100
committerLars Knoll <lars.knoll@qt.io>2021-01-22 07:02:55 +0000
commit98148969b112f82d2b49e77950ea5f6d8b37b8b2 (patch)
tree48fffe0533a647bb53bec7e6e33dee1b95fcd849 /src/plugins/qnx/common/windowgrabber.cpp
parentb947bcabfef5f0df32a4e09b55eaa581281b4edd (diff)
Get rid of plugins for MM backends
There's no need for having those in plugins and we can further remove abstractions and simplify our code if the code is directly compiled into Qt Multimedia. Change-Id: I5267a6a776375d99be8f0de4207f0288d963e620 Reviewed-by: Doris Verria <doris.verria@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
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