Edit

IABSD.fr/xenocara/lib/mesa/src/loader/loader_dri3_helper.h

Branch :

  • Show log

    Commit

  • Author : jsg
    Date : 2019-01-29 11:52:04
    Hash : 338bc0a2
    Message : Merge Mesa 18.3.2

  • lib/mesa/src/loader/loader_dri3_helper.h
  • /*
     * Copyright © 2013 Keith Packard
     * Copyright © 2015 Boyan Ding
     *
     * Permission to use, copy, modify, distribute, and sell this software and its
     * documentation for any purpose is hereby granted without fee, provided that
     * the above copyright notice appear in all copies and that both that copyright
     * notice and this permission notice appear in supporting documentation, and
     * that the name of the copyright holders not be used in advertising or
     * publicity pertaining to distribution of the software without specific,
     * written prior permission.  The copyright holders make no representations
     * about the suitability of this software for any purpose.  It is provided "as
     * is" without express or implied warranty.
     *
     * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
     * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
     * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
     * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
     * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
     * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
     * OF THIS SOFTWARE.
     */
    
    #ifndef LOADER_DRI3_HEADER_H
    #define LOADER_DRI3_HEADER_H
    
    #include <stdbool.h>
    #include <stdint.h>
    
    #include <xcb/xcb.h>
    #include <xcb/dri3.h>
    #include <xcb/present.h>
    
    #include <GL/gl.h>
    #include <GL/internal/dri_interface.h>
    #include <c11/threads.h>
    
    enum loader_dri3_buffer_type {
       loader_dri3_buffer_back = 0,
       loader_dri3_buffer_front = 1
    };
    
    struct loader_dri3_buffer {
       __DRIimage   *image;
       __DRIimage   *linear_buffer;
       uint32_t     pixmap;
    
       /* Synchronization between the client and X server is done using an
        * xshmfence that is mapped into an X server SyncFence. This lets the
        * client check whether the X server is done using a buffer with a simple
        * xshmfence call, rather than going to read X events from the wire.
        *
        * However, we can only wait for one xshmfence to be triggered at a time,
        * so we need to know *which* buffer is going to be idle next. We do that
        * by waiting for a PresentIdleNotify event. When that event arrives, the
        * 'busy' flag gets cleared and the client knows that the fence has been
        * triggered, and that the wait call will not block.
        */
    
       uint32_t     sync_fence;     /* XID of X SyncFence object */
       struct xshmfence *shm_fence; /* pointer to xshmfence object */
       bool         busy;           /* Set on swap, cleared on IdleNotify */
       bool         own_pixmap;     /* We allocated the pixmap ID, free on destroy */
       bool         reallocate;     /* Buffer should be reallocated and not reused */
    
       uint32_t     num_planes;
       uint32_t     size;
       int          strides[4];
       int          offsets[4];
       uint64_t     modifier;
       uint32_t     cpp;
       uint32_t     flags;
       uint32_t     width, height;
       uint64_t     last_swap;
    };
    
    
    #define LOADER_DRI3_MAX_BACK   4
    #define LOADER_DRI3_BACK_ID(i) (i)
    #define LOADER_DRI3_FRONT_ID   (LOADER_DRI3_MAX_BACK)
    
    static inline int
    loader_dri3_pixmap_buf_id(enum loader_dri3_buffer_type buffer_type)
    {
       if (buffer_type == loader_dri3_buffer_back)
          return LOADER_DRI3_BACK_ID(0);
       else
          return LOADER_DRI3_FRONT_ID;
    }
    
    struct loader_dri3_extensions {
       const __DRIcoreExtension *core;
       const __DRIimageDriverExtension *image_driver;
       const __DRI2flushExtension *flush;
       const __DRI2configQueryExtension *config;
       const __DRItexBufferExtension *tex_buffer;
       const __DRIimageExtension *image;
    };
    
    struct loader_dri3_drawable;
    
    struct loader_dri3_vtable {
       void (*set_drawable_size)(struct loader_dri3_drawable *, int, int);
       bool (*in_current_context)(struct loader_dri3_drawable *);
       __DRIcontext *(*get_dri_context)(struct loader_dri3_drawable *);
       __DRIscreen *(*get_dri_screen)(void);
       void (*flush_drawable)(struct loader_dri3_drawable *, unsigned);
       void (*show_fps)(struct loader_dri3_drawable *, uint64_t);
    };
    
    #define LOADER_DRI3_NUM_BUFFERS (1 + LOADER_DRI3_MAX_BACK)
    
    struct loader_dri3_drawable {
       xcb_connection_t *conn;
       xcb_screen_t *screen;
       __DRIdrawable *dri_drawable;
       xcb_drawable_t drawable;
       xcb_window_t window;
       int width;
       int height;
       int depth;
       uint8_t have_back;
       uint8_t have_fake_front;
       uint8_t is_pixmap;
    
       /* Information about the GPU owning the buffer */
       __DRIscreen *dri_screen;
       bool is_different_gpu;
       bool multiplanes_available;
    
       /* Present extension capabilities
        */
       uint32_t present_capabilities;
    
       /* SBC numbers are tracked by using the serial numbers
        * in the present request and complete events
        */
       uint64_t send_sbc;
       uint64_t recv_sbc;
    
       /* Last received UST/MSC values for pixmap present complete */
       uint64_t ust, msc;
    
       /* Last received UST/MSC values from present notify msc event */
       uint64_t notify_ust, notify_msc;
    
       struct loader_dri3_buffer *buffers[LOADER_DRI3_NUM_BUFFERS];
       int cur_back;
       int num_back;
       int cur_blit_source;
    
       uint32_t *stamp;
    
       xcb_present_event_t eid;
       xcb_gcontext_t gc;
       xcb_special_event_t *special_event;
    
       bool first_init;
       int swap_interval;
    
       struct loader_dri3_extensions *ext;
       const struct loader_dri3_vtable *vtable;
    
       unsigned int swap_method;
       unsigned int back_format;
       xcb_present_complete_mode_t last_present_mode;
    
       /* Currently protects the following fields:
        * event_cnd, has_event_waiter,
        * recv_sbc, ust, msc, recv_msc_serial,
        * notify_ust, notify_msc
        */
       mtx_t mtx;
       cnd_t event_cnd;
       bool has_event_waiter;
    };
    
    void
    loader_dri3_set_swap_interval(struct loader_dri3_drawable *draw,
                                  int interval);
    
    void
    loader_dri3_drawable_fini(struct loader_dri3_drawable *draw);
    
    int
    loader_dri3_drawable_init(xcb_connection_t *conn,
                              xcb_drawable_t drawable,
                              __DRIscreen *dri_screen,
                              bool is_different_gpu,
                              bool is_multiplanes_available,
                              const __DRIconfig *dri_config,
                              struct loader_dri3_extensions *ext,
                              const struct loader_dri3_vtable *vtable,
                              struct loader_dri3_drawable*);
    
    bool loader_dri3_wait_for_msc(struct loader_dri3_drawable *draw,
                                  int64_t target_msc,
                                  int64_t divisor, int64_t remainder,
                                  int64_t *ust, int64_t *msc, int64_t *sbc);
    
    int64_t
    loader_dri3_swap_buffers_msc(struct loader_dri3_drawable *draw,
                                 int64_t target_msc, int64_t divisor,
                                 int64_t remainder, unsigned flush_flags,
                                 bool force_copy);
    
    int
    loader_dri3_wait_for_sbc(struct loader_dri3_drawable *draw,
                             int64_t target_sbc, int64_t *ust,
                             int64_t *msc, int64_t *sbc);
    
    int loader_dri3_query_buffer_age(struct loader_dri3_drawable *draw);
    
    void
    loader_dri3_flush(struct loader_dri3_drawable *draw,
                      unsigned flags,
                      enum __DRI2throttleReason throttle_reason);
    
    void
    loader_dri3_copy_sub_buffer(struct loader_dri3_drawable *draw,
                                int x, int y,
                                int width, int height,
                                bool flush);
    
    void
    loader_dri3_copy_drawable(struct loader_dri3_drawable *draw,
                              xcb_drawable_t dest,
                              xcb_drawable_t src);
    
    void
    loader_dri3_wait_x(struct loader_dri3_drawable *draw);
    
    void
    loader_dri3_wait_gl(struct loader_dri3_drawable *draw);
    
    int loader_dri3_open(xcb_connection_t *conn,
                         xcb_window_t root,
                         uint32_t provider);
    
    __DRIimage *
    loader_dri3_create_image(xcb_connection_t *c,
                             xcb_dri3_buffer_from_pixmap_reply_t *bp_reply,
                             unsigned int format,
                             __DRIscreen *dri_screen,
                             const __DRIimageExtension *image,
                             void *loaderPrivate);
    
    #ifdef HAVE_DRI3_MODIFIERS
    __DRIimage *
    loader_dri3_create_image_from_buffers(xcb_connection_t *c,
                                          xcb_dri3_buffers_from_pixmap_reply_t *bp_reply,
                                          unsigned int format,
                                          __DRIscreen *dri_screen,
                                          const __DRIimageExtension *image,
                                          void *loaderPrivate);
    #endif
    int
    loader_dri3_get_buffers(__DRIdrawable *driDrawable,
                            unsigned int format,
                            uint32_t *stamp,
                            void *loaderPrivate,
                            uint32_t buffer_mask,
                            struct __DRIimageList *buffers);
    
    void
    loader_dri3_update_drawable_geometry(struct loader_dri3_drawable *draw);
    
    void
    loader_dri3_swapbuffer_barrier(struct loader_dri3_drawable *draw);
    
    void
    loader_dri3_close_screen(__DRIscreen *dri_screen);
    #endif