Home | History | Annotate | Download | only in dri2
      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