How to share texture memory between CPU/GPU for firefly's/rk3288 fbdev Mali-T764

I got the hardware video decoder working on my firefly/rk3288. I can blit the yuv/nv21 output frame to rgb frame memory using fireflys dedicated 2d acceleration hardware. All I need right now is a memory pointer, pointing directly to the texture memory, in order to use the decoded video frame in shaders. In android I would create a GraphicBuffer object and give it to eglCreateImageKHR() and use glEGLImageTargetTexture2DOES. Right now I use glTexSubImage2D to copy and I get about 12 fps for 1920x1080 frames, too slow for showing a movie.

What is the best way to do this for firefly linux 3.10 with fbdev mali t760 driver? How can I simply get a pointer sharing CPU/GPU texture memory? And is there maybe some sample code available?


Right now I stuck and waiting for X11 mali drivers that support XCreatePixmap that could hopefully bring me further. My goal is XBMC, mplayer, ... running on linux on firefly.


Any help would really be appreciated! TNX!


Mac


Background, see:

accelerated video / video processor (VPU) running on linux on RK3288 / firefly - FreakTab.com

Parents
  • Hi mac_l1,

    You are right: on Android you would use a GraphicBuffer:

    android::sp<android::GraphicBuffer> pGraphicBuffer = new android::GraphicBuffer(width,height, ...);
    eglImage = eglCreateImageKHR(eglDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)pGraBuf->getNativeBuffer(), NULL);
    
    
    

    For FBdev. because it's not a full window system things are a bit more hacky, you need to define a secret structure and use some secret color formats (Let me know which one you need and I'll give you the magic value):

    /* This is a magic value expected by the driver: let me know if you need a different format */
    #define YUYV_FORMAT  0x001022A88LL
    
    
    struct fbdev_pixmap
    {
      int width, height;
    
    
      struct
      {
      /** @brief The line stride of each plane.
      * For each plane required by the format, the number of bytes from one line of samples to the next. Other entries in
      * the array should be 0.
      */
      khronos_usize_t stride;
      /** @brief The byte size of each plane.
      * For each plane required by the format, the number of bytes taken up by that plane. That includes any space wasted
      * in partially-used blocks.
      */
      khronos_usize_t size;
      /** @brief The offset from the memory handle to each plane.
      * For each plane required by the format, the number of bytes from the start of the allocation to the start of that
      * plane. Other entries in the array should be 0.
      */
      khronos_usize_t offset;
      }
      planes[3];
    
    
      /** An integer that specifies the format of the pixmap. Its meaning is known by the Mali driver. */
      uint64_t pixmap_format;
      /* dma_buf fd for each of the plan */
      int handles[3];
    };
    
    struct fbdev_pixmap pixmap;
    memset(&pixmap, 0, sizeof(struct fbdev_pixmap));
    pixmap.width = width;
    pixmap.height = height;
    pixmap.handles[0] = dma_fd;
    pixmap.planes[0].stride = width * pixel_size;
    pixmap.planes[0].size = width * height * pixel_size;
    pixmap.pixmap_format = YUYV_FORMAT;
    
    
    _egl_img  = eglCreateImageKHR(_egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (EGLNativePixmapType) &pixmap, NULL));
    
    
    
Reply
  • Hi mac_l1,

    You are right: on Android you would use a GraphicBuffer:

    android::sp<android::GraphicBuffer> pGraphicBuffer = new android::GraphicBuffer(width,height, ...);
    eglImage = eglCreateImageKHR(eglDisplay, EGL_NO_CONTEXT, EGL_NATIVE_BUFFER_ANDROID, (EGLClientBuffer)pGraBuf->getNativeBuffer(), NULL);
    
    
    

    For FBdev. because it's not a full window system things are a bit more hacky, you need to define a secret structure and use some secret color formats (Let me know which one you need and I'll give you the magic value):

    /* This is a magic value expected by the driver: let me know if you need a different format */
    #define YUYV_FORMAT  0x001022A88LL
    
    
    struct fbdev_pixmap
    {
      int width, height;
    
    
      struct
      {
      /** @brief The line stride of each plane.
      * For each plane required by the format, the number of bytes from one line of samples to the next. Other entries in
      * the array should be 0.
      */
      khronos_usize_t stride;
      /** @brief The byte size of each plane.
      * For each plane required by the format, the number of bytes taken up by that plane. That includes any space wasted
      * in partially-used blocks.
      */
      khronos_usize_t size;
      /** @brief The offset from the memory handle to each plane.
      * For each plane required by the format, the number of bytes from the start of the allocation to the start of that
      * plane. Other entries in the array should be 0.
      */
      khronos_usize_t offset;
      }
      planes[3];
    
    
      /** An integer that specifies the format of the pixmap. Its meaning is known by the Mali driver. */
      uint64_t pixmap_format;
      /* dma_buf fd for each of the plan */
      int handles[3];
    };
    
    struct fbdev_pixmap pixmap;
    memset(&pixmap, 0, sizeof(struct fbdev_pixmap));
    pixmap.width = width;
    pixmap.height = height;
    pixmap.handles[0] = dma_fd;
    pixmap.planes[0].stride = width * pixel_size;
    pixmap.planes[0].size = width * height * pixel_size;
    pixmap.pixmap_format = YUYV_FORMAT;
    
    
    _egl_img  = eglCreateImageKHR(_egl_display, EGL_NO_CONTEXT, EGL_NATIVE_PIXMAP_KHR, (EGLNativePixmapType) &pixmap, NULL));
    
    
    
Children