How to share EGLImageKHR object between different devices

Hello,

I am trying to save screenshot of a qml quick controls application on a platform (running QT on wayland) by using native opengl functions .What I am doing is that using a RGB color render buffer with eglCreateImageKHR function and then send the EGLImageKHR void pointer to another device through Qt socket communication. I can successfully create EGLImage that means that there is no error from eglGetError function . For testing the EGLImageKHR object correctness, I bind it to another framebuffer by using glEglImageTargetRenderbufferStorageOES on the same process and read the pixel from glReadPixel function , create a png file from read buffer and observed that correct png is created with correct colors.

After that I tried to send this EGLImageKHR void pointer to another device or process and then create some png from the sended EGLImageKHR object and I do not see correct colored png ,only have a noise on the png.

Following is the code sample to create the EGLImageKHR from render buffer and then saving a tga_file from EGLImageKHR.

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// create render buffer and bind it to a framebuffer
glGenRenderbuffers( 1, &renderBuffer );
glBindRenderbuffer( GL_RENDERBUFFER, renderBuffer );
glRenderbufferStorage( GL_RENDERBUFFER, GL_RGB, mWinWidth, mWinHeight );
glBindRenderbuffer(GL_RENDERBUFFER, 0); //mwindow->openglContext()->defaultFramebufferObject());

if (glGetError()==GL_NO_ERROR)
{
//qDebug() << "Render buff storage is OK" << glGetError();
}
else
{
qDebug() << "Render buff storage error is " << glGetError();
}

glGenFramebuffers( 1, &frameBuffer );
glBindFramebuffer( GL_FRAMEBUFFER, frameBuffer);
glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, renderBuffer);

//printFramebufferInfo(frameBuffer);
if( glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
qDebug() << "Framebuffer error is " << glGetError();
}
else
{
//qDebug() << "Framebuffer is OK" << glGetError();
}

// create EGLImageKHR object
mWinWidth = mwindow->width();
mWinHeight = mwindow->height();

glGetIntegerv(GL_PACK_ALIGNMENT, &rowPack);
glPixelStorei(GL_PACK_ALIGNMENT, 1);
glBindFramebuffer(GL_READ_FRAMEBUFFER,mwindow->openglContext()->defaultFramebufferObject());
glBindFramebuffer(GL_DRAW_FRAMEBUFFER,frameBuffer);
glBlitFramebuffer(0, 0, mWinWidth, mWinHeight, 0, 0, mWinWidth, mWinHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);

m_display = reinterpret_cast<egldisplay>(reinterpret_cast<void*>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("egldisplay")));
m_context = QGuiApplication::platformNativeInterface()->nativeResourceForContext("eglcontext", mwindow->openglContext());

mImage = CreateImageKHR(m_display,m_context, EGL_GL_RENDERBUFFER_KHR,reinterpret_cast<eglclientbuffer>(renderBuffer), nullptr);

if (mImage == EGL_NO_IMAGE_KHR)
{
qDebug("failed to make image from target buffer: %s", get_egl_error());
return -1;
}

int size = mWinWidth * mWinHeight * 3;
sendEglImage(size);
glDeleteRenderbuffers(1,&renderBuffer);
renderBuffer = 0;
glDeleteFramebuffers(1,&frameBuffer);
frameBuffer = 0;

// send EGLImageKHR to client
sendEglImage(int size)
{
if (SenderSocket != NULL)
{
QByteArray data;
data.append(reinterpret_cast<const char*="">(mImage),size);
//data.append(reinterpret_cast<qbytearray *="">(mImage));
QDataStream out(&data, QIODevice::WriteOnly);
out.setDevice(SenderSocket);
out << data;
//qDebug() << "func " << __FUNCTION__ << "line" << __LINE__;
qDebug() << "func " << __FUNCTION__ << "line" << __LINE__ << "data size" << data.size();
}

QImage testImg((uchar *)mImage,640,480,QImage::Format_RGB888, nullptr, nullptr);
if(testImg.save("server.png"))
qDebug() << "Successfully saved image" << testImg;

DestroyImageKHR(m_display,mImage);
mImage = 0;
}

// Another approach to create a tga_file from EGLImageKHR is
FILE *out = fopen("tga_file", "w");
short TGAhead[] = {0, 2, 0, 0, 0, 0, 640, 480, 24};
fwrite(&TGAhead, sizeof(TGAhead), 1, out);
fwrite(mImage, mWinWidth * mWinHeight*3, 1, out);
fflush(out);
fclose(out);

// One more different trial

   int bufSize = mWinHeight * mWinWidth*3;

   unsigned char * trialBuff = new unsigned char[bufSize];

   memcpy(trialBuff,khrImage,bufSize);

   FILE *out = fopen("dada.txt", "w");

   fwrite(trialBuff, bufSize, 1, out);

   fflush(out);

   fsync(fileno(out));

   fclose(out);

   delete [] trialBuff;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

So When I try to create a png with QImage or with fwrite from EGLImageKHR object, I do not get a valid png or tga_file.

Note that I do not want to use glReadPixels function since it is causing high cpu load. Is there any idea how I can create some png file from EGLImageKHR and How I can send it to another device ?

Best Regards

Parents Reply Children
No data
More questions in this forum