1bf215546Sopenharmony_ci/*
2bf215546Sopenharmony_ci * Copyright © 2011 Intel Corporation
3bf215546Sopenharmony_ci * Copyright © 2021 NVIDIA Corporation
4bf215546Sopenharmony_ci *
5bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
6bf215546Sopenharmony_ci * copy of this software and associated documentation files (the "Software"),
7bf215546Sopenharmony_ci * to deal in the Software without restriction, including without limitation
8bf215546Sopenharmony_ci * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9bf215546Sopenharmony_ci * and/or sell copies of the Software, and to permit persons to whom the
10bf215546Sopenharmony_ci * Software is furnished to do so, subject to the following conditions:
11bf215546Sopenharmony_ci *
12bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the next
13bf215546Sopenharmony_ci * paragraph) shall be included in all copies or substantial portions of the
14bf215546Sopenharmony_ci * Software.
15bf215546Sopenharmony_ci *
16bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17bf215546Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19bf215546Sopenharmony_ci * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
20bf215546Sopenharmony_ci * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21bf215546Sopenharmony_ci * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22bf215546Sopenharmony_ci * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23bf215546Sopenharmony_ci * DEALINGS IN THE SOFTWARE.
24bf215546Sopenharmony_ci *
25bf215546Sopenharmony_ci * Authors:
26bf215546Sopenharmony_ci *    Benjamin Franzke <benjaminfranzke@googlemail.com>
27bf215546Sopenharmony_ci *    James Jones <jajones@nvidia.com>
28bf215546Sopenharmony_ci */
29bf215546Sopenharmony_ci
30bf215546Sopenharmony_ci#ifndef GBM_BACKEND_ABI_H_
31bf215546Sopenharmony_ci#define GBM_BACKEND_ABI_H_
32bf215546Sopenharmony_ci
33bf215546Sopenharmony_ci#include "gbm.h"
34bf215546Sopenharmony_ci
35bf215546Sopenharmony_ci/**
36bf215546Sopenharmony_ci * \file gbm_backend_abi.h
37bf215546Sopenharmony_ci * \brief ABI between the GBM loader and its backends
38bf215546Sopenharmony_ci */
39bf215546Sopenharmony_ci
40bf215546Sopenharmony_cistruct gbm_backend_desc;
41bf215546Sopenharmony_ci
42bf215546Sopenharmony_ci/**
43bf215546Sopenharmony_ci * The GBM backend interface version defined by this file.
44bf215546Sopenharmony_ci *
45bf215546Sopenharmony_ci * The GBM device interface version must be incremented whenever the structures
46bf215546Sopenharmony_ci * defined in this file are modified. To preserve ABI compatibility with
47bf215546Sopenharmony_ci * backends that support only older versions, modifications to this file must
48bf215546Sopenharmony_ci * consist only of appending new fields to the end of the structures defined in
49bf215546Sopenharmony_ci * it, defining new structures, or declaring new exported functions or global
50bf215546Sopenharmony_ci * variables.
51bf215546Sopenharmony_ci *
52bf215546Sopenharmony_ci * Note this version applies to ALL structures in this file, not just the core,
53bf215546Sopenharmony_ci * backend, and device structures which contain it explicitly. Buffer objects,
54bf215546Sopenharmony_ci * surfaces, and any other new structures introduced to this file are also part
55bf215546Sopenharmony_ci * of the backend ABI. The ABI version of an instance of any object in this file
56bf215546Sopenharmony_ci * is defined as the minimum of the version of the backend associated with the
57bf215546Sopenharmony_ci * object instance and the loader's core object version. Hence, any new objects
58bf215546Sopenharmony_ci * added to this file should contain either a reference to an existing object
59bf215546Sopenharmony_ci * defined here, or an explicit version field.
60bf215546Sopenharmony_ci *
61bf215546Sopenharmony_ci * A few examples of object versions:
62bf215546Sopenharmony_ci *
63bf215546Sopenharmony_ci * Backend ABI version: 0
64bf215546Sopenharmony_ci * Core ABI version: 3
65bf215546Sopenharmony_ci * ABI version of a device created by the backend: 0
66bf215546Sopenharmony_ci *
67bf215546Sopenharmony_ci * Backend ABI version: 2
68bf215546Sopenharmony_ci * Core ABI version: 1
69bf215546Sopenharmony_ci * ABI version of a surface created by a device from the backend: 1
70bf215546Sopenharmony_ci *
71bf215546Sopenharmony_ci * Backend ABI version: 4
72bf215546Sopenharmony_ci * Core ABI version: 4
73bf215546Sopenharmony_ci * ABI version of a buffer object created by a device from the backend: 4
74bf215546Sopenharmony_ci */
75bf215546Sopenharmony_ci#define GBM_BACKEND_ABI_VERSION 1
76bf215546Sopenharmony_ci
77bf215546Sopenharmony_ci/**
78bf215546Sopenharmony_ci * GBM device interface corresponding to GBM_BACKEND_ABI_VERSION = 0
79bf215546Sopenharmony_ci *
80bf215546Sopenharmony_ci * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_bo_v1, increment
81bf215546Sopenharmony_ci * GBM_BACKEND_ABI_VERSION, and append gbm_bo_v1 to gbm_bo.
82bf215546Sopenharmony_ci */
83bf215546Sopenharmony_cistruct gbm_device_v0 {
84bf215546Sopenharmony_ci   const struct gbm_backend_desc *backend_desc;
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci   /**
87bf215546Sopenharmony_ci    * The version of the GBM backend interface supported by this device and its
88bf215546Sopenharmony_ci    * child objects. This may be less than the maximum version supported by the
89bf215546Sopenharmony_ci    * GBM loader if the device was created by an older backend, or less than the
90bf215546Sopenharmony_ci    * maximum version supported by the backend if the device was created by an
91bf215546Sopenharmony_ci    * older loader. In other words, this will be:
92bf215546Sopenharmony_ci    *
93bf215546Sopenharmony_ci    *   MIN(backend GBM interface version, loader GBM interface version)
94bf215546Sopenharmony_ci    *
95bf215546Sopenharmony_ci    * It is the backend's responsibility to assign this field the value passed
96bf215546Sopenharmony_ci    * in by the GBM loader to the backend's create_device function. The GBM
97bf215546Sopenharmony_ci    * loader will pre-clamp the value based on the loader version and the
98bf215546Sopenharmony_ci    * version reported by the backend in its gbm_backend_v0::backend_version
99bf215546Sopenharmony_ci    * field. It is the loader's responsibility to respect this version when
100bf215546Sopenharmony_ci    * directly accessing a device instance or any child objects instantiated by
101bf215546Sopenharmony_ci    * a device instance.
102bf215546Sopenharmony_ci    */
103bf215546Sopenharmony_ci   uint32_t backend_version;
104bf215546Sopenharmony_ci
105bf215546Sopenharmony_ci   int fd;
106bf215546Sopenharmony_ci   const char *name;
107bf215546Sopenharmony_ci
108bf215546Sopenharmony_ci   void (*destroy)(struct gbm_device *gbm);
109bf215546Sopenharmony_ci   int (*is_format_supported)(struct gbm_device *gbm,
110bf215546Sopenharmony_ci                              uint32_t format,
111bf215546Sopenharmony_ci                              uint32_t usage);
112bf215546Sopenharmony_ci   int (*get_format_modifier_plane_count)(struct gbm_device *device,
113bf215546Sopenharmony_ci                                          uint32_t format,
114bf215546Sopenharmony_ci                                          uint64_t modifier);
115bf215546Sopenharmony_ci
116bf215546Sopenharmony_ci   /**
117bf215546Sopenharmony_ci    * Since version 1, usage is properly populated when modifiers are
118bf215546Sopenharmony_ci    * supplied. Version 0 always set usage to 0 in this case.
119bf215546Sopenharmony_ci    */
120bf215546Sopenharmony_ci   struct gbm_bo *(*bo_create)(struct gbm_device *gbm,
121bf215546Sopenharmony_ci                               uint32_t width, uint32_t height,
122bf215546Sopenharmony_ci                               uint32_t format,
123bf215546Sopenharmony_ci                               uint32_t usage,
124bf215546Sopenharmony_ci                               const uint64_t *modifiers,
125bf215546Sopenharmony_ci                               const unsigned int count);
126bf215546Sopenharmony_ci   struct gbm_bo *(*bo_import)(struct gbm_device *gbm, uint32_t type,
127bf215546Sopenharmony_ci                               void *buffer, uint32_t usage);
128bf215546Sopenharmony_ci   void *(*bo_map)(struct gbm_bo *bo,
129bf215546Sopenharmony_ci                               uint32_t x, uint32_t y,
130bf215546Sopenharmony_ci                               uint32_t width, uint32_t height,
131bf215546Sopenharmony_ci                               uint32_t flags, uint32_t *stride,
132bf215546Sopenharmony_ci                               void **map_data);
133bf215546Sopenharmony_ci   void (*bo_unmap)(struct gbm_bo *bo, void *map_data);
134bf215546Sopenharmony_ci   int (*bo_write)(struct gbm_bo *bo, const void *buf, size_t data);
135bf215546Sopenharmony_ci   int (*bo_get_fd)(struct gbm_bo *bo);
136bf215546Sopenharmony_ci   int (*bo_get_planes)(struct gbm_bo *bo);
137bf215546Sopenharmony_ci   union gbm_bo_handle (*bo_get_handle)(struct gbm_bo *bo, int plane);
138bf215546Sopenharmony_ci   int (*bo_get_plane_fd)(struct gbm_bo *bo, int plane);
139bf215546Sopenharmony_ci   uint32_t (*bo_get_stride)(struct gbm_bo *bo, int plane);
140bf215546Sopenharmony_ci   uint32_t (*bo_get_offset)(struct gbm_bo *bo, int plane);
141bf215546Sopenharmony_ci   uint64_t (*bo_get_modifier)(struct gbm_bo *bo);
142bf215546Sopenharmony_ci   void (*bo_destroy)(struct gbm_bo *bo);
143bf215546Sopenharmony_ci
144bf215546Sopenharmony_ci   /**
145bf215546Sopenharmony_ci    * Since version 1, flags are properly populated when modifiers are
146bf215546Sopenharmony_ci    * supplied. Version 0 always set flags to 0 in this case.
147bf215546Sopenharmony_ci    */
148bf215546Sopenharmony_ci   struct gbm_surface *(*surface_create)(struct gbm_device *gbm,
149bf215546Sopenharmony_ci                                         uint32_t width, uint32_t height,
150bf215546Sopenharmony_ci                                         uint32_t format, uint32_t flags,
151bf215546Sopenharmony_ci                                         const uint64_t *modifiers,
152bf215546Sopenharmony_ci                                         const unsigned count);
153bf215546Sopenharmony_ci   struct gbm_bo *(*surface_lock_front_buffer)(struct gbm_surface *surface);
154bf215546Sopenharmony_ci   void (*surface_release_buffer)(struct gbm_surface *surface,
155bf215546Sopenharmony_ci                                  struct gbm_bo *bo);
156bf215546Sopenharmony_ci   int (*surface_has_free_buffers)(struct gbm_surface *surface);
157bf215546Sopenharmony_ci   void (*surface_destroy)(struct gbm_surface *surface);
158bf215546Sopenharmony_ci};
159bf215546Sopenharmony_ci
160bf215546Sopenharmony_ci/**
161bf215546Sopenharmony_ci * The device used for the memory allocation.
162bf215546Sopenharmony_ci *
163bf215546Sopenharmony_ci * The members of this structure should be not accessed directly
164bf215546Sopenharmony_ci *
165bf215546Sopenharmony_ci * To modify this structure, introduce a new gbm_device_v<N> structure, add it
166bf215546Sopenharmony_ci * to the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
167bf215546Sopenharmony_ci */
168bf215546Sopenharmony_cistruct gbm_device {
169bf215546Sopenharmony_ci   /* Hack to make a gbm_device detectable by its first element. */
170bf215546Sopenharmony_ci   struct gbm_device *(*dummy)(int);
171bf215546Sopenharmony_ci   struct gbm_device_v0 v0;
172bf215546Sopenharmony_ci};
173bf215546Sopenharmony_ci
174bf215546Sopenharmony_ci/**
175bf215546Sopenharmony_ci * GBM buffer object interface corresponding to GBM_BACKEND_ABI_VERSION = 0
176bf215546Sopenharmony_ci *
177bf215546Sopenharmony_ci * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_bo_v1, increment
178bf215546Sopenharmony_ci * GBM_BACKEND_ABI_VERSION, and append gbm_bo_v1 to gbm_bo.
179bf215546Sopenharmony_ci */
180bf215546Sopenharmony_cistruct gbm_bo_v0 {
181bf215546Sopenharmony_ci   uint32_t width;
182bf215546Sopenharmony_ci   uint32_t height;
183bf215546Sopenharmony_ci   uint32_t stride;
184bf215546Sopenharmony_ci   uint32_t format;
185bf215546Sopenharmony_ci   union gbm_bo_handle  handle;
186bf215546Sopenharmony_ci   void *user_data;
187bf215546Sopenharmony_ci   void (*destroy_user_data)(struct gbm_bo *, void *);
188bf215546Sopenharmony_ci};
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_ci/**
191bf215546Sopenharmony_ci * The allocated buffer object.
192bf215546Sopenharmony_ci *
193bf215546Sopenharmony_ci * The members in this structure should not be accessed directly.
194bf215546Sopenharmony_ci *
195bf215546Sopenharmony_ci * To modify this structure, introduce a new gbm_bo_v<N> structure, add it to
196bf215546Sopenharmony_ci * the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
197bf215546Sopenharmony_ci */
198bf215546Sopenharmony_cistruct gbm_bo {
199bf215546Sopenharmony_ci   struct gbm_device *gbm;
200bf215546Sopenharmony_ci   struct gbm_bo_v0 v0;
201bf215546Sopenharmony_ci};
202bf215546Sopenharmony_ci
203bf215546Sopenharmony_ci/**
204bf215546Sopenharmony_ci * GBM surface interface corresponding to GBM_BACKEND_ABI_VERSION = 0
205bf215546Sopenharmony_ci *
206bf215546Sopenharmony_ci * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_surface_v1, increment
207bf215546Sopenharmony_ci * GBM_BACKEND_ABI_VERSION, and append gbm_surface_v1 to gbm_surface.
208bf215546Sopenharmony_ci */
209bf215546Sopenharmony_cistruct gbm_surface_v0 {
210bf215546Sopenharmony_ci   uint32_t width;
211bf215546Sopenharmony_ci   uint32_t height;
212bf215546Sopenharmony_ci   uint32_t format;
213bf215546Sopenharmony_ci   uint32_t flags;
214bf215546Sopenharmony_ci   struct {
215bf215546Sopenharmony_ci      uint64_t *modifiers;
216bf215546Sopenharmony_ci      unsigned count;
217bf215546Sopenharmony_ci   };
218bf215546Sopenharmony_ci};
219bf215546Sopenharmony_ci
220bf215546Sopenharmony_ci/**
221bf215546Sopenharmony_ci * An allocated GBM surface.
222bf215546Sopenharmony_ci *
223bf215546Sopenharmony_ci * To modify this structure, introduce a new gbm_surface_v<N> structure, add it
224bf215546Sopenharmony_ci * to the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
225bf215546Sopenharmony_ci */
226bf215546Sopenharmony_cistruct gbm_surface {
227bf215546Sopenharmony_ci   struct gbm_device *gbm;
228bf215546Sopenharmony_ci   struct gbm_surface_v0 v0;
229bf215546Sopenharmony_ci};
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_ci/**
232bf215546Sopenharmony_ci * GBM backend interfaces corresponding to GBM_BACKEND_ABI_VERSION = 0
233bf215546Sopenharmony_ci *
234bf215546Sopenharmony_ci * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_backend_v1, increment
235bf215546Sopenharmony_ci * GBM_BACKEND_ABI_VERSION, append gbm_backend_v1 to gbm_backend.
236bf215546Sopenharmony_ci */
237bf215546Sopenharmony_cistruct gbm_backend_v0 {
238bf215546Sopenharmony_ci   /**
239bf215546Sopenharmony_ci    * The version of the GBM backend interface supported by this backend. This
240bf215546Sopenharmony_ci    * is set by the backend itself, and may be greater or less than the version
241bf215546Sopenharmony_ci    * supported by the loader. It is the responsibility of the GBM loader to
242bf215546Sopenharmony_ci    * respect this version when accessing fields in this structure.
243bf215546Sopenharmony_ci    */
244bf215546Sopenharmony_ci   uint32_t backend_version;
245bf215546Sopenharmony_ci
246bf215546Sopenharmony_ci   const char *backend_name;
247bf215546Sopenharmony_ci   struct gbm_device *(*create_device)(int fd, uint32_t gbm_backend_version);
248bf215546Sopenharmony_ci};
249bf215546Sopenharmony_ci
250bf215546Sopenharmony_ci/**
251bf215546Sopenharmony_ci * The interface exposed by an external GBM backend.
252bf215546Sopenharmony_ci *
253bf215546Sopenharmony_ci * To modify this structure, introduce a new gbm_backend_v<N> structure, add it
254bf215546Sopenharmony_ci * to the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
255bf215546Sopenharmony_ci */
256bf215546Sopenharmony_cistruct gbm_backend {
257bf215546Sopenharmony_ci   struct gbm_backend_v0 v0;
258bf215546Sopenharmony_ci};
259bf215546Sopenharmony_ci
260bf215546Sopenharmony_ci/**
261bf215546Sopenharmony_ci * GBM interfaces exposed to GBM backends at GBM_BACKEND_ABI_VERSION >= 0
262bf215546Sopenharmony_ci *
263bf215546Sopenharmony_ci * DO NOT MODIFY THIS STRUCT. Instead, introduce a gbm_core_v1, increment
264bf215546Sopenharmony_ci * GBM_BACKEND_ABI_VERSION, and append gbm_core_v1 to gbm_backend.
265bf215546Sopenharmony_ci */
266bf215546Sopenharmony_cistruct gbm_core_v0 {
267bf215546Sopenharmony_ci   /**
268bf215546Sopenharmony_ci    * The version of the GBM backend interface supported by the GBM loader. This
269bf215546Sopenharmony_ci    * is set by the loader, and may be greater or less than the version
270bf215546Sopenharmony_ci    * supported by a given backend. It is the responsibility of the backend to
271bf215546Sopenharmony_ci    * respect this version when accessing fields in this structure and other
272bf215546Sopenharmony_ci    * structures allocated or modified by the loader.
273bf215546Sopenharmony_ci    */
274bf215546Sopenharmony_ci   uint32_t core_version;
275bf215546Sopenharmony_ci
276bf215546Sopenharmony_ci   uint32_t (*format_canonicalize)(uint32_t gbm_format);
277bf215546Sopenharmony_ci};
278bf215546Sopenharmony_ci
279bf215546Sopenharmony_ci/**
280bf215546Sopenharmony_ci * The interface exposed by the GBM core/loader code to GBM backends.
281bf215546Sopenharmony_ci *
282bf215546Sopenharmony_ci * To modify this structure, introduce a new gbm_core_v<N> structure, add it
283bf215546Sopenharmony_ci * to the end of this structure, and increment GBM_BACKEND_ABI_VERSION.
284bf215546Sopenharmony_ci */
285bf215546Sopenharmony_cistruct gbm_core {
286bf215546Sopenharmony_ci   struct gbm_core_v0 v0;
287bf215546Sopenharmony_ci};
288bf215546Sopenharmony_ci
289bf215546Sopenharmony_ci/**
290bf215546Sopenharmony_ci * The entrypoint an external GBM backend exports.
291bf215546Sopenharmony_ci *
292bf215546Sopenharmony_ci * Prior to creating any devices using the backend, GBM will look up and call
293bf215546Sopenharmony_ci * this function to request the backend's interface and convey the loader's
294bf215546Sopenharmony_ci * version and exported interface to the backend.
295bf215546Sopenharmony_ci *
296bf215546Sopenharmony_ci * DO NOT MODIFY THIS FUNCTION NAME OR PROTOTYPE. It must remain unchanged to
297bf215546Sopenharmony_ci * preserve backwards compatibility with existing GBM backends.
298bf215546Sopenharmony_ci */
299bf215546Sopenharmony_ci#define GBM_GET_BACKEND_PROC gbmint_get_backend
300bf215546Sopenharmony_ci#define _GBM_MKSTRX(s) _GBM_MKSTR(s)
301bf215546Sopenharmony_ci#define _GBM_MKSTR(s) #s
302bf215546Sopenharmony_ci#define GBM_GET_BACKEND_PROC_NAME _GBM_MKSTRX(GBM_GET_BACKEND_PROC)
303bf215546Sopenharmony_citypedef const struct gbm_backend *(*GBM_GET_BACKEND_PROC_PTR)(const struct gbm_core *gbm_core);
304bf215546Sopenharmony_ci
305bf215546Sopenharmony_ci#endif
306