Add offscreen GLX direct rendering with XDarwin's xpr backend (John

Harper).
This commit is contained in:
Torrey Lyons 2004-09-21 22:01:14 +00:00
parent 0514f8b656
commit 269012e601
4 changed files with 276 additions and 214 deletions

View File

@ -71,6 +71,7 @@ extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, void *
#define GLAQUA_DEBUG_MSG(a, ...)
#endif
// The following GL functions don't have an EXT suffix in OpenGL.framework.
GLboolean glAreTexturesResidentEXT(GLsizei a, const GLuint *b, GLboolean *c) {
return glAreTexturesResident(a, b, c);
@ -213,7 +214,8 @@ static GLboolean glAquaDestroyContext(__GLcontext *gc)
{
x_list *lst;
GLAQUA_DEBUG_MSG("glAquaDestroyContext (ctx 0x%x)\n", gc->ctx);
GLAQUA_DEBUG_MSG("glAquaDestroyContext (ctx 0x%x)\n",
(unsigned int) gc->ctx);
if (gc != NULL)
{
@ -240,7 +242,7 @@ static GLboolean glAquaLoseCurrent(__GLcontext *gc)
{
CGLError gl_err;
GLAQUA_DEBUG_MSG("glAquaLoseCurrent (ctx 0x%x)\n", gc->ctx);
GLAQUA_DEBUG_MSG("glAquaLoseCurrent (ctx 0x%x)\n", (unsigned int) gc->ctx);
gl_err = CGLSetCurrentContext(NULL);
if (gl_err != 0)
@ -308,35 +310,32 @@ static void unattach(__GLcontext *gc)
static void attach(__GLcontext *gc, __GLdrawablePrivate *glPriv)
{
__GLXdrawablePrivate *glxPriv;
GLAquaDrawableRec *aquaPriv;
DrawablePtr pDraw;
glxPriv = (__GLXdrawablePrivate *)glPriv->other;
if (glxPriv->type == DRAWABLE_WINDOW)
{
WindowPtr pWin = (WindowPtr) glxPriv->pDraw;
GLAquaDrawableRec *aquaPriv = (GLAquaDrawableRec *)glPriv->private;
x_list *lst;
aquaPriv = (GLAquaDrawableRec *)glPriv->private;
pDraw = glxPriv->pDraw;
if (aquaPriv->sid == 0)
{
if (!quartzProcs->CreateSurface(pWin->drawable.pScreen,
pWin->drawable.id, &pWin->drawable,
if (!quartzProcs->CreateSurface(pDraw->pScreen, pDraw->id, pDraw,
0, &aquaPriv->sid, NULL,
surface_notify, aquaPriv))
{
return;
}
aquaPriv->pDraw = &pWin->drawable;
aquaPriv->pDraw = pDraw;
}
if (!gc->isAttached || gc->sid != aquaPriv->sid)
{
x_list *lst;
if (xp_attach_gl_context(gc->ctx, aquaPriv->sid) != Success)
{
quartzProcs->DestroySurface(pWin->drawable.pScreen,
pWin->drawable.id, &pWin->drawable,
quartzProcs->DestroySurface(pDraw->pScreen, pDraw->id, pDraw,
surface_notify, aquaPriv);
if (surface_hash != NULL)
x_hash_table_remove(surface_hash, (void *) aquaPriv->sid);
@ -357,13 +356,8 @@ static void attach(__GLcontext *gc, __GLdrawablePrivate *glPriv)
x_hash_table_insert(surface_hash, (void *) gc->sid, lst);
}
GLAQUA_DEBUG_MSG("attached 0x%x to 0x%x\n", pWin->drawable.id,
aquaPriv->sid);
}
} else {
GLAQUA_DEBUG_MSG("attach: attach to non-window unimplemented\n");
CGLClearDrawable(gc->ctx);
gc->isAttached = FALSE;
GLAQUA_DEBUG_MSG("attached 0x%x to 0x%x\n", (unsigned int) pDraw->id,
(unsigned int) aquaPriv->sid);
}
}
@ -372,7 +366,7 @@ static GLboolean glAquaMakeCurrent(__GLcontext *gc)
__GLdrawablePrivate *glPriv = gc->interface.imports.getDrawablePrivate(gc);
CGLError gl_err;
GLAQUA_DEBUG_MSG("glAquaMakeCurrent (ctx 0x%x)\n", gc->ctx);
GLAQUA_DEBUG_MSG("glAquaMakeCurrent (ctx 0x%x)\n", (unsigned int) gc->ctx);
attach(gc, glPriv);
@ -408,7 +402,8 @@ static GLboolean glAquaForceCurrent(__GLcontext *gc)
{
CGLError gl_err;
GLAQUA_DEBUG_MSG("glAquaForceCurrent (ctx 0x%x)\n", gc->ctx);
GLAQUA_DEBUG_MSG("glAquaForceCurrent (ctx 0x%x)\n",
(unsigned int) gc->ctx);
gl_err = CGLSetCurrentContext(gc->ctx);
if (gl_err != 0)
@ -518,7 +513,7 @@ static CGLPixelFormatObj makeFormat(__GLcontextModes *mode)
if (gl_err != 0)
ErrorF("CGLChoosePixelFormat error: %s\n", CGLErrorString(gl_err));
GLAQUA_DEBUG_MSG("makeFormat done (0x%x)\n", result);
GLAQUA_DEBUG_MSG("makeFormat done (0x%x)\n", (unsigned int) result);
return result;
}
@ -782,6 +777,7 @@ static __GLXvisualConfig NullConfig = {
0 /* transparentIndex */
};
static inline int count_bits(uint32_t x)
{
x = x - ((x >> 1) & 0x55555555);
@ -866,8 +862,8 @@ static Bool init_visuals(int *nvisualp, VisualPtr *visualp,
for (i = 0; i < numVisuals; i++) {
int count;
count = ((pVisual[i].class == TrueColor
|| pVisual[i].class == DirectColor)
count = ((pVisual[i].class == TrueColor ||
pVisual[i].class == DirectColor)
? numRGBconfigs : numCIconfigs);
if (count == 0)
count = 1; /* preserve the existing visual */
@ -1162,8 +1158,8 @@ static Bool glAquaInitVisuals(VisualPtr *visualp, DepthPtr *depthp,
{
GLAQUA_DEBUG_MSG("glAquaInitVisuals\n");
if (0 == numConfigs) /* if no configs */
glAquaInitVisualConfigs(); /* ensure the visula configs are setup */
if (numConfigs == 0) /* if no configs */
glAquaInitVisualConfigs(); /* ensure the visual configs are setup */
/*
* Setup the visuals supported by this particular screen.

View File

@ -66,8 +66,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#include "x-hash.h"
#include "x-hook.h"
#include <AvailabilityMacros.h>
static int DRIScreenPrivIndex = -1;
static int DRIWindowPrivIndex = -1;
static int DRIPixmapPrivIndex = -1;
static RESTYPE DRIDrawablePrivResType;
@ -264,12 +267,15 @@ DRIExtensionInit(void)
DRIGeneration = serverGeneration;
}
/* Allocate a window private index with a zero sized private area for
/*
* Allocate a window private index with a zero sized private area for
* each window, then should a window become a DRI window, we'll hang
* a DRIWindowPrivateRec off of this private index.
* a DRIWindowPrivateRec off of this private index. Do same for pixmaps.
*/
if ((DRIWindowPrivIndex = AllocateWindowPrivateIndex()) < 0)
return FALSE;
if ((DRIPixmapPrivIndex = AllocatePixmapPrivateIndex()) < 0)
return FALSE;
DRIDrawablePrivResType = CreateNewResourceType(DRIDrawablePrivDelete);
@ -315,15 +321,24 @@ DRIAuthConnection(ScreenPtr pScreen, unsigned int magic)
}
static void
DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv, WindowPtr pWin)
DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv, DrawablePtr pDraw)
{
WindowPtr pTopWin;
xp_window_changes wc;
unsigned int flags = 0;
if (pDRIDrawablePriv->sid == 0)
return;
pTopWin = TopLevelParent(pWin);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
wc.depth = (pDraw->bitsPerPixel == 32 ? XP_DEPTH_ARGB8888
: pDraw->bitsPerPixel == 16 ? XP_DEPTH_RGB555 : XP_DEPTH_NIL);
if (wc.depth != XP_DEPTH_NIL)
flags |= XP_DEPTH;
#endif
if (pDraw->type == DRAWABLE_WINDOW) {
WindowPtr pWin = (WindowPtr) pDraw;
WindowPtr pTopWin = TopLevelParent(pWin);
wc.x = pWin->drawable.x - (pTopWin->drawable.x - pTopWin->borderWidth);
wc.y = pWin->drawable.y - (pTopWin->drawable.y - pTopWin->borderWidth);
@ -336,7 +351,18 @@ DRIUpdateSurface(DRIDrawablePrivPtr pDRIDrawablePriv, WindowPtr pWin)
wc.shape_tx = - (pTopWin->drawable.x - pTopWin->borderWidth);
wc.shape_ty = - (pTopWin->drawable.y - pTopWin->borderWidth);
xp_configure_surface(pDRIDrawablePriv->sid, XP_BOUNDS | XP_SHAPE, &wc);
flags |= XP_BOUNDS | XP_SHAPE;
} else if (pDraw->type == DRAWABLE_PIXMAP) {
wc.x = 0;
wc.y = 0;
wc.width = pDraw->width;
wc.height = pDraw->height;
wc.bit_gravity = XP_GRAVITY_NONE;
flags |= XP_BOUNDS;
}
xp_configure_surface(pDRIDrawablePriv->sid, flags, &wc);
}
Bool
@ -347,18 +373,14 @@ DRICreateSurface (ScreenPtr pScreen, Drawable id,
{
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pScreen);
DRIDrawablePrivPtr pDRIDrawablePriv;
WindowPtr pWin;
xp_window_id wid = 0;
if (pDrawable->type == DRAWABLE_WINDOW) {
pWin = (WindowPtr)pDrawable;
if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
pDRIDrawablePriv->refCount++;
}
else {
xp_window_id wid;
xp_surface_id sid;
WindowPtr pWin = (WindowPtr)pDrawable;
pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
if (pDRIDrawablePriv == NULL) {
xp_error err;
unsigned int key[2];
xp_window_changes wc;
/* allocate a DRI Window Private record */
@ -366,6 +388,12 @@ DRICreateSurface (ScreenPtr pScreen, Drawable id,
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) {
@ -374,79 +402,114 @@ DRICreateSurface (ScreenPtr pScreen, Drawable id,
}
/* allocate the physical surface */
err = xp_create_surface (wid, &sid);
err = xp_create_surface(wid, &pDRIDrawablePriv->sid);
if (err != Success) {
xfree(pDRIDrawablePriv);
return FALSE;
}
/* try to give the client access to the surface */
if (client_id != 0)
{
err = xp_export_surface (wid, sid, client_id, key);
if (err != Success) {
xp_destroy_surface (sid);
xfree (pDRIDrawablePriv);
return FALSE;
}
}
/* Make it visible */
wc.stack_mode = XP_MAPPED_ABOVE;
wc.sibling = 0;
err = xp_configure_surface (sid, XP_STACKING, &wc);
err = xp_configure_surface(pDRIDrawablePriv->sid, XP_STACKING, &wc);
if (err != Success)
{
xp_destroy_surface (sid);
xp_destroy_surface(pDRIDrawablePriv->sid);
xfree(pDRIDrawablePriv);
return FALSE;
}
/* add it to the list of DRI drawables for this screen */
pDRIDrawablePriv->sid = sid;
/* 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 = 1;
pDRIDrawablePriv->refCount = 0;
pDRIDrawablePriv->drawableIndex = -1;
pDRIDrawablePriv->key[0] = key[0];
pDRIDrawablePriv->key[1] = key[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 */
pWin->devPrivates[DRIWindowPrivIndex].ptr =
(pointer)pDRIDrawablePriv;
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 *) sid, pDRIDrawablePriv);
x_hash_table_insert(surface_hash,
(void *) pDRIDrawablePriv->sid, pDRIDrawablePriv);
/* track this in case this window is destroyed */
AddResource(id, DRIDrawablePrivResType, (pointer)pWin);
AddResource(id, DRIDrawablePrivResType, (pointer)pDrawable);
/* Initialize shape */
DRIUpdateSurface (pDRIDrawablePriv, pWin);
DRIUpdateSurface(pDRIDrawablePriv, pDrawable);
}
if (notify != NULL) {
pDRIDrawablePriv->notifiers
= x_hook_add (pDRIDrawablePriv->notifiers,
notify, notify_data);
}
pDRIDrawablePriv->refCount++;
*surface_id = pDRIDrawablePriv->sid;
if (ret_key != NULL)
{
if (ret_key != NULL) {
ret_key[0] = pDRIDrawablePriv->key[0];
ret_key[1] = pDRIDrawablePriv->key[1];
}
}
else { /* pixmap (or for GLX 1.3, a PBuffer) */
/* NOT_DONE */
return FALSE;
if (notify != NULL) {
pDRIDrawablePriv->notifiers = x_hook_add(pDRIDrawablePriv->notifiers,
notify, notify_data);
}
return TRUE;
@ -457,16 +520,18 @@ DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
void (*notify) (void *, void *), void *notify_data)
{
DRIDrawablePrivPtr pDRIDrawablePriv;
WindowPtr pWin;
if (pDrawable->type == DRAWABLE_WINDOW) {
pWin = (WindowPtr)pDrawable;
pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
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,
if (notify != NULL) {
pDRIDrawablePriv->notifiers = x_hook_remove(pDRIDrawablePriv->notifiers,
notify, notify_data);
}
if (--pDRIDrawablePriv->refCount <= 0) {
@ -475,11 +540,6 @@ DRIDestroySurface(ScreenPtr pScreen, Drawable id, DrawablePtr pDrawable,
FreeResourceByType(id, DRIDrawablePrivResType, FALSE);
}
}
}
else { /* pixmap (or for GLX 1.3, a PBuffer) */
/* NOT_DONE */
return FALSE;
}
return TRUE;
}
@ -489,12 +549,20 @@ DRIDrawablePrivDelete(pointer pResource, XID id)
{
DrawablePtr pDrawable = (DrawablePtr)pResource;
DRIScreenPrivPtr pDRIPriv = DRI_SCREEN_PRIV(pDrawable->pScreen);
DRIDrawablePrivPtr pDRIDrawablePriv;
WindowPtr pWin;
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 FALSE;
if (pDRIDrawablePriv->drawableIndex != -1) {
/* release drawable table entry */
@ -510,14 +578,14 @@ DRIDrawablePrivDelete(pointer pResource, XID id)
x_hook_free(pDRIDrawablePriv->notifiers);
xfree(pDRIDrawablePriv);
if (pDrawable->type == DRAWABLE_WINDOW) {
pWin->devPrivates[DRIWindowPrivIndex].ptr = NULL;
} else if (pDrawable->type == DRAWABLE_PIXMAP) {
pPix->devPrivates[DRIPixmapPrivIndex].ptr = NULL;
}
--pDRIPriv->nrWindows;
}
else { /* pixmap (or for GLX 1.3, a PBuffer) */
/* NOT_DONE */
return FALSE;
}
return TRUE;
}
@ -539,7 +607,6 @@ DRIWindowExposures(WindowPtr pWin, RegionPtr prgn, RegionPtr bsreg)
pDRIPriv->wrap.WindowExposures = pScreen->WindowExposures;
pScreen->WindowExposures = DRIWindowExposures;
}
void
@ -552,7 +619,7 @@ DRICopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
if (pDRIPriv->nrWindows > 0) {
pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin);
if (pDRIDrawablePriv != NULL) {
DRIUpdateSurface (pDRIDrawablePriv, pWin);
DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable);
}
}
@ -621,7 +688,7 @@ DRIClipNotify(WindowPtr pWin, int dx, int dy)
DRIDrawablePrivPtr pDRIDrawablePriv;
if ((pDRIDrawablePriv = DRI_DRAWABLE_PRIV_FROM_WINDOW(pWin))) {
DRIUpdateSurface (pDRIDrawablePriv, pWin);
DRIUpdateSurface(pDRIDrawablePriv, &pWin->drawable);
}
if (pDRIPriv->wrap.ClipNotify) {

View File

@ -36,6 +36,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/* Prototypes for AppleDRI functions */
#ifndef _DRI_H_
#define _DRI_H_
#include "Xdefs.h"
#include "scrnintstr.h"
@ -125,6 +126,4 @@ extern void DRIQueryVersion(int *majorVersion,
int *minorVersion,
int *patchVersion);
#define _DRI_H_
#endif

View File

@ -49,7 +49,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#define DRI_DRAWABLE_PRIV_FROM_PIXMAP(pPix) \
((DRIPixmapPrivIndex < 0) ? \
NULL : \
((DRIDrawablePrivPtr)((pPix)->devPrivates[DRIWindowPrivIndex].ptr)))
((DRIDrawablePrivPtr)((pPix)->devPrivates[DRIPixmapPrivIndex].ptr)))
typedef struct _DRIDrawablePrivRec
{