6#include <QAbstractEventDispatcher>
8#include <QGuiApplication>
11#include <qpa/qplatformnativeinterface.h>
13#include <QOpenGLContext>
14#include <QOpenGLFunctions>
25static PFNEGLCREATEIMAGEKHRPROC s_eglCreateImageKHR;
37 GLuint
getTexture(screen_window_t window,
const QSize &size);
40 bool grab(screen_window_t window);
41 bool resize(
const QSize &size);
44 screen_pixmap_t m_pixmap;
45 screen_buffer_t m_pixmapBuffer;
46 EGLImageKHR m_eglImage;
48 unsigned char *m_bufferAddress;
59 m_eglImageSupported(
false),
63 m_timer.setInterval(1000/60);
65 connect(&m_timer, &QTimer::timeout,
this, &QQnxWindowGrabber::triggerUpdate);
67 QCoreApplication::eventDispatcher()->installNativeEventFilter(
this);
72 if (!s_eglCreateImageKHR && qgetenv(
"QQNX_MM_DISABLE_EGLIMAGE_SUPPORT").toInt() == 0) {
73 s_eglCreateImageKHR =
reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress(
"eglCreateImageKHR"));
74 s_eglDestroyImageKHR =
reinterpret_cast<PFNEGLDESTROYIMAGEKHRPROC>(eglGetProcAddress(
"eglDestroyImageKHR"));
77 QPlatformNativeInterface *
const nativeInterface = QGuiApplication::platformNativeInterface();
78 if (nativeInterface) {
79 m_screenContext =
static_cast<screen_context_t>(
80 nativeInterface->nativeResourceForIntegration(
"screenContext"));
89 screen_create_window(&m_windowParent, m_screenContext);
90 screen_create_window_group(m_windowParent,
nullptr);
95 screen_destroy_window(m_windowParent);
96 QCoreApplication::eventDispatcher()->removeNativeEventFilter(
this);
101 m_timer.setInterval(1000/frameRate);
106 m_windowId = windowId;
113 checkForEglImageExtension();
122 m_startPending =
true;
126 m_startPending =
false;
128 if (!m_screenContext)
129 screen_get_window_property_pv(m_window, SCREEN_PROPERTY_CONTEXT,
reinterpret_cast<
void**>(&m_screenContext));
173 if (screen_get_event_property_iv(screen_event, SCREEN_PROPERTY_TYPE, &eventType) != 0) {
174 qWarning() <<
"QQnxWindowGrabber: Failed to query screen event type";
178 if (eventType != SCREEN_EVENT_CREATE)
181 screen_window_t window = 0;
182 if (screen_get_event_property_pv(screen_event, SCREEN_PROPERTY_WINDOW, (
void**)&window) != 0) {
183 qWarning() <<
"QQnxWindowGrabber: Failed to query window property";
187 const int maxIdStrLength = 128;
188 char idString[maxIdStrLength];
189 if (screen_get_window_property_cv(window, SCREEN_PROPERTY_ID_STRING, maxIdStrLength, idString) != 0) {
190 qWarning() <<
"QQnxWindowGrabber: Failed to query window ID string";
195 if (idString[0] !=
'\0' && m_windowId == idString) {
207 if (eventType ==
"screen_event_t") {
208 const screen_event_t event =
static_cast<screen_event_t>(message);
209 return handleScreenEvent(event);
218 memset(groupName, 0,
sizeof(groupName));
219 screen_get_window_property_cv(m_windowParent,
220 SCREEN_PROPERTY_GROUP,
221 sizeof(groupName) - 1,
223 return QByteArray(groupName);
228 return m_eglImageSupported;
233 m_eglImageSupported =
false;
235 if (!m_rhi || m_rhi->backend() != QRhi::OpenGLES2)
238 const EGLDisplay defaultDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
240 const char *vendor = eglQueryString(defaultDisplay, EGL_VENDOR);
242 if (vendor && std::strstr(vendor,
"VMWare"))
245 const char *eglExtensions = eglQueryString(defaultDisplay, EGL_EXTENSIONS);
250 m_eglImageSupported = std::strstr(eglExtensions,
"EGL_KHR_image")
251 && s_eglCreateImageKHR
252 && s_eglDestroyImageKHR;
257 int size[2] = { 0, 0 };
259 const int result = screen_get_window_property_iv(m_window, SCREEN_PROPERTY_SOURCE_SIZE, size);
263 qWarning() <<
"QQnxWindowGrabber: cannot get window size:" << strerror(errno);
267 if (m_size.width() != size[0] || m_size.height() != size[1])
268 m_size = QSize(size[0], size[1]);
270 emit updateScene(m_size);
277 if (isEglImageSupported())
278 std::swap(m_frontBuffer, m_backBuffer);
285 if (!frontBuffer->initialize(m_screenContext))
288 m_frontBuffer = std::move(frontBuffer);
298 return m_frontBuffer->getTexture(m_window, m_size);
306 return m_frontBuffer->getBuffer(m_window, m_size);
311 m_frontBuffer.reset();
312 m_backBuffer.reset();
320 m_bufferAddress(
nullptr),
328 glDeleteTextures(1, &m_glTexture);
332 screen_destroy_pixmap(m_pixmap);
337 if (screen_create_pixmap(&m_pixmap, screenContext) != 0) {
338 qWarning() <<
"QQnxWindowGrabber: cannot create pixmap:" << strerror(errno);
341 const int usage = SCREEN_USAGE_WRITE | SCREEN_USAGE_READ | SCREEN_USAGE_NATIVE;
342 screen_set_pixmap_property_iv(m_pixmap, SCREEN_PROPERTY_USAGE, &usage);
348 const int format = SCREEN_FORMAT_RGBX8888;
349 screen_set_pixmap_property_iv(m_pixmap, SCREEN_PROPERTY_FORMAT, &format);
356 if (m_pixmapBuffer) {
357 screen_destroy_pixmap_buffer(m_pixmap);
363 const int size[2] = { newSize.width(), newSize.height() };
365 screen_set_pixmap_property_iv(m_pixmap, SCREEN_PROPERTY_BUFFER_SIZE, size);
367 if (screen_create_pixmap_buffer(m_pixmap) == 0) {
368 screen_get_pixmap_property_pv(m_pixmap, SCREEN_PROPERTY_RENDER_BUFFERS,
369 reinterpret_cast<
void**>(&m_pixmapBuffer));
370 screen_get_buffer_property_pv(m_pixmapBuffer, SCREEN_PROPERTY_POINTER,
371 reinterpret_cast<
void**>(&m_bufferAddress));
372 screen_get_buffer_property_iv(m_pixmapBuffer, SCREEN_PROPERTY_STRIDE, &m_bufferStride);
384 const int rect[] = { 0, 0, m_size.width(), m_size.height() };
385 return screen_read_window(window, m_pixmapBuffer, 1, rect, 0) == 0;
389 screen_window_t window,
const QSize &size)
391 if (size != m_size && !resize(size))
394 if (!m_bufferAddress || !grab(window))
398 .width = m_size.width(),
399 .height = m_size.height(),
400 .stride = m_bufferStride,
401 .data = m_bufferAddress
407 if (size != m_size) {
411 glDeleteTextures(1, &m_glTexture);
412 glGenTextures(1, &m_glTexture);
414 glBindTexture(GL_TEXTURE_2D, m_glTexture);
416 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, 0);
422 m_eglImage = s_eglCreateImageKHR(eglGetDisplay(EGL_DEFAULT_DISPLAY), EGL_NO_CONTEXT,
423 EGL_NATIVE_PIXMAP_KHR, m_pixmap, 0);
424 glEGLImageTargetTexture2DOES(GL_TEXTURE_2D, m_eglImage);
427 if (!m_pixmap || !grab(window))
435#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)
static PFNEGLDESTROYIMAGEKHRPROC s_eglDestroyImageKHR