diff options
Diffstat (limited to 'nx-X11/lib/XvMC/hw/via/driDrawable.c')
-rw-r--r-- | nx-X11/lib/XvMC/hw/via/driDrawable.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/nx-X11/lib/XvMC/hw/via/driDrawable.c b/nx-X11/lib/XvMC/hw/via/driDrawable.c new file mode 100644 index 000000000..35934d89d --- /dev/null +++ b/nx-X11/lib/XvMC/hw/via/driDrawable.c @@ -0,0 +1,176 @@ +/***************************************************************************** + * driDrawable.c: Lean Version of DRI utilities. + * + * Copyright (c) 2005 Thomas Hellstrom. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <X11/Xlibint.h> +#include <X11/Xutil.h> +#include "xf86drm.h" +#include "drm.h" +#include "xf86dri.h" +#include "drm_sarea.h" +#include "driDrawable.h" + + +static unsigned +drawStamp(volatile drm_sarea_t *pSarea, int index) +{ + return pSarea->drawableTable[index].stamp; +} + +int +getDRIDrawableInfoLocked(void *drawHash, Display *display, int screen, Drawable draw, + unsigned lockFlags, int drmFD, drm_context_t drmContext, + drmAddress sarea, Bool updateInfo, drawableInfo **info, + unsigned long infoSize) +{ + drawableInfo *drawInfo; + void *res; + drm_drawable_t drmDraw=0; + volatile drm_sarea_t *pSarea = (drm_sarea_t *) sarea; + drm_clip_rect_t *clipFront, *clipBack; + + int ret; + + + if (drmHashLookup(drawHash, (unsigned long) draw, &res)) { + + /* + * The drawable is unknown to us. Create it and put it in the + * hash table. + */ + + DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); + if (!uniDRICreateDrawable(display, screen, draw, + &drmDraw)) { + DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); + return 1; + } + DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); + + + drawInfo = (drawableInfo *) malloc(infoSize); + if (!drawInfo) return 1; + + drawInfo->drmDraw = drmDraw; + drawInfo->stamp = 0; + drawInfo->clipFront = 0; + drawInfo->clipBack = 0; + + drmHashInsert( drawHash, (unsigned long) draw, drawInfo); + + } else { + drawInfo = res; + } + + + drawInfo->touched = FALSE; + while (!drawInfo->clipFront || drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) { + + /* + * The drawable has been touched since we last got info about it. + * obtain new info from the X server. + */ + + drawInfo->touched = TRUE; + + if (updateInfo || !drawInfo->clipFront) { + DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); + + ret = uniDRIGetDrawableInfo(display, screen, draw, + &drawInfo->index, &drawInfo->stamp, &drawInfo->x, + &drawInfo->y, &drawInfo->w, &drawInfo->h, + &drawInfo->numClipFront, &clipFront, + &drawInfo->backX, &drawInfo->backY, + &drawInfo->numClipBack, &clipBack); + + DRM_LIGHT_LOCK(drmFD, &pSarea->lock, drmContext); + + /* + * Error. Probably the drawable is destroyed. Return error and old values. + */ + + if (!ret) { + free(drawInfo); + drawInfo = NULL; + drmHashDelete(drawHash, (unsigned long) draw); + + DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); + uniDRIDestroyDrawable( display, screen, draw); + DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); + + return 1; + } + + if (drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) { + + /* + * The info is already outdated. Sigh. Have another go. + */ + + XFree(clipFront); + XFree(clipBack); + continue; + } + + if (drawInfo->clipFront) XFree(drawInfo->clipFront); + drawInfo->clipFront = clipFront; + if (drawInfo->clipBack) XFree(drawInfo->clipBack); + drawInfo->clipBack = clipBack; + } else { + if (!drawInfo->clipFront) drawInfo->clipFront = (drm_clip_rect_t *) ~0UL; + drawInfo->stamp = drawStamp(pSarea, drawInfo->index); + } + } + *info = drawInfo; + return 0; +} + +void +driDestroyHashContents(void *drawHash) +{ + unsigned long key; + void *content; + drawableInfo *drawInfo; + + + if (drmHashFirst(drawHash, &key, &content) < 1) + return; + drawInfo = (drawableInfo *) content; + if (drawInfo->clipBack) XFree(drawInfo->clipBack); + if (drawInfo->clipFront) XFree(drawInfo->clipFront); + free(drawInfo); + while(drmHashNext(drawHash, &key, &content) == 1) { + drawInfo = (drawableInfo *) content; + if (drawInfo->clipBack) XFree(drawInfo->clipBack); + if (drawInfo->clipFront) XFree(drawInfo->clipFront); + free(drawInfo); + } + + return ; +} + + |