From: Changyeon Lee Date: Fri, 30 Apr 2021 05:44:43 +0000 (+0900) Subject: Sync with codes from mesa 21.0.0 version X-Git-Tag: submit/tizen/20210618.071836~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c9106dbb9185d895b7b064ffcd3d4753eb1c5f07;p=platform%2Fcore%2Fuifw%2Flibgbm.git Sync with codes from mesa 21.0.0 version Change-Id: I5c692b622985a2f82661c20c8a0a11ada458ac98 --- diff --git a/backends/tbm/gbm_tbm.c b/backends/tbm/gbm_tbm.c index b000f34..b4a9da8 100644 --- a/backends/tbm/gbm_tbm.c +++ b/backends/tbm/gbm_tbm.c @@ -216,7 +216,9 @@ __gbm_tbm_bo_create_by_tbm_surface(struct gbm_device *gbm, static struct gbm_bo * __gbm_tbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, - uint32_t format, uint32_t usage) + uint32_t format, uint32_t usage, + const uint64_t *modifiers, + const unsigned int count) { tbm_surface_h tbm_surf; int flags = TBM_BO_DEFAULT; @@ -255,7 +257,9 @@ __gbm_tbm_get_gbm_bo(tbm_surface_h surf) static struct gbm_surface * __gbm_tbm_surface_create(struct gbm_device *gbm, uint32_t width, uint32_t height, - uint32_t format, uint32_t flags) + uint32_t format, uint32_t flags, + const uint64_t *modifiers, + const unsigned count) { struct gbm_tbm_surface *surf; int tbm_flags = 0; diff --git a/src/backend.c b/src/backend.c index 8749f57..b556864 100644 --- a/src/backend.c +++ b/src/backend.c @@ -30,15 +30,11 @@ #include #include #include -#include -#include "config.h" #include "backend.h" #define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) -static void *g_gbm_module; - #if HAVE_TBM extern const struct gbm_backend gbm_tbm_backend; #endif @@ -57,42 +53,14 @@ static const struct backend_desc backends[] = { static const void * load_backend(const struct backend_desc *backend) { - char path[PATH_MAX]; const void *init = NULL; - void *module = NULL; - const char *name; - const char *entrypoint = "gbm_backend"; if (backend == NULL) return NULL; - if (g_gbm_module) - return NULL; - - name = backend->name; - if (backend->builtin) { init = backend->builtin; - } else { - if (name[0] != '/') - snprintf(path, sizeof path, MODULEDIR "/%s", name); - else - snprintf(path, sizeof path, "%s", name); - - module = dlopen(path, RTLD_NOW | RTLD_GLOBAL); - if (!module) { - fprintf(stderr, - "failed to load module: %s\n", dlerror()); - return NULL; - } - - init = dlsym(module, entrypoint); - if (!init) { - dlclose(module); - return NULL; - } } - g_gbm_module = module; return init; } @@ -138,13 +106,3 @@ _gbm_create_device(int fd) return dev; } - -void -_gbm_close_device(void) -{ - if (g_gbm_module) { - dlclose(g_gbm_module); - g_gbm_module = NULL; - } -} - diff --git a/src/backend.h b/src/backend.h index 8609196..4a64375 100644 --- a/src/backend.h +++ b/src/backend.h @@ -32,7 +32,5 @@ struct gbm_device * _gbm_create_device(int fd); -void -_gbm_close_device(void); #endif diff --git a/src/gbm.c b/src/gbm.c index e62b694..954b3c3 100644 --- a/src/gbm.c +++ b/src/gbm.c @@ -31,20 +31,20 @@ #include #include -#include +#ifdef MAJOR_IN_MKDEV +#include +#endif +#ifdef MAJOR_IN_SYSMACROS +#include +#endif #include #include +#include #include "gbm.h" #include "gbmint.h" #include "backend.h" -#define ARRAY_SIZE(a) (sizeof(a)/sizeof((a)[0])) - -static struct gbm_device *devices[16]; - -static int device_num = 0; - /** Returns the file description for the gbm device * * \return The fd that the struct gbm_device was created with @@ -55,7 +55,6 @@ gbm_device_get_fd(struct gbm_device *gbm) return gbm->fd; } -/* FIXME: maybe superfluous, use udev subclass from the fd? */ /** Get the backend name for the given gbm device * * \return The backend name string - this belongs to the device and must not @@ -83,19 +82,23 @@ GBM_EXPORT int gbm_device_is_format_supported(struct gbm_device *gbm, uint32_t format, uint32_t usage) { - switch (format) - { - case GBM_BO_FORMAT_XRGB8888: - format = GBM_FORMAT_XRGB8888; - break; - case GBM_BO_FORMAT_ARGB8888: - format = GBM_FORMAT_ABGR8888; - break; - } - return gbm->is_format_supported(gbm, format, usage); } +/** Get the number of planes that are required for a given format+modifier + * + * \param gbm The gbm device returned from gbm_create_device() + * \param format The format to query + * \param modifier The modifier to query + */ +GBM_EXPORT int +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); +} + /** Destroy the gbm device and free all resources associated with it. * * \param gbm The device created using gbm_create_device() @@ -104,10 +107,8 @@ GBM_EXPORT void gbm_device_destroy(struct gbm_device *gbm) { gbm->refcount--; - if (gbm->refcount == 0) { + if (gbm->refcount == 0) gbm->destroy(gbm); - _gbm_close_device(); - } } /** Create a gbm device for allocating buffers @@ -117,7 +118,7 @@ gbm_device_destroy(struct gbm_device *gbm) * the file descriptor returned when opening a device such as \c * /dev/dri/card0 * - * \param fd The file descriptor for an backend specific device + * \param fd The file descriptor for a backend specific device * \return The newly created struct gbm_device. The resources associated with * the device should be freed with gbm_device_destroy() when it is no longer * needed. If the creation of the device failed NULL will be returned. @@ -129,13 +130,10 @@ gbm_create_device(int fd) struct stat buf; if (fd < 0 || fstat(fd, &buf) < 0 || !S_ISCHR(buf.st_mode)) { - fprintf(stderr, "gbm_create_device: invalid fd: %d\n", fd); + errno = EINVAL; return NULL; } - if (device_num == 0) - memset(devices, 0, sizeof devices); - gbm = _gbm_create_device(fd); if (gbm == NULL) return NULL; @@ -144,9 +142,6 @@ gbm_create_device(int fd) gbm->stat = buf; gbm->refcount = 1; - if (device_num < ARRAY_SIZE(devices)-1) - devices[device_num++] = gbm; - return gbm; } @@ -156,7 +151,7 @@ gbm_create_device(int fd) * \return The width of the allocated buffer object * */ -GBM_EXPORT unsigned int +GBM_EXPORT uint32_t gbm_bo_get_width(struct gbm_bo *bo) { return bo->width; @@ -167,7 +162,7 @@ gbm_bo_get_width(struct gbm_bo *bo) * \param bo The buffer object * \return The height of the allocated buffer object */ -GBM_EXPORT unsigned int +GBM_EXPORT uint32_t gbm_bo_get_height(struct gbm_bo *bo) { return bo->height; @@ -184,7 +179,20 @@ gbm_bo_get_height(struct gbm_bo *bo) GBM_EXPORT uint32_t gbm_bo_get_stride(struct gbm_bo *bo) { - return bo->stride; + return gbm_bo_get_stride_for_plane(bo, 0); +} + +/** Get the stride for the given plane + * + * \param bo The buffer object + * \param plane for which you want the stride + * + * \sa gbm_bo_get_stride() + */ +GBM_EXPORT uint32_t +gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane) +{ + return bo->gbm->bo_get_stride(bo, plane); } /** Get the format of the buffer object @@ -192,7 +200,7 @@ gbm_bo_get_stride(struct gbm_bo *bo) * The format of the pixels in the buffer. * * \param bo The buffer object - * \return The format of buffer object, on of the GBM_FORMAT_* codes + * \return The format of buffer object, one of the GBM_FORMAT_* codes */ GBM_EXPORT uint32_t gbm_bo_get_format(struct gbm_bo *bo) @@ -200,6 +208,101 @@ gbm_bo_get_format(struct gbm_bo *bo) return bo->format; } +/** Get the bit-per-pixel of the buffer object's format + * + * The bits-per-pixel of the buffer object's format. + * + * Note; The 'in-memory pixel' concept makes no sense for YUV formats + * (pixels are the result of the combination of multiple memory sources: + * Y, Cb & Cr; usually these are even in separate buffers), so YUV + * formats are not supported by this function. + * + * \param bo The buffer object + * \return The number of bits0per-pixel of the buffer object's format. + */ +GBM_EXPORT uint32_t +gbm_bo_get_bpp(struct gbm_bo *bo) +{ + switch (bo->format) { + default: + return 0; + case GBM_FORMAT_C8: + case GBM_FORMAT_R8: + case GBM_FORMAT_RGB332: + case GBM_FORMAT_BGR233: + return 8; + case GBM_FORMAT_GR88: + case GBM_FORMAT_XRGB4444: + case GBM_FORMAT_XBGR4444: + case GBM_FORMAT_RGBX4444: + case GBM_FORMAT_BGRX4444: + case GBM_FORMAT_ARGB4444: + case GBM_FORMAT_ABGR4444: + case GBM_FORMAT_RGBA4444: + case GBM_FORMAT_BGRA4444: + case GBM_FORMAT_XRGB1555: + case GBM_FORMAT_XBGR1555: + case GBM_FORMAT_RGBX5551: + case GBM_FORMAT_BGRX5551: + case GBM_FORMAT_ARGB1555: + case GBM_FORMAT_ABGR1555: + case GBM_FORMAT_RGBA5551: + case GBM_FORMAT_BGRA5551: + case GBM_FORMAT_RGB565: + case GBM_FORMAT_BGR565: + return 16; + case GBM_FORMAT_RGB888: + case GBM_FORMAT_BGR888: + return 24; + case GBM_FORMAT_XRGB8888: + case GBM_FORMAT_XBGR8888: + case GBM_FORMAT_RGBX8888: + case GBM_FORMAT_BGRX8888: + case GBM_FORMAT_ARGB8888: + case GBM_FORMAT_ABGR8888: + case GBM_FORMAT_RGBA8888: + case GBM_FORMAT_BGRA8888: + case GBM_FORMAT_XRGB2101010: + case GBM_FORMAT_XBGR2101010: + case GBM_FORMAT_RGBX1010102: + case GBM_FORMAT_BGRX1010102: + case GBM_FORMAT_ARGB2101010: + case GBM_FORMAT_ABGR2101010: + case GBM_FORMAT_RGBA1010102: + case GBM_FORMAT_BGRA1010102: + return 32; + case GBM_FORMAT_XBGR16161616F: + case GBM_FORMAT_ABGR16161616F: + return 64; + } +} + +/** Get the offset for the data of the specified plane + * + * Extra planes, and even the first plane, may have an offset from the start of + * the buffer object. This function will provide the offset for the given plane + * to be used in various KMS APIs. + * + * \param bo The buffer object + * \return The offset + */ +GBM_EXPORT uint32_t +gbm_bo_get_offset(struct gbm_bo *bo, int plane) +{ + return bo->gbm->bo_get_offset(bo, plane); +} + +/** Get the gbm device used to create the buffer object + * + * \param bo The buffer object + * \return Returns the gbm device with which the buffer object was created + */ +GBM_EXPORT struct gbm_device * +gbm_bo_get_device(struct gbm_bo *bo) +{ + return bo->gbm; +} + /** Get the handle of the buffer object * * This is stored in the platform generic union gbm_bo_handle type. However @@ -217,12 +320,13 @@ gbm_bo_get_handle(struct gbm_bo *bo) /** Get a DMA-BUF file descriptor for the buffer object * * This function creates a DMA-BUF (also known as PRIME) file descriptor - * handle for the buffer object. Eeach call to gbm_bo_get_fd() returns a new + * handle for the buffer object. Each call to gbm_bo_get_fd() returns a new * file descriptor and the caller is responsible for closing the file * descriptor. * \param bo The buffer object - * \return Returns a file descriptor referring to the underlying buffer + * \return Returns a file descriptor referring to the underlying buffer or -1 + * if an error occurs. */ GBM_EXPORT int gbm_bo_get_fd(struct gbm_bo *bo) @@ -230,19 +334,66 @@ gbm_bo_get_fd(struct gbm_bo *bo) return bo->gbm->bo_get_fd(bo); } +/** Get the number of planes for the given bo. + * + * \param bo The buffer object + * \return The number of planes + */ +GBM_EXPORT int +gbm_bo_get_plane_count(struct gbm_bo *bo) +{ + return bo->gbm->bo_get_planes(bo); +} + +/** Get the handle for the specified plane of the buffer object + * + * This function gets the handle for any plane associated with the BO. When + * dealing with multi-planar formats, or formats which might have implicit + * planes based on different underlying hardware it is necessary for the client + * to be able to get this information to pass to the DRM. + * + * \param bo The buffer object + * \param plane the plane to get a handle for + * + * \sa gbm_bo_get_handle() + */ +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); +} + +/** + * Get the chosen modifier for the buffer object + * + * This function returns the modifier that was chosen for the object. These + * properties may be generic, or platform/implementation dependent. + * + * \param bo The buffer object + * \return Returns the selected modifier (chosen by the implementation) for the + * BO. + * \sa gbm_bo_create_with_modifiers() where possible modifiers are set + * \sa gbm_surface_create_with_modifiers() where possible modifiers are set + * \sa define DRM_FORMAT_MOD_* in drm_fourcc.h for possible modifiers + */ +GBM_EXPORT uint64_t +gbm_bo_get_modifier(struct gbm_bo *bo) +{ + return bo->gbm->bo_get_modifier(bo); +} /** Write data into the buffer object * * If the buffer object was created with the GBM_BO_USE_WRITE flag, - * this function can used to write data into the buffer object. The - * data is copied directly into the object and it's the responsiblity + * this function can be used to write data into the buffer object. The + * data is copied directly into the object and it's the responsibility * of the caller to make sure the data represents valid pixel data, * according to the width, height, stride and format of the buffer object. * * \param bo The buffer object * \param buf The data to write * \param count The number of bytes to write - * \return Returns -1 on error, 0 otherwise + * \return Returns 0 on success, otherwise -1 is returned an errno set */ GBM_EXPORT int gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count) @@ -250,17 +401,6 @@ gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count) return bo->gbm->bo_write(bo, buf, count); } -/** Get the gbm device used to create the buffer object - * - * \param bo The buffer object - * \return Returns the gbm device with which the buffer object was created - */ -GBM_EXPORT struct gbm_device * -gbm_bo_get_device(struct gbm_bo *bo) -{ - return bo->gbm; -} - /** Set the user data associated with a buffer object * * \param bo The buffer object @@ -311,14 +451,14 @@ gbm_bo_destroy(struct gbm_bo *bo) * \param gbm The gbm device returned from gbm_create_device() * \param width The width for the buffer * \param height The height for the buffer - * \param format The format to use for the buffer + * \param format The format to use for the buffer, from GBM_FORMAT_* or + * GBM_BO_FORMAT_* tokens * \param usage The union of the usage flags for this buffer * * \return A newly allocated buffer that should be freed with gbm_bo_destroy() * when no longer needed. If an error occurs during allocation %NULL will be - * returned. + * returned and errno set. * - * \sa enum gbm_bo_format for the list of formats * \sa enum gbm_bo_flags for the list of usage flags */ GBM_EXPORT struct gbm_bo * @@ -326,48 +466,58 @@ gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t usage) { - if (width == 0 || height == 0) + if (width == 0 || height == 0) { + errno = EINVAL; return NULL; + } + + return gbm->bo_create(gbm, width, height, format, usage, NULL, 0); +} - if (usage & GBM_BO_USE_CURSOR_64X64 && - (width != 64 || height != 64)) +GBM_EXPORT struct gbm_bo * +gbm_bo_create_with_modifiers(struct gbm_device *gbm, + uint32_t width, uint32_t height, + uint32_t format, + const uint64_t *modifiers, + const unsigned int count) +{ + if (width == 0 || height == 0) { + errno = EINVAL; return NULL; + } - switch (format) - { - case GBM_BO_FORMAT_XRGB8888: - format = GBM_FORMAT_XRGB8888; - break; - case GBM_BO_FORMAT_ARGB8888: - format = GBM_FORMAT_ABGR8888; - break; + if ((count && !modifiers) || (modifiers && !count)) { + errno = EINVAL; + return NULL; } - return gbm->bo_create(gbm, width, height, format, usage); + return gbm->bo_create(gbm, width, height, format, 0, modifiers, count); } /** - * Create a gbm buffer object from an foreign object + * Create a gbm buffer object from a foreign object * * This function imports a foreign object and creates a new gbm bo for it. - * This enabled using the foreign object with a display API such as KMS. - * Currently two types of foreign objects are supported, indicated by the type + * This enables using the foreign object with a display API such as KMS. + * Currently these types of foreign objects are supported, indicated by the type * argument: * * GBM_BO_IMPORT_WL_BUFFER * GBM_BO_IMPORT_EGL_IMAGE * GBM_BO_IMPORT_FD + * GBM_BO_IMPORT_FD_MODIFIER * - * The the gbm bo shares the underlying pixels but its life-time is + * The gbm bo shares the underlying pixels but its life-time is * independent of the foreign object. * * \param gbm The gbm device returned from gbm_create_device() - * \param gbm The type of object we're importing - * \param gbm Pointer to the external object + * \param type The type of object we're importing + * \param buffer Pointer to the external object * \param usage The union of the usage flags for this buffer * * \return A newly allocated buffer object that should be freed with - * gbm_bo_destroy() when no longer needed. + * gbm_bo_destroy() when no longer needed. On error, %NULL is returned + * and errno is set. * * \sa enum gbm_bo_flags for the list of usage flags */ @@ -378,6 +528,64 @@ gbm_bo_import(struct gbm_device *gbm, return gbm->bo_import(gbm, type, buffer, usage); } +/** + * Map a region of a gbm buffer object for cpu access + * + * This function maps a region of a gbm bo for cpu read and/or write + * access. + * + * The mapping exposes a linear view of the buffer object even if the buffer + * has a non-linear modifier. + * + * This function may require intermediate buffer copies (ie. it may be slow). + * + * \param bo The buffer object + * \param x The X (top left origin) starting position of the mapped region for + * the buffer + * \param y The Y (top left origin) starting position of the mapped region for + * the buffer + * \param width The width of the mapped region for the buffer + * \param height The height of the mapped region for the buffer + * \param flags The union of the GBM_BO_TRANSFER_* flags for this buffer + * \param stride Ptr for returned stride in bytes of the mapped region + * \param map_data Returned opaque ptr for the mapped region + * + * \return Address of the mapped buffer that should be unmapped with + * gbm_bo_unmap() when no longer needed. On error, %NULL is returned + * and errno is set. + * + * \sa enum gbm_bo_transfer_flags for the list of flags + */ +GBM_EXPORT void * +gbm_bo_map(struct gbm_bo *bo, + uint32_t x, uint32_t y, + uint32_t width, uint32_t height, + uint32_t flags, uint32_t *stride, void **map_data) +{ + if (!bo || width == 0 || height == 0 || !stride || !map_data) { + errno = EINVAL; + return NULL; + } + + return bo->gbm->bo_map(bo, x, y, width, height, + flags, stride, map_data); +} + +/** + * Unmap a previously mapped region of a gbm buffer object + * + * This function unmaps a region of a gbm bo for cpu read and/or write + * access. + * + * \param bo The buffer object + * \param map_data opaque ptr returned from prior gbm_bo_map + */ +GBM_EXPORT void +gbm_bo_unmap(struct gbm_bo *bo, void *map_data) +{ + bo->gbm->bo_unmap(bo, map_data); +} + /** * Allocate a surface object * @@ -397,17 +605,23 @@ gbm_surface_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags) { - switch (format) - { - case GBM_BO_FORMAT_XRGB8888: - format = GBM_FORMAT_XRGB8888; - break; - case GBM_BO_FORMAT_ARGB8888: - format = GBM_FORMAT_ABGR8888; - break; + return gbm->surface_create(gbm, width, height, format, flags, NULL, 0); +} + +GBM_EXPORT struct gbm_surface * +gbm_surface_create_with_modifiers(struct gbm_device *gbm, + uint32_t width, uint32_t height, + uint32_t format, + const uint64_t *modifiers, + const unsigned int count) +{ + if ((count && !modifiers) || (modifiers && !count)) { + errno = EINVAL; + return NULL; } - return gbm->surface_create(gbm, width, height, format, flags); + return gbm->surface_create(gbm, width, height, format, 0, + modifiers, count); } /** @@ -475,7 +689,7 @@ gbm_surface_release_buffer(struct gbm_surface *surf, struct gbm_bo *bo) * * Before starting a new frame, the surface must have a buffer * available for rendering. Initially, a gbm surface will have a free - * buffer, but after one of more buffers have been locked (\sa + * buffer, but after one or more buffers have been locked (\sa * gbm_surface_lock_front_buffer()), the application must check for a * free buffer before rendering. * @@ -491,3 +705,39 @@ gbm_surface_has_free_buffers(struct gbm_surface *surf) { return surf->gbm->surface_has_free_buffers(surf); } + +/* The two GBM_BO_FORMAT_[XA]RGB8888 formats alias the GBM_FORMAT_* + * formats of the same name. We want to accept them whenever someone + * has a GBM format, but never return them to the user. */ +uint32_t +gbm_format_canonicalize(uint32_t gbm_format) +{ + switch (gbm_format) { + case GBM_BO_FORMAT_XRGB8888: + return GBM_FORMAT_XRGB8888; + case GBM_BO_FORMAT_ARGB8888: + return GBM_FORMAT_ARGB8888; + default: + return gbm_format; + } +} + +/** + * Returns a string representing the fourcc format name. + * + * \param desc Caller-provided storage for the format name string. + * \return String containing the fourcc of the format. + */ +GBM_EXPORT char * +gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc) +{ + gbm_format = gbm_format_canonicalize(gbm_format); + + desc->name[0] = gbm_format; + desc->name[1] = gbm_format >> 8; + desc->name[2] = gbm_format >> 16; + desc->name[3] = gbm_format >> 24; + desc->name[4] = 0; + + return desc->name; +} diff --git a/src/gbm.h b/src/gbm.h index ca2dd4c..d5edb8a 100644 --- a/src/gbm.h +++ b/src/gbm.h @@ -28,15 +28,16 @@ #ifndef _GBM_H_ #define _GBM_H_ +#define __GBM__ 1 + +#include +#include + #ifdef __cplusplus extern "C" { #endif -#define __GBM__ 1 - -#include - /** * \file gbm.h * \brief Generic Buffer Manager @@ -76,6 +77,12 @@ enum gbm_bo_format { GBM_BO_FORMAT_ARGB8888 }; + +/** + * The FourCC format codes are taken from the drm_fourcc.h definition, and + * re-namespaced. New GBM formats must not be added, unless they are + * identical ports from drm_fourcc. + */ #define __gbm_fourcc_code(a,b,c,d) ((uint32_t)(a) | ((uint32_t)(b) << 8) | \ ((uint32_t)(c) << 16) | ((uint32_t)(d) << 24)) @@ -84,6 +91,12 @@ enum gbm_bo_format { /* color index */ #define GBM_FORMAT_C8 __gbm_fourcc_code('C', '8', ' ', ' ') /* [7:0] C */ +/* 8 bpp Red */ +#define GBM_FORMAT_R8 __gbm_fourcc_code('R', '8', ' ', ' ') /* [7:0] R */ + +/* 16 bpp RG */ +#define GBM_FORMAT_GR88 __gbm_fourcc_code('G', 'R', '8', '8') /* [15:0] G:R 8:8 little endian */ + /* 8 bpp RGB */ #define GBM_FORMAT_RGB332 __gbm_fourcc_code('R', 'G', 'B', '8') /* [7:0] R:G:B 3:3:2 */ #define GBM_FORMAT_BGR233 __gbm_fourcc_code('B', 'G', 'R', '8') /* [7:0] B:G:R 2:3:3 */ @@ -137,6 +150,15 @@ enum gbm_bo_format { #define GBM_FORMAT_RGBA1010102 __gbm_fourcc_code('R', 'A', '3', '0') /* [31:0] R:G:B:A 10:10:10:2 little endian */ #define GBM_FORMAT_BGRA1010102 __gbm_fourcc_code('B', 'A', '3', '0') /* [31:0] B:G:R:A 10:10:10:2 little endian */ +/* + * Floating point 64bpp RGB + * IEEE 754-2008 binary16 half-precision float + * [15:0] sign:exponent:mantissa 1:5:10 + */ +#define GBM_FORMAT_XBGR16161616F __gbm_fourcc_code('X', 'B', '4', 'H') /* [63:0] x:B:G:R 16:16:16:16 little endian */ + +#define GBM_FORMAT_ABGR16161616F __gbm_fourcc_code('A', 'B', '4', 'H') /* [63:0] A:B:G:R 16:16:16:16 little endian */ + /* packed YCbCr */ #define GBM_FORMAT_YUYV __gbm_fourcc_code('Y', 'U', 'Y', 'V') /* [31:0] Cr0:Y1:Cb0:Y0 8:8:8:8 little endian */ #define GBM_FORMAT_YVYU __gbm_fourcc_code('Y', 'V', 'Y', 'U') /* [31:0] Cb0:Y1:Cr0:Y0 8:8:8:8 little endian */ @@ -177,6 +199,9 @@ enum gbm_bo_format { #define GBM_FORMAT_YUV444 __gbm_fourcc_code('Y', 'U', '2', '4') /* non-subsampled Cb (1) and Cr (2) planes */ #define GBM_FORMAT_YVU444 __gbm_fourcc_code('Y', 'V', '2', '4') /* non-subsampled Cr (1) and Cb (2) planes */ +struct gbm_format_name_desc { + char name[5]; +}; /** * Flags to indicate the intended use for the buffer - these are passed into @@ -206,13 +231,19 @@ enum gbm_bo_flags { GBM_BO_USE_RENDERING = (1 << 2), /** * Buffer can be used for gbm_bo_write. This is guaranteed to work - * with GBM_BO_USE_CURSOR. but may not work for other combinations. + * with GBM_BO_USE_CURSOR, but may not work for other combinations. */ GBM_BO_USE_WRITE = (1 << 3), /** * Buffer is linear, i.e. not tiled. */ GBM_BO_USE_LINEAR = (1 << 4), + /** + * Buffer is protected, i.e. encrypted and not readable by CPU or any + * other non-secure / non-trusted components nor by non-trusted OpenGL, + * OpenCL, and Vulkan applications. + */ + GBM_BO_USE_PROTECTED = (1 << 5), }; int @@ -225,6 +256,11 @@ int gbm_device_is_format_supported(struct gbm_device *gbm, uint32_t format, uint32_t usage); +int +gbm_device_get_format_modifier_plane_count(struct gbm_device *gbm, + uint32_t format, + uint64_t modifier); + void gbm_device_destroy(struct gbm_device *gbm); @@ -236,9 +272,16 @@ gbm_bo_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags); +struct gbm_bo * +gbm_bo_create_with_modifiers(struct gbm_device *gbm, + uint32_t width, uint32_t height, + uint32_t format, + const uint64_t *modifiers, + const unsigned int count); #define GBM_BO_IMPORT_WL_BUFFER 0x5501 #define GBM_BO_IMPORT_EGL_IMAGE 0x5502 #define GBM_BO_IMPORT_FD 0x5503 +#define GBM_BO_IMPORT_FD_MODIFIER 0x5504 struct gbm_import_fd_data { int fd; @@ -248,10 +291,58 @@ struct gbm_import_fd_data { uint32_t format; }; +#define GBM_MAX_PLANES 4 + +struct gbm_import_fd_modifier_data { + uint32_t width; + uint32_t height; + uint32_t format; + uint32_t num_fds; + int fds[GBM_MAX_PLANES]; + int strides[GBM_MAX_PLANES]; + int offsets[GBM_MAX_PLANES]; + uint64_t modifier; +}; + struct gbm_bo * gbm_bo_import(struct gbm_device *gbm, uint32_t type, void *buffer, uint32_t usage); +/** + * Flags to indicate the type of mapping for the buffer - these are + * passed into gbm_bo_map(). The caller must set the union of all the + * flags that are appropriate. + * + * These flags are independent of the GBM_BO_USE_* creation flags. However, + * mapping the buffer may require copying to/from a staging buffer. + * + * See also: pipe_map_flags + */ +enum gbm_bo_transfer_flags { + /** + * Buffer contents read back (or accessed directly) at transfer + * create time. + */ + GBM_BO_TRANSFER_READ = (1 << 0), + /** + * Buffer contents will be written back at unmap time + * (or modified as a result of being accessed directly). + */ + GBM_BO_TRANSFER_WRITE = (1 << 1), + /** + * Read/modify/write + */ + GBM_BO_TRANSFER_READ_WRITE = (GBM_BO_TRANSFER_READ | GBM_BO_TRANSFER_WRITE), +}; + +void * +gbm_bo_map(struct gbm_bo *bo, + uint32_t x, uint32_t y, uint32_t width, uint32_t height, + uint32_t flags, uint32_t *stride, void **map_data); + +void +gbm_bo_unmap(struct gbm_bo *bo, void *map_data); + uint32_t gbm_bo_get_width(struct gbm_bo *bo); @@ -261,9 +352,18 @@ gbm_bo_get_height(struct gbm_bo *bo); uint32_t gbm_bo_get_stride(struct gbm_bo *bo); +uint32_t +gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane); + uint32_t gbm_bo_get_format(struct gbm_bo *bo); +uint32_t +gbm_bo_get_bpp(struct gbm_bo *bo); + +uint32_t +gbm_bo_get_offset(struct gbm_bo *bo, int plane); + struct gbm_device * gbm_bo_get_device(struct gbm_bo *bo); @@ -273,6 +373,15 @@ gbm_bo_get_handle(struct gbm_bo *bo); int gbm_bo_get_fd(struct gbm_bo *bo); +uint64_t +gbm_bo_get_modifier(struct gbm_bo *bo); + +int +gbm_bo_get_plane_count(struct gbm_bo *bo); + +union gbm_bo_handle +gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane); + int gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count); @@ -291,6 +400,13 @@ gbm_surface_create(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, uint32_t flags); +struct gbm_surface * +gbm_surface_create_with_modifiers(struct gbm_device *gbm, + uint32_t width, uint32_t height, + uint32_t format, + const uint64_t *modifiers, + const unsigned int count); + struct gbm_bo * gbm_surface_lock_front_buffer(struct gbm_surface *surface); @@ -303,6 +419,9 @@ gbm_surface_has_free_buffers(struct gbm_surface *surface); void gbm_surface_destroy(struct gbm_surface *surface); +char * +gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc); + #ifdef __cplusplus } #endif diff --git a/src/gbmint.h b/src/gbmint.h index e073b9a..1925774 100644 --- a/src/gbmint.h +++ b/src/gbmint.h @@ -32,7 +32,7 @@ #include /* GCC visibility */ -#if defined(__GNUC__) && __GNUC__ >= 4 +#if defined(__GNUC__) #define GBM_EXPORT __attribute__ ((visibility("default"))) #else #define GBM_EXPORT @@ -61,20 +61,38 @@ struct gbm_device { int (*is_format_supported)(struct gbm_device *gbm, uint32_t format, uint32_t usage); + int (*get_format_modifier_plane_count)(struct gbm_device *device, + uint32_t format, + uint64_t modifier); struct gbm_bo *(*bo_create)(struct gbm_device *gbm, uint32_t width, uint32_t height, uint32_t format, - uint32_t usage); + uint32_t usage, + const uint64_t *modifiers, + const unsigned int count); struct gbm_bo *(*bo_import)(struct gbm_device *gbm, uint32_t type, void *buffer, uint32_t usage); + void *(*bo_map)(struct gbm_bo *bo, + uint32_t x, uint32_t y, + uint32_t width, uint32_t height, + uint32_t flags, uint32_t *stride, + void **map_data); + void (*bo_unmap)(struct gbm_bo *bo, void *map_data); int (*bo_write)(struct gbm_bo *bo, const void *buf, size_t data); int (*bo_get_fd)(struct gbm_bo *bo); + int (*bo_get_planes)(struct gbm_bo *bo); + union gbm_bo_handle (*bo_get_handle)(struct gbm_bo *bo, int plane); + uint32_t (*bo_get_stride)(struct gbm_bo *bo, int plane); + uint32_t (*bo_get_offset)(struct gbm_bo *bo, int plane); + uint64_t (*bo_get_modifier)(struct gbm_bo *bo); void (*bo_destroy)(struct gbm_bo *bo); struct gbm_surface *(*surface_create)(struct gbm_device *gbm, uint32_t width, uint32_t height, - uint32_t format, uint32_t flags); + uint32_t format, uint32_t flags, + const uint64_t *modifiers, + const unsigned count); struct gbm_bo *(*surface_lock_front_buffer)(struct gbm_surface *surface); void (*surface_release_buffer)(struct gbm_surface *surface, struct gbm_bo *bo); @@ -104,6 +122,10 @@ struct gbm_surface { uint32_t height; uint32_t format; uint32_t flags; + struct { + uint64_t *modifiers; + unsigned count; + }; }; struct gbm_backend { @@ -111,4 +133,7 @@ struct gbm_backend { struct gbm_device *(*create_device)(int fd); }; +uint32_t +gbm_format_canonicalize(uint32_t gbm_format); + #endif