egl_dri2.h revision 7e102996
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 Høgsberg <krh@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/* forward declarations to avoid pulling wayland headers everywhere */ 47struct wl_egl_window; 48struct wl_event_queue; 49struct wl_callback; 50struct wl_display; 51struct wl_drm; 52struct wl_registry; 53struct wl_shm; 54struct wl_surface; 55struct zwp_linux_dmabuf_v1; 56#endif 57 58#include <GL/gl.h> 59#include <GL/internal/dri_interface.h> 60 61#ifdef HAVE_DRM_PLATFORM 62#include <gbm_driint.h> 63#endif 64 65#ifdef HAVE_ANDROID_PLATFORM 66#define LOG_TAG "EGL-DRI2" 67 68#include <system/window.h> 69#include <hardware/gralloc.h> 70#endif /* HAVE_ANDROID_PLATFORM */ 71 72#include "eglconfig.h" 73#include "eglcontext.h" 74#include "egldevice.h" 75#include "egldisplay.h" 76#include "egldriver.h" 77#include "eglcurrent.h" 78#include "egllog.h" 79#include "eglsurface.h" 80#include "eglimage.h" 81#include "eglsync.h" 82 83#include "util/u_vector.h" 84 85struct wl_buffer; 86 87struct dri2_egl_display_vtbl { 88 int (*authenticate)(_EGLDisplay *disp, uint32_t id); 89 90 _EGLSurface* (*create_window_surface)(_EGLDriver *drv, _EGLDisplay *disp, 91 _EGLConfig *config, 92 void *native_window, 93 const EGLint *attrib_list); 94 95 _EGLSurface* (*create_pixmap_surface)(_EGLDriver *drv, _EGLDisplay *disp, 96 _EGLConfig *config, 97 void *native_pixmap, 98 const EGLint *attrib_list); 99 100 _EGLSurface* (*create_pbuffer_surface)(_EGLDriver *drv, _EGLDisplay *disp, 101 _EGLConfig *config, 102 const EGLint *attrib_list); 103 104 EGLBoolean (*destroy_surface)(_EGLDriver *drv, _EGLDisplay *disp, 105 _EGLSurface *surface); 106 107 EGLBoolean (*swap_interval)(_EGLDriver *drv, _EGLDisplay *disp, 108 _EGLSurface *surf, EGLint interval); 109 110 _EGLImage* (*create_image)(_EGLDriver *drv, _EGLDisplay *disp, 111 _EGLContext *ctx, EGLenum target, 112 EGLClientBuffer buffer, 113 const EGLint *attr_list); 114 115 EGLBoolean (*swap_buffers)(_EGLDriver *drv, _EGLDisplay *disp, 116 _EGLSurface *surf); 117 118 EGLBoolean (*swap_buffers_with_damage)(_EGLDriver *drv, _EGLDisplay *disp, 119 _EGLSurface *surface, 120 const EGLint *rects, EGLint n_rects); 121 122 EGLBoolean (*set_damage_region)(_EGLDriver *drv, _EGLDisplay *disp, 123 _EGLSurface *surface, 124 const EGLint *rects, EGLint n_rects); 125 126 EGLBoolean (*swap_buffers_region)(_EGLDriver *drv, _EGLDisplay *disp, 127 _EGLSurface *surf, EGLint numRects, 128 const EGLint *rects); 129 130 EGLBoolean (*post_sub_buffer)(_EGLDriver *drv, _EGLDisplay *disp, 131 _EGLSurface *surf, 132 EGLint x, EGLint y, 133 EGLint width, EGLint height); 134 135 EGLBoolean (*copy_buffers)(_EGLDriver *drv, _EGLDisplay *disp, 136 _EGLSurface *surf, void *native_pixmap_target); 137 138 EGLint (*query_buffer_age)(_EGLDriver *drv, _EGLDisplay *disp, 139 _EGLSurface *surf); 140 141 EGLBoolean (*query_surface)(_EGLDriver *drv, _EGLDisplay *disp, 142 _EGLSurface *surf, EGLint attribute, 143 EGLint *value); 144 145 struct wl_buffer* (*create_wayland_buffer_from_image)( 146 _EGLDriver *drv, _EGLDisplay *disp, _EGLImage *img); 147 148 EGLBoolean (*get_sync_values)(_EGLDisplay *display, _EGLSurface *surface, 149 EGLuint64KHR *ust, EGLuint64KHR *msc, 150 EGLuint64KHR *sbc); 151 152 __DRIdrawable *(*get_dri_drawable)(_EGLSurface *surf); 153 154 void (*close_screen_notify)(_EGLDisplay *disp); 155 156 /* Used in EGL_KHR_mutable_render_buffer to update the native window's 157 * shared buffer mode. 158 */ 159 bool (*set_shared_buffer_mode)(_EGLDisplay *disp, _EGLSurface *surf, 160 bool mode); 161}; 162 163struct dri2_egl_display 164{ 165 const struct dri2_egl_display_vtbl *vtbl; 166 167 int dri2_major; 168 int dri2_minor; 169 __DRIscreen *dri_screen; 170 bool own_dri_screen; 171 const __DRIconfig **driver_configs; 172 void *driver; 173 const __DRIcoreExtension *core; 174 const __DRIimageDriverExtension *image_driver; 175 const __DRIdri2Extension *dri2; 176 const __DRIswrastExtension *swrast; 177 const __DRI2flushExtension *flush; 178 const __DRI2flushControlExtension *flush_control; 179 const __DRItexBufferExtension *tex_buffer; 180 const __DRIimageExtension *image; 181 const __DRIrobustnessExtension *robustness; 182 const __DRInoErrorExtension *no_error; 183 const __DRI2configQueryExtension *config; 184 const __DRI2fenceExtension *fence; 185 const __DRI2blobExtension *blob; 186 const __DRI2rendererQueryExtension *rendererQuery; 187 const __DRI2interopExtension *interop; 188 const __DRIconfigOptionsExtension *configOptions; 189 const __DRImutableRenderBufferDriverExtension *mutable_render_buffer; 190 int fd; 191 192 /* dri2_initialize/dri2_terminate increment/decrement this count, so does 193 * dri2_make_current (tracks if there are active contexts/surfaces). */ 194 int ref_count; 195 196 bool own_device; 197 bool invalidate_available; 198 int min_swap_interval; 199 int max_swap_interval; 200 int default_swap_interval; 201#ifdef HAVE_DRM_PLATFORM 202 struct gbm_dri_device *gbm_dri; 203#endif 204 205 char *driver_name; 206 207 const __DRIextension **loader_extensions; 208 const __DRIextension **driver_extensions; 209 210#ifdef HAVE_X11_PLATFORM 211 xcb_connection_t *conn; 212 xcb_screen_t *screen; 213 bool swap_available; 214#ifdef HAVE_DRI3 215 bool multibuffers_available; 216 int dri3_major_version; 217 int dri3_minor_version; 218 int present_major_version; 219 int present_minor_version; 220 struct loader_dri3_extensions loader_dri3_ext; 221#endif 222#endif 223 224#ifdef HAVE_WAYLAND_PLATFORM 225 struct wl_display *wl_dpy; 226 struct wl_display *wl_dpy_wrapper; 227 struct wl_registry *wl_registry; 228 struct wl_drm *wl_server_drm; 229 struct wl_drm *wl_drm; 230 struct wl_shm *wl_shm; 231 struct wl_event_queue *wl_queue; 232 struct zwp_linux_dmabuf_v1 *wl_dmabuf; 233 struct u_vector *wl_modifiers; 234 bool authenticated; 235 unsigned formats; 236 uint32_t capabilities; 237 char *device_name; 238#endif 239 240#ifdef HAVE_ANDROID_PLATFORM 241 const gralloc_module_t *gralloc; 242#endif 243 244 bool is_render_node; 245 bool is_different_gpu; 246}; 247 248struct dri2_egl_context 249{ 250 _EGLContext base; 251 __DRIcontext *dri_context; 252}; 253 254#ifdef HAVE_WAYLAND_PLATFORM 255enum wayland_buffer_type { 256 WL_BUFFER_FRONT, 257 WL_BUFFER_BACK, 258 WL_BUFFER_THIRD, 259 WL_BUFFER_COUNT 260}; 261#endif 262 263struct dri2_egl_surface 264{ 265 _EGLSurface base; 266 __DRIdrawable *dri_drawable; 267 __DRIbuffer buffers[5]; 268 bool have_fake_front; 269 270#ifdef HAVE_X11_PLATFORM 271 xcb_drawable_t drawable; 272 xcb_xfixes_region_t region; 273 int depth; 274 int bytes_per_pixel; 275 xcb_gcontext_t gc; 276 xcb_gcontext_t swapgc; 277#endif 278 279#ifdef HAVE_WAYLAND_PLATFORM 280 struct wl_egl_window *wl_win; 281 int dx; 282 int dy; 283 struct wl_event_queue *wl_queue; 284 struct wl_surface *wl_surface_wrapper; 285 struct wl_display *wl_dpy_wrapper; 286 struct wl_drm *wl_drm_wrapper; 287 struct wl_callback *throttle_callback; 288 int format; 289#endif 290 291#ifdef HAVE_DRM_PLATFORM 292 struct gbm_dri_surface *gbm_surf; 293#endif 294 295 /* EGL-owned buffers */ 296 __DRIbuffer *local_buffers[__DRI_BUFFER_COUNT]; 297 298#if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM) 299 struct { 300#ifdef HAVE_WAYLAND_PLATFORM 301 struct wl_buffer *wl_buffer; 302 bool wl_release; 303 __DRIimage *dri_image; 304 /* for is_different_gpu case. NULL else */ 305 __DRIimage *linear_copy; 306 /* for swrast */ 307 void *data; 308 int data_size; 309#endif 310#ifdef HAVE_DRM_PLATFORM 311 struct gbm_bo *bo; 312#endif 313 bool locked; 314 int age; 315 } color_buffers[4], *back, *current; 316#endif 317 318#ifdef HAVE_ANDROID_PLATFORM 319 struct ANativeWindow *window; 320 struct ANativeWindowBuffer *buffer; 321 __DRIimage *dri_image_back; 322 __DRIimage *dri_image_front; 323 324 /* Used to record all the buffers created by ANativeWindow and their ages. 325 * Allocate number of color_buffers based on query to android bufferqueue 326 * and save color_buffers_count. 327 */ 328 int color_buffers_count; 329 struct { 330 struct ANativeWindowBuffer *buffer; 331 int age; 332 } *color_buffers, *back; 333#endif 334 335#if defined(HAVE_SURFACELESS_PLATFORM) 336 __DRIimage *front; 337 unsigned int visual; 338#endif 339 int out_fence_fd; 340 EGLBoolean enable_out_fence; 341}; 342 343struct dri2_egl_config 344{ 345 _EGLConfig base; 346 const __DRIconfig *dri_config[2][2]; 347}; 348 349struct dri2_egl_image 350{ 351 _EGLImage base; 352 __DRIimage *dri_image; 353}; 354 355struct dri2_egl_sync { 356 _EGLSync base; 357 mtx_t mutex; 358 cnd_t cond; 359 int refcount; 360 void *fence; 361}; 362 363/* From xmlpool/options.h, user exposed so should be stable */ 364#define DRI_CONF_VBLANK_NEVER 0 365#define DRI_CONF_VBLANK_DEF_INTERVAL_0 1 366#define DRI_CONF_VBLANK_DEF_INTERVAL_1 2 367#define DRI_CONF_VBLANK_ALWAYS_SYNC 3 368 369/* standard typecasts */ 370_EGL_DRIVER_STANDARD_TYPECASTS(dri2_egl) 371_EGL_DRIVER_TYPECAST(dri2_egl_image, _EGLImage, obj) 372_EGL_DRIVER_TYPECAST(dri2_egl_sync, _EGLSync, obj) 373 374extern const __DRIimageLookupExtension image_lookup_extension; 375extern const __DRIuseInvalidateExtension use_invalidate; 376extern const __DRIbackgroundCallableExtension background_callable_extension; 377 378EGLBoolean 379dri2_load_driver(_EGLDisplay *disp); 380 381/* Helper for platforms not using dri2_create_screen */ 382void 383dri2_setup_screen(_EGLDisplay *disp); 384 385void 386dri2_setup_swap_interval(_EGLDisplay *disp, int max_swap_interval); 387 388EGLBoolean 389dri2_load_driver_swrast(_EGLDisplay *disp); 390 391EGLBoolean 392dri2_load_driver_dri3(_EGLDisplay *disp); 393 394EGLBoolean 395dri2_create_screen(_EGLDisplay *disp); 396 397EGLBoolean 398dri2_setup_extensions(_EGLDisplay *disp); 399 400__DRIdrawable * 401dri2_surface_get_dri_drawable(_EGLSurface *surf); 402 403__DRIimage * 404dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data); 405 406struct dri2_egl_config * 407dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id, 408 EGLint surface_type, const EGLint *attr_list, 409 const unsigned int *rgba_masks); 410 411_EGLImage * 412dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp, 413 _EGLContext *ctx, EGLenum target, 414 EGLClientBuffer buffer, const EGLint *attr_list); 415 416_EGLImage * 417dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx, 418 EGLClientBuffer buffer, const EGLint *attr_list); 419 420#ifdef HAVE_X11_PLATFORM 421EGLBoolean 422dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp); 423void 424dri2_teardown_x11(struct dri2_egl_display *dri2_dpy); 425unsigned int 426dri2_x11_get_red_mask_for_depth(struct dri2_egl_display *dri2_dpy, int depth); 427#else 428static inline EGLBoolean 429dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp) 430{ 431 return _eglError(EGL_NOT_INITIALIZED, "X11 platform not built"); 432} 433static inline void 434dri2_teardown_x11(struct dri2_egl_display *dri2_dpy) {} 435static inline unsigned int 436dri2_x11_get_red_mask_for_depth(struct dri2_egl_display *dri2_dpy, int depth) 437{ 438 return 0; 439} 440#endif 441 442#ifdef HAVE_DRM_PLATFORM 443EGLBoolean 444dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp); 445void 446dri2_teardown_drm(struct dri2_egl_display *dri2_dpy); 447#else 448static inline EGLBoolean 449dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp) 450{ 451 return _eglError(EGL_NOT_INITIALIZED, "GBM/DRM platform not built"); 452} 453static inline void 454dri2_teardown_drm(struct dri2_egl_display *dri2_dpy) {} 455#endif 456 457#ifdef HAVE_WAYLAND_PLATFORM 458EGLBoolean 459dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp); 460void 461dri2_teardown_wayland(struct dri2_egl_display *dri2_dpy); 462bool 463dri2_wl_is_format_supported(void* user_data, uint32_t format); 464#else 465static inline EGLBoolean 466dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp) 467{ 468 return _eglError(EGL_NOT_INITIALIZED, "Wayland platform not built"); 469} 470static inline void 471dri2_teardown_wayland(struct dri2_egl_display *dri2_dpy) {} 472#endif 473 474#ifdef HAVE_ANDROID_PLATFORM 475EGLBoolean 476dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp); 477#else 478static inline EGLBoolean 479dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp) 480{ 481 return _eglError(EGL_NOT_INITIALIZED, "Android platform not built"); 482} 483#endif 484 485#ifdef HAVE_SURFACELESS_PLATFORM 486EGLBoolean 487dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp); 488#else 489static inline EGLBoolean 490dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp) 491{ 492 return _eglError(EGL_NOT_INITIALIZED, "Surfaceless platform not built"); 493} 494#endif 495 496void 497dri2_flush_drawable_for_swapbuffers(_EGLDisplay *disp, _EGLSurface *draw); 498 499const __DRIconfig * 500dri2_get_dri_config(struct dri2_egl_config *conf, EGLint surface_type, 501 EGLenum colorspace); 502 503static inline void 504dri2_set_WL_bind_wayland_display(_EGLDriver *drv, _EGLDisplay *disp) 505{ 506#ifdef HAVE_WAYLAND_PLATFORM 507 struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp); 508 509 (void) drv; 510 511 if (dri2_dpy->device_name && dri2_dpy->image) { 512 if (dri2_dpy->image->base.version >= 10 && 513 dri2_dpy->image->getCapabilities != NULL) { 514 int capabilities; 515 516 capabilities = 517 dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen); 518 disp->Extensions.WL_bind_wayland_display = 519 (capabilities & __DRI_IMAGE_CAP_GLOBAL_NAMES) != 0; 520 } else { 521 disp->Extensions.WL_bind_wayland_display = EGL_TRUE; 522 } 523 } 524#endif 525} 526 527void 528dri2_display_destroy(_EGLDisplay *disp); 529 530__DRIbuffer * 531dri2_egl_surface_alloc_local_buffer(struct dri2_egl_surface *dri2_surf, 532 unsigned int att, unsigned int format); 533 534void 535dri2_egl_surface_free_local_buffers(struct dri2_egl_surface *dri2_surf); 536 537EGLBoolean 538dri2_init_surface(_EGLSurface *surf, _EGLDisplay *disp, EGLint type, 539 _EGLConfig *conf, const EGLint *attrib_list, EGLBoolean enable_out_fence); 540 541void 542dri2_fini_surface(_EGLSurface *surf); 543 544EGLBoolean 545dri2_create_drawable(struct dri2_egl_display *dri2_dpy, 546 const __DRIconfig *config, 547 struct dri2_egl_surface *dri2_surf); 548 549static inline uint64_t 550combine_u32_into_u64(uint32_t hi, uint32_t lo) 551{ 552 return (((uint64_t) hi) << 32) | (((uint64_t) lo) & 0xffffffff); 553} 554 555#endif /* EGL_DRI2_INCLUDED */ 556