summaryrefslogtreecommitdiffstats
path: root/src/loader/loader_dri3_helper.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/loader/loader_dri3_helper.h')
-rw-r--r--src/loader/loader_dri3_helper.h232
1 files changed, 232 insertions, 0 deletions
diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h
new file mode 100644
index 00000000000..54c2a52f5e1
--- /dev/null
+++ b/src/loader/loader_dri3_helper.h
@@ -0,0 +1,232 @@
+/*
+ * 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/present.h>
+
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.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 */
+
+ uint32_t size;
+ uint32_t pitch;
+ uint32_t cpp;
+ uint32_t flags;
+ uint32_t width, height;
+ uint64_t last_swap;
+
+ enum loader_dri3_buffer_type buffer_type;
+};
+
+
+#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 {
+ int (*get_swap_interval)(struct loader_dri3_drawable *);
+ int (*clamp_swap_interval)(struct loader_dri3_drawable *, int);
+ void (*set_swap_interval)(struct loader_dri3_drawable *, int);
+ 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 *);
+ 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;
+ __DRIdrawable *dri_drawable;
+ xcb_drawable_t drawable;
+ int width;
+ int height;
+ int depth;
+ uint8_t have_back;
+ uint8_t have_fake_front;
+ uint8_t is_pixmap;
+ uint8_t flipping;
+
+ /* Information about the GPU owning the buffer */
+ __DRIscreen *dri_screen;
+ bool is_different_gpu;
+
+ /* 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;
+
+ /* Serial numbers for tracking wait_for_msc events */
+ uint32_t send_msc_serial;
+ uint32_t recv_msc_serial;
+
+ struct loader_dri3_buffer *buffers[LOADER_DRI3_NUM_BUFFERS];
+ int cur_back;
+ int num_back;
+
+ uint32_t *stamp;
+
+ xcb_present_event_t eid;
+ xcb_gcontext_t gc;
+ xcb_special_event_t *special_event;
+
+ bool first_init;
+
+ struct loader_dri3_extensions *ext;
+ struct loader_dri3_vtable *vtable;
+};
+
+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,
+ const __DRIconfig *dri_config,
+ struct loader_dri3_extensions *ext,
+ 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);
+
+int
+loader_dri3_get_buffers(__DRIdrawable *driDrawable,
+ unsigned int format,
+ uint32_t *stamp,
+ void *loaderPrivate,
+ uint32_t buffer_mask,
+ struct __DRIimageList *buffers);
+
+#endif