diff --git a/src/egl/drivers/dri2/platform_drm.c b/src/egl/drivers/dri2/platform_drm.c index 8b392f3e788..2b329437f88 100644 --- a/src/egl/drivers/dri2/platform_drm.c +++ b/src/egl/drivers/dri2/platform_drm.c @@ -113,7 +113,7 @@ dri2_drm_config_is_compatible(struct dri2_egl_display *dri2_dpy, for (i = 0; i < dri2_dpy->gbm_dri->num_visuals; i++) { visual = &dri2_dpy->gbm_dri->visual_table[i]; - if (visual->gbm_format == surface->format) + if (visual->gbm_format == surface->v0.format) break; } @@ -173,8 +173,8 @@ dri2_drm_create_window_surface(_EGLDisplay *disp, _EGLConfig *conf, surf = gbm_dri_surface(surface); dri2_surf->gbm_surf = surf; - dri2_surf->base.Width = surf->base.width; - dri2_surf->base.Height = surf->base.height; + dri2_surf->base.Width = surf->base.v0.width; + dri2_surf->base.Height = surf->base.v0.height; surf->dri_private = dri2_surf; if (!dri2_create_drawable(dri2_dpy, config, dri2_surf, dri2_surf->gbm_surf)) @@ -244,21 +244,21 @@ get_back_bo(struct dri2_egl_surface *dri2_surf) if (dri2_surf->back == NULL) return -1; if (dri2_surf->back->bo == NULL) { - if (surf->base.modifiers) + if (surf->base.v0.modifiers) dri2_surf->back->bo = gbm_bo_create_with_modifiers(&dri2_dpy->gbm_dri->base, - surf->base.width, - surf->base.height, - surf->base.format, - surf->base.modifiers, - surf->base.count); + surf->base.v0.width, + surf->base.v0.height, + surf->base.v0.format, + surf->base.v0.modifiers, + surf->base.v0.count); else { - unsigned flags = surf->base.flags; + unsigned flags = surf->base.v0.flags; if (dri2_surf->base.ProtectedContent) flags |= GBM_BO_USE_PROTECTED; dri2_surf->back->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base, - surf->base.width, - surf->base.height, - surf->base.format, + surf->base.v0.width, + surf->base.v0.height, + surf->base.v0.format, flags); } @@ -283,8 +283,10 @@ get_swrast_front_bo(struct dri2_egl_surface *dri2_surf) if (dri2_surf->current->bo == NULL) dri2_surf->current->bo = gbm_bo_create(&dri2_dpy->gbm_dri->base, - surf->base.width, surf->base.height, - surf->base.format, surf->base.flags); + surf->base.v0.width, + surf->base.v0.height, + surf->base.v0.format, + surf->base.v0.flags); if (dri2_surf->current->bo == NULL) return -1; @@ -545,7 +547,7 @@ swrast_put_image2(__DRIdrawable *driDrawable, if (gbm_dri_bo_map_dumb(bo) == NULL) return; - internal_stride = bo->base.stride; + internal_stride = bo->base.v0.stride; dst = bo->map + x_bytes + (y * internal_stride); src = data; @@ -587,7 +589,7 @@ swrast_get_image(__DRIdrawable *driDrawable, x_bytes = x * (bpp >> 3); width_bytes = width * (bpp >> 3); - internal_stride = bo->base.stride; + internal_stride = bo->base.v0.stride; stride = width_bytes; if (gbm_dri_bo_map_dumb(bo) == NULL) @@ -759,9 +761,9 @@ dri2_initialize_drm(_EGLDisplay *disp) dri2_dpy->gbm_dri->swrast_put_image2 = swrast_put_image2; dri2_dpy->gbm_dri->swrast_get_image = swrast_get_image; - dri2_dpy->gbm_dri->base.surface_lock_front_buffer = lock_front_buffer; - dri2_dpy->gbm_dri->base.surface_release_buffer = release_buffer; - dri2_dpy->gbm_dri->base.surface_has_free_buffers = has_free_buffers; + dri2_dpy->gbm_dri->base.v0.surface_lock_front_buffer = lock_front_buffer; + dri2_dpy->gbm_dri->base.v0.surface_release_buffer = release_buffer; + dri2_dpy->gbm_dri->base.v0.surface_has_free_buffers = has_free_buffers; if (!dri2_setup_extensions(disp)) { err = "DRI2: failed to find required DRI extensions"; diff --git a/src/gbm/backends/dri/gbm_dri.c b/src/gbm/backends/dri/gbm_dri.c index baac0909025..53a1d5bb8ef 100644 --- a/src/gbm/backends/dri/gbm_dri.c +++ b/src/gbm/backends/dri/gbm_dri.c @@ -153,8 +153,8 @@ swrast_get_drawable_info(__DRIdrawable *driDrawable, *x = 0; *y = 0; - *width = surf->base.width; - *height = surf->base.height; + *width = surf->base.v0.width; + *height = surf->base.v0.height; } static void @@ -398,12 +398,12 @@ dri_screen_create_dri2(struct gbm_dri_device *dri, char *driver_name) return -1; if (dri->dri2->base.version >= 4) { - dri->screen = dri->dri2->createNewScreen2(0, dri->base.fd, + dri->screen = dri->dri2->createNewScreen2(0, dri->base.v0.fd, dri->loader_extensions, dri->driver_extensions, &dri->driver_configs, dri); } else { - dri->screen = dri->dri2->createNewScreen(0, dri->base.fd, + dri->screen = dri->dri2->createNewScreen(0, dri->base.v0.fd, dri->loader_extensions, &dri->driver_configs, dri); } @@ -471,7 +471,7 @@ dri_screen_create(struct gbm_dri_device *dri) { char *driver_name; - driver_name = loader_get_driver_for_fd(dri->base.fd); + driver_name = loader_get_driver_for_fd(dri->base.v0.fd); if (!driver_name) return -1; @@ -576,7 +576,7 @@ static const struct gbm_dri_visual gbm_dri_visuals_table[] = { static int gbm_format_to_dri_format(uint32_t gbm_format) { - gbm_format = gbm_core.format_canonicalize(gbm_format); + gbm_format = gbm_core.v0.format_canonicalize(gbm_format); for (size_t i = 0; i < ARRAY_SIZE(gbm_dri_visuals_table); i++) { if (gbm_dri_visuals_table[i].gbm_format == gbm_format) return gbm_dri_visuals_table[i].dri_image_format; @@ -607,7 +607,7 @@ gbm_dri_is_format_supported(struct gbm_device *gbm, if ((usage & GBM_BO_USE_CURSOR) && (usage & GBM_BO_USE_RENDERING)) return 0; - format = gbm_core.format_canonicalize(format); + format = gbm_core.v0.format_canonicalize(format); if (gbm_format_to_dri_format(format) == 0) return 0; @@ -644,7 +644,7 @@ gbm_dri_get_format_modifier_plane_count(struct gbm_device *gbm, !dri->image->queryDmaBufFormatModifierAttribs) return -1; - format = gbm_core.format_canonicalize(format); + format = gbm_core.v0.format_canonicalize(format); if (gbm_format_to_dri_format(format) == 0) return -1; @@ -725,7 +725,7 @@ gbm_dri_bo_get_handle_for_plane(struct gbm_bo *_bo, int plane) /* Preserve legacy behavior if plane is 0 */ if (plane == 0) { /* NOTE: return _bo->handle, *NOT* bo->handle which is invalid at this point */ - return _bo->handle; + return _bo->v0.handle; } errno = ENOSYS; @@ -806,7 +806,7 @@ gbm_dri_bo_get_stride(struct gbm_bo *_bo, int plane) if (!dri->image || dri->image->base.version < 11 || !dri->image->fromPlanar) { /* Preserve legacy behavior if plane is 0 */ if (plane == 0) - return _bo->stride; + return _bo->v0.stride; errno = ENOSYS; return 0; @@ -819,7 +819,7 @@ gbm_dri_bo_get_stride(struct gbm_bo *_bo, int plane) if (bo->image == NULL) { assert(plane == 0); - return _bo->stride; + return _bo->v0.stride; } image = dri->image->fromPlanar(bo->image, plane, NULL); @@ -915,7 +915,7 @@ gbm_dri_bo_destroy(struct gbm_bo *_bo) gbm_dri_bo_unmap_dumb(bo); memset(&arg, 0, sizeof(arg)); arg.handle = bo->handle; - drmIoctl(dri->base.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg); + drmIoctl(dri->base.v0.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &arg); } free(bo); @@ -992,7 +992,7 @@ gbm_dri_bo_import(struct gbm_device *gbm, /* GBM's GBM_FORMAT_* tokens are a strict superset of the DRI FourCC * tokens accepted by createImageFromFds, except for not supporting * the sARGB format. */ - fourcc = gbm_core.format_canonicalize(fd_data->format); + fourcc = gbm_core.v0.format_canonicalize(fd_data->format); image = dri->image->createImageFromFds(dri->screen, fd_data->width, @@ -1025,7 +1025,7 @@ gbm_dri_bo_import(struct gbm_device *gbm, /* GBM's GBM_FORMAT_* tokens are a strict superset of the DRI FourCC * tokens accepted by createImageFromDmaBufs2, except for not supporting * the sARGB format. */ - fourcc = gbm_core.format_canonicalize(fd_data->format); + fourcc = gbm_core.v0.format_canonicalize(fd_data->format); image = dri->image->createImageFromDmaBufs2(dri->screen, fd_data->width, fd_data->height, fourcc, @@ -1072,16 +1072,16 @@ gbm_dri_bo_import(struct gbm_device *gbm, } bo->base.gbm = gbm; - bo->base.format = gbm_format; + bo->base.v0.format = gbm_format; dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_WIDTH, - (int*)&bo->base.width); + (int*)&bo->base.v0.width); dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HEIGHT, - (int*)&bo->base.height); + (int*)&bo->base.v0.height); dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, - (int*)&bo->base.stride); + (int*)&bo->base.v0.stride); dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, - &bo->base.handle.s32); + &bo->base.v0.handle.s32); return &bo->base; } @@ -1116,16 +1116,16 @@ create_dumb(struct gbm_device *gbm, create_arg.width = width; create_arg.height = height; - ret = drmIoctl(dri->base.fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg); + ret = drmIoctl(dri->base.v0.fd, DRM_IOCTL_MODE_CREATE_DUMB, &create_arg); if (ret) goto free_bo; bo->base.gbm = gbm; - bo->base.width = width; - bo->base.height = height; - bo->base.stride = create_arg.pitch; - bo->base.format = format; - bo->base.handle.u32 = create_arg.handle; + bo->base.v0.width = width; + bo->base.v0.height = height; + bo->base.v0.stride = create_arg.pitch; + bo->base.v0.format = format; + bo->base.v0.handle.u32 = create_arg.handle; bo->handle = create_arg.handle; bo->size = create_arg.size; @@ -1137,7 +1137,7 @@ create_dumb(struct gbm_device *gbm, destroy_dumb: memset(&destroy_arg, 0, sizeof destroy_arg); destroy_arg.handle = create_arg.handle; - drmIoctl(dri->base.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg); + drmIoctl(dri->base.v0.fd, DRM_IOCTL_MODE_DESTROY_DUMB, &destroy_arg); free_bo: free(bo); @@ -1161,7 +1161,7 @@ gbm_dri_bo_create(struct gbm_device *gbm, */ assert(!(usage && count)); - format = gbm_core.format_canonicalize(format); + format = gbm_core.v0.format_canonicalize(format); if (usage & GBM_BO_USE_WRITE || dri->image == NULL) return create_dumb(gbm, width, height, format, usage); @@ -1171,9 +1171,9 @@ gbm_dri_bo_create(struct gbm_device *gbm, return NULL; bo->base.gbm = gbm; - bo->base.width = width; - bo->base.height = height; - bo->base.format = format; + bo->base.v0.width = width; + bo->base.v0.height = height; + bo->base.v0.format = format; dri_format = gbm_format_to_dri_format(format); if (dri_format == 0) { @@ -1209,9 +1209,9 @@ gbm_dri_bo_create(struct gbm_device *gbm, assert(gbm_dri_bo_get_modifier(&bo->base) != DRM_FORMAT_MOD_INVALID); dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_HANDLE, - &bo->base.handle.s32); + &bo->base.v0.handle.s32); dri->image->queryImage(bo->image, __DRI_IMAGE_ATTRIB_STRIDE, - (int *) &bo->base.stride); + (int *) &bo->base.v0.stride); return &bo->base; @@ -1231,8 +1231,8 @@ gbm_dri_bo_map(struct gbm_bo *_bo, /* If it's a dumb buffer, we already have a mapping */ if (bo->map) { - *map_data = (char *)bo->map + (bo->base.stride * y) + (x * 4); - *stride = bo->base.stride; + *map_data = (char *)bo->map + (bo->base.v0.stride * y) + (x * 4); + *stride = bo->base.v0.stride; return *map_data; } @@ -1320,17 +1320,17 @@ gbm_dri_surface_create(struct gbm_device *gbm, } surf->base.gbm = gbm; - surf->base.width = width; - surf->base.height = height; - surf->base.format = gbm_core.format_canonicalize(format); - surf->base.flags = flags; + surf->base.v0.width = width; + surf->base.v0.height = height; + surf->base.v0.format = gbm_core.v0.format_canonicalize(format); + surf->base.v0.flags = flags; if (!modifiers) { assert(!count); return &surf->base; } - surf->base.modifiers = calloc(count, sizeof(*modifiers)); - if (count && !surf->base.modifiers) { + surf->base.v0.modifiers = calloc(count, sizeof(*modifiers)); + if (count && !surf->base.v0.modifiers) { errno = ENOMEM; free(surf); return NULL; @@ -1340,8 +1340,8 @@ gbm_dri_surface_create(struct gbm_device *gbm, * created. This deferred creation can fail due to a modifier-format * mismatch. The result is the client has a surface but no object to back it. */ - surf->base.count = count; - memcpy(surf->base.modifiers, modifiers, count * sizeof(*modifiers)); + surf->base.v0.count = count; + memcpy(surf->base.v0.modifiers, modifiers, count * sizeof(*modifiers)); return &surf->base; } @@ -1351,7 +1351,7 @@ gbm_dri_surface_destroy(struct gbm_surface *_surf) { struct gbm_dri_surface *surf = gbm_dri_surface(_surf); - free(surf->base.modifiers); + free(surf->base.v0.modifiers); free(surf); } @@ -1375,38 +1375,46 @@ dri_destroy(struct gbm_device *gbm) } static struct gbm_device * -dri_device_create(int fd) +dri_device_create(int fd, uint32_t gbm_backend_version) { struct gbm_dri_device *dri; int ret; bool force_sw; + /* + * Since the DRI backend is built-in to the loader, the loader ABI version is + * guaranteed to match this backend's ABI version + */ + assert(gbm_core.v0.core_version == GBM_BACKEND_ABI_VERSION); + assert(gbm_core.v0.core_version == gbm_backend_version); + dri = calloc(1, sizeof *dri); if (!dri) return NULL; - dri->base.fd = fd; - dri->base.bo_create = gbm_dri_bo_create; - dri->base.bo_import = gbm_dri_bo_import; - dri->base.bo_map = gbm_dri_bo_map; - dri->base.bo_unmap = gbm_dri_bo_unmap; - dri->base.is_format_supported = gbm_dri_is_format_supported; - dri->base.get_format_modifier_plane_count = + dri->base.v0.fd = fd; + dri->base.v0.backend_version = gbm_backend_version; + dri->base.v0.bo_create = gbm_dri_bo_create; + dri->base.v0.bo_import = gbm_dri_bo_import; + dri->base.v0.bo_map = gbm_dri_bo_map; + dri->base.v0.bo_unmap = gbm_dri_bo_unmap; + dri->base.v0.is_format_supported = gbm_dri_is_format_supported; + dri->base.v0.get_format_modifier_plane_count = gbm_dri_get_format_modifier_plane_count; - dri->base.bo_write = gbm_dri_bo_write; - dri->base.bo_get_fd = gbm_dri_bo_get_fd; - dri->base.bo_get_planes = gbm_dri_bo_get_planes; - dri->base.bo_get_handle = gbm_dri_bo_get_handle_for_plane; - dri->base.bo_get_plane_fd = gbm_dri_bo_get_plane_fd; - dri->base.bo_get_stride = gbm_dri_bo_get_stride; - dri->base.bo_get_offset = gbm_dri_bo_get_offset; - dri->base.bo_get_modifier = gbm_dri_bo_get_modifier; - dri->base.bo_destroy = gbm_dri_bo_destroy; - dri->base.destroy = dri_destroy; - dri->base.surface_create = gbm_dri_surface_create; - dri->base.surface_destroy = gbm_dri_surface_destroy; + dri->base.v0.bo_write = gbm_dri_bo_write; + dri->base.v0.bo_get_fd = gbm_dri_bo_get_fd; + dri->base.v0.bo_get_planes = gbm_dri_bo_get_planes; + dri->base.v0.bo_get_handle = gbm_dri_bo_get_handle_for_plane; + dri->base.v0.bo_get_plane_fd = gbm_dri_bo_get_plane_fd; + dri->base.v0.bo_get_stride = gbm_dri_bo_get_stride; + dri->base.v0.bo_get_offset = gbm_dri_bo_get_offset; + dri->base.v0.bo_get_modifier = gbm_dri_bo_get_modifier; + dri->base.v0.bo_destroy = gbm_dri_bo_destroy; + dri->base.v0.destroy = dri_destroy; + dri->base.v0.surface_create = gbm_dri_surface_create; + dri->base.v0.surface_destroy = gbm_dri_surface_destroy; - dri->base.name = "drm"; + dri->base.v0.name = "drm"; dri->visual_table = gbm_dri_visuals_table; dri->num_visuals = ARRAY_SIZE(gbm_dri_visuals_table); @@ -1434,6 +1442,7 @@ err_dri: } struct gbm_backend gbm_dri_backend = { - .backend_name = "dri", - .create_device = dri_device_create, + .v0.backend_version = GBM_BACKEND_ABI_VERSION, + .v0.backend_name = "dri", + .v0.create_device = dri_device_create, }; diff --git a/src/gbm/backends/dri/gbm_driint.h b/src/gbm/backends/dri/gbm_driint.h index d321fe2be07..9e77ba5887c 100644 --- a/src/gbm/backends/dri/gbm_driint.h +++ b/src/gbm/backends/dri/gbm_driint.h @@ -170,12 +170,12 @@ gbm_dri_bo_map_dumb(struct gbm_dri_bo *bo) memset(&map_arg, 0, sizeof(map_arg)); map_arg.handle = bo->handle; - ret = drmIoctl(bo->base.gbm->fd, DRM_IOCTL_MODE_MAP_DUMB, &map_arg); + ret = drmIoctl(bo->base.gbm->v0.fd, DRM_IOCTL_MODE_MAP_DUMB, &map_arg); if (ret) return NULL; bo->map = mmap(0, bo->size, PROT_WRITE, - MAP_SHARED, bo->base.gbm->fd, map_arg.offset); + MAP_SHARED, bo->base.gbm->v0.fd, map_arg.offset); if (bo->map == MAP_FAILED) { bo->map = NULL; return NULL; diff --git a/src/gbm/main/backend.c b/src/gbm/main/backend.c index f22600b9d8b..c5824a1a392 100644 --- a/src/gbm/main/backend.c +++ b/src/gbm/main/backend.c @@ -30,10 +30,12 @@ #include #include #include +#include #include "backend.h" #define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) +#define VER_MIN(a, b) ((a) < (b) ? (a) : (b)) extern const struct gbm_backend gbm_dri_backend; @@ -51,15 +53,19 @@ find_backend(const char *name, int fd) { struct gbm_device *dev = NULL; unsigned i; + uint32_t abi_ver; for (i = 0; i < ARRAY_SIZE(backends); ++i) { if (name && strcmp(backends[i].name, name)) continue; - dev = backends[i].backend->create_device(fd); + abi_ver = VER_MIN(GBM_BACKEND_ABI_VERSION, + backends[i].backend->v0.backend_version); + dev = backends[i].backend->v0.create_device(fd, abi_ver); if (dev) { - dev->backend_desc = &backends[i]; + assert(abi_ver == dev->v0.backend_version); + dev->v0.backend_desc = &backends[i]; break; } } @@ -96,5 +102,5 @@ _gbm_create_device(int fd) void _gbm_device_destroy(struct gbm_device *gbm) { - gbm->destroy(gbm); + gbm->v0.destroy(gbm); } diff --git a/src/gbm/main/gbm.c b/src/gbm/main/gbm.c index 8831350257c..d81931a7483 100644 --- a/src/gbm/main/gbm.c +++ b/src/gbm/main/gbm.c @@ -52,7 +52,7 @@ GBM_EXPORT int gbm_device_get_fd(struct gbm_device *gbm) { - return gbm->fd; + return gbm->v0.fd; } /** Get the backend name for the given gbm device @@ -63,7 +63,7 @@ gbm_device_get_fd(struct gbm_device *gbm) GBM_EXPORT const char * gbm_device_get_backend_name(struct gbm_device *gbm) { - return gbm->name; + return gbm->v0.name; } /** Test if a format is supported for a given set of usage flags. @@ -82,7 +82,7 @@ GBM_EXPORT int gbm_device_is_format_supported(struct gbm_device *gbm, uint32_t format, uint32_t usage) { - return gbm->is_format_supported(gbm, format, usage); + return gbm->v0.is_format_supported(gbm, format, usage); } /** Get the number of planes that are required for a given format+modifier @@ -96,7 +96,7 @@ gbm_device_get_format_modifier_plane_count(struct gbm_device *gbm, uint32_t format, uint64_t modifier) { - return gbm->get_format_modifier_plane_count(gbm, format, modifier); + return gbm->v0.get_format_modifier_plane_count(gbm, format, modifier); } /** Destroy the gbm device and free all resources associated with it. @@ -150,7 +150,7 @@ gbm_create_device(int fd) GBM_EXPORT uint32_t gbm_bo_get_width(struct gbm_bo *bo) { - return bo->width; + return bo->v0.width; } /** Get the height of the buffer object @@ -161,7 +161,7 @@ gbm_bo_get_width(struct gbm_bo *bo) GBM_EXPORT uint32_t gbm_bo_get_height(struct gbm_bo *bo) { - return bo->height; + return bo->v0.height; } /** Get the stride of the buffer object @@ -188,7 +188,7 @@ gbm_bo_get_stride(struct gbm_bo *bo) GBM_EXPORT uint32_t gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane) { - return bo->gbm->bo_get_stride(bo, plane); + return bo->gbm->v0.bo_get_stride(bo, plane); } /** Get the format of the buffer object @@ -201,7 +201,7 @@ gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane) GBM_EXPORT uint32_t gbm_bo_get_format(struct gbm_bo *bo) { - return bo->format; + return bo->v0.format; } /** Get the bit-per-pixel of the buffer object's format @@ -219,7 +219,7 @@ gbm_bo_get_format(struct gbm_bo *bo) GBM_EXPORT uint32_t gbm_bo_get_bpp(struct gbm_bo *bo) { - switch (bo->format) { + switch (bo->v0.format) { default: return 0; case GBM_FORMAT_C8: @@ -285,7 +285,7 @@ gbm_bo_get_bpp(struct gbm_bo *bo) GBM_EXPORT uint32_t gbm_bo_get_offset(struct gbm_bo *bo, int plane) { - return bo->gbm->bo_get_offset(bo, plane); + return bo->gbm->v0.bo_get_offset(bo, plane); } /** Get the gbm device used to create the buffer object @@ -310,7 +310,7 @@ gbm_bo_get_device(struct gbm_bo *bo) GBM_EXPORT union gbm_bo_handle gbm_bo_get_handle(struct gbm_bo *bo) { - return bo->handle; + return bo->v0.handle; } /** Get a DMA-BUF file descriptor for the buffer object @@ -327,7 +327,7 @@ gbm_bo_get_handle(struct gbm_bo *bo) GBM_EXPORT int gbm_bo_get_fd(struct gbm_bo *bo) { - return bo->gbm->bo_get_fd(bo); + return bo->gbm->v0.bo_get_fd(bo); } /** Get the number of planes for the given bo. @@ -338,7 +338,7 @@ gbm_bo_get_fd(struct gbm_bo *bo) GBM_EXPORT int gbm_bo_get_plane_count(struct gbm_bo *bo) { - return bo->gbm->bo_get_planes(bo); + return bo->gbm->v0.bo_get_planes(bo); } /** Get the handle for the specified plane of the buffer object @@ -356,7 +356,7 @@ gbm_bo_get_plane_count(struct gbm_bo *bo) GBM_EXPORT union gbm_bo_handle gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane) { - return bo->gbm->bo_get_handle(bo, plane); + return bo->gbm->v0.bo_get_handle(bo, plane); } /** Get a DMA-BUF file descriptor for the specified plane of the buffer object @@ -376,7 +376,7 @@ gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane) GBM_EXPORT int gbm_bo_get_fd_for_plane(struct gbm_bo *bo, int plane) { - return bo->gbm->bo_get_plane_fd(bo, plane); + return bo->gbm->v0.bo_get_plane_fd(bo, plane); } /** @@ -395,7 +395,7 @@ gbm_bo_get_fd_for_plane(struct gbm_bo *bo, int plane) GBM_EXPORT uint64_t gbm_bo_get_modifier(struct gbm_bo *bo) { - return bo->gbm->bo_get_modifier(bo); + return bo->gbm->v0.bo_get_modifier(bo); } /** Write data into the buffer object @@ -414,7 +414,7 @@ gbm_bo_get_modifier(struct gbm_bo *bo) GBM_EXPORT int gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count) { - return bo->gbm->bo_write(bo, buf, count); + return bo->gbm->v0.bo_write(bo, buf, count); } /** Set the user data associated with a buffer object @@ -428,8 +428,8 @@ GBM_EXPORT void gbm_bo_set_user_data(struct gbm_bo *bo, void *data, void (*destroy_user_data)(struct gbm_bo *, void *)) { - bo->user_data = data; - bo->destroy_user_data = destroy_user_data; + bo->v0.user_data = data; + bo->v0.destroy_user_data = destroy_user_data; } /** Get the user data associated with a buffer object @@ -443,7 +443,7 @@ gbm_bo_set_user_data(struct gbm_bo *bo, void *data, GBM_EXPORT void * gbm_bo_get_user_data(struct gbm_bo *bo) { - return bo->user_data; + return bo->v0.user_data; } /** @@ -455,10 +455,10 @@ gbm_bo_get_user_data(struct gbm_bo *bo) GBM_EXPORT void gbm_bo_destroy(struct gbm_bo *bo) { - if (bo->destroy_user_data) - bo->destroy_user_data(bo, bo->user_data); + if (bo->v0.destroy_user_data) + bo->v0.destroy_user_data(bo, bo->v0.user_data); - bo->gbm->bo_destroy(bo); + bo->gbm->v0.bo_destroy(bo); } /** @@ -487,7 +487,7 @@ gbm_bo_create(struct gbm_device *gbm, return NULL; } - return gbm->bo_create(gbm, width, height, format, usage, NULL, 0); + return gbm->v0.bo_create(gbm, width, height, format, usage, NULL, 0); } GBM_EXPORT struct gbm_bo * @@ -507,7 +507,7 @@ gbm_bo_create_with_modifiers(struct gbm_device *gbm, return NULL; } - return gbm->bo_create(gbm, width, height, format, 0, modifiers, count); + return gbm->v0.bo_create(gbm, width, height, format, 0, modifiers, count); } /** @@ -541,7 +541,7 @@ GBM_EXPORT struct gbm_bo * gbm_bo_import(struct gbm_device *gbm, uint32_t type, void *buffer, uint32_t usage) { - return gbm->bo_import(gbm, type, buffer, usage); + return gbm->v0.bo_import(gbm, type, buffer, usage); } /** @@ -583,8 +583,8 @@ gbm_bo_map(struct gbm_bo *bo, return NULL; } - return bo->gbm->bo_map(bo, x, y, width, height, - flags, stride, map_data); + return bo->gbm->v0.bo_map(bo, x, y, width, height, + flags, stride, map_data); } /** @@ -599,7 +599,7 @@ gbm_bo_map(struct gbm_bo *bo, GBM_EXPORT void gbm_bo_unmap(struct gbm_bo *bo, void *map_data) { - bo->gbm->bo_unmap(bo, map_data); + bo->gbm->v0.bo_unmap(bo, map_data); } /** @@ -621,7 +621,7 @@ gbm_surface_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags) { - return gbm->surface_create(gbm, width, height, format, flags, NULL, 0); + return gbm->v0.surface_create(gbm, width, height, format, flags, NULL, 0); } GBM_EXPORT struct gbm_surface * @@ -636,8 +636,8 @@ gbm_surface_create_with_modifiers(struct gbm_device *gbm, return NULL; } - return gbm->surface_create(gbm, width, height, format, 0, - modifiers, count); + return gbm->v0.surface_create(gbm, width, height, format, 0, + modifiers, count); } /** @@ -652,7 +652,7 @@ gbm_surface_create_with_modifiers(struct gbm_device *gbm, GBM_EXPORT void gbm_surface_destroy(struct gbm_surface *surf) { - surf->gbm->surface_destroy(surf); + surf->gbm->v0.surface_destroy(surf); } /** @@ -679,7 +679,7 @@ gbm_surface_destroy(struct gbm_surface *surf) GBM_EXPORT struct gbm_bo * gbm_surface_lock_front_buffer(struct gbm_surface *surf) { - return surf->gbm->surface_lock_front_buffer(surf); + return surf->gbm->v0.surface_lock_front_buffer(surf); } /** @@ -697,7 +697,7 @@ gbm_surface_lock_front_buffer(struct gbm_surface *surf) GBM_EXPORT void gbm_surface_release_buffer(struct gbm_surface *surf, struct gbm_bo *bo) { - surf->gbm->surface_release_buffer(surf, bo); + surf->gbm->v0.surface_release_buffer(surf, bo); } /** @@ -719,7 +719,7 @@ gbm_surface_release_buffer(struct gbm_surface *surf, struct gbm_bo *bo) GBM_EXPORT int gbm_surface_has_free_buffers(struct gbm_surface *surf) { - return surf->gbm->surface_has_free_buffers(surf); + return surf->gbm->v0.surface_has_free_buffers(surf); } /* The two GBM_BO_FORMAT_[XA]RGB8888 formats alias the GBM_FORMAT_* @@ -763,5 +763,6 @@ gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc) * code that need to be accessed directly by GBM backends. */ struct gbm_core gbm_core = { - .format_canonicalize = format_canonicalize, + .v0.core_version = GBM_BACKEND_ABI_VERSION, + .v0.format_canonicalize = format_canonicalize, }; diff --git a/src/gbm/main/gbm_backend_abi.h b/src/gbm/main/gbm_backend_abi.h index 6b802826306..1bf73b75120 100644 --- a/src/gbm/main/gbm_backend_abi.h +++ b/src/gbm/main/gbm_backend_abi.h @@ -1,5 +1,6 @@ /* * Copyright © 2011 Intel Corporation + * Copyright © 2021 NVIDIA Corporation * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -23,6 +24,7 @@ * * Authors: * Benjamin Franzke + * James Jones */ #ifndef GBM_BACKEND_ABI_H_ @@ -38,16 +40,68 @@ struct gbm_backend_desc; /** - * The device used for the memory allocation. + * The GBM backend interface version defined by this file. * - * The members of this structure should be not accessed directly + * The GBM device interface version must be incremented whenever the structures + * defined in this file are modified. To preserve ABI compatibility with + * backends that support only older versions, modifications to this file must + * consist only of appending new fields to the end of the structures defined in + * it, defining new structures, or declaring new exported functions or global + * variables. + * + * Note this version applies to ALL structures in this file, not just the core, + * backend, and device structures which contain it explicitly. Buffer objects, + * surfaces, and any other new structures introduced to this file are also part + * of the backend ABI. The ABI version of an instance of any object in this file + * is defined as the minimum of the version of the backend associated with the + * object instance and the loader's core object version. Hence, any new objects + * added to this file should contain either a reference to an existing object + * defined here, or an explicit version field. + * + * A few examples of object versions: + * + * Backend ABI version: 0 + * Core ABI version: 3 + * ABI version of a device created by the backend: 0 + * + * Backend ABI version: 2 + * Core ABI version: 1 + * ABI version of a surface created by a device from the backend: 1 + * + * Backend ABI version: 4 + * Core ABI version: 4 + * ABI version of a buffer object created by a device from the backend: 4 */ -struct gbm_device { - /* Hack to make a gbm_device detectable by its first element. */ - struct gbm_device *(*dummy)(int); +#define GBM_BACKEND_ABI_VERSION 0 +/** + * GBM device interface corresponding to GBM_BACKEND_ABI_VERSION = 0 + * + * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_bo_v1, increment + * GBM_BACKEND_ABI_VERSION, and append gbm_bo_v1 to gbm_bo. + */ +struct gbm_device_v0 { const struct gbm_backend_desc *backend_desc; + /** + * The version of the GBM backend interface supported by this device and its + * child objects. This may be less than the maximum version supported by the + * GBM loader if the device was created by an older backend, or less than the + * maximum version supported by the backend if the device was created by an + * older loader. In other words, this will be: + * + * MIN(backend GBM interface version, loader GBM interface version) + * + * It is the backend's responsibility to assign this field the value passed + * in by the GBM loader to the backend's create_device function. The GBM + * loader will pre-clamp the value based on the loader version and the + * version reported by the backend in its gbm_backend_v0::backend_version + * field. It is the loader's responsibility to respect this version when + * directly accessing a device instance or any child objects instantiated by + * a device instance. + */ + uint32_t backend_version; + int fd; const char *name; @@ -96,12 +150,26 @@ struct gbm_device { }; /** - * The allocated buffer object. + * The device used for the memory allocation. * - * The members in this structure should not be accessed directly. + * The members of this structure should be not accessed directly + * + * To modify this structure, introduce a new gbm_device_v structure, add it + * to the end of this structure, and increment GBM_BACKEND_ABI_VERSION. */ -struct gbm_bo { - struct gbm_device *gbm; +struct gbm_device { + /* Hack to make a gbm_device detectable by its first element. */ + struct gbm_device *(*dummy)(int); + struct gbm_device_v0 v0; +}; + +/** + * GBM buffer object interface corresponding to GBM_BACKEND_ABI_VERSION = 0 + * + * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_bo_v1, increment + * GBM_BACKEND_ABI_VERSION, and append gbm_bo_v1 to gbm_bo. + */ +struct gbm_bo_v0 { uint32_t width; uint32_t height; uint32_t stride; @@ -111,8 +179,26 @@ struct gbm_bo { void (*destroy_user_data)(struct gbm_bo *, void *); }; -struct gbm_surface { +/** + * The allocated buffer object. + * + * The members in this structure should not be accessed directly. + * + * To modify this structure, introduce a new gbm_bo_v structure, add it to + * the end of this structure, and increment GBM_BACKEND_ABI_VERSION. + */ +struct gbm_bo { struct gbm_device *gbm; + struct gbm_bo_v0 v0; +}; + +/** + * GBM surface interface corresponding to GBM_BACKEND_ABI_VERSION = 0 + * + * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_surface_v1, increment + * GBM_BACKEND_ABI_VERSION, and append gbm_surface_v1 to gbm_surface. + */ +struct gbm_surface_v0 { uint32_t width; uint32_t height; uint32_t format; @@ -123,13 +209,73 @@ struct gbm_surface { }; }; -struct gbm_backend { - const char *backend_name; - struct gbm_device *(*create_device)(int fd); +/** + * An allocated GBM surface. + * + * To modify this structure, introduce a new gbm_surface_v structure, add it + * to the end of this structure, and increment GBM_BACKEND_ABI_VERSION. + */ +struct gbm_surface { + struct gbm_device *gbm; + struct gbm_surface_v0 v0; }; -struct gbm_core { +/** + * GBM backend interfaces corresponding to GBM_BACKEND_ABI_VERSION = 0 + * + * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_backend_v1, increment + * GBM_BACKEND_ABI_VERSION, append gbm_backend_v1 to gbm_backend. + */ +struct gbm_backend_v0 { + /** + * The version of the GBM backend interface supported by this backend. This + * is set by the backend itself, and may be greater or less than the version + * supported by the loader. It is the responsibility of the GBM loader to + * respect this version when accessing fields in this structure. + */ + uint32_t backend_version; + + const char *backend_name; + struct gbm_device *(*create_device)(int fd, uint32_t gbm_backend_version); +}; + +/** + * The interface exposed by an external GBM backend. + * + * To modify this structure, introduce a new gbm_backend_v structure, add it + * to the end of this structure, and increment GBM_BACKEND_ABI_VERSION. + */ +struct gbm_backend { + struct gbm_backend_v0 v0; +}; + +/** + * GBM interfaces exposed to GBM backends at GBM_BACKEND_ABI_VERSION >= 0 + * + * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_core_v1, increment + * GBM_BACKEND_ABI_VERSION, and append gbm_core_v1 to gbm_backend. + */ +struct gbm_core_v0 { + /** + * The version of the GBM backend interface supported by the GBM loader. This + * is set by the loader, and may be greater or less than the version + * supported by a given backend. It is the responsibility of the backend to + * respect this version when accessing fields in this structure and other + * structures allocated or modified by the loader. + */ + uint32_t core_version; + uint32_t (*format_canonicalize)(uint32_t gbm_format); }; +/** + * The interface exposed by the GBM core/loader code to GBM backends. + * + * To modify this structure, introduce a new gbm_core_v structure, add it + * to the end of this structure, and increment GBM_BACKEND_ABI_VERSION. + */ +struct gbm_core { + struct gbm_core_v0 v0; +}; + #endif