EGLFrame Interoperablity with openGL and OSD Frame

Hi guys
I want to OSD on frame( NVMM, I420, UYVY, RGBA, NV12, …) some shape( like rectangle) , text and image after doing process on it with CUDA. I can access on frame on CUDA
]( buffer through nvbuffer with zero copy and doing process on it but I need to draw some shape’s like rectangle,tringle, circle, fill rectangle, …, draw text, draw Image.
OpenCV does some of OSDes for us but it uses CPU resources and not good solution.
We can use CUDA to draw shape but we don’t want consume CUDA resources for OSD because It is mostly used in our process.
nvOSD doesn’t provides drawing but in its comment it is written that MODE_GPU hasn’t been implemented and MODE_HW just support rectangle drawing. However It doesn’t support Image OSD.

I think the best solution is to use openGL and offscreen rendering. I need access to openGL buffer like PBO through EGLImage with zero copy (egl openGL interoperablity). In addition to, I need off screen rendering without window and result of OSD must exists on original NvBuffer.
Some posts are here to solve this problem but none of them solve my problem.
and this is my code.

 int dmabuf_fd = 0;
    /* Mapping a buffer can fail (non-writable) */
    if (gst_buffer_map (buffer, &map, GST_MAP_WRITE)) {
        ExtractFdFromNvBuffer((void *), &dmabuf_fd);  
        CUresult status;
        CUeglFrame eglFrame;
        CUgraphicsResource pResource = NULL;
        int ret;
        EGLDisplay egl_display;
        egl_display =   eglGetDisplay(EGL_DEFAULT_DISPLAY);
        if (!eglInitialize(egl_display, NULL, NULL))
            fprintf(stderr, "Erro while initialize EGL display connection\n");
        EGLImageKHR egl_image;
        // Create EGLImage from dmabuf fd
        egl_image = NvEGLImageFromFd(egl_display, dmabuf_fd);
        if (egl_image == NULL)
            fprintf(stderr, "Erro egl_image Null\n");
            EGLDisplay egl_display;
            EGLSurface egl_surface;
            EGLContext egl_context;
            /* EGL context creation */
            EGLConfig egl_config;
            EGLint matching_configs;
            const EGLint config_attrib_list[] = {
                EGL_RED_SIZE, 8,
                EGL_GREEN_SIZE, 8,
                EGL_BLUE_SIZE, 8,
                EGL_ALPHA_SIZE, 8,
                EGL_DEPTH_SIZE, 16,
            const EGLint pbuffer_attrib_list[] = {
            const EGLint context_attrib_list[] = {
                EGL_CONTEXT_CLIENT_VERSION, 2,
            eglChooseConfig(egl_display, config_attrib_list, &egl_config, 1, &matching_configs);
#if defined USE_SURFACE
            printf("using surface, glEGLImageTargetTexture2DOES will work!\n");
            egl_surface = eglCreatePbufferSurface(egl_display, egl_config, pbuffer_attrib_list);
            egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, context_attrib_list);
            eglMakeCurrent(egl_display, egl_surface, egl_surface, egl_context);
            printf("NOT using surface, glEGLImageTargetTexture2DOES will NOT work\n");
            //egl_surface = eglCreatePbufferSurface (egl_display, egl_config, pbuffer_attrib_list);
            egl_context = eglCreateContext(egl_display, egl_config, EGL_NO_CONTEXT, context_attrib_list);
            eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, egl_context);
            GLuint texture;
            glGenTextures(1, &texture);
            glBindTexture(GL_TEXTURE_EXTERNAL_OES, texture);
            glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, egl_image);
            // The code starting from Line 12 to Line 34 is the newly added API sequence.
            GLuint binding_fbo;
            GLuint fbo;
            glGetIntegerv(GL_READ_FRAMEBUFFER_BINDING, (GLint *)&binding_fbo);
            glGenFramebuffers(1, &fbo);
            glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo);
            glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_EXTERNAL_OES, texture, 0);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            cv::Mat imOSD = imread("/home/nvidia/index1.jpeg",cv::IMREAD_UNCHANGED);
            cv::cvtColor(imOSD, imOSD, cv::COLOR_RGBA2BGRA);
            glDrawPixels( imOSD.cols, imOSD.rows, GL_RGBA, GL_UNSIGNED_BYTE, );
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glScissor(0, 0,1920, 1080);
            // Remember to disable scissor test, or, perhaps reset the scissor rectangle:
            float rectCoord[16] = {-1.0f,-1.0f ,0.6f,-0.9f ,0.6f,-0.9f  ,0.6f,0.6f ,0.6f,0.6f,-1.0f,1.0f, -1.0f,1.0f,-1.0f,-1.0f }; // two coords per vertex.
            glVertexPointer( 2, GL_FLOAT, 0, rectCoord );  // Set data type and location.
            glEnableClientState( GL_VERTEX_ARRAY );  // Enable use of arrays.
            glDrawArrays(GL_LINES, 0,8);
            cv::Mat image(1080, 1920, CV_8UC4);
            // readback is the EGLImage data;
            glReadPixels(0, 0, 1920, 1080, GL_RGBA, GL_UNSIGNED_BYTE,;
            glBindFramebuffer(GL_READ_FRAMEBUFFER, binding_fbo);
            glDeleteFramebuffers(1, &fbo);
            NvDestroyEGLImage(egl_display, egl_image);
            egl_image = EGL_NO_IMAGE_KHR;
            /* Terminate EGL */
            eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
            eglDestroyContext(egl_display, egl_context);
            eglDestroySurface(egl_display, egl_surface);
        gst_buffer_unmap (buffer, &map);

I need piece of code to do it.

There is no body to help me? please guys?
I couldn’t solve my problem.
thanks for having me.