6#include <QAbstractEventDispatcher>
8#include <QGuiApplication>
11#include <qpa/qplatformnativeinterface.h>
13#include <QOpenGLContext>
14#include <QOpenGLFunctions>
18#include <QtMultimedia/private/qeglimagefunctions_p.h>
19#include <QtMultimedia/private/qmultimedia_gl_support_p.h>
28using QtMultimediaPrivate::EGLImageHandle;
29using QtMultimediaPrivate::GlTextureDeleter;
30using QtMultimediaPrivate::GlTextureHandle;
31using QtMultimediaPrivate::QEglImageFunctions;
42 GLuint
getTexture(screen_window_t window,
const QSize &size);
45 bool grab(screen_window_t window);
46 bool resize(
const QSize &size);
49 screen_pixmap_t m_pixmap;
50 screen_buffer_t m_pixmapBuffer;
51 EGLImageHandle m_eglImage;
52 GlTextureHandle m_glTexture;
53 unsigned char *m_bufferAddress;
64 m_eglImageSupported(
false),
68 m_timer.setInterval(1000/60);
70 connect(&m_timer, &QTimer::timeout,
this, &QQnxWindowGrabber::triggerUpdate);
72 QCoreApplication::eventDispatcher()->installNativeEventFilter(
this);
74 QPlatformNativeInterface *
const nativeInterface = QGuiApplication::platformNativeInterface();
75 if (nativeInterface) {
76 m_screenContext =
static_cast<screen_context_t>(
77 nativeInterface->nativeResourceForIntegration(
"screenContext"));
86 screen_create_window(&m_windowParent, m_screenContext);
87 screen_create_window_group(m_windowParent,
nullptr);
92 screen_destroy_window(m_windowParent);
93 QCoreApplication::eventDispatcher()->removeNativeEventFilter(
this);
98 m_timer.setInterval(1000/frameRate);
103 m_windowId = windowId;
110 checkForEglImageExtension();
119 m_startPending =
true;
123 m_startPending =
false;
125 if (!m_screenContext)
126 screen_get_window_property_pv(m_window, SCREEN_PROPERTY_CONTEXT,
reinterpret_cast<
void**>(&m_screenContext));
170 if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) {
171 qWarning() <<
"QQnxWindowGrabber: Failed to query screen event type";
175 if (eventType != SCREEN_EVENT_CREATE)
178 screen_window_t window = 0;
179 if (screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_WINDOW, (
void**)&window) != 0) {
180 qWarning() <<
"QQnxWindowGrabber: Failed to query window property";
184 const int maxIdStrLength = 128;
185 char idString[maxIdStrLength];
186 if (screen_get_window_property_cv(window, SCREEN_PROPERTY_ID_STRING, maxIdStrLength, idString) != 0) {
187 qWarning() <<
"QQnxWindowGrabber: Failed to query window ID string";
192 if (idString[0] !=
'\0' && m_windowId == idString) {
204 if (eventType ==
"screen_event_t") {
205 const screen_event_t event =
static_cast<screen_event_t>(message);
206 return handleScreenEvent(event);
215 memset(groupName, 0,
sizeof(groupName));
216 screen_get_window_property_cv(m_windowParent,
217 SCREEN_PROPERTY_GROUP,
218 sizeof(groupName) - 1,
220 return QByteArray(groupName);
225 return m_eglImageSupported;
230 m_eglImageSupported =
false;
232 if (!m_rhi || m_rhi->backend() != QRhi::OpenGLES2)
238 if (qgetenv(
"QQNX_MM_DISABLE_EGLIMAGE_SUPPORT").toInt() != 0)
241 const EGLDisplay defaultDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
243 const char *vendor = eglQueryString(defaultDisplay, EGL_VENDOR);
245 if (vendor && std::strstr(vendor,
"VMWare"))
248 m_eglImageSupported = QEglImageFunctions::instance().isValid();
253 int size[2] = { 0, 0 };
255 const int result = screen_get_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, size);
259 qWarning() <<
"QQnxWindowGrabber: cannot get window size:" << strerror(errno);
263 if (m_size.width() != size[0] || m_size.height() != size[1])
264 m_size = QSize(size[0], size[1]);
266 emit updateScene(m_size);
274 std::swap(m_frontBuffer, m_backBuffer);
281 if (!frontBuffer->initialize(m_screenContext))
284 m_frontBuffer = std::move(frontBuffer);
294 return m_frontBuffer->getTexture(m_window, m_size);
302 return m_frontBuffer->getBuffer(m_window, m_size);
307 m_frontBuffer.reset();
308 m_backBuffer.reset();
314 m_bufferAddress(
nullptr),
322 screen_destroy_pixmap(m_pixmap);
327 if (screen_create_pixmap(&m_pixmap, screenContext) != 0) {
328 qWarning() <<
"QQnxWindowGrabber: cannot create pixmap:" << strerror(errno);
331 const int usage = SCREEN_USAGE_WRITE | SCREEN_USAGE_READ | SCREEN_USAGE_NATIVE;
332 screen_set_pixmap_property_iv(m_pixmap, SCREEN_PROPERTY_USAGE, &usage);
338 const int format = SCREEN_FORMAT_RGBX8888;
339 screen_set_pixmap_property_iv(m_pixmap, SCREEN_PROPERTY_FORMAT, &format);
346 if (m_pixmapBuffer) {
347 screen_destroy_pixmap_buffer(m_pixmap);
353 const int size[2] = { newSize.width(), newSize.height() };
355 screen_set_pixmap_property_iv(m_pixmap, SCREEN_PROPERTY_BUFFER_SIZE, size);
357 if (screen_create_pixmap_buffer(m_pixmap) == 0) {
358 screen_get_pixmap_property_pv(m_pixmap, SCREEN_PROPERTY_RENDER_BUFFERS,
359 reinterpret_cast<
void**>(&m_pixmapBuffer));
360 screen_get_buffer_property_pv(m_pixmapBuffer, SCREEN_PROPERTY_POINTER,
361 reinterpret_cast<
void**>(&m_bufferAddress));
362 screen_get_buffer_property_iv(m_pixmapBuffer, SCREEN_PROPERTY_STRIDE, &m_bufferStride);
374 const int rect[] = { 0, 0, m_size.width(), m_size.height() };
375 return screen_read_window(window, m_pixmapBuffer, 1, rect, 0) == 0;
379 screen_window_t window,
const QSize &size)
381 if (size != m_size && !resize(size))
384 if (!m_bufferAddress || !grab(window))
388 .width = m_size.width(),
389 .height = m_size.height(),
390 .stride = m_bufferStride,
391 .data = m_bufferAddress
397 if (size != m_size) {
401 GLuint glTexture = 0;
402 glGenTextures(1, &glTexture);
403 m_glTexture = GlTextureHandle(glTexture, GlTextureDeleter(QOpenGLContext::currentContext()));
405 const auto &eglImageFunctions = QEglImageFunctions::instance();
407 glBindTexture(GL_TEXTURE_2D, m_glTexture.get());
409 eglImageFunctions.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, 0);
414 m_eglImage = eglImageFunctions.eglCreateImage(eglGetDisplay(EGL_DEFAULT_DISPLAY),
415 EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR,
417 eglImageFunctions.glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage.get());
420 if (!m_pixmap || !grab(window))
423 return m_glTexture.get();
428#include "moc_qqnxwindowgrabber_p.cpp"
~QQnxWindowGrabberImage()
bool initialize(screen_context_t screenContext)
GLuint getTexture(screen_window_t window, const QSize &size)
QQnxWindowGrabber::BufferView getBuffer(screen_window_t window, const QSize &size)
QQnxWindowGrabber(QObject *parent=0)
bool isEglImageSupported() const
bool nativeEventFilter(const QByteArray &eventType, void *message, qintptr *result) override
This method is called for every native event.
BufferView getNextBuffer()
void setWindowId(const QByteArray &windowId)
bool handleScreenEvent(screen_event_t event)
QByteArray windowGroupId() const
void setFrameRate(int frameRate)