1 /* 2 * Copyright 2011 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Kristian Hgsberg <krh (at) bitplanet.net> 26 */ 27 28 #ifndef EGL_DRI2_INCLUDED 29 #define EGL_DRI2_INCLUDED 30 31 #include <stdbool.h> 32 #include <stdint.h> 33 34 #ifdef HAVE_X11_PLATFORM 35 #include <xcb/xcb.h> 36 #include <xcb/dri2.h> 37 #include <xcb/xfixes.h> 38 #include <X11/Xlib-xcb.h> 39 40 #ifdef HAVE_DRI3 41 #include "loader_dri3_helper.h" 42 #endif 43 #endif 44 45 #ifdef HAVE_WAYLAND_PLATFORM 46 #include <wayland-client.h> 47 #include "wayland/wayland-egl/wayland-egl-backend.h" 48 /* forward declarations of protocol elements */ 49 struct zwp_linux_dmabuf_v1; 50 #endif 51 52 #include <GL/gl.h> 53 #include <GL/internal/dri_interface.h> 54 55 #ifdef HAVE_DRM_PLATFORM 56 #include <gbm_driint.h> 57 #endif 58 59 #ifdef HAVE_ANDROID_PLATFORM 60 #define LOG_TAG "EGL-DRI2" 61 62 #include <system/window.h> 63 #include <hardware/gralloc.h> 64 #endif /* HAVE_ANDROID_PLATFORM */ 65 66 #include "eglconfig.h" 67 #include "eglcontext.h" 68 #include "egldisplay.h" 69 #include "egldriver.h" 70 #include "eglcurrent.h" 71 #include "egllog.h" 72 #include "eglsurface.h" 73 #include "eglimage.h" 74 #include "eglsync.h" 75 76 #include "util/u_vector.h" 77 78 struct wl_buffer; 79 80 struct dri2_egl_display_vtbl { 81 int (*authenticate)(_EGLDisplay *disp, uint32_t id); 82 83 _EGLSurface* (*create_window_surface)(_EGLDriver *drv, _EGLDisplay *dpy, 84 _EGLConfig *config, 85 void *native_window, 86 const EGLint *attrib_list); 87 88 _EGLSurface* (*create_pixmap_surface)(_EGLDriver *drv, _EGLDisplay *dpy, 89 _EGLConfig *config, 90 void *native_pixmap, 91 const EGLint *attrib_list); 92 93 _EGLSurface* (*create_pbuffer_surface)(_EGLDriver *drv, _EGLDisplay *dpy, 94 _EGLConfig *config, 95 const EGLint *attrib_list); 96 97 EGLBoolean (*destroy_surface)(_EGLDriver *drv, _EGLDisplay *dpy, 98 _EGLSurface *surface); 99 100 EGLBoolean (*swap_interval)(_EGLDriver *drv, _EGLDisplay *dpy, 101 _EGLSurface *surf, EGLint interval); 102 103 _EGLImage* (*create_image)(_EGLDriver *drv, _EGLDisplay *dpy, 104 _EGLContext *ctx, EGLenum target, 105 EGLClientBuffer buffer, 106 const EGLint *attr_list); 107 108 EGLBoolean (*swap_buffers)(_EGLDriver *drv, _EGLDisplay *dpy, 109 _EGLSurface *surf); 110 111 EGLBoolean (*swap_buffers_with_damage)(_EGLDriver *drv, _EGLDisplay *dpy, 112 _EGLSurface *surface, 113 const EGLint *rects, EGLint n_rects); 114 115 EGLBoolean (*set_damage_region)(_EGLDriver *drv, _EGLDisplay *dpy, 116 _EGLSurface *surface, 117 const EGLint *rects, EGLint n_rects); 118 119 EGLBoolean (*swap_buffers_region)(_EGLDriver *drv, _EGLDisplay *dpy, 120 _EGLSurface *surf, EGLint numRects, 121 const EGLint *rects); 122 123 EGLBoolean (*post_sub_buffer)(_EGLDriver *drv, _EGLDisplay *dpy, 124 _EGLSurface *surf, 125 EGLint x, EGLint y, 126 EGLint width, EGLint height); 127 128 EGLBoolean (*copy_buffers)(_EGLDriver *drv, _EGLDisplay *dpy, 129 _EGLSurface *surf, void *native_pixmap_target); 130 131 EGLint (*query_buffer_age)(_EGLDriver *drv, _EGLDisplay *dpy, 132 _EGLSurface *surf); 133 134 EGLBoolean (*query_surface)(_EGLDriver *drv, _EGLDisplay *dpy, 135 _EGLSurface *surf, EGLint attribute, 136 EGLint *value); 137 138 struct wl_buffer* (*create_wayland_buffer_from_image)( 139 _EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img); 140 141 EGLBoolean (*get_sync_values)(_EGLDisplay *display, _EGLSurface *surface, 142 EGLuint64KHR *ust, EGLuint64KHR *msc, 143 EGLuint64KHR *sbc); 144 145 __DRIdrawable *(*get_dri_drawable)(_EGLSurface *surf); 146 147 void (*close_screen_notify)(_EGLDisplay *dpy); 148 }; 149 150 struct dri2_egl_display 151 { 152 const struct dri2_egl_display_vtbl *vtbl; 153 154 int dri2_major; 155 int dri2_minor; 156 __DRIscreen *dri_screen; 157 bool own_dri_screen; 158 const __DRIconfig **driver_configs; 159 void *driver; 160 const __DRIcoreExtension *core; 161 const __DRIimageDriverExtension *image_driver; 162 const __DRIdri2Extension *dri2; 163 const __DRIswrastExtension *swrast; 164 const __DRI2flushExtension *flush; 165 const __DRI2flushControlExtension *flush_control; 166 const __DRItexBufferExtension *tex_buffer; 167 const __DRIimageExtension *image; 168 const __DRIrobustnessExtension *robustness; 169 const __DRInoErrorExtension *no_error; 170 const __DRI2configQueryExtension *config; 171 const __DRI2fenceExtension *fence; 172 const __DRI2rendererQueryExtension *rendererQuery; 173 const __DRI2interopExtension *interop; 174 int fd; 175 176 /* dri2_initialize/dri2_terminate increment/decrement this count, so does 177 * dri2_make_current (tracks if there are active contexts/surfaces). */ 178 int ref_count; 179 180 bool own_device; 181 bool invalidate_available; 182 int min_swap_interval; 183 int max_swap_interval; 184 int default_swap_interval; 185 #ifdef HAVE_DRM_PLATFORM 186 struct gbm_dri_device *gbm_dri; 187 #endif 188 189 char *driver_name; 190 191 const __DRIextension **loader_extensions; 192 const __DRIextension **driver_extensions; 193 194 #ifdef HAVE_X11_PLATFORM 195 xcb_connection_t *conn; 196 xcb_screen_t *screen; 197 bool swap_available; 198 #ifdef HAVE_DRI3 199 struct loader_dri3_extensions loader_dri3_ext; 200 #endif 201 #endif 202 203 #ifdef HAVE_WAYLAND_PLATFORM 204 struct wl_display *wl_dpy; 205 struct wl_display *wl_dpy_wrapper; 206 struct wl_registry *wl_registry; 207 struct wl_drm *wl_server_drm; 208 struct wl_drm *wl_drm; 209 struct wl_shm *wl_shm; 210 struct wl_event_queue *wl_queue; 211 struct zwp_linux_dmabuf_v1 *wl_dmabuf; 212 struct { 213 struct u_vector xrgb2101010; 214 struct u_vector argb2101010; 215 struct u_vector xrgb8888; 216 struct u_vector argb8888; 217 struct u_vector rgb565; 218 } wl_modifiers; 219 bool authenticated; 220 int formats; 221 uint32_t capabilities; 222 char *device_name; 223 #endif 224 225 #ifdef HAVE_ANDROID_PLATFORM 226 const gralloc_module_t *gralloc; 227 #endif 228 229 bool is_render_node; 230 bool is_different_gpu; 231 }; 232 233 struct dri2_egl_context 234 { 235 _EGLContext base; 236 __DRIcontext *dri_context; 237 }; 238 239 #ifdef HAVE_WAYLAND_PLATFORM 240 enum wayland_buffer_type { 241 WL_BUFFER_FRONT, 242 WL_BUFFER_BACK, 243 WL_BUFFER_THIRD, 244 WL_BUFFER_COUNT 245 }; 246 #endif 247 248 struct dri2_egl_surface 249 { 250 _EGLSurface base; 251 __DRIdrawable *dri_drawable; 252 __DRIbuffer buffers[5]; 253 bool have_fake_front; 254 255 #ifdef HAVE_X11_PLATFORM 256 xcb_drawable_t drawable; 257 xcb_xfixes_region_t region; 258 int depth; 259 int bytes_per_pixel; 260 xcb_gcontext_t gc; 261 xcb_gcontext_t swapgc; 262 #endif 263 264 #ifdef HAVE_WAYLAND_PLATFORM 265 struct wl_egl_window *wl_win; 266 int dx; 267 int dy; 268 struct wl_event_queue *wl_queue; 269 struct wl_surface *wl_surface_wrapper; 270 struct wl_display *wl_dpy_wrapper; 271 struct wl_drm *wl_drm_wrapper; 272 struct wl_callback *throttle_callback; 273 int format; 274 #endif 275 276 #ifdef HAVE_DRM_PLATFORM 277 struct gbm_dri_surface *gbm_surf; 278 #endif 279 280 /* EGL-owned buffers */ 281 __DRIbuffer *local_buffers[__DRI_BUFFER_COUNT]; 282 283 #if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM) 284 struct { 285 #ifdef HAVE_WAYLAND_PLATFORM 286 struct wl_buffer *wl_buffer; 287 __DRIimage *dri_image; 288 /* for is_different_gpu case. NULL else */ 289 __DRIimage *linear_copy; 290 /* for swrast */ 291 void *data; 292 int data_size; 293 #endif 294 #ifdef HAVE_DRM_PLATFORM 295 struct gbm_bo *bo; 296 #endif 297 bool locked; 298 int age; 299 } color_buffers[4], *back, *current; 300 #endif 301 302 #ifdef HAVE_ANDROID_PLATFORM 303 struct ANativeWindow *window; 304 struct ANativeWindowBuffer *buffer; 305 __DRIimage *dri_image_back; 306 __DRIimage *dri_image_front; 307 308 /* Used to record all the buffers created by ANativeWindow and their ages. 309 * Usually Android uses at most triple buffers in ANativeWindow 310 * so hardcode the number of color_buffers to 3. 311 */ 312 struct { 313 struct ANativeWindowBuffer *buffer; 314 int age; 315 } color_buffers[3], *back; 316 #endif 317 318 #if defined(HAVE_SURFACELESS_PLATFORM) 319 __DRIimage *front; 320 unsigned int visual; 321 #endif 322 int out_fence_fd; 323 EGLBoolean enable_out_fence; 324 }; 325 326 struct dri2_egl_config 327 { 328 _EGLConfig base; 329 const __DRIconfig *dri_config[2][2]; 330 }; 331 332 struct dri2_egl_image 333 { 334 _EGLImage base; 335 __DRIimage *dri_image; 336 }; 337 338 struct dri2_egl_sync { 339 _EGLSync base; 340 mtx_t mutex; 341 cnd_t cond; 342 int refcount; 343 void *fence; 344 }; 345 346 /* From xmlpool/options.h, user exposed so should be stable */ 347 #define DRI_CONF_VBLANK_NEVER 0 348 #define DRI_CONF_VBLANK_DEF_INTERVAL_0 1 349 #define DRI_CONF_VBLANK_DEF_INTERVAL_1 2 350 #define DRI_CONF_VBLANK_ALWAYS_SYNC 3 351 352 /* standard typecasts */ 353 _EGL_DRIVER_STANDARD_TYPECASTS(dri2_egl) 354 _EGL_DRIVER_TYPECAST(dri2_egl_image, _EGLImage, obj) 355 _EGL_DRIVER_TYPECAST(dri2_egl_sync, _EGLSync, obj) 356 357 extern const __DRIimageLookupExtension image_lookup_extension; 358 extern const __DRIuseInvalidateExtension use_invalidate; 359 extern const __DRIbackgroundCallableExtension background_callable_extension; 360 361 EGLBoolean 362 dri2_load_driver(_EGLDisplay *disp); 363 364 /* Helper for platforms not using dri2_create_screen */ 365 void 366 dri2_setup_screen(_EGLDisplay *disp); 367 368 void 369 dri2_setup_swap_interval(_EGLDisplay *disp, int max_swap_interval); 370 371 EGLBoolean 372 dri2_load_driver_swrast(_EGLDisplay *disp); 373 374 EGLBoolean 375 dri2_load_driver_dri3(_EGLDisplay *disp); 376 377 EGLBoolean 378 dri2_create_screen(_EGLDisplay *disp); 379 380 EGLBoolean 381 dri2_setup_extensions(_EGLDisplay *disp); 382 383 __DRIdrawable * 384 dri2_surface_get_dri_drawable(_EGLSurface *surf); 385 386 __DRIimage * 387 dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data); 388 389 struct dri2_egl_config * 390 dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, 391 EGLint surface_type, const EGLint *attr_list, 392 const unsigned int *rgba_masks); 393 394 _EGLImage * 395 dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, 396 _EGLContext *ctx, EGLenum target, 397 EGLClientBuffer buffer, const EGLint *attr_list); 398 399 _EGLImage * 400 dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx, 401 EGLClientBuffer buffer, const EGLint *attr_list); 402 403 #ifdef HAVE_X11_PLATFORM 404 EGLBoolean 405 dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp); 406 void 407 dri2_teardown_x11(struct dri2_egl_display *dri2_dpy); 408 #else 409 static inline EGLBoolean 410 dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp) 411 { 412 return _eglError(EGL_NOT_INITIALIZED, "X11 platform not built"); 413 } 414 static inline void 415 dri2_teardown_x11(struct dri2_egl_display *dri2_dpy) {} 416 #endif 417 418 #ifdef HAVE_DRM_PLATFORM 419 EGLBoolean 420 dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp); 421 void 422 dri2_teardown_drm(struct dri2_egl_display *dri2_dpy); 423 #else 424 static inline EGLBoolean 425 dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp) 426 { 427 return _eglError(EGL_NOT_INITIALIZED, "GBM/DRM platform not built"); 428 } 429 static inline void 430 dri2_teardown_drm(struct dri2_egl_display *dri2_dpy) {} 431 #endif 432 433 #ifdef HAVE_WAYLAND_PLATFORM 434 EGLBoolean 435 dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp); 436 void 437 dri2_teardown_wayland(struct dri2_egl_display *dri2_dpy); 438 #else 439 static inline EGLBoolean 440 dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) 441 { 442 return _eglError(EGL_NOT_INITIALIZED, "Wayland platform not built"); 443 } 444 static inline void 445 dri2_teardown_wayland(struct dri2_egl_display *dri2_dpy) {} 446 #endif 447 448 #ifdef HAVE_ANDROID_PLATFORM 449 EGLBoolean 450 dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp); 451 #else 452 static inline EGLBoolean 453 dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp) 454 { 455 return _eglError(EGL_NOT_INITIALIZED, "Android platform not built"); 456 } 457 #endif 458 459 #ifdef HAVE_SURFACELESS_PLATFORM 460 EGLBoolean 461 dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp); 462 #else 463 static inline EGLBoolean 464 dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp) 465 { 466 return _eglError(EGL_NOT_INITIALIZED, "Surfaceless platform not built"); 467 } 468 #endif 469 470 void 471 dri2_flush_drawable_for_swapbuffers(_EGLDisplay *disp, _EGLSurface *draw); 472 473 const __DRIconfig * 474 dri2_get_dri_config(struct dri2_egl_config *conf, EGLint surface_type, 475 EGLenum colorspace); 476 477 static inline void 478 dri2_set_WL_bind_wayland_display(_EGLDriver *drv, _EGLDisplay *disp) 479 { 480 #ifdef HAVE_WAYLAND_PLATFORM 481 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 482 483 (void) drv; 484 485 if (dri2_dpy->device_name && dri2_dpy->image) { 486 if (dri2_dpy->image->base.version >= 10 && 487 dri2_dpy->image->getCapabilities != NULL) { 488 int capabilities; 489 490 capabilities = 491 dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen); 492 disp->Extensions.WL_bind_wayland_display = 493 (capabilities & __DRI_IMAGE_CAP_GLOBAL_NAMES) != 0; 494 } else { 495 disp->Extensions.WL_bind_wayland_display = EGL_TRUE; 496 } 497 } 498 #endif 499 } 500 501 void 502 dri2_display_destroy(_EGLDisplay *disp); 503 504 __DRIbuffer * 505 dri2_egl_surface_alloc_local_buffer(struct dri2_egl_surface *dri2_surf, 506 unsigned int att, unsigned int format); 507 508 void 509 dri2_egl_surface_free_local_buffers(struct dri2_egl_surface *dri2_surf); 510 511 EGLBoolean 512 dri2_init_surface(_EGLSurface *surf, _EGLDisplay *dpy, EGLint type, 513 _EGLConfig *conf, const EGLint *attrib_list, EGLBoolean enable_out_fence); 514 515 void 516 dri2_fini_surface(_EGLSurface *surf); 517 518 #endif /* EGL_DRI2_INCLUDED */ 519