13464ebd5Sriastradh/* 23464ebd5Sriastradh * Copyright © 2011 Intel Corporation 33464ebd5Sriastradh * 43464ebd5Sriastradh * Permission is hereby granted, free of charge, to any person obtaining a 53464ebd5Sriastradh * copy of this software and associated documentation files (the "Software"), 63464ebd5Sriastradh * to deal in the Software without restriction, including without limitation 73464ebd5Sriastradh * the rights to use, copy, modify, merge, publish, distribute, sublicense, 83464ebd5Sriastradh * and/or sell copies of the Software, and to permit persons to whom the 93464ebd5Sriastradh * Software is furnished to do so, subject to the following conditions: 103464ebd5Sriastradh * 113464ebd5Sriastradh * The above copyright notice and this permission notice (including the next 123464ebd5Sriastradh * paragraph) shall be included in all copies or substantial portions of the 133464ebd5Sriastradh * Software. 143464ebd5Sriastradh * 153464ebd5Sriastradh * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 163464ebd5Sriastradh * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 173464ebd5Sriastradh * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 183464ebd5Sriastradh * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 193464ebd5Sriastradh * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 203464ebd5Sriastradh * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 213464ebd5Sriastradh * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 223464ebd5Sriastradh * DEALINGS IN THE SOFTWARE. 233464ebd5Sriastradh * 243464ebd5Sriastradh * Authors: 253464ebd5Sriastradh * Benjamin Franzke <benjaminfranzke@googlemail.com> 263464ebd5Sriastradh */ 273464ebd5Sriastradh 283464ebd5Sriastradh#include <stddef.h> 293464ebd5Sriastradh#include <stdio.h> 303464ebd5Sriastradh#include <stdlib.h> 313464ebd5Sriastradh#include <string.h> 323464ebd5Sriastradh#include <stdint.h> 333464ebd5Sriastradh 3401e04c3fSmrg#ifdef MAJOR_IN_MKDEV 3501e04c3fSmrg#include <sys/mkdev.h> 3601e04c3fSmrg#endif 3701e04c3fSmrg#ifdef MAJOR_IN_SYSMACROS 3801e04c3fSmrg#include <sys/sysmacros.h> 3901e04c3fSmrg#endif 403464ebd5Sriastradh#include <sys/stat.h> 413464ebd5Sriastradh#include <unistd.h> 42af69d88dSmrg#include <errno.h> 433464ebd5Sriastradh 443464ebd5Sriastradh#include "gbm.h" 453464ebd5Sriastradh#include "gbmint.h" 463464ebd5Sriastradh#include "backend.h" 473464ebd5Sriastradh 48af69d88dSmrg/** Returns the file description for the gbm device 49af69d88dSmrg * 50af69d88dSmrg * \return The fd that the struct gbm_device was created with 51af69d88dSmrg */ 523464ebd5SriastradhGBM_EXPORT int 533464ebd5Sriastradhgbm_device_get_fd(struct gbm_device *gbm) 543464ebd5Sriastradh{ 557ec681f3Smrg return gbm->v0.fd; 563464ebd5Sriastradh} 573464ebd5Sriastradh 58af69d88dSmrg/** Get the backend name for the given gbm device 59af69d88dSmrg * 60af69d88dSmrg * \return The backend name string - this belongs to the device and must not 61af69d88dSmrg * be freed 62af69d88dSmrg */ 633464ebd5SriastradhGBM_EXPORT const char * 643464ebd5Sriastradhgbm_device_get_backend_name(struct gbm_device *gbm) 653464ebd5Sriastradh{ 667ec681f3Smrg return gbm->v0.name; 673464ebd5Sriastradh} 683464ebd5Sriastradh 69af69d88dSmrg/** Test if a format is supported for a given set of usage flags. 70af69d88dSmrg * 71af69d88dSmrg * \param gbm The created buffer manager 72af69d88dSmrg * \param format The format to test 737ec681f3Smrg * \param flags A bitmask of the usages to test the format against 74af69d88dSmrg * \return 1 if the format is supported otherwise 0 75af69d88dSmrg * 76af69d88dSmrg * \sa enum gbm_bo_flags for the list of flags that the format can be 77af69d88dSmrg * tested against 78af69d88dSmrg * 79af69d88dSmrg * \sa enum gbm_bo_format for the list of formats 80af69d88dSmrg */ 81af69d88dSmrgGBM_EXPORT int 823464ebd5Sriastradhgbm_device_is_format_supported(struct gbm_device *gbm, 837ec681f3Smrg uint32_t format, uint32_t flags) 843464ebd5Sriastradh{ 857ec681f3Smrg return gbm->v0.is_format_supported(gbm, format, flags); 863464ebd5Sriastradh} 873464ebd5Sriastradh 8801e04c3fSmrg/** Get the number of planes that are required for a given format+modifier 8901e04c3fSmrg * 9001e04c3fSmrg * \param gbm The gbm device returned from gbm_create_device() 9101e04c3fSmrg * \param format The format to query 9201e04c3fSmrg * \param modifier The modifier to query 9301e04c3fSmrg */ 9401e04c3fSmrgGBM_EXPORT int 9501e04c3fSmrggbm_device_get_format_modifier_plane_count(struct gbm_device *gbm, 9601e04c3fSmrg uint32_t format, 9701e04c3fSmrg uint64_t modifier) 9801e04c3fSmrg{ 997ec681f3Smrg return gbm->v0.get_format_modifier_plane_count(gbm, format, modifier); 10001e04c3fSmrg} 10101e04c3fSmrg 102af69d88dSmrg/** Destroy the gbm device and free all resources associated with it. 103af69d88dSmrg * 104af69d88dSmrg * \param gbm The device created using gbm_create_device() 105af69d88dSmrg */ 1063464ebd5SriastradhGBM_EXPORT void 1073464ebd5Sriastradhgbm_device_destroy(struct gbm_device *gbm) 1083464ebd5Sriastradh{ 1097ec681f3Smrg _gbm_device_destroy(gbm); 1103464ebd5Sriastradh} 1113464ebd5Sriastradh 112af69d88dSmrg/** Create a gbm device for allocating buffers 113af69d88dSmrg * 114af69d88dSmrg * The file descriptor passed in is used by the backend to communicate with 115af69d88dSmrg * platform for allocating the memory. For allocations using DRI this would be 116af69d88dSmrg * the file descriptor returned when opening a device such as \c 117af69d88dSmrg * /dev/dri/card0 118af69d88dSmrg * 11901e04c3fSmrg * \param fd The file descriptor for a backend specific device 120af69d88dSmrg * \return The newly created struct gbm_device. The resources associated with 121af69d88dSmrg * the device should be freed with gbm_device_destroy() when it is no longer 122af69d88dSmrg * needed. If the creation of the device failed NULL will be returned. 123af69d88dSmrg */ 1243464ebd5SriastradhGBM_EXPORT struct gbm_device * 1253464ebd5Sriastradhgbm_create_device(int fd) 1263464ebd5Sriastradh{ 1273464ebd5Sriastradh struct gbm_device *gbm = NULL; 1283464ebd5Sriastradh struct stat buf; 1293464ebd5Sriastradh 1303464ebd5Sriastradh if (fd < 0 || fstat(fd, &buf) < 0 || !S_ISCHR(buf.st_mode)) { 131af69d88dSmrg errno = EINVAL; 1323464ebd5Sriastradh return NULL; 1333464ebd5Sriastradh } 1343464ebd5Sriastradh 1353464ebd5Sriastradh gbm = _gbm_create_device(fd); 1363464ebd5Sriastradh if (gbm == NULL) 1373464ebd5Sriastradh return NULL; 1383464ebd5Sriastradh 1393464ebd5Sriastradh gbm->dummy = gbm_create_device; 1403464ebd5Sriastradh 1413464ebd5Sriastradh return gbm; 1423464ebd5Sriastradh} 1433464ebd5Sriastradh 144af69d88dSmrg/** Get the width of the buffer object 145af69d88dSmrg * 146af69d88dSmrg * \param bo The buffer object 147af69d88dSmrg * \return The width of the allocated buffer object 148af69d88dSmrg * 149af69d88dSmrg */ 15001e04c3fSmrgGBM_EXPORT uint32_t 1513464ebd5Sriastradhgbm_bo_get_width(struct gbm_bo *bo) 1523464ebd5Sriastradh{ 1537ec681f3Smrg return bo->v0.width; 1543464ebd5Sriastradh} 1553464ebd5Sriastradh 156af69d88dSmrg/** Get the height of the buffer object 157af69d88dSmrg * 158af69d88dSmrg * \param bo The buffer object 159af69d88dSmrg * \return The height of the allocated buffer object 160af69d88dSmrg */ 16101e04c3fSmrgGBM_EXPORT uint32_t 1623464ebd5Sriastradhgbm_bo_get_height(struct gbm_bo *bo) 1633464ebd5Sriastradh{ 1647ec681f3Smrg return bo->v0.height; 1653464ebd5Sriastradh} 1663464ebd5Sriastradh 167af69d88dSmrg/** Get the stride of the buffer object 168af69d88dSmrg * 169af69d88dSmrg * This is calculated by the backend when it does the allocation in 170af69d88dSmrg * gbm_bo_create() 171af69d88dSmrg * 172af69d88dSmrg * \param bo The buffer object 173af69d88dSmrg * \return The stride of the allocated buffer object in bytes 174af69d88dSmrg */ 1753464ebd5SriastradhGBM_EXPORT uint32_t 176af69d88dSmrggbm_bo_get_stride(struct gbm_bo *bo) 1773464ebd5Sriastradh{ 17801e04c3fSmrg return gbm_bo_get_stride_for_plane(bo, 0); 17901e04c3fSmrg} 18001e04c3fSmrg 18101e04c3fSmrg/** Get the stride for the given plane 18201e04c3fSmrg * 18301e04c3fSmrg * \param bo The buffer object 18401e04c3fSmrg * \param plane for which you want the stride 18501e04c3fSmrg * 18601e04c3fSmrg * \sa gbm_bo_get_stride() 18701e04c3fSmrg */ 18801e04c3fSmrgGBM_EXPORT uint32_t 18901e04c3fSmrggbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane) 19001e04c3fSmrg{ 1917ec681f3Smrg return bo->gbm->v0.bo_get_stride(bo, plane); 1923464ebd5Sriastradh} 1933464ebd5Sriastradh 194af69d88dSmrg/** Get the format of the buffer object 195af69d88dSmrg * 196af69d88dSmrg * The format of the pixels in the buffer. 197af69d88dSmrg * 198af69d88dSmrg * \param bo The buffer object 19901e04c3fSmrg * \return The format of buffer object, one of the GBM_FORMAT_* codes 200af69d88dSmrg */ 201af69d88dSmrgGBM_EXPORT uint32_t 202af69d88dSmrggbm_bo_get_format(struct gbm_bo *bo) 203af69d88dSmrg{ 2047ec681f3Smrg return bo->v0.format; 205af69d88dSmrg} 206af69d88dSmrg 20701e04c3fSmrg/** Get the bit-per-pixel of the buffer object's format 20801e04c3fSmrg * 20901e04c3fSmrg * The bits-per-pixel of the buffer object's format. 21001e04c3fSmrg * 21101e04c3fSmrg * Note; The 'in-memory pixel' concept makes no sense for YUV formats 21201e04c3fSmrg * (pixels are the result of the combination of multiple memory sources: 21301e04c3fSmrg * Y, Cb & Cr; usually these are even in separate buffers), so YUV 21401e04c3fSmrg * formats are not supported by this function. 21501e04c3fSmrg * 21601e04c3fSmrg * \param bo The buffer object 21701e04c3fSmrg * \return The number of bits0per-pixel of the buffer object's format. 21801e04c3fSmrg */ 21901e04c3fSmrgGBM_EXPORT uint32_t 22001e04c3fSmrggbm_bo_get_bpp(struct gbm_bo *bo) 22101e04c3fSmrg{ 2227ec681f3Smrg switch (bo->v0.format) { 22301e04c3fSmrg default: 22401e04c3fSmrg return 0; 22501e04c3fSmrg case GBM_FORMAT_C8: 22601e04c3fSmrg case GBM_FORMAT_R8: 22701e04c3fSmrg case GBM_FORMAT_RGB332: 22801e04c3fSmrg case GBM_FORMAT_BGR233: 22901e04c3fSmrg return 8; 23001e04c3fSmrg case GBM_FORMAT_GR88: 23101e04c3fSmrg case GBM_FORMAT_XRGB4444: 23201e04c3fSmrg case GBM_FORMAT_XBGR4444: 23301e04c3fSmrg case GBM_FORMAT_RGBX4444: 23401e04c3fSmrg case GBM_FORMAT_BGRX4444: 23501e04c3fSmrg case GBM_FORMAT_ARGB4444: 23601e04c3fSmrg case GBM_FORMAT_ABGR4444: 23701e04c3fSmrg case GBM_FORMAT_RGBA4444: 23801e04c3fSmrg case GBM_FORMAT_BGRA4444: 23901e04c3fSmrg case GBM_FORMAT_XRGB1555: 24001e04c3fSmrg case GBM_FORMAT_XBGR1555: 24101e04c3fSmrg case GBM_FORMAT_RGBX5551: 24201e04c3fSmrg case GBM_FORMAT_BGRX5551: 24301e04c3fSmrg case GBM_FORMAT_ARGB1555: 24401e04c3fSmrg case GBM_FORMAT_ABGR1555: 24501e04c3fSmrg case GBM_FORMAT_RGBA5551: 24601e04c3fSmrg case GBM_FORMAT_BGRA5551: 24701e04c3fSmrg case GBM_FORMAT_RGB565: 24801e04c3fSmrg case GBM_FORMAT_BGR565: 24901e04c3fSmrg return 16; 25001e04c3fSmrg case GBM_FORMAT_RGB888: 25101e04c3fSmrg case GBM_FORMAT_BGR888: 25201e04c3fSmrg return 24; 25301e04c3fSmrg case GBM_FORMAT_XRGB8888: 25401e04c3fSmrg case GBM_FORMAT_XBGR8888: 25501e04c3fSmrg case GBM_FORMAT_RGBX8888: 25601e04c3fSmrg case GBM_FORMAT_BGRX8888: 25701e04c3fSmrg case GBM_FORMAT_ARGB8888: 25801e04c3fSmrg case GBM_FORMAT_ABGR8888: 25901e04c3fSmrg case GBM_FORMAT_RGBA8888: 26001e04c3fSmrg case GBM_FORMAT_BGRA8888: 26101e04c3fSmrg case GBM_FORMAT_XRGB2101010: 26201e04c3fSmrg case GBM_FORMAT_XBGR2101010: 26301e04c3fSmrg case GBM_FORMAT_RGBX1010102: 26401e04c3fSmrg case GBM_FORMAT_BGRX1010102: 26501e04c3fSmrg case GBM_FORMAT_ARGB2101010: 26601e04c3fSmrg case GBM_FORMAT_ABGR2101010: 26701e04c3fSmrg case GBM_FORMAT_RGBA1010102: 26801e04c3fSmrg case GBM_FORMAT_BGRA1010102: 26901e04c3fSmrg return 32; 2707ec681f3Smrg case GBM_FORMAT_XBGR16161616F: 2717ec681f3Smrg case GBM_FORMAT_ABGR16161616F: 2727ec681f3Smrg return 64; 27301e04c3fSmrg } 27401e04c3fSmrg} 27501e04c3fSmrg 27601e04c3fSmrg/** Get the offset for the data of the specified plane 27701e04c3fSmrg * 27801e04c3fSmrg * Extra planes, and even the first plane, may have an offset from the start of 27901e04c3fSmrg * the buffer object. This function will provide the offset for the given plane 28001e04c3fSmrg * to be used in various KMS APIs. 28101e04c3fSmrg * 28201e04c3fSmrg * \param bo The buffer object 28301e04c3fSmrg * \return The offset 28401e04c3fSmrg */ 28501e04c3fSmrgGBM_EXPORT uint32_t 28601e04c3fSmrggbm_bo_get_offset(struct gbm_bo *bo, int plane) 28701e04c3fSmrg{ 2887ec681f3Smrg return bo->gbm->v0.bo_get_offset(bo, plane); 28901e04c3fSmrg} 29001e04c3fSmrg 29101e04c3fSmrg/** Get the gbm device used to create the buffer object 29201e04c3fSmrg * 29301e04c3fSmrg * \param bo The buffer object 29401e04c3fSmrg * \return Returns the gbm device with which the buffer object was created 29501e04c3fSmrg */ 29601e04c3fSmrgGBM_EXPORT struct gbm_device * 29701e04c3fSmrggbm_bo_get_device(struct gbm_bo *bo) 29801e04c3fSmrg{ 29901e04c3fSmrg return bo->gbm; 30001e04c3fSmrg} 30101e04c3fSmrg 302af69d88dSmrg/** Get the handle of the buffer object 303af69d88dSmrg * 304af69d88dSmrg * This is stored in the platform generic union gbm_bo_handle type. However 305af69d88dSmrg * the format of this handle is platform specific. 306af69d88dSmrg * 307af69d88dSmrg * \param bo The buffer object 308af69d88dSmrg * \return Returns the handle of the allocated buffer object 309af69d88dSmrg */ 3103464ebd5SriastradhGBM_EXPORT union gbm_bo_handle 3113464ebd5Sriastradhgbm_bo_get_handle(struct gbm_bo *bo) 3123464ebd5Sriastradh{ 3137ec681f3Smrg return bo->v0.handle; 3143464ebd5Sriastradh} 3153464ebd5Sriastradh 316af69d88dSmrg/** Get a DMA-BUF file descriptor for the buffer object 317af69d88dSmrg * 318af69d88dSmrg * This function creates a DMA-BUF (also known as PRIME) file descriptor 31901e04c3fSmrg * handle for the buffer object. Each call to gbm_bo_get_fd() returns a new 320af69d88dSmrg * file descriptor and the caller is responsible for closing the file 321af69d88dSmrg * descriptor. 322af69d88dSmrg 323af69d88dSmrg * \param bo The buffer object 32401e04c3fSmrg * \return Returns a file descriptor referring to the underlying buffer or -1 32501e04c3fSmrg * if an error occurs. 326af69d88dSmrg */ 327af69d88dSmrgGBM_EXPORT int 328af69d88dSmrggbm_bo_get_fd(struct gbm_bo *bo) 329af69d88dSmrg{ 3307ec681f3Smrg return bo->gbm->v0.bo_get_fd(bo); 331af69d88dSmrg} 332af69d88dSmrg 33301e04c3fSmrg/** Get the number of planes for the given bo. 33401e04c3fSmrg * 33501e04c3fSmrg * \param bo The buffer object 33601e04c3fSmrg * \return The number of planes 33701e04c3fSmrg */ 33801e04c3fSmrgGBM_EXPORT int 33901e04c3fSmrggbm_bo_get_plane_count(struct gbm_bo *bo) 34001e04c3fSmrg{ 3417ec681f3Smrg return bo->gbm->v0.bo_get_planes(bo); 34201e04c3fSmrg} 34301e04c3fSmrg 34401e04c3fSmrg/** Get the handle for the specified plane of the buffer object 34501e04c3fSmrg * 34601e04c3fSmrg * This function gets the handle for any plane associated with the BO. When 34701e04c3fSmrg * dealing with multi-planar formats, or formats which might have implicit 34801e04c3fSmrg * planes based on different underlying hardware it is necessary for the client 34901e04c3fSmrg * to be able to get this information to pass to the DRM. 35001e04c3fSmrg * 35101e04c3fSmrg * \param bo The buffer object 35201e04c3fSmrg * \param plane the plane to get a handle for 35301e04c3fSmrg * 35401e04c3fSmrg * \sa gbm_bo_get_handle() 35501e04c3fSmrg */ 35601e04c3fSmrgGBM_EXPORT union gbm_bo_handle 35701e04c3fSmrggbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane) 35801e04c3fSmrg{ 3597ec681f3Smrg return bo->gbm->v0.bo_get_handle(bo, plane); 3607ec681f3Smrg} 3617ec681f3Smrg 3627ec681f3Smrg/** Get a DMA-BUF file descriptor for the specified plane of the buffer object 3637ec681f3Smrg * 3647ec681f3Smrg * This function creates a DMA-BUF (also known as PRIME) file descriptor 3657ec681f3Smrg * handle for the specified plane of the buffer object. Each call to 3667ec681f3Smrg * gbm_bo_get_fd_for_plane() returns a new file descriptor and the caller is 3677ec681f3Smrg * responsible for closing the file descriptor. 3687ec681f3Smrg 3697ec681f3Smrg * \param bo The buffer object 3707ec681f3Smrg * \param plane The plane to get a DMA-BUF for 3717ec681f3Smrg * \return Returns a file descriptor referring to the underlying buffer or -1 3727ec681f3Smrg * if an error occurs. 3737ec681f3Smrg * 3747ec681f3Smrg * \sa gbm_bo_get_fd() 3757ec681f3Smrg */ 3767ec681f3SmrgGBM_EXPORT int 3777ec681f3Smrggbm_bo_get_fd_for_plane(struct gbm_bo *bo, int plane) 3787ec681f3Smrg{ 3797ec681f3Smrg return bo->gbm->v0.bo_get_plane_fd(bo, plane); 38001e04c3fSmrg} 38101e04c3fSmrg 38201e04c3fSmrg/** 38301e04c3fSmrg * Get the chosen modifier for the buffer object 38401e04c3fSmrg * 38501e04c3fSmrg * This function returns the modifier that was chosen for the object. These 38601e04c3fSmrg * properties may be generic, or platform/implementation dependent. 38701e04c3fSmrg * 38801e04c3fSmrg * \param bo The buffer object 38901e04c3fSmrg * \return Returns the selected modifier (chosen by the implementation) for the 39001e04c3fSmrg * BO. 39101e04c3fSmrg * \sa gbm_bo_create_with_modifiers() where possible modifiers are set 39201e04c3fSmrg * \sa gbm_surface_create_with_modifiers() where possible modifiers are set 39301e04c3fSmrg * \sa define DRM_FORMAT_MOD_* in drm_fourcc.h for possible modifiers 39401e04c3fSmrg */ 39501e04c3fSmrgGBM_EXPORT uint64_t 39601e04c3fSmrggbm_bo_get_modifier(struct gbm_bo *bo) 39701e04c3fSmrg{ 3987ec681f3Smrg return bo->gbm->v0.bo_get_modifier(bo); 39901e04c3fSmrg} 400af69d88dSmrg 401af69d88dSmrg/** Write data into the buffer object 402af69d88dSmrg * 403af69d88dSmrg * If the buffer object was created with the GBM_BO_USE_WRITE flag, 40401e04c3fSmrg * this function can be used to write data into the buffer object. The 40501e04c3fSmrg * data is copied directly into the object and it's the responsibility 406af69d88dSmrg * of the caller to make sure the data represents valid pixel data, 407af69d88dSmrg * according to the width, height, stride and format of the buffer object. 408af69d88dSmrg * 409af69d88dSmrg * \param bo The buffer object 410af69d88dSmrg * \param buf The data to write 411af69d88dSmrg * \param count The number of bytes to write 412af69d88dSmrg * \return Returns 0 on success, otherwise -1 is returned an errno set 413af69d88dSmrg */ 414af69d88dSmrgGBM_EXPORT int 415af69d88dSmrggbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count) 416af69d88dSmrg{ 4177ec681f3Smrg return bo->gbm->v0.bo_write(bo, buf, count); 418af69d88dSmrg} 419af69d88dSmrg 420af69d88dSmrg/** Set the user data associated with a buffer object 421af69d88dSmrg * 422af69d88dSmrg * \param bo The buffer object 423af69d88dSmrg * \param data The data to associate to the buffer object 424af69d88dSmrg * \param destroy_user_data A callback (which may be %NULL) that will be 425af69d88dSmrg * called prior to the buffer destruction 426af69d88dSmrg */ 427af69d88dSmrgGBM_EXPORT void 428af69d88dSmrggbm_bo_set_user_data(struct gbm_bo *bo, void *data, 429af69d88dSmrg void (*destroy_user_data)(struct gbm_bo *, void *)) 430af69d88dSmrg{ 4317ec681f3Smrg bo->v0.user_data = data; 4327ec681f3Smrg bo->v0.destroy_user_data = destroy_user_data; 433af69d88dSmrg} 434af69d88dSmrg 435af69d88dSmrg/** Get the user data associated with a buffer object 436af69d88dSmrg * 437af69d88dSmrg * \param bo The buffer object 438af69d88dSmrg * \return Returns the user data associated with the buffer object or %NULL 439af69d88dSmrg * if no data was associated with it 440af69d88dSmrg * 441af69d88dSmrg * \sa gbm_bo_set_user_data() 442af69d88dSmrg */ 443af69d88dSmrgGBM_EXPORT void * 444af69d88dSmrggbm_bo_get_user_data(struct gbm_bo *bo) 445af69d88dSmrg{ 4467ec681f3Smrg return bo->v0.user_data; 447af69d88dSmrg} 448af69d88dSmrg 449af69d88dSmrg/** 450af69d88dSmrg * Destroys the given buffer object and frees all resources associated with 451af69d88dSmrg * it. 452af69d88dSmrg * 453af69d88dSmrg * \param bo The buffer object 454af69d88dSmrg */ 4553464ebd5SriastradhGBM_EXPORT void 4563464ebd5Sriastradhgbm_bo_destroy(struct gbm_bo *bo) 4573464ebd5Sriastradh{ 4587ec681f3Smrg if (bo->v0.destroy_user_data) 4597ec681f3Smrg bo->v0.destroy_user_data(bo, bo->v0.user_data); 460af69d88dSmrg 4617ec681f3Smrg bo->gbm->v0.bo_destroy(bo); 4623464ebd5Sriastradh} 4633464ebd5Sriastradh 464af69d88dSmrg/** 465af69d88dSmrg * Allocate a buffer object for the given dimensions 466af69d88dSmrg * 467af69d88dSmrg * \param gbm The gbm device returned from gbm_create_device() 468af69d88dSmrg * \param width The width for the buffer 469af69d88dSmrg * \param height The height for the buffer 4709f464c52Smaya * \param format The format to use for the buffer, from GBM_FORMAT_* or 4719f464c52Smaya * GBM_BO_FORMAT_* tokens 4727ec681f3Smrg * \param flags The union of the usage flags for this buffer 473af69d88dSmrg * 474af69d88dSmrg * \return A newly allocated buffer that should be freed with gbm_bo_destroy() 475af69d88dSmrg * when no longer needed. If an error occurs during allocation %NULL will be 476af69d88dSmrg * returned and errno set. 477af69d88dSmrg * 478af69d88dSmrg * \sa enum gbm_bo_flags for the list of usage flags 479af69d88dSmrg */ 4803464ebd5SriastradhGBM_EXPORT struct gbm_bo * 4813464ebd5Sriastradhgbm_bo_create(struct gbm_device *gbm, 4823464ebd5Sriastradh uint32_t width, uint32_t height, 4837ec681f3Smrg uint32_t format, uint32_t flags) 4843464ebd5Sriastradh{ 485af69d88dSmrg if (width == 0 || height == 0) { 486af69d88dSmrg errno = EINVAL; 4873464ebd5Sriastradh return NULL; 488af69d88dSmrg } 4893464ebd5Sriastradh 4907ec681f3Smrg return gbm->v0.bo_create(gbm, width, height, format, flags, NULL, 0); 4913464ebd5Sriastradh} 4923464ebd5Sriastradh 49301e04c3fSmrgGBM_EXPORT struct gbm_bo * 49401e04c3fSmrggbm_bo_create_with_modifiers(struct gbm_device *gbm, 49501e04c3fSmrg uint32_t width, uint32_t height, 49601e04c3fSmrg uint32_t format, 49701e04c3fSmrg const uint64_t *modifiers, 49801e04c3fSmrg const unsigned int count) 4997ec681f3Smrg{ 5007ec681f3Smrg uint32_t flags = 0; 5017ec681f3Smrg 5027ec681f3Smrg /* 5037ec681f3Smrg * ABI version 1 added the modifiers+flags capability. Backends from 5047ec681f3Smrg * prior versions may fail if "unknown" flags are provided along with 5057ec681f3Smrg * modifiers, but assume scanout is required when modifiers are used. 5067ec681f3Smrg * Newer backends expect scanout to be explicitly requested if required, 5077ec681f3Smrg * but applications using this older interface rely on the older implied 5087ec681f3Smrg * requirement, so that behavior must be preserved. 5097ec681f3Smrg */ 5107ec681f3Smrg if (gbm->v0.backend_version >= 1) { 5117ec681f3Smrg flags |= GBM_BO_USE_SCANOUT; 5127ec681f3Smrg } 5137ec681f3Smrg 5147ec681f3Smrg return gbm_bo_create_with_modifiers2(gbm, width, height, format, modifiers, 5157ec681f3Smrg count, flags); 5167ec681f3Smrg} 5177ec681f3Smrg 5187ec681f3SmrgGBM_EXPORT struct gbm_bo * 5197ec681f3Smrggbm_bo_create_with_modifiers2(struct gbm_device *gbm, 5207ec681f3Smrg uint32_t width, uint32_t height, 5217ec681f3Smrg uint32_t format, 5227ec681f3Smrg const uint64_t *modifiers, 5237ec681f3Smrg const unsigned int count, 5247ec681f3Smrg uint32_t flags) 52501e04c3fSmrg{ 52601e04c3fSmrg if (width == 0 || height == 0) { 52701e04c3fSmrg errno = EINVAL; 52801e04c3fSmrg return NULL; 52901e04c3fSmrg } 53001e04c3fSmrg 53101e04c3fSmrg if ((count && !modifiers) || (modifiers && !count)) { 53201e04c3fSmrg errno = EINVAL; 53301e04c3fSmrg return NULL; 53401e04c3fSmrg } 53501e04c3fSmrg 5367ec681f3Smrg if (modifiers && (flags & GBM_BO_USE_LINEAR)) { 5377ec681f3Smrg errno = EINVAL; 5387ec681f3Smrg return NULL; 5397ec681f3Smrg } 5407ec681f3Smrg 5417ec681f3Smrg return gbm->v0.bo_create(gbm, width, height, format, flags, modifiers, count); 54201e04c3fSmrg} 5439f464c52Smaya 544af69d88dSmrg/** 5459f464c52Smaya * Create a gbm buffer object from a foreign object 546af69d88dSmrg * 547af69d88dSmrg * This function imports a foreign object and creates a new gbm bo for it. 5489f464c52Smaya * This enables using the foreign object with a display API such as KMS. 5499f464c52Smaya * Currently these types of foreign objects are supported, indicated by the type 550af69d88dSmrg * argument: 551af69d88dSmrg * 552af69d88dSmrg * GBM_BO_IMPORT_WL_BUFFER 553af69d88dSmrg * GBM_BO_IMPORT_EGL_IMAGE 554af69d88dSmrg * GBM_BO_IMPORT_FD 5559f464c52Smaya * GBM_BO_IMPORT_FD_MODIFIER 556af69d88dSmrg * 55701e04c3fSmrg * The gbm bo shares the underlying pixels but its life-time is 558af69d88dSmrg * independent of the foreign object. 559af69d88dSmrg * 560af69d88dSmrg * \param gbm The gbm device returned from gbm_create_device() 56101e04c3fSmrg * \param type The type of object we're importing 56201e04c3fSmrg * \param buffer Pointer to the external object 5637ec681f3Smrg * \param flags The union of the usage flags for this buffer 564af69d88dSmrg * 565af69d88dSmrg * \return A newly allocated buffer object that should be freed with 566af69d88dSmrg * gbm_bo_destroy() when no longer needed. On error, %NULL is returned 567af69d88dSmrg * and errno is set. 568af69d88dSmrg * 569af69d88dSmrg * \sa enum gbm_bo_flags for the list of usage flags 570af69d88dSmrg */ 5713464ebd5SriastradhGBM_EXPORT struct gbm_bo * 572af69d88dSmrggbm_bo_import(struct gbm_device *gbm, 5737ec681f3Smrg uint32_t type, void *buffer, uint32_t flags) 5743464ebd5Sriastradh{ 5757ec681f3Smrg return gbm->v0.bo_import(gbm, type, buffer, flags); 576af69d88dSmrg} 577af69d88dSmrg 57801e04c3fSmrg/** 57901e04c3fSmrg * Map a region of a gbm buffer object for cpu access 58001e04c3fSmrg * 58101e04c3fSmrg * This function maps a region of a gbm bo for cpu read and/or write 58201e04c3fSmrg * access. 58301e04c3fSmrg * 5847ec681f3Smrg * The mapping exposes a linear view of the buffer object even if the buffer 5857ec681f3Smrg * has a non-linear modifier. 5867ec681f3Smrg * 5877ec681f3Smrg * This function may require intermediate buffer copies (ie. it may be slow). 5887ec681f3Smrg * 58901e04c3fSmrg * \param bo The buffer object 59001e04c3fSmrg * \param x The X (top left origin) starting position of the mapped region for 59101e04c3fSmrg * the buffer 59201e04c3fSmrg * \param y The Y (top left origin) starting position of the mapped region for 59301e04c3fSmrg * the buffer 59401e04c3fSmrg * \param width The width of the mapped region for the buffer 59501e04c3fSmrg * \param height The height of the mapped region for the buffer 59601e04c3fSmrg * \param flags The union of the GBM_BO_TRANSFER_* flags for this buffer 59701e04c3fSmrg * \param stride Ptr for returned stride in bytes of the mapped region 59801e04c3fSmrg * \param map_data Returned opaque ptr for the mapped region 59901e04c3fSmrg * 60001e04c3fSmrg * \return Address of the mapped buffer that should be unmapped with 60101e04c3fSmrg * gbm_bo_unmap() when no longer needed. On error, %NULL is returned 60201e04c3fSmrg * and errno is set. 60301e04c3fSmrg * 60401e04c3fSmrg * \sa enum gbm_bo_transfer_flags for the list of flags 60501e04c3fSmrg */ 60601e04c3fSmrgGBM_EXPORT void * 60701e04c3fSmrggbm_bo_map(struct gbm_bo *bo, 60801e04c3fSmrg uint32_t x, uint32_t y, 60901e04c3fSmrg uint32_t width, uint32_t height, 61001e04c3fSmrg uint32_t flags, uint32_t *stride, void **map_data) 61101e04c3fSmrg{ 61201e04c3fSmrg if (!bo || width == 0 || height == 0 || !stride || !map_data) { 61301e04c3fSmrg errno = EINVAL; 61401e04c3fSmrg return NULL; 61501e04c3fSmrg } 61601e04c3fSmrg 6177ec681f3Smrg return bo->gbm->v0.bo_map(bo, x, y, width, height, 6187ec681f3Smrg flags, stride, map_data); 61901e04c3fSmrg} 62001e04c3fSmrg 62101e04c3fSmrg/** 62201e04c3fSmrg * Unmap a previously mapped region of a gbm buffer object 62301e04c3fSmrg * 62401e04c3fSmrg * This function unmaps a region of a gbm bo for cpu read and/or write 62501e04c3fSmrg * access. 62601e04c3fSmrg * 62701e04c3fSmrg * \param bo The buffer object 62801e04c3fSmrg * \param map_data opaque ptr returned from prior gbm_bo_map 62901e04c3fSmrg */ 63001e04c3fSmrgGBM_EXPORT void 63101e04c3fSmrggbm_bo_unmap(struct gbm_bo *bo, void *map_data) 63201e04c3fSmrg{ 6337ec681f3Smrg bo->gbm->v0.bo_unmap(bo, map_data); 63401e04c3fSmrg} 63501e04c3fSmrg 636af69d88dSmrg/** 637af69d88dSmrg * Allocate a surface object 638af69d88dSmrg * 639af69d88dSmrg * \param gbm The gbm device returned from gbm_create_device() 640af69d88dSmrg * \param width The width for the surface 641af69d88dSmrg * \param height The height for the surface 642af69d88dSmrg * \param format The format to use for the surface 643af69d88dSmrg * 644af69d88dSmrg * \return A newly allocated surface that should be freed with 645af69d88dSmrg * gbm_surface_destroy() when no longer needed. If an error occurs 646af69d88dSmrg * during allocation %NULL will be returned. 647af69d88dSmrg * 648af69d88dSmrg * \sa enum gbm_bo_format for the list of formats 649af69d88dSmrg */ 650af69d88dSmrgGBM_EXPORT struct gbm_surface * 651af69d88dSmrggbm_surface_create(struct gbm_device *gbm, 652af69d88dSmrg uint32_t width, uint32_t height, 653af69d88dSmrg uint32_t format, uint32_t flags) 654af69d88dSmrg{ 6557ec681f3Smrg return gbm->v0.surface_create(gbm, width, height, format, flags, NULL, 0); 65601e04c3fSmrg} 65701e04c3fSmrg 65801e04c3fSmrgGBM_EXPORT struct gbm_surface * 65901e04c3fSmrggbm_surface_create_with_modifiers(struct gbm_device *gbm, 66001e04c3fSmrg uint32_t width, uint32_t height, 66101e04c3fSmrg uint32_t format, 66201e04c3fSmrg const uint64_t *modifiers, 66301e04c3fSmrg const unsigned int count) 6647ec681f3Smrg{ 6657ec681f3Smrg uint32_t flags = 0; 6667ec681f3Smrg 6677ec681f3Smrg /* 6687ec681f3Smrg * ABI version 1 added the modifiers+flags capability. Backends from 6697ec681f3Smrg * prior versions may fail if "unknown" flags are provided along with 6707ec681f3Smrg * modifiers, but assume scanout is required when modifiers are used. 6717ec681f3Smrg * Newer backends expect scanout to be explicitly requested if required, 6727ec681f3Smrg * but applications using this older interface rely on the older implied 6737ec681f3Smrg * requirement, so that behavior must be preserved. 6747ec681f3Smrg */ 6757ec681f3Smrg if (gbm->v0.backend_version >= 1) { 6767ec681f3Smrg flags |= GBM_BO_USE_SCANOUT; 6777ec681f3Smrg } 6787ec681f3Smrg 6797ec681f3Smrg return gbm_surface_create_with_modifiers2(gbm, width, height, format, 6807ec681f3Smrg modifiers, count, 6817ec681f3Smrg flags); 6827ec681f3Smrg} 6837ec681f3Smrg 6847ec681f3SmrgGBM_EXPORT struct gbm_surface * 6857ec681f3Smrggbm_surface_create_with_modifiers2(struct gbm_device *gbm, 6867ec681f3Smrg uint32_t width, uint32_t height, 6877ec681f3Smrg uint32_t format, 6887ec681f3Smrg const uint64_t *modifiers, 6897ec681f3Smrg const unsigned int count, 6907ec681f3Smrg uint32_t flags) 69101e04c3fSmrg{ 69201e04c3fSmrg if ((count && !modifiers) || (modifiers && !count)) { 69301e04c3fSmrg errno = EINVAL; 69401e04c3fSmrg return NULL; 69501e04c3fSmrg } 69601e04c3fSmrg 6977ec681f3Smrg if (modifiers && (flags & GBM_BO_USE_LINEAR)) { 6987ec681f3Smrg errno = EINVAL; 6997ec681f3Smrg return NULL; 7007ec681f3Smrg } 7017ec681f3Smrg 7027ec681f3Smrg return gbm->v0.surface_create(gbm, width, height, format, flags, 7037ec681f3Smrg modifiers, count); 704af69d88dSmrg} 705af69d88dSmrg 706af69d88dSmrg/** 707af69d88dSmrg * Destroys the given surface and frees all resources associated with 708af69d88dSmrg * it. 709af69d88dSmrg * 710af69d88dSmrg * All buffers locked with gbm_surface_lock_front_buffer() should be 711af69d88dSmrg * released prior to calling this function. 712af69d88dSmrg * 713af69d88dSmrg * \param surf The surface 714af69d88dSmrg */ 715af69d88dSmrgGBM_EXPORT void 716af69d88dSmrggbm_surface_destroy(struct gbm_surface *surf) 717af69d88dSmrg{ 7187ec681f3Smrg surf->gbm->v0.surface_destroy(surf); 719af69d88dSmrg} 720af69d88dSmrg 721af69d88dSmrg/** 722af69d88dSmrg * Lock the surface's current front buffer 723af69d88dSmrg * 724af69d88dSmrg * Lock rendering to the surface's current front buffer until it is 725af69d88dSmrg * released with gbm_surface_release_buffer(). 726af69d88dSmrg * 727af69d88dSmrg * This function must be called exactly once after calling 728af69d88dSmrg * eglSwapBuffers. Calling it before any eglSwapBuffer has happened 729af69d88dSmrg * on the surface or two or more times after eglSwapBuffers is an 730af69d88dSmrg * error. A new bo representing the new front buffer is returned. On 731af69d88dSmrg * multiple invocations, all the returned bos must be released in 732af69d88dSmrg * order to release the actual surface buffer. 733af69d88dSmrg * 734af69d88dSmrg * \param surf The surface 735af69d88dSmrg * 736af69d88dSmrg * \return A buffer object that should be released with 737af69d88dSmrg * gbm_surface_release_buffer() when no longer needed. The implementation 738af69d88dSmrg * is free to reuse buffers released with gbm_surface_release_buffer() so 739af69d88dSmrg * this bo should not be destroyed using gbm_bo_destroy(). If an error 740af69d88dSmrg * occurs this function returns %NULL. 741af69d88dSmrg */ 742af69d88dSmrgGBM_EXPORT struct gbm_bo * 743af69d88dSmrggbm_surface_lock_front_buffer(struct gbm_surface *surf) 744af69d88dSmrg{ 7457ec681f3Smrg return surf->gbm->v0.surface_lock_front_buffer(surf); 746af69d88dSmrg} 7473464ebd5Sriastradh 748af69d88dSmrg/** 749af69d88dSmrg * Release a locked buffer obtained with gbm_surface_lock_front_buffer() 750af69d88dSmrg * 751af69d88dSmrg * Returns the underlying buffer to the gbm surface. Releasing a bo 752af69d88dSmrg * will typically make gbm_surface_has_free_buffer() return 1 and thus 753af69d88dSmrg * allow rendering the next frame, but not always. The implementation 754af69d88dSmrg * may choose to destroy the bo immediately or reuse it, in which case 755af69d88dSmrg * the user data associated with it is unchanged. 756af69d88dSmrg * 757af69d88dSmrg * \param surf The surface 758af69d88dSmrg * \param bo The buffer object 759af69d88dSmrg */ 760af69d88dSmrgGBM_EXPORT void 761af69d88dSmrggbm_surface_release_buffer(struct gbm_surface *surf, struct gbm_bo *bo) 762af69d88dSmrg{ 7637ec681f3Smrg surf->gbm->v0.surface_release_buffer(surf, bo); 764af69d88dSmrg} 765af69d88dSmrg 766af69d88dSmrg/** 767af69d88dSmrg * Return whether or not a surface has free (non-locked) buffers 768af69d88dSmrg * 769af69d88dSmrg * Before starting a new frame, the surface must have a buffer 770af69d88dSmrg * available for rendering. Initially, a gbm surface will have a free 77101e04c3fSmrg * buffer, but after one or more buffers have been locked (\sa 772af69d88dSmrg * gbm_surface_lock_front_buffer()), the application must check for a 773af69d88dSmrg * free buffer before rendering. 774af69d88dSmrg * 775af69d88dSmrg * If a surface doesn't have a free buffer, the application must 776af69d88dSmrg * return a buffer to the surface using gbm_surface_release_buffer() 777af69d88dSmrg * and after that, the application can query for free buffers again. 778af69d88dSmrg * 779af69d88dSmrg * \param surf The surface 780af69d88dSmrg * \return 1 if the surface has free buffers, 0 otherwise 781af69d88dSmrg */ 782af69d88dSmrgGBM_EXPORT int 783af69d88dSmrggbm_surface_has_free_buffers(struct gbm_surface *surf) 784af69d88dSmrg{ 7857ec681f3Smrg return surf->gbm->v0.surface_has_free_buffers(surf); 7863464ebd5Sriastradh} 7879f464c52Smaya 7889f464c52Smaya/* The two GBM_BO_FORMAT_[XA]RGB8888 formats alias the GBM_FORMAT_* 7899f464c52Smaya * formats of the same name. We want to accept them whenever someone 7909f464c52Smaya * has a GBM format, but never return them to the user. */ 7917ec681f3Smrgstatic uint32_t 7927ec681f3Smrgformat_canonicalize(uint32_t gbm_format) 7939f464c52Smaya{ 7949f464c52Smaya switch (gbm_format) { 7959f464c52Smaya case GBM_BO_FORMAT_XRGB8888: 7969f464c52Smaya return GBM_FORMAT_XRGB8888; 7979f464c52Smaya case GBM_BO_FORMAT_ARGB8888: 7989f464c52Smaya return GBM_FORMAT_ARGB8888; 7999f464c52Smaya default: 8009f464c52Smaya return gbm_format; 8019f464c52Smaya } 8029f464c52Smaya} 8039f464c52Smaya 8049f464c52Smaya/** 8059f464c52Smaya * Returns a string representing the fourcc format name. 8069f464c52Smaya * 8079f464c52Smaya * \param desc Caller-provided storage for the format name string. 8089f464c52Smaya * \return String containing the fourcc of the format. 8099f464c52Smaya */ 8109f464c52SmayaGBM_EXPORT char * 8119f464c52Smayagbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc) 8129f464c52Smaya{ 8137ec681f3Smrg gbm_format = format_canonicalize(gbm_format); 8149f464c52Smaya 8159f464c52Smaya desc->name[0] = gbm_format; 8169f464c52Smaya desc->name[1] = gbm_format >> 8; 8179f464c52Smaya desc->name[2] = gbm_format >> 16; 8189f464c52Smaya desc->name[3] = gbm_format >> 24; 8199f464c52Smaya desc->name[4] = 0; 8209f464c52Smaya 8219f464c52Smaya return desc->name; 8229f464c52Smaya} 8237ec681f3Smrg 8247ec681f3Smrg/** 8257ec681f3Smrg * A global table of functions and global variables defined in the core GBM 8267ec681f3Smrg * code that need to be accessed directly by GBM backends. 8277ec681f3Smrg */ 8287ec681f3Smrgstruct gbm_core gbm_core = { 8297ec681f3Smrg .v0.core_version = GBM_BACKEND_ABI_VERSION, 8307ec681f3Smrg .v0.format_canonicalize = format_canonicalize, 8317ec681f3Smrg}; 832