xref: /aosp_15_r20/external/mesa3d/src/gallium/frontends/dri/loader_dri3_helper.h (revision 6104692788411f58d303aa86923a9ff6ecaded22)
1 /*
2  * Copyright © 2013 Keith Packard
3  * Copyright © 2015 Boyan Ding
4  *
5  * Permission to use, copy, modify, distribute, and sell this software and its
6  * documentation for any purpose is hereby granted without fee, provided that
7  * the above copyright notice appear in all copies and that both that copyright
8  * notice and this permission notice appear in supporting documentation, and
9  * that the name of the copyright holders not be used in advertising or
10  * publicity pertaining to distribution of the software without specific,
11  * written prior permission.  The copyright holders make no representations
12  * about the suitability of this software for any purpose.  It is provided "as
13  * is" without express or implied warranty.
14  *
15  * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16  * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
17  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
18  * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
19  * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
20  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
21  * OF THIS SOFTWARE.
22  */
23 
24 #ifndef LOADER_DRI3_HEADER_H
25 #define LOADER_DRI3_HEADER_H
26 
27 #include <stdbool.h>
28 #include <stdint.h>
29 
30 #include <xcb/xcb.h>
31 #include <xcb/dri3.h>
32 #include <xcb/present.h>
33 
34 #include <GL/gl.h>
35 #include "mesa_interface.h"
36 #include "util/macros.h"
37 #include <c11/threads.h>
38 
39 enum loader_dri3_buffer_type {
40    loader_dri3_buffer_back = 0,
41    loader_dri3_buffer_front = 1
42 };
43 
44 struct loader_dri3_buffer {
45    __DRIimage   *image;
46    uint32_t     pixmap;
47 
48    /* default case: linear buffer allocated in render gpu vram.
49     * p2p case: linear buffer allocated in display gpu vram and imported
50     *           to render gpu. p2p case is enabled when driver name matches
51     *           while creating screen in dri3_create_screen() function.
52     */
53    __DRIimage   *linear_buffer;
54 
55    /* Synchronization between the client and X server is done using an
56     * xshmfence that is mapped into an X server SyncFence. This lets the
57     * client check whether the X server is done using a buffer with a simple
58     * xshmfence call, rather than going to read X events from the wire.
59     *
60     * However, we can only wait for one xshmfence to be triggered at a time,
61     * so we need to know *which* buffer is going to be idle next. We do that
62     * by waiting for a PresentIdleNotify event. When that event arrives, the
63     * 'busy' flag gets cleared and the client knows that the fence has been
64     * triggered, and that the wait call will not block.
65     */
66 
67    uint32_t     sync_fence;     /* XID of X SyncFence object */
68    struct xshmfence *shm_fence; /* pointer to xshmfence object */
69    bool         busy;           /* Set on swap, cleared on IdleNotify */
70    bool         own_pixmap;     /* We allocated the pixmap ID, free on destroy */
71    bool         reallocate;     /* Buffer should be reallocated and not reused */
72 
73    uint32_t     num_planes;
74    uint32_t     size;
75    int          strides[4];
76    int          offsets[4];
77    uint64_t     modifier;
78    uint32_t     cpp;
79    uint32_t     flags;
80    uint32_t     width, height;
81    uint64_t     last_swap;
82 };
83 
84 
85 #define LOADER_DRI3_MAX_BACK   4
86 #define LOADER_DRI3_BACK_ID(i) (i)
87 #define LOADER_DRI3_FRONT_ID   (LOADER_DRI3_MAX_BACK)
88 
89 static inline int
loader_dri3_pixmap_buf_id(enum loader_dri3_buffer_type buffer_type)90 loader_dri3_pixmap_buf_id(enum loader_dri3_buffer_type buffer_type)
91 {
92    if (buffer_type == loader_dri3_buffer_back)
93       return LOADER_DRI3_BACK_ID(0);
94    else
95       return LOADER_DRI3_FRONT_ID;
96 }
97 
98 struct loader_dri3_drawable;
99 
100 struct loader_dri3_vtable {
101    void (*set_drawable_size)(struct loader_dri3_drawable *, int, int);
102    bool (*in_current_context)(struct loader_dri3_drawable *);
103    __DRIcontext *(*get_dri_context)(struct loader_dri3_drawable *);
104    __DRIscreen *(*get_dri_screen)(void);
105    void (*flush_drawable)(struct loader_dri3_drawable *, unsigned);
106 };
107 
108 #define LOADER_DRI3_NUM_BUFFERS (1 + LOADER_DRI3_MAX_BACK)
109 
110 enum loader_dri3_drawable_type {
111    LOADER_DRI3_DRAWABLE_UNKNOWN,
112    LOADER_DRI3_DRAWABLE_WINDOW,
113    LOADER_DRI3_DRAWABLE_PIXMAP,
114    LOADER_DRI3_DRAWABLE_PBUFFER,
115 };
116 
117 struct loader_dri3_drawable {
118    xcb_connection_t *conn;
119    xcb_screen_t *screen;
120    __DRIdrawable *dri_drawable;
121    xcb_drawable_t drawable;
122    xcb_window_t window;
123    xcb_xfixes_region_t region;
124    int width;
125    int height;
126    int depth;
127    uint8_t have_back;
128    uint8_t have_fake_front;
129    enum loader_dri3_drawable_type type;
130 
131    /* Information about the GPU owning the buffer */
132    bool multiplanes_available;
133    bool prefer_back_buffer_reuse;
134    __DRIscreen *dri_screen_render_gpu;
135    /* dri_screen_display_gpu holds display GPU in case of prime gpu offloading else
136     * dri_screen_render_gpu and dri_screen_display_gpu is same.
137     * In case of prime gpu offloading, if display and render driver names are different
138     * (potentially not compatible), dri_screen_display_gpu will be NULL but fd_display_gpu
139     * will still hold fd for display driver.
140     */
141    __DRIscreen *dri_screen_display_gpu;
142 
143    /* SBC numbers are tracked by using the serial numbers
144     * in the present request and complete events
145     */
146    uint64_t send_sbc;
147    uint64_t recv_sbc;
148 
149    /* Last received UST/MSC values for pixmap present complete */
150    uint64_t ust, msc;
151 
152    /* Last received UST/MSC values from present notify msc event */
153    uint64_t notify_ust, notify_msc;
154 
155    struct loader_dri3_buffer *buffers[LOADER_DRI3_NUM_BUFFERS];
156    int cur_back;
157    int cur_num_back;
158    int max_num_back;
159    int cur_blit_source;
160 
161    uint32_t *stamp;
162 
163    xcb_present_event_t eid;
164    xcb_gcontext_t gc;
165    xcb_special_event_t *special_event;
166 
167    bool first_init;
168    bool adaptive_sync;
169    bool adaptive_sync_active;
170    bool block_on_depleted_buffers;
171    bool queries_buffer_age;
172    int swap_interval;
173 
174    const struct loader_dri3_vtable *vtable;
175 
176    unsigned int back_format;
177    xcb_present_complete_mode_t last_present_mode;
178 
179    bool is_protected_content;
180 
181    /* Currently protects the following fields:
182     * event_cnd, has_event_waiter,
183     * recv_sbc, ust, msc, recv_msc_serial,
184     * notify_ust, notify_msc
185     */
186    mtx_t mtx;
187    cnd_t event_cnd;
188    unsigned last_special_event_sequence;
189    bool has_event_waiter;
190 };
191 
192 PUBLIC void
193 loader_dri3_set_swap_interval(struct loader_dri3_drawable *draw,
194                               int interval);
195 
196 PUBLIC void
197 loader_dri3_drawable_fini(struct loader_dri3_drawable *draw);
198 
199 PUBLIC int
200 loader_dri3_drawable_init(xcb_connection_t *conn,
201                           xcb_drawable_t drawable,
202                           enum loader_dri3_drawable_type type,
203                           __DRIscreen *dri_screen_render_gpu,
204                           __DRIscreen *dri_screen_display_gpu,
205                           bool is_multiplanes_available,
206                           bool prefer_back_buffer_reuse,
207                           const __DRIconfig *dri_config,
208                           const struct loader_dri3_vtable *vtable,
209                           struct loader_dri3_drawable*);
210 
211 PUBLIC bool loader_dri3_wait_for_msc(struct loader_dri3_drawable *draw,
212                               int64_t target_msc,
213                               int64_t divisor, int64_t remainder,
214                               int64_t *ust, int64_t *msc, int64_t *sbc);
215 
216 PUBLIC int64_t
217 loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
218                              int64_t target_msc, int64_t divisor,
219                              int64_t remainder, unsigned flush_flags,
220                              const int *rects, int n_rects,
221                              bool force_copy);
222 
223 PUBLIC int
224 loader_dri3_wait_for_sbc(struct loader_dri3_drawable *draw,
225                          int64_t target_sbc, int64_t *ust,
226                          int64_t *msc, int64_t *sbc);
227 
228 PUBLIC int loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw);
229 
230 PUBLIC void
231 loader_dri3_flush(struct loader_dri3_drawable *draw,
232                   unsigned flags,
233                   enum __DRI2throttleReason throttle_reason);
234 
235 PUBLIC void
236 loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
237                             int x, int y,
238                             int width, int height,
239                             bool flush);
240 
241 PUBLIC void
242 loader_dri3_copy_drawable(struct loader_dri3_drawable *draw,
243                           xcb_drawable_t dest,
244                           xcb_drawable_t src);
245 
246 PUBLIC void
247 loader_dri3_wait_x(struct loader_dri3_drawable *draw);
248 
249 PUBLIC void
250 loader_dri3_wait_gl(struct loader_dri3_drawable *draw);
251 
252 PUBLIC __DRIimage *
253 loader_dri3_create_image(xcb_connection_t *c,
254                          xcb_dri3_buffer_from_pixmap_reply_t *bp_reply,
255                          unsigned int fourcc,
256                          __DRIscreen *dri_screen,
257                          void *loaderPrivate);
258 
259 #ifdef HAVE_X11_DRM
260 PUBLIC __DRIimage *
261 loader_dri3_create_image_from_buffers(xcb_connection_t *c,
262                                       xcb_dri3_buffers_from_pixmap_reply_t *bp_reply,
263                                       unsigned int fourcc,
264                                       __DRIscreen *dri_screen,
265                                       void *loaderPrivate);
266 #endif
267 PUBLIC int
268 loader_dri3_get_buffers(__DRIdrawable *driDrawable,
269                         unsigned int format,
270                         uint32_t *stamp,
271                         void *loaderPrivate,
272                         uint32_t buffer_mask,
273                         struct __DRIimageList *buffers);
274 
275 PUBLIC void
276 loader_dri3_update_drawable_geometry(struct loader_dri3_drawable *draw);
277 
278 PUBLIC void
279 loader_dri3_swapbuffer_barrier(struct loader_dri3_drawable *draw);
280 
281 PUBLIC void
282 loader_dri3_close_screen(__DRIscreen *dri_screen);
283 __DRIimage *
284 loader_dri3_get_pixmap_buffer(xcb_connection_t *conn, xcb_drawable_t pixmap, __DRIscreen *screen,
285                               unsigned fourcc, bool multiplanes_available,
286                               int *width, int *height, void *loader_data);
287 #endif
288