/*1* Copyright © 2011 Intel Corporation2*3* Permission is hereby granted, free of charge, to any person obtaining a4* copy of this software and associated documentation files (the "Software"),5* to deal in the Software without restriction, including without limitation6* the rights to use, copy, modify, merge, publish, distribute, sublicense,7* and/or sell copies of the Software, and to permit persons to whom the8* Software is furnished to do so, subject to the following conditions:9*10* The above copyright notice and this permission notice (including the next11* paragraph) shall be included in all copies or substantial portions of the12* Software.13*14* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,15* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF16* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND17* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT18* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,19* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,20* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER21* DEALINGS IN THE SOFTWARE.22*23* Authors:24* Benjamin Franzke <[email protected]>25*/2627#include <stddef.h>28#include <stdio.h>29#include <stdlib.h>30#include <string.h>31#include <stdint.h>3233#ifdef MAJOR_IN_MKDEV34#include <sys/mkdev.h>35#endif36#ifdef MAJOR_IN_SYSMACROS37#include <sys/sysmacros.h>38#endif39#include <sys/stat.h>40#include <unistd.h>41#include <errno.h>4243#include "gbm.h"44#include "gbmint.h"45#include "backend.h"4647/** Returns the file description for the gbm device48*49* \return The fd that the struct gbm_device was created with50*/51GBM_EXPORT int52gbm_device_get_fd(struct gbm_device *gbm)53{54return gbm->v0.fd;55}5657/** Get the backend name for the given gbm device58*59* \return The backend name string - this belongs to the device and must not60* be freed61*/62GBM_EXPORT const char *63gbm_device_get_backend_name(struct gbm_device *gbm)64{65return gbm->v0.name;66}6768/** Test if a format is supported for a given set of usage flags.69*70* \param gbm The created buffer manager71* \param format The format to test72* \param usage A bitmask of the usages to test the format against73* \return 1 if the format is supported otherwise 074*75* \sa enum gbm_bo_flags for the list of flags that the format can be76* tested against77*78* \sa enum gbm_bo_format for the list of formats79*/80GBM_EXPORT int81gbm_device_is_format_supported(struct gbm_device *gbm,82uint32_t format, uint32_t usage)83{84return gbm->v0.is_format_supported(gbm, format, usage);85}8687/** Get the number of planes that are required for a given format+modifier88*89* \param gbm The gbm device returned from gbm_create_device()90* \param format The format to query91* \param modifier The modifier to query92*/93GBM_EXPORT int94gbm_device_get_format_modifier_plane_count(struct gbm_device *gbm,95uint32_t format,96uint64_t modifier)97{98return gbm->v0.get_format_modifier_plane_count(gbm, format, modifier);99}100101/** Destroy the gbm device and free all resources associated with it.102*103* \param gbm The device created using gbm_create_device()104*/105GBM_EXPORT void106gbm_device_destroy(struct gbm_device *gbm)107{108_gbm_device_destroy(gbm);109}110111/** Create a gbm device for allocating buffers112*113* The file descriptor passed in is used by the backend to communicate with114* platform for allocating the memory. For allocations using DRI this would be115* the file descriptor returned when opening a device such as \c116* /dev/dri/card0117*118* \param fd The file descriptor for a backend specific device119* \return The newly created struct gbm_device. The resources associated with120* the device should be freed with gbm_device_destroy() when it is no longer121* needed. If the creation of the device failed NULL will be returned.122*/123GBM_EXPORT struct gbm_device *124gbm_create_device(int fd)125{126struct gbm_device *gbm = NULL;127struct stat buf;128129if (fd < 0 || fstat(fd, &buf) < 0 || !S_ISCHR(buf.st_mode)) {130errno = EINVAL;131return NULL;132}133134gbm = _gbm_create_device(fd);135if (gbm == NULL)136return NULL;137138gbm->dummy = gbm_create_device;139140return gbm;141}142143/** Get the width of the buffer object144*145* \param bo The buffer object146* \return The width of the allocated buffer object147*148*/149GBM_EXPORT uint32_t150gbm_bo_get_width(struct gbm_bo *bo)151{152return bo->v0.width;153}154155/** Get the height of the buffer object156*157* \param bo The buffer object158* \return The height of the allocated buffer object159*/160GBM_EXPORT uint32_t161gbm_bo_get_height(struct gbm_bo *bo)162{163return bo->v0.height;164}165166/** Get the stride of the buffer object167*168* This is calculated by the backend when it does the allocation in169* gbm_bo_create()170*171* \param bo The buffer object172* \return The stride of the allocated buffer object in bytes173*/174GBM_EXPORT uint32_t175gbm_bo_get_stride(struct gbm_bo *bo)176{177return gbm_bo_get_stride_for_plane(bo, 0);178}179180/** Get the stride for the given plane181*182* \param bo The buffer object183* \param plane for which you want the stride184*185* \sa gbm_bo_get_stride()186*/187GBM_EXPORT uint32_t188gbm_bo_get_stride_for_plane(struct gbm_bo *bo, int plane)189{190return bo->gbm->v0.bo_get_stride(bo, plane);191}192193/** Get the format of the buffer object194*195* The format of the pixels in the buffer.196*197* \param bo The buffer object198* \return The format of buffer object, one of the GBM_FORMAT_* codes199*/200GBM_EXPORT uint32_t201gbm_bo_get_format(struct gbm_bo *bo)202{203return bo->v0.format;204}205206/** Get the bit-per-pixel of the buffer object's format207*208* The bits-per-pixel of the buffer object's format.209*210* Note; The 'in-memory pixel' concept makes no sense for YUV formats211* (pixels are the result of the combination of multiple memory sources:212* Y, Cb & Cr; usually these are even in separate buffers), so YUV213* formats are not supported by this function.214*215* \param bo The buffer object216* \return The number of bits0per-pixel of the buffer object's format.217*/218GBM_EXPORT uint32_t219gbm_bo_get_bpp(struct gbm_bo *bo)220{221switch (bo->v0.format) {222default:223return 0;224case GBM_FORMAT_C8:225case GBM_FORMAT_R8:226case GBM_FORMAT_RGB332:227case GBM_FORMAT_BGR233:228return 8;229case GBM_FORMAT_GR88:230case GBM_FORMAT_XRGB4444:231case GBM_FORMAT_XBGR4444:232case GBM_FORMAT_RGBX4444:233case GBM_FORMAT_BGRX4444:234case GBM_FORMAT_ARGB4444:235case GBM_FORMAT_ABGR4444:236case GBM_FORMAT_RGBA4444:237case GBM_FORMAT_BGRA4444:238case GBM_FORMAT_XRGB1555:239case GBM_FORMAT_XBGR1555:240case GBM_FORMAT_RGBX5551:241case GBM_FORMAT_BGRX5551:242case GBM_FORMAT_ARGB1555:243case GBM_FORMAT_ABGR1555:244case GBM_FORMAT_RGBA5551:245case GBM_FORMAT_BGRA5551:246case GBM_FORMAT_RGB565:247case GBM_FORMAT_BGR565:248return 16;249case GBM_FORMAT_RGB888:250case GBM_FORMAT_BGR888:251return 24;252case GBM_FORMAT_XRGB8888:253case GBM_FORMAT_XBGR8888:254case GBM_FORMAT_RGBX8888:255case GBM_FORMAT_BGRX8888:256case GBM_FORMAT_ARGB8888:257case GBM_FORMAT_ABGR8888:258case GBM_FORMAT_RGBA8888:259case GBM_FORMAT_BGRA8888:260case GBM_FORMAT_XRGB2101010:261case GBM_FORMAT_XBGR2101010:262case GBM_FORMAT_RGBX1010102:263case GBM_FORMAT_BGRX1010102:264case GBM_FORMAT_ARGB2101010:265case GBM_FORMAT_ABGR2101010:266case GBM_FORMAT_RGBA1010102:267case GBM_FORMAT_BGRA1010102:268return 32;269case GBM_FORMAT_XBGR16161616F:270case GBM_FORMAT_ABGR16161616F:271return 64;272}273}274275/** Get the offset for the data of the specified plane276*277* Extra planes, and even the first plane, may have an offset from the start of278* the buffer object. This function will provide the offset for the given plane279* to be used in various KMS APIs.280*281* \param bo The buffer object282* \return The offset283*/284GBM_EXPORT uint32_t285gbm_bo_get_offset(struct gbm_bo *bo, int plane)286{287return bo->gbm->v0.bo_get_offset(bo, plane);288}289290/** Get the gbm device used to create the buffer object291*292* \param bo The buffer object293* \return Returns the gbm device with which the buffer object was created294*/295GBM_EXPORT struct gbm_device *296gbm_bo_get_device(struct gbm_bo *bo)297{298return bo->gbm;299}300301/** Get the handle of the buffer object302*303* This is stored in the platform generic union gbm_bo_handle type. However304* the format of this handle is platform specific.305*306* \param bo The buffer object307* \return Returns the handle of the allocated buffer object308*/309GBM_EXPORT union gbm_bo_handle310gbm_bo_get_handle(struct gbm_bo *bo)311{312return bo->v0.handle;313}314315/** Get a DMA-BUF file descriptor for the buffer object316*317* This function creates a DMA-BUF (also known as PRIME) file descriptor318* handle for the buffer object. Each call to gbm_bo_get_fd() returns a new319* file descriptor and the caller is responsible for closing the file320* descriptor.321322* \param bo The buffer object323* \return Returns a file descriptor referring to the underlying buffer or -1324* if an error occurs.325*/326GBM_EXPORT int327gbm_bo_get_fd(struct gbm_bo *bo)328{329return bo->gbm->v0.bo_get_fd(bo);330}331332/** Get the number of planes for the given bo.333*334* \param bo The buffer object335* \return The number of planes336*/337GBM_EXPORT int338gbm_bo_get_plane_count(struct gbm_bo *bo)339{340return bo->gbm->v0.bo_get_planes(bo);341}342343/** Get the handle for the specified plane of the buffer object344*345* This function gets the handle for any plane associated with the BO. When346* dealing with multi-planar formats, or formats which might have implicit347* planes based on different underlying hardware it is necessary for the client348* to be able to get this information to pass to the DRM.349*350* \param bo The buffer object351* \param plane the plane to get a handle for352*353* \sa gbm_bo_get_handle()354*/355GBM_EXPORT union gbm_bo_handle356gbm_bo_get_handle_for_plane(struct gbm_bo *bo, int plane)357{358return bo->gbm->v0.bo_get_handle(bo, plane);359}360361/** Get a DMA-BUF file descriptor for the specified plane of the buffer object362*363* This function creates a DMA-BUF (also known as PRIME) file descriptor364* handle for the specified plane of the buffer object. Each call to365* gbm_bo_get_fd_for_plane() returns a new file descriptor and the caller is366* responsible for closing the file descriptor.367368* \param bo The buffer object369* \param plane The plane to get a DMA-BUF for370* \return Returns a file descriptor referring to the underlying buffer or -1371* if an error occurs.372*373* \sa gbm_bo_get_fd()374*/375GBM_EXPORT int376gbm_bo_get_fd_for_plane(struct gbm_bo *bo, int plane)377{378return bo->gbm->v0.bo_get_plane_fd(bo, plane);379}380381/**382* Get the chosen modifier for the buffer object383*384* This function returns the modifier that was chosen for the object. These385* properties may be generic, or platform/implementation dependent.386*387* \param bo The buffer object388* \return Returns the selected modifier (chosen by the implementation) for the389* BO.390* \sa gbm_bo_create_with_modifiers() where possible modifiers are set391* \sa gbm_surface_create_with_modifiers() where possible modifiers are set392* \sa define DRM_FORMAT_MOD_* in drm_fourcc.h for possible modifiers393*/394GBM_EXPORT uint64_t395gbm_bo_get_modifier(struct gbm_bo *bo)396{397return bo->gbm->v0.bo_get_modifier(bo);398}399400/** Write data into the buffer object401*402* If the buffer object was created with the GBM_BO_USE_WRITE flag,403* this function can be used to write data into the buffer object. The404* data is copied directly into the object and it's the responsibility405* of the caller to make sure the data represents valid pixel data,406* according to the width, height, stride and format of the buffer object.407*408* \param bo The buffer object409* \param buf The data to write410* \param count The number of bytes to write411* \return Returns 0 on success, otherwise -1 is returned an errno set412*/413GBM_EXPORT int414gbm_bo_write(struct gbm_bo *bo, const void *buf, size_t count)415{416return bo->gbm->v0.bo_write(bo, buf, count);417}418419/** Set the user data associated with a buffer object420*421* \param bo The buffer object422* \param data The data to associate to the buffer object423* \param destroy_user_data A callback (which may be %NULL) that will be424* called prior to the buffer destruction425*/426GBM_EXPORT void427gbm_bo_set_user_data(struct gbm_bo *bo, void *data,428void (*destroy_user_data)(struct gbm_bo *, void *))429{430bo->v0.user_data = data;431bo->v0.destroy_user_data = destroy_user_data;432}433434/** Get the user data associated with a buffer object435*436* \param bo The buffer object437* \return Returns the user data associated with the buffer object or %NULL438* if no data was associated with it439*440* \sa gbm_bo_set_user_data()441*/442GBM_EXPORT void *443gbm_bo_get_user_data(struct gbm_bo *bo)444{445return bo->v0.user_data;446}447448/**449* Destroys the given buffer object and frees all resources associated with450* it.451*452* \param bo The buffer object453*/454GBM_EXPORT void455gbm_bo_destroy(struct gbm_bo *bo)456{457if (bo->v0.destroy_user_data)458bo->v0.destroy_user_data(bo, bo->v0.user_data);459460bo->gbm->v0.bo_destroy(bo);461}462463/**464* Allocate a buffer object for the given dimensions465*466* \param gbm The gbm device returned from gbm_create_device()467* \param width The width for the buffer468* \param height The height for the buffer469* \param format The format to use for the buffer, from GBM_FORMAT_* or470* GBM_BO_FORMAT_* tokens471* \param usage The union of the usage flags for this buffer472*473* \return A newly allocated buffer that should be freed with gbm_bo_destroy()474* when no longer needed. If an error occurs during allocation %NULL will be475* returned and errno set.476*477* \sa enum gbm_bo_flags for the list of usage flags478*/479GBM_EXPORT struct gbm_bo *480gbm_bo_create(struct gbm_device *gbm,481uint32_t width, uint32_t height,482uint32_t format, uint32_t usage)483{484if (width == 0 || height == 0) {485errno = EINVAL;486return NULL;487}488489return gbm->v0.bo_create(gbm, width, height, format, usage, NULL, 0);490}491492GBM_EXPORT struct gbm_bo *493gbm_bo_create_with_modifiers(struct gbm_device *gbm,494uint32_t width, uint32_t height,495uint32_t format,496const uint64_t *modifiers,497const unsigned int count)498{499if (width == 0 || height == 0) {500errno = EINVAL;501return NULL;502}503504if ((count && !modifiers) || (modifiers && !count)) {505errno = EINVAL;506return NULL;507}508509return gbm->v0.bo_create(gbm, width, height, format, 0, modifiers, count);510}511512/**513* Create a gbm buffer object from a foreign object514*515* This function imports a foreign object and creates a new gbm bo for it.516* This enables using the foreign object with a display API such as KMS.517* Currently these types of foreign objects are supported, indicated by the type518* argument:519*520* GBM_BO_IMPORT_WL_BUFFER521* GBM_BO_IMPORT_EGL_IMAGE522* GBM_BO_IMPORT_FD523* GBM_BO_IMPORT_FD_MODIFIER524*525* The gbm bo shares the underlying pixels but its life-time is526* independent of the foreign object.527*528* \param gbm The gbm device returned from gbm_create_device()529* \param type The type of object we're importing530* \param buffer Pointer to the external object531* \param usage The union of the usage flags for this buffer532*533* \return A newly allocated buffer object that should be freed with534* gbm_bo_destroy() when no longer needed. On error, %NULL is returned535* and errno is set.536*537* \sa enum gbm_bo_flags for the list of usage flags538*/539GBM_EXPORT struct gbm_bo *540gbm_bo_import(struct gbm_device *gbm,541uint32_t type, void *buffer, uint32_t usage)542{543return gbm->v0.bo_import(gbm, type, buffer, usage);544}545546/**547* Map a region of a gbm buffer object for cpu access548*549* This function maps a region of a gbm bo for cpu read and/or write550* access.551*552* The mapping exposes a linear view of the buffer object even if the buffer553* has a non-linear modifier.554*555* This function may require intermediate buffer copies (ie. it may be slow).556*557* \param bo The buffer object558* \param x The X (top left origin) starting position of the mapped region for559* the buffer560* \param y The Y (top left origin) starting position of the mapped region for561* the buffer562* \param width The width of the mapped region for the buffer563* \param height The height of the mapped region for the buffer564* \param flags The union of the GBM_BO_TRANSFER_* flags for this buffer565* \param stride Ptr for returned stride in bytes of the mapped region566* \param map_data Returned opaque ptr for the mapped region567*568* \return Address of the mapped buffer that should be unmapped with569* gbm_bo_unmap() when no longer needed. On error, %NULL is returned570* and errno is set.571*572* \sa enum gbm_bo_transfer_flags for the list of flags573*/574GBM_EXPORT void *575gbm_bo_map(struct gbm_bo *bo,576uint32_t x, uint32_t y,577uint32_t width, uint32_t height,578uint32_t flags, uint32_t *stride, void **map_data)579{580if (!bo || width == 0 || height == 0 || !stride || !map_data) {581errno = EINVAL;582return NULL;583}584585return bo->gbm->v0.bo_map(bo, x, y, width, height,586flags, stride, map_data);587}588589/**590* Unmap a previously mapped region of a gbm buffer object591*592* This function unmaps a region of a gbm bo for cpu read and/or write593* access.594*595* \param bo The buffer object596* \param map_data opaque ptr returned from prior gbm_bo_map597*/598GBM_EXPORT void599gbm_bo_unmap(struct gbm_bo *bo, void *map_data)600{601bo->gbm->v0.bo_unmap(bo, map_data);602}603604/**605* Allocate a surface object606*607* \param gbm The gbm device returned from gbm_create_device()608* \param width The width for the surface609* \param height The height for the surface610* \param format The format to use for the surface611*612* \return A newly allocated surface that should be freed with613* gbm_surface_destroy() when no longer needed. If an error occurs614* during allocation %NULL will be returned.615*616* \sa enum gbm_bo_format for the list of formats617*/618GBM_EXPORT struct gbm_surface *619gbm_surface_create(struct gbm_device *gbm,620uint32_t width, uint32_t height,621uint32_t format, uint32_t flags)622{623return gbm->v0.surface_create(gbm, width, height, format, flags, NULL, 0);624}625626GBM_EXPORT struct gbm_surface *627gbm_surface_create_with_modifiers(struct gbm_device *gbm,628uint32_t width, uint32_t height,629uint32_t format,630const uint64_t *modifiers,631const unsigned int count)632{633if ((count && !modifiers) || (modifiers && !count)) {634errno = EINVAL;635return NULL;636}637638return gbm->v0.surface_create(gbm, width, height, format, 0,639modifiers, count);640}641642/**643* Destroys the given surface and frees all resources associated with644* it.645*646* All buffers locked with gbm_surface_lock_front_buffer() should be647* released prior to calling this function.648*649* \param surf The surface650*/651GBM_EXPORT void652gbm_surface_destroy(struct gbm_surface *surf)653{654surf->gbm->v0.surface_destroy(surf);655}656657/**658* Lock the surface's current front buffer659*660* Lock rendering to the surface's current front buffer until it is661* released with gbm_surface_release_buffer().662*663* This function must be called exactly once after calling664* eglSwapBuffers. Calling it before any eglSwapBuffer has happened665* on the surface or two or more times after eglSwapBuffers is an666* error. A new bo representing the new front buffer is returned. On667* multiple invocations, all the returned bos must be released in668* order to release the actual surface buffer.669*670* \param surf The surface671*672* \return A buffer object that should be released with673* gbm_surface_release_buffer() when no longer needed. The implementation674* is free to reuse buffers released with gbm_surface_release_buffer() so675* this bo should not be destroyed using gbm_bo_destroy(). If an error676* occurs this function returns %NULL.677*/678GBM_EXPORT struct gbm_bo *679gbm_surface_lock_front_buffer(struct gbm_surface *surf)680{681return surf->gbm->v0.surface_lock_front_buffer(surf);682}683684/**685* Release a locked buffer obtained with gbm_surface_lock_front_buffer()686*687* Returns the underlying buffer to the gbm surface. Releasing a bo688* will typically make gbm_surface_has_free_buffer() return 1 and thus689* allow rendering the next frame, but not always. The implementation690* may choose to destroy the bo immediately or reuse it, in which case691* the user data associated with it is unchanged.692*693* \param surf The surface694* \param bo The buffer object695*/696GBM_EXPORT void697gbm_surface_release_buffer(struct gbm_surface *surf, struct gbm_bo *bo)698{699surf->gbm->v0.surface_release_buffer(surf, bo);700}701702/**703* Return whether or not a surface has free (non-locked) buffers704*705* Before starting a new frame, the surface must have a buffer706* available for rendering. Initially, a gbm surface will have a free707* buffer, but after one or more buffers have been locked (\sa708* gbm_surface_lock_front_buffer()), the application must check for a709* free buffer before rendering.710*711* If a surface doesn't have a free buffer, the application must712* return a buffer to the surface using gbm_surface_release_buffer()713* and after that, the application can query for free buffers again.714*715* \param surf The surface716* \return 1 if the surface has free buffers, 0 otherwise717*/718GBM_EXPORT int719gbm_surface_has_free_buffers(struct gbm_surface *surf)720{721return surf->gbm->v0.surface_has_free_buffers(surf);722}723724/* The two GBM_BO_FORMAT_[XA]RGB8888 formats alias the GBM_FORMAT_*725* formats of the same name. We want to accept them whenever someone726* has a GBM format, but never return them to the user. */727static uint32_t728format_canonicalize(uint32_t gbm_format)729{730switch (gbm_format) {731case GBM_BO_FORMAT_XRGB8888:732return GBM_FORMAT_XRGB8888;733case GBM_BO_FORMAT_ARGB8888:734return GBM_FORMAT_ARGB8888;735default:736return gbm_format;737}738}739740/**741* Returns a string representing the fourcc format name.742*743* \param desc Caller-provided storage for the format name string.744* \return String containing the fourcc of the format.745*/746GBM_EXPORT char *747gbm_format_get_name(uint32_t gbm_format, struct gbm_format_name_desc *desc)748{749gbm_format = format_canonicalize(gbm_format);750751desc->name[0] = gbm_format;752desc->name[1] = gbm_format >> 8;753desc->name[2] = gbm_format >> 16;754desc->name[3] = gbm_format >> 24;755desc->name[4] = 0;756757return desc->name;758}759760/**761* A global table of functions and global variables defined in the core GBM762* code that need to be accessed directly by GBM backends.763*/764struct gbm_core gbm_core = {765.v0.core_version = GBM_BACKEND_ABI_VERSION,766.v0.format_canonicalize = format_canonicalize,767};768769770