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