Hello,
I want to download an existing openGL texture into userspace (gstreamer) with zero-copy performance. I am trying to follow the steps outlined by Anand on (https://e2e.ti.com/support/embedded/linux/f/354/p/563420/2066253#2066253
1. Import DMABUF as a GBM BO
2. Create a pixmap surface out of it
3. Create an EGL Image based on the pixmap
As well as seeing the solution on (https://e2e.ti.com/support/arm/sitara_arm/f/791/t/606575?tisearch=e2e-quicksearch&keymatch=Pixmap), the user says a pixmap surface was not necessary. With these steps, I am able to create an EGLImage and connect it to my openGL texture as follows in the code snippet. I am using omap_bo_map to get a void pointer which I can read and pass into gstreamer. I've found that this pointer with an offset of (480*800*4=1536000) corresponds to some garbled up color data which I believe has come from my texture. Is this the correct approach for texture download from GPU to userspace? Why is the data I am reading out from omap_bo_map all jumbled up as shown in the attached image?
I've also come to think that dmabuf architecture may be handy in this application. If my EGLImage does contain the valid texture data, how can I use the dmabuf framework to share this to gstreamer? If anyone has any instructions or resources on how to use dmabuf to share (download) openGL textures, that would be appreciated.
int Width = 800;
int Height = 480;
int dri_fd = open("/dev/dri/card0",O_RDWR | O_CLOEXEC);
struct gbm_device *gbmDev = gbm_create_device(dri_fd);
struct omap_device* omapDev = omap_device_new(dri_fd);
struct omap_bo* lpOmapBo = omap_bo_new( omapDev, Width * Height * 4, 3 );
static void* omap_bo_mapped_stat = omap_bo_map(lpOmapBo);
struct gbm_import_fd_data GbmImportData;
GbmImportData.fd = omap_bo_dmabuf( lpOmapBo );
GbmImportData.width = Width;
GbmImportData.height = Height;
GbmImportData.stride = Width * 4;
GbmImportData.format = GBM_BO_FORMAT_ARGB8888;
static GbmBo* lpBo_stat = gbm_bo_import( gbmDev_stat, GBM_BO_IMPORT_FD, &GbmImportData,
GBM_BO_USE_SCANOUT );
QEGLNativeContext qEglContext = qvariant_cast<QEGLNativeContext>(m_context->nativeHandle());
const EGLint attrib_list[] = {
EGL_IMAGE_PRESERVED_KHR, true,
EGL_NONE
};
PFNEGLCREATEIMAGEKHRPROC eglCreateImageKHR = reinterpret_cast<PFNEGLCREATEIMAGEKHRPROC>(eglGetProcAddress("eglCreateImageKHR"));
EGLImageKHR eglImageHandle_stat = eglCreateImageKHR(qEglContext.display(), EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, lpBo_stat, attrib_list);
if(eglImageHandle_stat == EGL_NO_IMAGE_KHR)
{
qDebug("eglImageHandle == EGL_NO_IMAGE_KHR");
fprintf(stderr, "[ERR] failed to create eglImage: 0x%04x\n", eglGetError());
}
else
{
fprintf(stderr, "eglImage created!");
}
glBindTexture(GL_TEXTURE_EXTERNAL_OES, m_fbo->texture());
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_EXTERNAL_OES, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
PFNGLEGLIMAGETARGETTEXTURE2DOESPROC glEGLImageTargetTexture2DOES = reinterpret_cast<PFNGLEGLIMAGETARGETTEXTURE2DOESPROC>(eglGetProcAddress("glEGLImageTargetTexture2DOES"));
glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, eglImageHandle_stat);
Here is an example of the type of frames I am receiving. You can see that there is some valid part of my texture showing (the letters in the middle). Gstreamer is treating the buffer as ABGR.
Thank you,
Vishal
