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 <stdint.h>
     32 
     33 #ifdef HAVE_X11_PLATFORM
     34 #include <xcb/xcb.h>
     35 #include <xcb/dri2.h>
     36 #include <xcb/xfixes.h>
     37 #include <X11/Xlib-xcb.h>
     38 
     39 #ifdef HAVE_DRI3
     40 #include "loader_dri3_helper.h"
     41 #endif
     42 #endif
     43 
     44 #ifdef HAVE_WAYLAND_PLATFORM
     45 #include <wayland-client.h>
     46 #include "wayland-egl-priv.h"
     47 #endif
     48 
     49 #include <GL/gl.h>
     50 #include <GL/internal/dri_interface.h>
     51 
     52 #ifdef HAVE_DRM_PLATFORM
     53 #include <gbm_driint.h>
     54 #endif
     55 
     56 #ifdef HAVE_ANDROID_PLATFORM
     57 #define LOG_TAG "EGL-DRI2"
     58 
     59 #include <system/window.h>
     60 
     61 #include "platform_android_gralloc_drm.h"
     62 #include <hardware/gralloc.h>
     63 #include <cutils/log.h>
     64 
     65 #endif /* HAVE_ANDROID_PLATFORM */
     66 
     67 #include "eglconfig.h"
     68 #include "eglcontext.h"
     69 #include "egldisplay.h"
     70 #include "egldriver.h"
     71 #include "eglcurrent.h"
     72 #include "egllog.h"
     73 #include "eglsurface.h"
     74 #include "eglimage.h"
     75 #include "eglsync.h"
     76 
     77 struct wl_buffer;
     78 
     79 struct dri2_egl_driver
     80 {
     81    _EGLDriver base;
     82 
     83    void *handle;
     84    _EGLProc (*get_proc_address)(const char *procname);
     85    void (*glFlush)(void);
     86 };
     87 
     88 struct dri2_egl_display_vtbl {
     89    int (*authenticate)(_EGLDisplay *disp, uint32_t id);
     90 
     91    _EGLSurface* (*create_window_surface)(_EGLDriver *drv, _EGLDisplay *dpy,
     92                                          _EGLConfig *config,
     93                                          void *native_window,
     94                                          const EGLint *attrib_list);
     95 
     96    _EGLSurface* (*create_pixmap_surface)(_EGLDriver *drv, _EGLDisplay *dpy,
     97                                          _EGLConfig *config,
     98                                          void *native_pixmap,
     99                                          const EGLint *attrib_list);
    100 
    101    _EGLSurface* (*create_pbuffer_surface)(_EGLDriver *drv, _EGLDisplay *dpy,
    102                                           _EGLConfig *config,
    103                                           const EGLint *attrib_list);
    104 
    105    EGLBoolean (*destroy_surface)(_EGLDriver *drv, _EGLDisplay *dpy,
    106                                  _EGLSurface *surface);
    107 
    108    EGLBoolean (*swap_interval)(_EGLDriver *drv, _EGLDisplay *dpy,
    109                                _EGLSurface *surf, EGLint interval);
    110 
    111    _EGLImage* (*create_image)(_EGLDriver *drv, _EGLDisplay *dpy,
    112                               _EGLContext *ctx, EGLenum target,
    113                               EGLClientBuffer buffer,
    114                               const EGLint *attr_list);
    115 
    116    EGLBoolean (*swap_buffers)(_EGLDriver *drv, _EGLDisplay *dpy,
    117                               _EGLSurface *surf);
    118 
    119    EGLBoolean (*swap_buffers_with_damage)(_EGLDriver *drv, _EGLDisplay *dpy,
    120                                           _EGLSurface *surface,
    121                                           const EGLint *rects, EGLint n_rects);
    122 
    123    EGLBoolean (*swap_buffers_region)(_EGLDriver *drv, _EGLDisplay *dpy,
    124                                      _EGLSurface *surf, EGLint numRects,
    125                                      const EGLint *rects);
    126 
    127    EGLBoolean (*post_sub_buffer)(_EGLDriver *drv, _EGLDisplay *dpy,
    128                                  _EGLSurface *surf,
    129                                  EGLint x, EGLint y,
    130                                  EGLint width, EGLint height);
    131 
    132    EGLBoolean (*copy_buffers)(_EGLDriver *drv, _EGLDisplay *dpy,
    133                               _EGLSurface *surf, void *native_pixmap_target);
    134 
    135    EGLint (*query_buffer_age)(_EGLDriver *drv, _EGLDisplay *dpy,
    136                               _EGLSurface *surf);
    137 
    138    EGLBoolean (*query_surface)(_EGLDriver *drv, _EGLDisplay *dpy,
    139                                _EGLSurface *surf, EGLint attribute,
    140                                EGLint *value);
    141 
    142    struct wl_buffer* (*create_wayland_buffer_from_image)(
    143                         _EGLDriver *drv, _EGLDisplay *dpy, _EGLImage *img);
    144 
    145    EGLBoolean (*get_sync_values)(_EGLDisplay *display, _EGLSurface *surface,
    146                                  EGLuint64KHR *ust, EGLuint64KHR *msc,
    147                                  EGLuint64KHR *sbc);
    148 
    149    __DRIdrawable *(*get_dri_drawable)(_EGLSurface *surf);
    150 };
    151 
    152 struct dri2_egl_display
    153 {
    154    const struct dri2_egl_display_vtbl *vtbl;
    155 
    156    int                       dri2_major;
    157    int                       dri2_minor;
    158    __DRIscreen              *dri_screen;
    159    int                       own_dri_screen;
    160    const __DRIconfig       **driver_configs;
    161    void                     *driver;
    162    const __DRIcoreExtension       *core;
    163    const __DRIimageDriverExtension *image_driver;
    164    const __DRIdri2Extension       *dri2;
    165    const __DRIswrastExtension     *swrast;
    166    const __DRI2flushExtension     *flush;
    167    const __DRItexBufferExtension  *tex_buffer;
    168    const __DRIimageExtension      *image;
    169    const __DRIrobustnessExtension *robustness;
    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    int                       own_device;
    181    int                       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    int                      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    int                       authenticated;
    212    int                       formats;
    213    uint32_t                  capabilities;
    214    char                     *device_name;
    215 #endif
    216 
    217 #ifdef HAVE_ANDROID_PLATFORM
    218    const gralloc_module_t *gralloc;
    219 #endif
    220 
    221    int                       is_render_node;
    222    int                       is_different_gpu;
    223 };
    224 
    225 struct dri2_egl_context
    226 {
    227    _EGLContext   base;
    228    __DRIcontext *dri_context;
    229 };
    230 
    231 #ifdef HAVE_WAYLAND_PLATFORM
    232 enum wayland_buffer_type {
    233    WL_BUFFER_FRONT,
    234    WL_BUFFER_BACK,
    235    WL_BUFFER_THIRD,
    236    WL_BUFFER_COUNT
    237 };
    238 #endif
    239 
    240 struct dri2_egl_surface
    241 {
    242    _EGLSurface          base;
    243    __DRIdrawable       *dri_drawable;
    244    __DRIbuffer          buffers[5];
    245    int                  buffer_count;
    246    int                  have_fake_front;
    247 
    248 #ifdef HAVE_X11_PLATFORM
    249    xcb_drawable_t       drawable;
    250    xcb_xfixes_region_t  region;
    251    int                  depth;
    252    int                  bytes_per_pixel;
    253    xcb_gcontext_t       gc;
    254    xcb_gcontext_t       swapgc;
    255 #endif
    256 
    257 #ifdef HAVE_WAYLAND_PLATFORM
    258    struct wl_egl_window  *wl_win;
    259    int                    dx;
    260    int                    dy;
    261    struct wl_callback    *throttle_callback;
    262    int                    format;
    263 #endif
    264 
    265 #ifdef HAVE_DRM_PLATFORM
    266    struct gbm_dri_surface *gbm_surf;
    267 #endif
    268 
    269 #if defined(HAVE_WAYLAND_PLATFORM) || defined(HAVE_DRM_PLATFORM)
    270    __DRIbuffer           *dri_buffers[__DRI_BUFFER_COUNT];
    271    struct {
    272 #ifdef HAVE_WAYLAND_PLATFORM
    273       struct wl_buffer   *wl_buffer;
    274       __DRIimage         *dri_image;
    275       /* for is_different_gpu case. NULL else */
    276       __DRIimage         *linear_copy;
    277       /* for swrast */
    278       void *data;
    279       int data_size;
    280 #endif
    281 #ifdef HAVE_DRM_PLATFORM
    282       struct gbm_bo       *bo;
    283 #endif
    284       int                 locked;
    285       int                 age;
    286    } color_buffers[4], *back, *current;
    287 #endif
    288 
    289 #ifdef HAVE_ANDROID_PLATFORM
    290    struct ANativeWindow *window;
    291    struct ANativeWindowBuffer *buffer;
    292    __DRIimage *dri_image_back;
    293    __DRIimage *dri_image_front;
    294 
    295    /* EGL-owned buffers */
    296    __DRIbuffer           *local_buffers[__DRI_BUFFER_COUNT];
    297 #endif
    298 
    299 #if defined(HAVE_SURFACELESS_PLATFORM)
    300       __DRIimage           *front;
    301       unsigned int         visual;
    302 #endif
    303 };
    304 
    305 struct dri2_egl_config
    306 {
    307    _EGLConfig         base;
    308    const __DRIconfig *dri_single_config[2];
    309    const __DRIconfig *dri_double_config[2];
    310 };
    311 
    312 struct dri2_egl_image
    313 {
    314    _EGLImage   base;
    315    __DRIimage *dri_image;
    316 };
    317 
    318 struct dri2_egl_sync {
    319    _EGLSync base;
    320    mtx_t mutex;
    321    cnd_t cond;
    322    int refcount;
    323    void *fence;
    324 };
    325 
    326 /* From xmlpool/options.h, user exposed so should be stable */
    327 #define DRI_CONF_VBLANK_NEVER 0
    328 #define DRI_CONF_VBLANK_DEF_INTERVAL_0 1
    329 #define DRI_CONF_VBLANK_DEF_INTERVAL_1 2
    330 #define DRI_CONF_VBLANK_ALWAYS_SYNC 3
    331 
    332 /* standard typecasts */
    333 _EGL_DRIVER_STANDARD_TYPECASTS(dri2_egl)
    334 _EGL_DRIVER_TYPECAST(dri2_egl_image, _EGLImage, obj)
    335 _EGL_DRIVER_TYPECAST(dri2_egl_sync, _EGLSync, obj)
    336 
    337 extern const __DRIimageLookupExtension image_lookup_extension;
    338 extern const __DRIuseInvalidateExtension use_invalidate;
    339 
    340 EGLBoolean
    341 dri2_load_driver(_EGLDisplay *disp);
    342 
    343 /* Helper for platforms not using dri2_create_screen */
    344 void
    345 dri2_setup_screen(_EGLDisplay *disp);
    346 
    347 EGLBoolean
    348 dri2_load_driver_swrast(_EGLDisplay *disp);
    349 
    350 EGLBoolean
    351 dri2_load_driver_dri3(_EGLDisplay *disp);
    352 
    353 EGLBoolean
    354 dri2_create_screen(_EGLDisplay *disp);
    355 
    356 __DRIdrawable *
    357 dri2_surface_get_dri_drawable(_EGLSurface *surf);
    358 
    359 __DRIimage *
    360 dri2_lookup_egl_image(__DRIscreen *screen, void *image, void *data);
    361 
    362 struct dri2_egl_config *
    363 dri2_add_config(_EGLDisplay *disp, const __DRIconfig *dri_config, int id,
    364                 EGLint surface_type, const EGLint *attr_list,
    365                 const unsigned int *rgba_masks);
    366 
    367 _EGLImage *
    368 dri2_create_image_khr(_EGLDriver *drv, _EGLDisplay *disp,
    369                       _EGLContext *ctx, EGLenum target,
    370                       EGLClientBuffer buffer, const EGLint *attr_list);
    371 
    372 _EGLImage *
    373 dri2_create_image_dma_buf(_EGLDisplay *disp, _EGLContext *ctx,
    374                           EGLClientBuffer buffer, const EGLint *attr_list);
    375 
    376 EGLBoolean
    377 dri2_initialize_x11(_EGLDriver *drv, _EGLDisplay *disp);
    378 
    379 EGLBoolean
    380 dri2_initialize_drm(_EGLDriver *drv, _EGLDisplay *disp);
    381 
    382 EGLBoolean
    383 dri2_initialize_wayland(_EGLDriver *drv, _EGLDisplay *disp);
    384 
    385 EGLBoolean
    386 dri2_initialize_android(_EGLDriver *drv, _EGLDisplay *disp);
    387 
    388 EGLBoolean
    389 dri2_initialize_surfaceless(_EGLDriver *drv, _EGLDisplay *disp);
    390 
    391 void
    392 dri2_flush_drawable_for_swapbuffers(_EGLDisplay *disp, _EGLSurface *draw);
    393 
    394 const __DRIconfig *
    395 dri2_get_dri_config(struct dri2_egl_config *conf, EGLint surface_type,
    396                     EGLenum colorspace);
    397 
    398 static inline void
    399 dri2_set_WL_bind_wayland_display(_EGLDriver *drv, _EGLDisplay *disp)
    400 {
    401 #ifdef HAVE_WAYLAND_PLATFORM
    402    struct dri2_egl_display *dri2_dpy = dri2_egl_display(disp);
    403 
    404    (void) drv;
    405 
    406    if (dri2_dpy->device_name && dri2_dpy->image) {
    407        if (dri2_dpy->image->base.version >= 10 &&
    408            dri2_dpy->image->getCapabilities != NULL) {
    409            int capabilities;
    410 
    411            capabilities =
    412                dri2_dpy->image->getCapabilities(dri2_dpy->dri_screen);
    413            disp->Extensions.WL_bind_wayland_display =
    414                (capabilities & __DRI_IMAGE_CAP_GLOBAL_NAMES) != 0;
    415        } else {
    416            disp->Extensions.WL_bind_wayland_display = EGL_TRUE;
    417        }
    418    }
    419 #endif
    420 }
    421 
    422 #endif /* EGL_DRI2_INCLUDED */
    423