static PixmapPtr xwl_dri3_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp) { struct xwl_screen *xwl_screen = xwl_screen_get(screen); struct gbm_import_fd_data data; struct gbm_bo *bo; PixmapPtr pixmap; if (width == 0 || height == 0 || depth < 15 || bpp != BitsPerPixel(depth) || stride < width * bpp / 8) return NULL; data.fd = fd; data.width = width; data.height = height; data.stride = stride; data.format = gbm_format_for_depth(depth); bo = gbm_bo_import(xwl_screen->gbm, GBM_BO_IMPORT_FD, &data, GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING); if (bo == NULL) return NULL; pixmap = xwl_glamor_create_pixmap_for_bo(screen, bo, depth); if (pixmap == NULL) { gbm_bo_destroy(bo); return NULL; } return pixmap; }
uint32_t update_buffer_nativesurface(struct ivi_share_nativesurface *p_nativesurface) { if (NULL == p_nativesurface || NULL == p_nativesurface->surface) { return IVI_SHAREBUFFER_NOT_AVAILABLE; } struct drm_backend *backend = (struct drm_backend*)p_nativesurface->surface->compositor->backend; if (NULL == backend) { return IVI_SHAREBUFFER_NOT_AVAILABLE; } struct weston_buffer *buffer = p_nativesurface->surface->buffer_ref.buffer; if (!buffer) { return IVI_SHAREBUFFER_NOT_AVAILABLE; } struct gbm_bo *bo = gbm_bo_import(backend->gbm, GBM_BO_IMPORT_WL_BUFFER, buffer->legacy_buffer, GBM_BO_USE_SCANOUT); if (!bo) { weston_log("failed to import gbm_bo\n"); return IVI_SHAREBUFFER_INVALID; } struct drm_gem_flink flink = {0}; flink.handle = gbm_bo_get_handle(bo).u32; if (drmIoctl(gbm_device_get_fd(backend->gbm), DRM_IOCTL_GEM_FLINK, &flink) != 0) { weston_log("gem_flink: returned non-zero failed\n"); gbm_bo_destroy(bo); return IVI_SHAREBUFFER_INVALID; } uint32_t name = flink.name; uint32_t width = gbm_bo_get_width(bo); uint32_t height = gbm_bo_get_height(bo); uint32_t stride = gbm_bo_get_stride(bo); uint32_t format = IVI_SHARE_SURFACE_FORMAT_ARGB8888; uint32_t ret = IVI_SHAREBUFFER_STABLE; if (name != p_nativesurface->name) { ret |= IVI_SHAREBUFFER_DAMAGE; } if (width != p_nativesurface->width) { ret |= IVI_SHAREBUFFER_CONFIGURE; } if (height != p_nativesurface->height) { ret |= IVI_SHAREBUFFER_CONFIGURE; } if (stride != p_nativesurface->stride) { ret |= IVI_SHAREBUFFER_CONFIGURE; } p_nativesurface->name = name; p_nativesurface->width = width; p_nativesurface->height = height; p_nativesurface->stride = stride; p_nativesurface->format = format; gbm_bo_destroy(bo); return ret; }
int glamor_egl_dri3_fd_name_from_tex(ScreenPtr screen, PixmapPtr pixmap, unsigned int tex, Bool want_name, CARD16 *stride, CARD32 *size) { #ifdef GLAMOR_HAS_GBM ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_screen_private *glamor_priv = glamor_get_screen_private(screen); struct glamor_egl_screen_private *glamor_egl; EGLImageKHR image; struct gbm_bo *bo; int fd = -1; EGLint attribs[] = { EGL_IMAGE_PRESERVED_KHR, EGL_TRUE, EGL_GL_TEXTURE_LEVEL_KHR, 0, EGL_NONE }; glamor_egl = glamor_egl_get_screen_private(scrn); glamor_get_context(glamor_priv); image = dixLookupPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key); if (image == EGL_NO_IMAGE_KHR || image == NULL) { image = eglCreateImageKHR(glamor_egl->display, glamor_egl->context, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer) (uintptr_t) tex, attribs); if (image == EGL_NO_IMAGE_KHR) goto failure; dixSetPrivate(&pixmap->devPrivates, glamor_egl_pixmap_private_key, image); glamor_set_pixmap_type(pixmap, GLAMOR_TEXTURE_DRM); } bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0); if (!bo) goto failure; pixmap->devKind = gbm_bo_get_stride(bo); if (want_name) { if (glamor_egl->has_gem) glamor_get_name_from_bo(glamor_egl->fd, bo, &fd); } else { if (glamor_get_fd_from_bo(glamor_egl->fd, bo, &fd)) { *stride = pixmap->devKind; *size = pixmap->devKind * gbm_bo_get_height(bo); } } gbm_bo_destroy(bo); failure: glamor_put_context(glamor_priv); return fd; #else return -1; #endif }
PixmapPtr glamor_egl_dri3_pixmap_from_fd(ScreenPtr screen, int fd, CARD16 width, CARD16 height, CARD16 stride, CARD8 depth, CARD8 bpp) { #ifdef GLAMOR_HAS_GBM ScrnInfoPtr scrn = xf86ScreenToScrn(screen); struct glamor_egl_screen_private *glamor_egl; struct gbm_bo *bo; EGLImageKHR image; PixmapPtr pixmap; Bool ret = FALSE; EGLint attribs[] = { EGL_WIDTH, 0, EGL_HEIGHT, 0, EGL_LINUX_DRM_FOURCC_EXT, DRM_FORMAT_ARGB8888, EGL_DMA_BUF_PLANE0_FD_EXT, 0, EGL_DMA_BUF_PLANE0_OFFSET_EXT, 0, EGL_DMA_BUF_PLANE0_PITCH_EXT, 0, EGL_NONE }; glamor_egl = glamor_egl_get_screen_private(scrn); if (!glamor_egl->dri3_capable) return NULL; if (bpp != 32 || !(depth == 24 || depth == 32) || width == 0 || height == 0) return NULL; attribs[1] = width; attribs[3] = height; attribs[7] = fd; attribs[11] = stride; image = eglCreateImageKHR(glamor_egl->display, EGL_NO_CONTEXT, EGL_LINUX_DMA_BUF_EXT, NULL, attribs); if (image == EGL_NO_IMAGE_KHR) return NULL; /* EGL_EXT_image_dma_buf_import can impose restrictions on the * usage of the image. Use gbm_bo to bypass the limitations. */ bo = gbm_bo_import(glamor_egl->gbm, GBM_BO_IMPORT_EGL_IMAGE, image, 0); eglDestroyImageKHR(glamor_egl->display, image); if (!bo) return NULL; pixmap = screen->CreatePixmap(screen, 0, 0, depth, 0); screen->ModifyPixmapHeader(pixmap, width, height, 0, 0, stride, NULL); ret = glamor_egl_create_textured_pixmap_from_gbm_bo(pixmap, bo); gbm_bo_destroy(bo); if (ret) return pixmap; else { screen->DestroyPixmap(pixmap); return NULL; } #else return NULL; #endif }
static _EGLSurface * dri2_create_surface(_EGLDriver *drv, _EGLDisplay *disp, EGLint type, _EGLConfig *conf, EGLNativeWindowType window, const EGLint *attrib_list) { struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); struct dri2_egl_config *dri2_conf = dri2_egl_config(conf); struct dri2_egl_surface *dri2_surf; struct gbm_dri_surface *surf; struct gbm_bo *bo; _EGLImage *img; EGLint attr[10]; (void) drv; dri2_surf = calloc(1, sizeof *dri2_surf); if (!dri2_surf) { _eglError(EGL_BAD_ALLOC, "dri2_create_surface"); return NULL; } if (!_eglInitSurface(&dri2_surf->base, disp, type, conf, attrib_list)) goto cleanup_surf; switch (type) { case EGL_WINDOW_BIT: if (!window) return NULL; surf = gbm_dri_surface((struct gbm_surface *) window); dri2_surf->gbm_surf = surf; dri2_surf->base.Width = surf->base.width; dri2_surf->base.Height = surf->base.height; surf->dri_private = dri2_surf; break; default: goto cleanup_surf; } attr[0] = EGL_WIDTH; attr[1] = surf->base.width; attr[2] = EGL_HEIGHT; attr[3] = surf->base.height; attr[4] = EGL_DRM_BUFFER_FORMAT_MESA; attr[5] = EGL_DRM_BUFFER_FORMAT_ARGB32_MESA; attr[6] = EGL_DRM_BUFFER_USE_MESA; attr[7] = EGL_DRM_BUFFER_USE_SHARE_MESA; attr[8] = EGL_NONE; img = drv->API.CreateDRMImageMESA(drv, disp, attr); dri2_surf->egl_front = img; dri2_surf->khr_front = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR; bo = gbm_bo_import(&dri2_dpy->gbm_dri->base.base, GBM_BO_IMPORT_EGL_IMAGE, dri2_surf->khr_front, 0); if( bo == NULL){ _eglError(EGL_BAD_ALLOC, "gbm_bo_create front buffer"); goto cleanup_surf; } dri2_surf->color_buffers[1].bo = bo; img = drv->API.CreateDRMImageMESA(drv, disp, attr); dri2_surf->egl_back = img; dri2_surf->khr_back = (img) ? _eglLinkImage(img) : EGL_NO_IMAGE_KHR; bo = gbm_bo_import(&dri2_dpy->gbm_dri->base.base, GBM_BO_IMPORT_EGL_IMAGE, dri2_surf->khr_back, 0); if( bo == NULL){ _eglError(EGL_BAD_ALLOC, "gbm_bo_create back buffer"); goto cleanup_surf; } dri2_surf->color_buffers[2].bo = bo; dri2_surf->dri_drawable = (*dri2_dpy->dri2->createNewDrawable) (dri2_dpy->dri_screen, dri2_conf->dri_double_config, dri2_surf->gbm_surf); if (dri2_surf->dri_drawable == NULL) { _eglError(EGL_BAD_ALLOC, "dri2->createNewDrawable"); goto cleanup_surf; } return &dri2_surf->base; cleanup_surf: free(dri2_surf); return NULL; }