c54c668032e6e35f167808122986124ac9e1aa8d
[mesa.git] / src / loader / loader_dri3_helper.h
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 <GL/internal/dri_interface.h>
36 #include <c11/threads.h>
37
38 enum loader_dri3_buffer_type {
39 loader_dri3_buffer_back = 0,
40 loader_dri3_buffer_front = 1
41 };
42
43 struct loader_dri3_buffer {
44 __DRIimage *image;
45 __DRIimage *linear_buffer;
46 uint32_t pixmap;
47
48 /* Synchronization between the client and X server is done using an
49 * xshmfence that is mapped into an X server SyncFence. This lets the
50 * client check whether the X server is done using a buffer with a simple
51 * xshmfence call, rather than going to read X events from the wire.
52 *
53 * However, we can only wait for one xshmfence to be triggered at a time,
54 * so we need to know *which* buffer is going to be idle next. We do that
55 * by waiting for a PresentIdleNotify event. When that event arrives, the
56 * 'busy' flag gets cleared and the client knows that the fence has been
57 * triggered, and that the wait call will not block.
58 */
59
60 uint32_t sync_fence; /* XID of X SyncFence object */
61 struct xshmfence *shm_fence; /* pointer to xshmfence object */
62 bool busy; /* Set on swap, cleared on IdleNotify */
63 bool own_pixmap; /* We allocated the pixmap ID, free on destroy */
64
65 uint32_t num_planes;
66 uint32_t size;
67 int strides[4];
68 int offsets[4];
69 uint64_t modifier;
70 uint32_t cpp;
71 uint32_t flags;
72 uint32_t width, height;
73 uint64_t last_swap;
74 };
75
76
77 #define LOADER_DRI3_MAX_BACK 4
78 #define LOADER_DRI3_BACK_ID(i) (i)
79 #define LOADER_DRI3_FRONT_ID (LOADER_DRI3_MAX_BACK)
80
81 static inline int
82 loader_dri3_pixmap_buf_id(enum loader_dri3_buffer_type buffer_type)
83 {
84 if (buffer_type == loader_dri3_buffer_back)
85 return LOADER_DRI3_BACK_ID(0);
86 else
87 return LOADER_DRI3_FRONT_ID;
88 }
89
90 struct loader_dri3_extensions {
91 const __DRIcoreExtension *core;
92 const __DRIimageDriverExtension *image_driver;
93 const __DRI2flushExtension *flush;
94 const __DRI2configQueryExtension *config;
95 const __DRItexBufferExtension *tex_buffer;
96 const __DRIimageExtension *image;
97 };
98
99 struct loader_dri3_drawable;
100
101 struct loader_dri3_vtable {
102 void (*set_drawable_size)(struct loader_dri3_drawable *, int, int);
103 bool (*in_current_context)(struct loader_dri3_drawable *);
104 __DRIcontext *(*get_dri_context)(struct loader_dri3_drawable *);
105 __DRIscreen *(*get_dri_screen)(void);
106 void (*flush_drawable)(struct loader_dri3_drawable *, unsigned);
107 void (*show_fps)(struct loader_dri3_drawable *, uint64_t);
108 };
109
110 #define LOADER_DRI3_NUM_BUFFERS (1 + LOADER_DRI3_MAX_BACK)
111
112 struct loader_dri3_drawable {
113 xcb_connection_t *conn;
114 __DRIdrawable *dri_drawable;
115 xcb_drawable_t drawable;
116 int width;
117 int height;
118 int depth;
119 uint8_t have_back;
120 uint8_t have_fake_front;
121 uint8_t is_pixmap;
122
123 /* Information about the GPU owning the buffer */
124 __DRIscreen *dri_screen;
125 bool is_different_gpu;
126 bool multiplanes_available;
127
128 /* Present extension capabilities
129 */
130 uint32_t present_capabilities;
131
132 /* SBC numbers are tracked by using the serial numbers
133 * in the present request and complete events
134 */
135 uint64_t send_sbc;
136 uint64_t recv_sbc;
137
138 /* Last received UST/MSC values for pixmap present complete */
139 uint64_t ust, msc;
140
141 /* Last received UST/MSC values from present notify msc event */
142 uint64_t notify_ust, notify_msc;
143
144 struct loader_dri3_buffer *buffers[LOADER_DRI3_NUM_BUFFERS];
145 int cur_back;
146 int num_back;
147 int cur_blit_source;
148
149 uint32_t *stamp;
150
151 xcb_present_event_t eid;
152 xcb_gcontext_t gc;
153 xcb_special_event_t *special_event;
154
155 bool first_init;
156 int swap_interval;
157
158 struct loader_dri3_extensions *ext;
159 const struct loader_dri3_vtable *vtable;
160
161 unsigned int swap_method;
162 unsigned int back_format;
163 xcb_present_complete_mode_t last_present_mode;
164
165 /* Currently protects the following fields:
166 * event_cnd, has_event_waiter,
167 * recv_sbc, ust, msc, recv_msc_serial,
168 * notify_ust, notify_msc
169 */
170 mtx_t mtx;
171 cnd_t event_cnd;
172 bool has_event_waiter;
173 };
174
175 void
176 loader_dri3_set_swap_interval(struct loader_dri3_drawable *draw,
177 int interval);
178
179 void
180 loader_dri3_drawable_fini(struct loader_dri3_drawable *draw);
181
182 int
183 loader_dri3_drawable_init(xcb_connection_t *conn,
184 xcb_drawable_t drawable,
185 __DRIscreen *dri_screen,
186 bool is_different_gpu,
187 bool is_multiplanes_available,
188 const __DRIconfig *dri_config,
189 struct loader_dri3_extensions *ext,
190 const struct loader_dri3_vtable *vtable,
191 struct loader_dri3_drawable*);
192
193 bool loader_dri3_wait_for_msc(struct loader_dri3_drawable *draw,
194 int64_t target_msc,
195 int64_t divisor, int64_t remainder,
196 int64_t *ust, int64_t *msc, int64_t *sbc);
197
198 int64_t
199 loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
200 int64_t target_msc, int64_t divisor,
201 int64_t remainder, unsigned flush_flags,
202 bool force_copy);
203
204 int
205 loader_dri3_wait_for_sbc(struct loader_dri3_drawable *draw,
206 int64_t target_sbc, int64_t *ust,
207 int64_t *msc, int64_t *sbc);
208
209 int loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw);
210
211 void
212 loader_dri3_flush(struct loader_dri3_drawable *draw,
213 unsigned flags,
214 enum __DRI2throttleReason throttle_reason);
215
216 void
217 loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
218 int x, int y,
219 int width, int height,
220 bool flush);
221
222 void
223 loader_dri3_copy_drawable(struct loader_dri3_drawable *draw,
224 xcb_drawable_t dest,
225 xcb_drawable_t src);
226
227 void
228 loader_dri3_wait_x(struct loader_dri3_drawable *draw);
229
230 void
231 loader_dri3_wait_gl(struct loader_dri3_drawable *draw);
232
233 int loader_dri3_open(xcb_connection_t *conn,
234 xcb_window_t root,
235 uint32_t provider);
236
237 __DRIimage *
238 loader_dri3_create_image(xcb_connection_t *c,
239 xcb_dri3_buffer_from_pixmap_reply_t *bp_reply,
240 unsigned int format,
241 __DRIscreen *dri_screen,
242 const __DRIimageExtension *image,
243 void *loaderPrivate);
244
245 __DRIimage *
246 loader_dri3_create_image_from_buffers(xcb_connection_t *c,
247 xcb_dri3_buffers_from_pixmap_reply_t *bp_reply,
248 unsigned int format,
249 __DRIscreen *dri_screen,
250 const __DRIimageExtension *image,
251 void *loaderPrivate);
252
253 int
254 loader_dri3_get_buffers(__DRIdrawable *driDrawable,
255 unsigned int format,
256 uint32_t *stamp,
257 void *loaderPrivate,
258 uint32_t buffer_mask,
259 struct __DRIimageList *buffers);
260
261 void
262 loader_dri3_update_drawable_geometry(struct loader_dri3_drawable *draw);
263
264 void
265 loader_dri3_swapbuffer_barrier(struct loader_dri3_drawable *draw);
266
267 void
268 loader_dri3_close_screen(__DRIscreen *dri_screen);
269 #endif