Bool DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable, void (*notify) (void *, void *), void *notify_data) { DRIDrawablePrivPtr pDRIDrawablePriv; if (pDrawable->type == DRAWABLE_WINDOW) { pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW((WindowPtr)pDrawable); } else if (pDrawable->type == DRAWABLE_PIXMAP) { pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP((PixmapPtr)pDrawable); } else { return FALSE; } if (pDRIDrawablePriv != NULL) { if (notify != NULL) { pDRIDrawablePriv->notifiers = x_hook_remove(pDRIDrawablePriv->notifiers, notify, notify_data); } if (--pDRIDrawablePriv->refCount <= 0) { /* This calls back to DRIDrawablePrivDelete which frees the private area */ FreeResourceByType(id, DRIDrawablePrivResType, FALSE); } } return TRUE; }
/* * The assumption is that this is called when the refCount of a surface * drops to <= 0, or the window/pixmap is destroyed. */ Bool DRIDrawablePrivDelete(pointer pResource, XID id) { DrawablePtr pDrawable = (DrawablePtr)pResource; DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen); DRIDrawablePrivPtr pDRIDrawablePriv = NULL; WindowPtr pWin = NULL; PixmapPtr pPix = NULL; if (pDrawable->type == DRAWABLE_WINDOW) { pWin = (WindowPtr)pDrawable; pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); } else if (pDrawable->type == DRAWABLE_PIXMAP) { pPix = (PixmapPtr)pDrawable; pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix); } if (pDRIDrawablePriv == NULL) { /* * We reuse __func__ and the resource type for the GLXPixmap code. * Attempt to free a pixmap buffer associated with the resource * if possible. */ return DRIFreePixmapImp(pDrawable); } if (pDRIDrawablePriv->drawableIndex != -1) { /* release drawable table entry */ pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL; } if (pDRIDrawablePriv->sid != 0) { DRISurfaceNotify(pDRIDrawablePriv->sid, AppleDRISurfaceNotifyDestroyed); } if (pDRIDrawablePriv->notifiers != NULL) x_hook_free(pDRIDrawablePriv->notifiers); free(pDRIDrawablePriv); if (pDrawable->type == DRAWABLE_WINDOW) { dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL); } else if (pDrawable->type == DRAWABLE_PIXMAP) { dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL); } --pDRIPriv->nrWindows; return TRUE; }
Bool DRIDrawablePrivDelete(pointer pResource, XID id) { DrawablePtr pDrawable = (DrawablePtr)pResource; DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen); DRIDrawablePrivPtr pDRIDrawablePriv = NULL; WindowPtr pWin = NULL; PixmapPtr pPix = NULL; if (pDrawable->type == DRAWABLE_WINDOW) { pWin = (WindowPtr)pDrawable; pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); } else if (pDrawable->type == DRAWABLE_PIXMAP) { pPix = (PixmapPtr)pDrawable; pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix); } if (pDRIDrawablePriv == NULL) { return DRIFreePixmapImp(pDrawable); } if (pDRIDrawablePriv->drawableIndex != -1) { /* release drawable table entry */ pDRIPriv->DRIDrawables[pDRIDrawablePriv->drawableIndex] = NULL; } if (pDRIDrawablePriv->sid != 0) { xp_destroy_surface(pDRIDrawablePriv->sid); x_hash_table_remove(surface_hash, x_cvt_uint_to_vptr(pDRIDrawablePriv->sid)); } if (pDRIDrawablePriv->notifiers != NULL) x_hook_free(pDRIDrawablePriv->notifiers); xfree(pDRIDrawablePriv); if (pDrawable->type == DRAWABLE_WINDOW) { dixSetPrivate(&pWin->devPrivates, DRIWindowPrivKey, NULL); } else if (pDrawable->type == DRAWABLE_PIXMAP) { dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, NULL); } --pDRIPriv->nrWindows; return TRUE; }
Bool DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable, void (*notify)(void *, void *), void *notify_data) { DRIDrawablePrivPtr pDRIDrawablePriv; if (pDrawable->type == DRAWABLE_WINDOW) { pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW((WindowPtr)pDrawable); } else if (pDrawable->type == DRAWABLE_PIXMAP) { pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP((PixmapPtr)pDrawable); } else { return FALSE; } if (pDRIDrawablePriv != NULL) { /* * This doesn't seem to be used, because notify is NULL in all callers. */ if (notify != NULL) { pDRIDrawablePriv->notifiers = x_hook_remove( pDRIDrawablePriv->notifiers, notify, notify_data); } --pDRIDrawablePriv->refCount; /* * Check if the drawable privates still have a reference to the * surface. */ if (pDRIDrawablePriv->refCount <= 0) { /* * This calls back to DRIDrawablePrivDelete which * frees the private area and dispatches events, if needed. */ FreeResourceByType(id, DRIDrawablePrivResType, FALSE); } } return TRUE; }
/* Return NULL if an error occurs. */ static DRIDrawablePrivPtr CreateSurfaceForPixmap(ScreenPtr pScreen, PixmapPtr pPix) { DRIDrawablePrivPtr pDRIDrawablePriv; pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix); if (pDRIDrawablePriv == NULL) { xp_error err; /* allocate a DRI Window Private record */ if (!(pDRIDrawablePriv = calloc(1, sizeof(*pDRIDrawablePriv)))) { return NULL; } pDRIDrawablePriv->pDraw = (DrawablePtr)pPix; pDRIDrawablePriv->pScreen = pScreen; pDRIDrawablePriv->refCount = 0; pDRIDrawablePriv->drawableIndex = -1; pDRIDrawablePriv->notifiers = NULL; /* Passing a null window id to Xplugin in 10.3+ asks for an accelerated offscreen surface. */ err = xp_create_surface(0, &pDRIDrawablePriv->sid); if (err != Success) { free(pDRIDrawablePriv); return NULL; } /* * The DRIUpdateSurface will be called to resize the surface * after this function, if the export is successful. */ /* save private off of preallocated index */ dixSetPrivate(&pPix->devPrivates, DRIPixmapPrivKey, pDRIDrawablePriv); } return pDRIDrawablePriv; }
Bool DRICreateSurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable, xp_client_id client_id, xp_surface_id *surface_id, unsigned int ret_key[2], void (*notify) (void *arg, void *data), void *notify_data) { DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen); DRIDrawablePrivPtr pDRIDrawablePriv; xp_window_id wid = 0; if (pDrawable->type == DRAWABLE_WINDOW) { WindowPtr pWin = (WindowPtr)pDrawable; pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin); if (pDRIDrawablePriv == NULL) { xp_error err; xp_window_changes wc; /* allocate a DRI Window Private record */ if (!(pDRIDrawablePriv = xalloc(sizeof(DRIDrawablePrivRec)))) { return FALSE; } pDRIDrawablePriv->pDraw = pDrawable; pDRIDrawablePriv->pScreen = pScreen; pDRIDrawablePriv->refCount = 0; pDRIDrawablePriv->drawableIndex = -1; pDRIDrawablePriv->notifiers = NULL; /* find the physical window */ wid = (xp_window_id) RootlessFrameForWindow(pWin, TRUE); if (wid == 0) { xfree(pDRIDrawablePriv); return FALSE; } /* allocate the physical surface */ err = xp_create_surface(wid, &pDRIDrawablePriv->sid); if (err != Success) { xfree(pDRIDrawablePriv); return FALSE; } /* Make it visible */ wc.stack_mode = XP_MAPPED_ABOVE; wc.sibling = 0; err = xp_configure_surface(pDRIDrawablePriv->sid, XP_STACKING, &wc); if (err != Success) { xp_destroy_surface(pDRIDrawablePriv->sid); xfree(pDRIDrawablePriv); return FALSE; } /* save private off of preallocated index */ pWin->devPrivates[DRIWindowPrivIndex].ptr = (pointer)pDRIDrawablePriv; } } #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030 else if (pDrawable->type == DRAWABLE_PIXMAP) { PixmapPtr pPix = (PixmapPtr)pDrawable; pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix); if (pDRIDrawablePriv == NULL) { xp_error err; /* allocate a DRI Window Private record */ if (!(pDRIDrawablePriv = xcalloc(1, sizeof(DRIDrawablePrivRec)))) { return FALSE; } pDRIDrawablePriv->pDraw = pDrawable; pDRIDrawablePriv->pScreen = pScreen; pDRIDrawablePriv->refCount = 0; pDRIDrawablePriv->drawableIndex = -1; pDRIDrawablePriv->notifiers = NULL; /* Passing a null window id to Xplugin in 10.3+ asks for an accelerated offscreen surface. */ err = xp_create_surface(0, &pDRIDrawablePriv->sid); if (err != Success) { xfree(pDRIDrawablePriv); return FALSE; } /* save private off of preallocated index */ pPix->devPrivates[DRIPixmapPrivIndex].ptr = (pointer)pDRIDrawablePriv; } } #endif else { /* for GLX 1.3, a PBuffer */ /* NOT_DONE */ return FALSE; } /* Finish initialization of new surfaces */ if (pDRIDrawablePriv->refCount == 0) { unsigned int key[2] = {0}; xp_error err; /* try to give the client access to the surface */ if (client_id != 0 && wid != 0) { err = xp_export_surface(wid, pDRIDrawablePriv->sid, client_id, key); if (err != Success) { xp_destroy_surface(pDRIDrawablePriv->sid); xfree(pDRIDrawablePriv); return FALSE; } } pDRIDrawablePriv->key[0] = key[0]; pDRIDrawablePriv->key[1] = key[1]; ++pDRIPriv->nrWindows; /* and stash it by surface id */ if (surface_hash == NULL) surface_hash = x_hash_table_new(NULL, NULL, NULL, NULL); x_hash_table_insert(surface_hash, (void *) pDRIDrawablePriv->sid, pDRIDrawablePriv); /* track this in case this window is destroyed */ AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable); /* Initialize shape */ DRIUpdateSurface(pDRIDrawablePriv, pDrawable); } pDRIDrawablePriv->refCount++; *surface_id = pDRIDrawablePriv->sid; if (ret_key != NULL) { ret_key[0] = pDRIDrawablePriv->key[0]; ret_key[1] = pDRIDrawablePriv->key[1]; } if (notify != NULL) { pDRIDrawablePriv->notifiers = x_hook_add(pDRIDrawablePriv->notifiers, notify, notify_data); } return TRUE; }