diff options
Diffstat (limited to 'vmwgfx')
-rw-r--r-- | vmwgfx/Makefile.am | 3 | ||||
-rw-r--r-- | vmwgfx/vmwgfx_dri2.c | 3 | ||||
-rw-r--r-- | vmwgfx/vmwgfx_saa.c | 55 | ||||
-rw-r--r-- | vmwgfx/vmwgfx_saa.h | 4 | ||||
-rw-r--r-- | vmwgfx/wsbm_util.h | 79 |
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 |