summaryrefslogtreecommitdiff
path: root/vmwgfx
diff options
context:
space:
mode:
Diffstat (limited to 'vmwgfx')
-rw-r--r--vmwgfx/Makefile.am3
-rw-r--r--vmwgfx/vmwgfx_dri2.c3
-rw-r--r--vmwgfx/vmwgfx_saa.c55
-rw-r--r--vmwgfx/vmwgfx_saa.h4
-rw-r--r--vmwgfx/wsbm_util.h79
5 files changed, 100 insertions, 44 deletions
diff --git a/vmwgfx/Makefile.am b/vmwgfx/Makefile.am
index ce4b115..3c31543 100644
--- a/vmwgfx/Makefile.am
+++ b/vmwgfx/Makefile.am
@@ -19,7 +19,8 @@ vmwgfx_drv_la_SOURCES = \
vmwgfx_bootstrap.c \
vmwgfx_overlay.c \
vmwgfx_ctrl.c \
- vmwgfx_ctrl.h
+ vmwgfx_ctrl.h \
+ wsbm_util.h
diff --git a/vmwgfx/vmwgfx_dri2.c b/vmwgfx/vmwgfx_dri2.c
index b80c813..1529cdb 100644
--- a/vmwgfx/vmwgfx_dri2.c
+++ b/vmwgfx/vmwgfx_dri2.c
@@ -41,6 +41,7 @@
#include "gcstruct.h"
#include "gc.h"
#include "vmwgfx_saa.h"
+#include "wsbm_util.h"
#ifdef DRI2
typedef struct {
@@ -175,7 +176,7 @@ dri2_do_destroy_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer)
if (private->refcount == 1) {
struct vmwgfx_saa_pixmap *vpix = vmwgfx_saa_pixmap(private->pPixmap);
if (--vpix->hw_is_dri2_fronts == 0)
- vmwgfx_remove_dri2_list(vpix);
+ WSBMLISTDELINIT(&vpix->sync_x_head);
}
private->srf = NULL;
diff --git a/vmwgfx/vmwgfx_saa.c b/vmwgfx/vmwgfx_saa.c
index 5b84409..f733328 100644
--- a/vmwgfx/vmwgfx_saa.c
+++ b/vmwgfx/vmwgfx_saa.c
@@ -55,7 +55,7 @@ struct vmwgfx_saa {
uint32_t src_handle;
Bool can_optimize_dma;
void (*present_flush) (ScreenPtr pScreen);
- struct vmwgfx_saa_pixmap *dri2_flush_list;
+ struct _WsbmListHead sync_x_list;
};
static inline struct vmwgfx_saa *
@@ -426,57 +426,31 @@ vmwgfx_create_pixmap(struct saa_driver *driver, struct saa_pixmap *spix,
int w, int h, int depth,
unsigned int usage_hint, int bpp, int *new_pitch)
{
- *new_pitch = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
+ struct vmwgfx_saa_pixmap *vpix = to_vmwgfx_saa_pixmap(spix);
+ *new_pitch = ((w * bpp + FB_MASK) >> FB_SHIFT) * sizeof(FbBits);
+ WSBMINITLISTHEAD(&vpix->sync_x_head);
return TRUE;
}
-
-static void
-vmwgfx_add_dri2_list(struct vmwgfx_saa *vsaa,
- struct vmwgfx_saa_pixmap *vpix)
-{
- vpix->next_dri2 = vsaa->dri2_flush_list;
- vpix->prevnext_dri2 = &vsaa->dri2_flush_list;
- vsaa->dri2_flush_list = vpix;
- if (vpix->next_dri2)
- vpix->next_dri2->prevnext_dri2 = &vpix->next_dri2;
-}
-
-void
-vmwgfx_remove_dri2_list(struct vmwgfx_saa_pixmap *vpix)
-{
- if (vpix->next_dri2)
- vpix->next_dri2->prevnext_dri2 = vpix->prevnext_dri2;
-
- if (vpix->prevnext_dri2)
- *vpix->prevnext_dri2 = vpix->next_dri2;
-
- vpix->next_dri2 = NULL;
- vpix->prevnext_dri2 = NULL;
-}
-
-
void
vmwgfx_flush_dri2(ScreenPtr pScreen)
{
struct vmwgfx_saa *vsaa =
to_vmwgfx_saa(saa_get_driver(pScreen));
- struct vmwgfx_saa_pixmap *next = vsaa->dri2_flush_list;
- struct vmwgfx_saa_pixmap *cur;
+ struct _WsbmListHead *list, *next;
- while(next) {
- struct saa_pixmap *spix = &next->base;
+ WSBMLISTFOREACHSAFE(list, next, &vsaa->sync_x_list) {
+ struct vmwgfx_saa_pixmap *vpix =
+ WSBMLISTENTRY(list, struct vmwgfx_saa_pixmap, sync_x_head);
+ struct saa_pixmap *spix = &vpix->base;
PixmapPtr pixmap = spix->pixmap;
if (vmwgfx_upload_to_hw(&vsaa->driver, pixmap, &spix->dirty_shadow)) {
REGION_EMPTY(vsaa->pScreen, &spix->dirty_shadow);
- cur = next;
- next = next->next_dri2;
- vmwgfx_remove_dri2_list(cur);
- } else
- next = next->next_dri2;
+ WSBMLISTDELINIT(list);
+ }
}
}
@@ -498,7 +472,7 @@ vmwgfx_destroy_pixmap(struct saa_driver *driver, PixmapPtr pixmap)
*/
vmwgfx_pixmap_remove_present(vpix);
- vmwgfx_remove_dri2_list(vpix);
+ WSBMLISTDELINIT(&vpix->sync_x_head);
if (vpix->hw_is_dri2_fronts)
LogMessage(X_ERROR, "Incorrect dri2 front count.\n");
@@ -996,8 +970,8 @@ vmwgfx_operation_complete(struct saa_driver *driver,
return;
REGION_EMPTY(vsaa->pScreen, &spix->dirty_shadow);
} else {
- if (!vpix->prevnext_dri2)
- vmwgfx_add_dri2_list(vsaa, vpix);
+ if (WSBMLISTEMPTY(&vpix->sync_x_head))
+ WSBMLISTADDTAIL(&vpix->sync_x_head, &vsaa->sync_x_list);
}
}
}
@@ -1102,6 +1076,7 @@ vmwgfx_saa_init(ScreenPtr pScreen, int drm_fd, struct xa_tracker *xat,
vsaa->drm_fd = drm_fd;
vsaa->present_flush = present_flush;
vsaa->can_optimize_dma = FALSE;
+ WSBMINITLISTHEAD(&vsaa->sync_x_list);
vsaa->driver = vmwgfx_saa_driver;
if (!saa_driver_init(pScreen, &vsaa->driver))
diff --git a/vmwgfx/vmwgfx_saa.h b/vmwgfx/vmwgfx_saa.h
index 1a42cac..c7aae79 100644
--- a/vmwgfx/vmwgfx_saa.h
+++ b/vmwgfx/vmwgfx_saa.h
@@ -31,6 +31,7 @@
#include "saa.h"
#include <xa_tracker.h>
#include "vmwgfx_drmi.h"
+#include "wsbm_util.h"
#define VMWGFX_FLAG_FORCE_GMR (1 << 0) /* Create with GMR as backing store */
#define VMWGFX_FLAG_FORCE_SURFACE (1 << 1) /* Create with surface as backing store */
@@ -51,8 +52,7 @@ struct vmwgfx_saa_pixmap {
int scanout_refcnt;
uint32_t fb_id;
int hw_is_dri2_fronts;
- struct vmwgfx_saa_pixmap *next_dri2;
- struct vmwgfx_saa_pixmap **prevnext_dri2;
+ struct _WsbmListHead sync_x_head;
};
static inline struct vmwgfx_saa_pixmap *
diff --git a/vmwgfx/wsbm_util.h b/vmwgfx/wsbm_util.h
new file mode 100644
index 0000000..2a2613b
--- /dev/null
+++ b/vmwgfx/wsbm_util.h
@@ -0,0 +1,79 @@
+/*
+ * This file is not copyrighted.
+ */
+
+#ifndef _WSBM_UTIL_H_
+#define _WSBM_UTIL_H_
+
+#include <stddef.h>
+
+#ifndef containerOf
+#define containerOf(__item, __type, __field) \
+ ((__type *)(((char *) (__item)) - offsetof(__type, __field)))
+#endif
+
+struct _WsbmListHead
+{
+ struct _WsbmListHead *prev;
+ struct _WsbmListHead *next;
+};
+
+#define WSBMINITLISTHEAD(__item) \
+ do{ \
+ (__item)->prev = (__item); \
+ (__item)->next = (__item); \
+ } while (0)
+
+#define WSBMLISTADD(__item, __list) \
+ do { \
+ (__item)->prev = (__list); \
+ (__item)->next = (__list)->next; \
+ (__list)->next->prev = (__item); \
+ (__list)->next = (__item); \
+ } while (0)
+
+#define WSBMLISTADDTAIL(__item, __list) \
+ do { \
+ (__item)->next = (__list); \
+ (__item)->prev = (__list)->prev; \
+ (__list)->prev->next = (__item); \
+ (__list)->prev = (__item); \
+ } while(0)
+
+#define WSBMLISTDEL(__item) \
+ do { \
+ (__item)->prev->next = (__item)->next; \
+ (__item)->next->prev = (__item)->prev; \
+ } while(0)
+
+#define WSBMLISTDELINIT(__item) \
+ do { \
+ (__item)->prev->next = (__item)->next; \
+ (__item)->next->prev = (__item)->prev; \
+ (__item)->next = (__item); \
+ (__item)->prev = (__item); \
+ } while(0)
+
+#define WSBMLISTFOREACH(__item, __list) \
+ for((__item) = (__list)->next; (__item) != (__list); (__item) = (__item)->next)
+
+#define WSBMLISTFOREACHPREV(__item, __list) \
+ for((__item) = (__list)->prev; (__item) != (__list); (__item) = (__item)->prev)
+
+#define WSBMLISTFOREACHSAFE(__item, __next, __list) \
+ for((__item) = (__list)->next, (__next) = (__item)->next; \
+ (__item) != (__list); \
+ (__item) = (__next), (__next) = (__item)->next)
+
+#define WSBMLISTFOREACHPREVSAFE(__item, __prev, __list) \
+ for((__item) = (__list)->prev, (__prev) = (__item->prev); \
+ (__item) != (__list); \
+ (__item) = (__prev), (__prev) = (__item)->prev)
+
+#define WSBMLISTENTRY(__item, __type, __field) \
+ containerOf(__item, __type, __field)
+
+#define WSBMLISTEMPTY(__item) \
+ ((__item)->next == (__item))
+
+#endif