driDrawable.c revision 90b17f1b
1/***************************************************************************** 2 * driDrawable.c: Lean Version of DRI utilities. 3 * 4 * Copyright (c) 2005 Thomas Hellstrom. All rights reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 * AUTHOR(S) OR COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 25#include <X11/Xlibint.h> 26#include <X11/Xutil.h> 27#include "xf86drm.h" 28#include "drm.h" 29#include "xf86dri.h" 30#include "drm_sarea.h" 31#include "driDrawable.h" 32 33static unsigned 34drawStamp(volatile drm_sarea_t * pSarea, int index) 35{ 36 return pSarea->drawableTable[index].stamp; 37} 38 39int 40getDRIDrawableInfoLocked(void *drawHash, Display * display, int screen, 41 Drawable draw, unsigned lockFlags, int drmFD, drm_context_t drmContext, 42 drmAddress sarea, Bool updateInfo, drawableInfo ** info, 43 unsigned long infoSize) 44{ 45 drawableInfo *drawInfo; 46 void *res; 47 drm_drawable_t drmDraw = 0; 48 volatile drm_sarea_t *pSarea = (drm_sarea_t *) sarea; 49 drm_clip_rect_t *clipFront, *clipBack; 50 51 int ret; 52 53 if (drmHashLookup(drawHash, (unsigned long)draw, &res)) { 54 55 /* 56 * The drawable is unknown to us. Create it and put it in the 57 * hash table. 58 */ 59 60 DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); 61 if (!uniDRICreateDrawable(display, screen, draw, &drmDraw)) { 62 DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); 63 return 1; 64 } 65 DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); 66 67 drawInfo = (drawableInfo *) malloc(infoSize); 68 if (!drawInfo) 69 return 1; 70 71 drawInfo->drmDraw = drmDraw; 72 drawInfo->stamp = 0; 73 drawInfo->clipFront = 0; 74 drawInfo->clipBack = 0; 75 76 drmHashInsert(drawHash, (unsigned long)draw, drawInfo); 77 78 } else { 79 drawInfo = res; 80 } 81 82 drawInfo->touched = FALSE; 83 while (!drawInfo->clipFront 84 || drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) { 85 86 /* 87 * The drawable has been touched since we last got info about it. 88 * obtain new info from the X server. 89 */ 90 91 drawInfo->touched = TRUE; 92 93 if (updateInfo || !drawInfo->clipFront) { 94 DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); 95 96 ret = uniDRIGetDrawableInfo(display, screen, draw, 97 &drawInfo->index, &drawInfo->stamp, &drawInfo->x, 98 &drawInfo->y, &drawInfo->w, &drawInfo->h, 99 &drawInfo->numClipFront, &clipFront, 100 &drawInfo->backX, &drawInfo->backY, 101 &drawInfo->numClipBack, &clipBack); 102 103 DRM_LIGHT_LOCK(drmFD, &pSarea->lock, drmContext); 104 105 /* 106 * Error. Probably the drawable is destroyed. Return error and old values. 107 */ 108 109 if (!ret) { 110 free(drawInfo); 111 drawInfo = NULL; 112 drmHashDelete(drawHash, (unsigned long)draw); 113 114 DRM_UNLOCK(drmFD, &pSarea->lock, drmContext); 115 uniDRIDestroyDrawable(display, screen, draw); 116 DRM_LOCK(drmFD, &pSarea->lock, drmContext, lockFlags); 117 118 return 1; 119 } 120 121 if (drawInfo->stamp != drawStamp(pSarea, drawInfo->index)) { 122 123 /* 124 * The info is already outdated. Sigh. Have another go. 125 */ 126 127 XFree(clipFront); 128 XFree(clipBack); 129 continue; 130 } 131 132 if (drawInfo->clipFront) 133 XFree(drawInfo->clipFront); 134 drawInfo->clipFront = clipFront; 135 if (drawInfo->clipBack) 136 XFree(drawInfo->clipBack); 137 drawInfo->clipBack = clipBack; 138 } else { 139 if (!drawInfo->clipFront) 140 drawInfo->clipFront = (drm_clip_rect_t *) ~ 0UL; 141 drawInfo->stamp = drawStamp(pSarea, drawInfo->index); 142 } 143 } 144 *info = drawInfo; 145 return 0; 146} 147 148void 149driDestroyHashContents(void *drawHash) 150{ 151 unsigned long key; 152 void *content; 153 drawableInfo *drawInfo; 154 155 if (drmHashFirst(drawHash, &key, &content) < 1) 156 return; 157 drawInfo = (drawableInfo *) content; 158 if (drawInfo->clipBack) 159 XFree(drawInfo->clipBack); 160 if (drawInfo->clipFront) 161 XFree(drawInfo->clipFront); 162 free(drawInfo); 163 while (drmHashNext(drawHash, &key, &content) == 1) { 164 drawInfo = (drawableInfo *) content; 165 if (drawInfo->clipBack) 166 XFree(drawInfo->clipBack); 167 if (drawInfo->clipFront) 168 XFree(drawInfo->clipFront); 169 free(drawInfo); 170 } 171 172 return; 173} 174