[Glamor] [PATCH] Allow to create textured pixmaps from gbm_bo without using gem names

davyaxel at free.fr davyaxel at free.fr
Sat Nov 23 05:19:20 PST 2013


On 23/11/2013, zhigang gong wrote :
> At the time I developed glamor, the extension of creating egl image from gl texture was
> not implemented in mesa. Now mesa already supported it,  and we can provide these new
> APIs to DDR driver. Just as you said, we may need a new API in libglamor.so to query a
> pixmap's type and texture unit id, then we don't need to access the pixmap's private data
> structure.
> The new API you implemented will give DDR a chance to support DRI more efficiently.
> Currently, when the client want to create a dri2 buffer on a textured only pixmap, it will
> trigger a glamor_fixup function to create a new textured_drm pixmap and then copy the
> old buffer to this new buffer. Now we can avoid this extra copy with this new API at that
> case.
> Thanks,
> Zhigang Gong.

The other dri3 helper could look like that:

PixmapPtr  glamor_egl_get_pixmap_from_fd (ScreenPtr screen,
                                          int fd,
                                          int width,
                                          int height,
                                          int stride,                   
                                          int depth,
                                          int bpp)
{
  PixmapPtr pixmap;
  struct glamor_egl_screen_private *glamor_egl;
  EGLImageKHR image;
  struct gbm_bo* bo;
  EGLint attribs[] = {
        EGL_WIDTH, 0,
        EGL_HEIGHT, 0,
        EGL_LINUX_DRM_FOURCC_EXT, 0,
        EGL_DMA_BUF_PLANE0_FD_EXT, 0,
        EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0,
        EGL_DMA_BUF_PLANE0_PITCH_EXT, 0,
        EGL_NONE
    };
   ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
   glamor_egl = glamor_egl_get_screen_private(scrn);

/* we have no way to choose between RGB or others. Favor RGB */
 
  switch(bpp){
    case 16:
      if (depth == 16)
          attribs[5] = DRM_FORMAT_RGB565;
      break;
    case 24:
      if (depth == 24)
        attribs[5] = DRM_FORMAT_RGB888;
      break;
    case 32:
      if (depth == 24)
        attribs [5] = DRM_FORMAT_XRGB8888;
      else if (depth == 32)
        attribs [5] = DRM_FORMAT_ARGB8888;
  }
  if (attribs[5] == 0 || width==0 || height == 0)
    goto failure;

  pixmap = fbCreatePixmap(screen, 0, 0, depth, 0);
  attribs[1] = width;
  attribs[3] = height;
  attribs[7] = fd;
  attribs[11] = stride;
  screen->ModifyPixmapHeader (pixmap, width, height, 0, 0,
                  stride, NULL);

  image = glamor_egl->egl_create_image_khr(glamor_egl->display,
                                                                       EGL_NO_CONTEXT,
                                                                       EGL_LINUX_DMA_BUF_EXT,
                                                                       NULL, attribs);
  if (image == EGL_NO_IMAGE_KHR)
    goto destroy_pixmap;
  /* images imported with EGL_LINUX_DMA_BUF_EXT have
      restrictions about their use, since they can potentially
      be of YUV format. Convert to gbm_bo, which accepts
      only non YUV formats, and then do not share the same
      limitations */
  bo = gbm_bo_import(glamor_egl->gbm,GBM_BO_IMPORT_EGL_IMAGE,image,0);
  glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
  if(!bo)
    goto destroy_pixmap;
  if(!glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo))
    goto destroy_bo;
  gbm_bo_destroy(bo);
  return pixmap;

destroy_bo:
  gbm_bo_destroy(bo);
destroy_pixmap: 
  fbDestroyPixmap(pixmap);
failure:
  return NULL;
}

For the dri2 use case you mention, 
It'll probably need a glamor_egl_get_name_from_pixmap.


Axel Davy

> On Fri, Nov 22, 2013 at 6:45 AM, <davyaxel at free.fr> wrote:
>
>     Hi,
>
>     I've got pixmap->fd working with this experimental function (on intel):
>
>     Bool glamor_egl_get_fd_from_pixmap(PixmapPtr pixmap, int* fd)
>     {
>       struct glamor_pixmap_private * priv = glamor_get_pixmap_private(pixmap);
>       ScreenPtr screen = pixmap->drawable.pScreen;
>       ScrnInfoPtr scrn = xf86ScreenToScrn(screen);
>       struct glamor_egl_screen_private *glamor_egl;
>       EGLImageKHR image;
>       GLuint texture;
>       Bool ret = FALSE;
>       struct gbm_bo* bo;
>       EGLint attribs[] = {
>             EGL_IMAGE_PRESERVED_KHR, EGL_TRUE,
>             EGL_GL_TEXTURE_LEVEL_KHR, 0,
>             EGL_NONE
>       };
>
>       glamor_egl = glamor_egl_get_screen_private(scrn);
>       switch (priv->type)
>       {
>         case GLAMOR_TEXTURE_DRM:
>         case GLAMOR_TEXTURE_ONLY:
>            glamor_egl_make_current(screen);
>            image = glamor_egl->egl_create_image_khr(glamor_egl->display,
>                              glamor_egl->context,
>                              EGL_GL_TEXTURE_2D_KHR,
>                              priv->base.fbo->tex, attribs);
>            if (image == EGL_NO_IMAGE_KHR)
>             goto leave;
>            bo = gbm_bo_import(glamor_egl->gbm,GBM_BO_IMPORT_EGL_IMAGE,image,0);
>            glamor_egl->egl_destroy_image_khr(glamor_egl->display, image);
>            ret = glamor_get_fd_from_bo(glamor_egl->fd,bo,fd);
>            if(ret)
>            {
>               glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM);
>               pixmap->devKind = gbm_bo_get_stride(bo);
>            }
>            gbm_bo_destroy(bo);
>            break;
>         default: return 0;
>       }
>       leave:
>       glamor_egl_restore_context(screen);
>             return ret;
>     }
>
>     int
>     glamor_get_fd_from_bo (int gbm_fd, struct gbm_bo *bo, int *fd)
>     {
>       union gbm_bo_handle handle;
>       struct drm_prime_handle args;
>
>       handle = gbm_bo_get_handle(bo);
>       args.handle = handle.u32;
>       args.flags = DRM_CLOEXEC;
>       if (ioctl (gbm_fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args))
>         return FALSE;
>       *fd = args.fd;
>       return TRUE;
>     }
>
>
>     Of course there are some missing checks, etc.
>     And it needs glamor_egl.c has access to the glamor_pixmap_private to get the texture.
>     I think it would be better to have a function glamor_get_pixmap_texture_number that glamor_egl would have access to.
>
>     Feel free to add comments
>
>     Axel Davy
>     _______________________________________________
>     Glamor mailing list
>     Glamor at lists.freedesktop.org
>     http://lists.freedesktop.org/mailman/listinfo/glamor 
>


More information about the Glamor mailing list