dri3: Switch texmaps to a linked list, from DRC/TurboVNC

This commit is contained in:
Lauri Kasanen 2024-03-14 13:04:50 +02:00
parent bb2d903113
commit 766a55d08f
No known key found for this signature in database

View File

@ -55,9 +55,12 @@ typedef struct gbm_pixmap gbm_pixmap;
static DevPrivateKeyRec dri3_pixmap_private_key; static DevPrivateKeyRec dri3_pixmap_private_key;
static struct timeval start; static struct timeval start;
#define MAX_TEXPIXMAPS 32 struct texpixmap {
static PixmapPtr texpixmaps[MAX_TEXPIXMAPS]; PixmapPtr pixmap;
static uint32_t num_texpixmaps; struct xorg_list entry;
};
static struct xorg_list texpixmaps;
static CARD32 update_texpixmaps(OsTimerPtr timer, CARD32 time, void *arg); static CARD32 update_texpixmaps(OsTimerPtr timer, CARD32 time, void *arg);
static OsTimerPtr texpixmaptimer; static OsTimerPtr texpixmaptimer;
@ -110,25 +113,21 @@ static gbm_pixmap *gbm_pixmap_get(PixmapPtr pixmap)
static void add_texpixmap(PixmapPtr pix) static void add_texpixmap(PixmapPtr pix)
{ {
uint32_t i; struct texpixmap *ptr;
for (i = 0; i < MAX_TEXPIXMAPS; i++) {
if (texpixmaps[i] == pix) xorg_list_for_each_entry(ptr, &texpixmaps, entry) {
if (ptr->pixmap == pix)
return; return;
} }
for (i = 0; i < MAX_TEXPIXMAPS; i++) { ptr = calloc(1, sizeof(struct texpixmap));
if (!texpixmaps[i]) { ptr->pixmap = pix;
texpixmaps[i] = pix; pix->refcnt++;
pix->refcnt++; xorg_list_append(&ptr->entry, &texpixmaps);
num_texpixmaps++;
// start if not running
if (!texpixmaptimer)
texpixmaptimer = TimerSet(NULL, 0, 16, update_texpixmaps, NULL);
return;
}
}
ErrorF("Max number of texpixmaps reached\n"); // start if not running
if (!texpixmaptimer)
texpixmaptimer = TimerSet(NULL, 0, 16, update_texpixmaps, NULL);
} }
static PixmapPtr static PixmapPtr
@ -313,38 +312,41 @@ void xvnc_sync_dri3_textures(void)
// This is called both from the global damage report and the timer, // This is called both from the global damage report and the timer,
// to account for cases that do not use the damage report. // to account for cases that do not use the damage report.
uint32_t i, y; uint32_t y;
gbm_pixmap *gp; gbm_pixmap *gp;
uint8_t *src, *dst; uint8_t *src, *dst;
uint32_t srcstride, dststride; uint32_t srcstride, dststride;
void *opaque = NULL; void *opaque = NULL;
struct texpixmap *ptr, *tmpptr;
for (i = 0; i < MAX_TEXPIXMAPS; i++) { // We may not be running on hw if there's a compositor using PRESENT on llvmpipe
if (!texpixmaps[i]) if (!driNode)
continue; return;
if (texpixmaps[i]->refcnt == 1) {
xorg_list_for_each_entry_safe(ptr, tmpptr, &texpixmaps, entry) {
if (ptr->pixmap->refcnt == 1) {
// We are the only user left, delete it // We are the only user left, delete it
texpixmaps[i]->drawable.pScreen->DestroyPixmap(texpixmaps[i]); ptr->pixmap->drawable.pScreen->DestroyPixmap(ptr->pixmap);
texpixmaps[i] = NULL; xorg_list_del(&ptr->entry);
num_texpixmaps--; free(ptr);
continue; continue;
} }
gp = gbm_pixmap_get(texpixmaps[i]); gp = gbm_pixmap_get(ptr->pixmap);
opaque = NULL; opaque = NULL;
dst = gbm_bo_map(gp->bo, 0, 0, dst = gbm_bo_map(gp->bo, 0, 0,
texpixmaps[i]->drawable.width, ptr->pixmap->drawable.width,
texpixmaps[i]->drawable.height, ptr->pixmap->drawable.height,
GBM_BO_TRANSFER_WRITE, &dststride, &opaque); GBM_BO_TRANSFER_WRITE, &dststride, &opaque);
if (!dst) { if (!dst) {
ErrorF("gbm map failed, errno %d\n", errno); ErrorF("gbm map failed, errno %d\n", errno);
continue; continue;
} }
srcstride = texpixmaps[i]->devKind; srcstride = ptr->pixmap->devKind;
src = texpixmaps[i]->devPrivate.ptr; src = ptr->pixmap->devPrivate.ptr;
for (y = 0; y < texpixmaps[i]->drawable.height; y++) { for (y = 0; y < ptr->pixmap->drawable.height; y++) {
memcpy(dst, src, srcstride); memcpy(dst, src, srcstride);
dst += dststride; dst += dststride;
src += srcstride; src += srcstride;
@ -358,7 +360,7 @@ static CARD32 update_texpixmaps(OsTimerPtr timer, CARD32 time, void *arg)
{ {
xvnc_sync_dri3_textures(); xvnc_sync_dri3_textures();
if (!num_texpixmaps) { if (xorg_list_is_empty(&texpixmaps)) {
TimerFree(texpixmaptimer); TimerFree(texpixmaptimer);
texpixmaptimer = NULL; texpixmaptimer = NULL;
return 0; return 0;
@ -387,6 +389,8 @@ void xvnc_init_dri3(void)
if (!priv.gbm) if (!priv.gbm)
FatalError("Failed to create gbm\n"); FatalError("Failed to create gbm\n");
xorg_list_init(&texpixmaps);
if (!dri3_screen_init(screenInfo.screens[0], &xvnc_dri3_info)) if (!dri3_screen_init(screenInfo.screens[0], &xvnc_dri3_info))
FatalError("Couldn't init dri3\n"); FatalError("Couldn't init dri3\n");
} }