#include "wl_egl.h" #include #include #include #include #include #include #include #include //#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define EGL_EGLEXT_PROTOTYPES #define GL_GLEXT_PROTOTYPES #include #include #include #include #include #include #include #include #include #include #include #include static EGLDisplay m_display = nullptr; static EGLConfig m_config = nullptr; static EGLContext m_context = nullptr; static PFNEGLCREATEIMAGEKHRPROC CreateImageKHR; //static struct zwp_linux_dmabuf_v1 *dmabuf = nullptr; static const char *get_egl_error() { switch (eglGetError()) { case EGL_SUCCESS: return "EGL_SUCCESS"; case EGL_NOT_INITIALIZED: return "EGL_NOT_INITIALIZED"; case EGL_BAD_ACCESS: return "EGL_BAD_ACCESS"; case EGL_BAD_ALLOC: return "EGL_BAD_ALLOC"; case EGL_BAD_ATTRIBUTE: return "EGL_BAD_ATTRIBUTE"; case EGL_BAD_CONTEXT: return "EGL_BAD_CONTEXT"; case EGL_BAD_CONFIG: return "EGL_BAD_CONFIG"; case EGL_BAD_CURRENT_SURFACE: return "EGL_BAD_CURRENT_SURFACE"; case EGL_BAD_DISPLAY: return "EGL_BAD_DISPLAY"; case EGL_BAD_SURFACE: return "EGL_BAD_SURFACE"; case EGL_BAD_MATCH: return "EGL_BAD_MATCH"; case EGL_BAD_PARAMETER: return "EGL_BAD_PARAMETER"; case EGL_BAD_NATIVE_PIXMAP: return "EGL_BAD_NATIVE_PIXMAP"; case EGL_BAD_NATIVE_WINDOW: return "EGL_BAD_NATIVE_WINDOW"; case EGL_CONTEXT_LOST: return "EGL_CONTEXT_LOST"; default: return "EGL_???"; } } WaylandEgl::WaylandEgl(QObject* parent ) { connect(this, SIGNAL(windowChanged(QQuickWindow*)), this, SLOT(handleWindowChanged(QQuickWindow*))); } void WaylandEgl::handleWindowChanged(QQuickWindow *win) { qDebug() << "function" << __FUNCTION__ << "line " << __LINE__; if (win) { qDebug() << "function" << __FUNCTION__ << "line " << __LINE__ << "win" << win; connect(win, SIGNAL(afterRendering()), this, SLOT(paint()), Qt::DirectConnection); //connect(win, SIGNAL(beforeSynchronizing()), this, SLOT(sync()), Qt::DirectConnection); win->setClearBeforeRendering(false); mwindow = win; } } void WaylandEgl::paint() { qDebug() << "function" << __FUNCTION__ << "line " << __LINE__ << "win" << mwindow; performEglSetup(); } void WaylandEgl::sync() { qDebug() << "function" << __FUNCTION__ << "line " << __LINE__; } void WaylandEgl::cleanup() { qDebug() << "function" << __FUNCTION__ << "line " << __LINE__; } int WaylandEgl::performEglSetup() { QPlatformNativeInterface * nativeInterface = QGuiApplication::platformNativeInterface(); if (nativeInterface) { qDebug() << "App is running on:" << QGuiApplication::platformName() ; if (mwindow->handle()) { qDebug() << "Window:" << mwindow; qDebug() << "Window Surface Type:" << mwindow->surfaceType(); m_display = reinterpret_cast (reinterpret_cast(nativeInterface->nativeResourceForIntegration("egldisplay"))); if (m_display) { qDebug() << "Egl Display is " << m_display; } else { qDebug() << "Egl Display not get"; //return -1; } QOpenGLContext * openglContext; if (mwindow->openglContext()) { qDebug() << "Opengl context " ; openglContext = mwindow->openglContext(); } else { qDebug() << "No openglt context"; openglContext = QOpenGLContext::currentContext(); qDebug() << "Open gl contex"<< openglContext; if (!openglContext) { openglContext = QOpenGLContext::globalShareContext(); qDebug() << "Open gl contex after null"<< openglContext; } } if (openglContext) { m_config = nativeInterface->nativeResourceForContext("eglconfig",openglContext); qDebug() << "EGL config" << m_config; m_context = nativeInterface->nativeResourceForContext("eglcontext", openglContext); qDebug() << "EGL eglcontext" << m_context; } else { qDebug() << "No opengl context"; return -1; } } else { qDebug() << "No Window sheet" ; return -1; } GLuint source; glGenRenderbuffers(1,&source); glBindRenderbuffer(GL_RENDERBUFFER, source); if (glGetError()==GL_NO_ERROR) { qDebug() << "Render buff storage is OK" << glGetError(); } else { qDebug() << "Render buff storage error is " << glGetError(); } if (glIsRenderbuffer(source)) { qDebug() << "Source is Render buffer"; } else { qDebug() << "Source is not Render buffer"; } glRenderbufferStorage(GL_RENDERBUFFER, GL_RGBA8, static_cast(mwindow->width()), static_cast(mwindow->height())); if (glGetError()==GL_NO_ERROR) { qDebug() << "Render buff storage is OK" << glGetError(); } else { qDebug() << "Render buff storage error is " << glGetError(); } GLint samples, format , width, height; glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples); glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_INTERNAL_FORMAT, &format); glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width); glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height); qDebug() << "Buff width " << width; qDebug() << "Buff height " << height; qDebug() << "Buff format " << format; qDebug() << "Buff samples " << samples; GLuint framebuffer; glGenFramebuffers(1, &framebuffer); glBindFramebuffer(GL_FRAMEBUFFER, framebuffer); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, source); if (glGetError()==GL_NO_ERROR) { qDebug() << "Frame buff storage is OK" << glGetError(); } else { qDebug() << "Frame buff storage error is " << glGetError(); } GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); switch(status) { case GL_FRAMEBUFFER_COMPLETE: qDebug("Framebuffer verified complete."); break; case GL_FRAMEBUFFER_UNSUPPORTED: qDebug("GL_FRAMEBUFFER_UNSUPPORTED"); break; case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: qDebug("GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT "); break; default: qDebug("Other framebuffer error: %i", status); break; } glDeleteFramebuffers(1, &framebuffer); CreateImageKHR = (PFNEGLCREATEIMAGEKHRPROC)eglGetProcAddress("eglCreateImageKHR"); if (!CreateImageKHR) { qDebug() << "No image khr"; return -1; } EGLImageKHR image = CreateImageKHR(m_display, m_context, EGL_GL_RENDERBUFFER_KHR, reinterpret_cast(source), nullptr); if (image == EGL_NO_IMAGE_KHR) { qDebug("failed to make image from target buffer: %s", get_egl_error()); return -1; } qDebug() << "Image is "<< image; static const PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = reinterpret_cast(eglGetProcAddress("glEGLImageTargetTexture2DOES")); if (!glEGLImageTargetTexture2DOES) { qDebug() << "glEGLImageTargetTexture2DOES not supported"; } glEGLImageTargetRenderbufferStorageOES(GL_RENDERBUFFER, image); if (glGetError()==GL_NO_ERROR) { qDebug() << "glEGLImageTargetRenderbufferStorageOES buff is OK" << glGetError(); } else { qDebug() << "glEGLImageTargetRenderbufferStorageOES buff error is " << glGetError(); } int size = mwindow->width()*mwindow->height()*4; //uint8_t *b = (uint8_t*) image; uint8_t *ptr = new uint8_t[size]; memset(ptr,0,size); memcpy(ptr,image,size); if (ptr) { qDebug() << " Size of a" << sizeof (image); QImage m_lastFrame = QImage(mwindow->width(), mwindow->height(),QImage::Format_ARGB32); memcpy(m_lastFrame.bits(), ptr, size); // We write the image data into the new QImage m_lastFrame.save("gluu.png"); } qDebug() << "Finito"; } return 0; }